<commit_before>/* eslint react/jsx-no-bind: 0 */

import React from 'react';
import IconButton from './announcement_icon_button';

const musicList = [
  { name: 'Listen.moe', url: 'https://listen.moe/stream' },
  { name: 'AnimeNfo Radio', url: 'http://itori.animenfo.com:443/;' },
  { name: 'LoFi hip hop Radio', url: 'http://hyades.shoutca.st:8043/stream' },
  { name: 'Linn Classical', url: 'http://89.16.185.174:8004/stream' },
  { name: 'Linn Jazz', url: 'http://89.16.185.174:8000/stream' },
  { name: 'canal-jazz.eu', url: 'http://91.121.59.45:10024/stream' },
  { name: 'Poolside.fm', url: 'http://stream.radio.co/s98f81d47e/listen' },
  { name: 'Drum \'n Bass', sub: 'dubplate.fm', url: 'http://sc2.dubplate.fm:5000/DnB/192' },
  { name: 'FUTURE-BASS-MIX', url: 'http://stream.zenolive.com/am16uk1f4k5tv' },
  {
    name: 'TOP 40 RU',
    sub: 'European Hit Radio',
    url: 'http://stream.europeanhitradio.com:8000/Stream_35.aac',
  },
  {
    name: 'REMIXES RU',
    sub: 'European Hit Radio',
    url: 'http://stream.europeanhitradio.com:8000/Stream_33.aac',
  },
  { name: 'FMHIPHOP.COM', url: 'http://149.56.175.167:5708/;' },
  { name: 'Vapor.fm', url: 'https://vapor.fm:8000/stream' },
];

export default class Music extends React.PureComponent {

  state = {
    audio: new Audio(),
    name: '',
    isPlaying: false,
  };

  musicTogglePlay() {
    const { audio, name, isPlaying } = this.state;

    if (!name) return this.musicChangeSrc(0);

    this.setState({ isPlaying: !isPlaying });
    return isPlaying ? audio.pause() : audio.play();
  }

  musicChangeSrc(index) {
    const { audio } = this.state;

    audio.src = musicList[index].url;
    audio.play();
    this.setState({ name: musicList[index].name, isPlaying: true });
  }

  render () {
    const { name, isPlaying } = this.state;

    return (

        {isPlaying ? name : 'Not Playing'}
        <IconButton icon={isPlaying ? 'pause' : 'play'} onClick={() => this.musicTogglePlay()} size={17}  title='Enjoy Kirishima Music!' />

          {musicList.map((item, index) =>
 this.musicChangeSrc(index)}>{item.name}
)}

    );
  }

}
<commit_msg>fix web radio<commit_after>/* eslint react/jsx-no-bind: 0 */

import React from 'react';
import IconButton from './announcement_icon_button';

const musicList = [
  { name: 'Listen.moe', url: 'https://listen.moe/stream' },
  { name: 'AnimeNfo Radio', url: 'https://itori.animenfo.com:443/;' },
  { name: 'LoFi hip hop Radio', url: 'https://hyades.shoutca.st:8043/stream' },
  { name: 'Linn Classical', url: 'https://89.16.185.174:8004/stream' },
  { name: 'Linn Jazz', url: 'https://89.16.185.174:8000/stream' },
  { name: 'canal-jazz.eu', url: 'https://91.121.59.45:10024/stream' },
  { name: 'Poolside.fm', url: 'https://stream.radio.co/s98f81d47e/listen' },
  { name: 'Drum \'n Bass', sub: 'dubplate.fm', url: 'https://sc2.dubplate.fm:5000/DnB/192' },
  { name: 'FUTURE-BASS-MIX', url: 'https://stream.zenolive.com/am16uk1f4k5tv' },
  {
    name: 'TOP 40 RU',
    sub: 'European Hit Radio',
    url: 'https://stream.europeanhitradio.com:8000/Stream_35.aac',
  },
  {
    name: 'REMIXES RU',
    sub: 'European Hit Radio',
    url: 'https://stream.europeanhitradio.com:8000/Stream_33.aac',
  },
  { name: 'FMHIPHOP.COM', url: 'https://149.56.175.167:5708/;' },
  { name: 'Vapor.fm', url: 'https://vapor.fm:8000/stream' },
];

export default class Music extends React.PureComponent {

  state = {
    audio: new Audio(),
    name: '',
    isPlaying: false,
  };

  musicTogglePlay() {
    const { audio, name, isPlaying } = this.state;

    if (!name) return this.musicChangeSrc(0);

    this.setState({ isPlaying: !isPlaying });
    return isPlaying ? audio.pause() : audio.play();
  }

  musicChangeSrc(index) {
    const { audio } = this.state;

    audio.src = musicList[index].url;
    audio.play();
    this.setState({ name: musicList[index].name, isPlaying: true });
  }

  render () {
    const { name, isPlaying } = this.state;

    return (

        {isPlaying ? name : 'Not Playing'}
        <IconButton icon={isPlaying ? 'pause' : 'play'} onClick={() => this.musicTogglePlay()} size={17}  title='Enjoy Kirishima Music!' />

          {musicList.map((item, index) =>
 this.musicChangeSrc(index)}>{item.name}
)}

    );
  }

}
<|endoftext|>


<commit_before>"use strict";
var ORG = window.ORG ? window.ORG : {};
ORG.NETMELODY = ORG.NETMELODY ? ORG.NETMELODY : {};
ORG.NETMELODY.CIEYE = {};

ORG.NETMELODY.CIEYE.newBuildWidget = function(buildJson) {
    var buildDiv = $("

").addClass("progress-bar"),
        barDiv   = $("

");

    function updateProgress(percent) {
        barDiv.attr("style", "width: " + percent + "%");
    }

    function updateStatus(status) {
        barDiv.removeClass();
        barDiv.addClass(status);
    }

    function refresh(newBuildJson) {
        updateProgress(newBuildJson.progress);
        updateStatus(newBuildJson.status);
    }

    function initialise() {
        buildDiv.append(barDiv);
        refresh(buildJson);
    }

    initialise();

    return {
        "updateFrom": refresh,
        "getContent": function() { return buildDiv; }
    };
};

ORG.NETMELODY.CIEYE.newMugshotWidget = function(sponsorJson, sizeCalculator) {
    var image;

    function resizeImage() {
        var maxSize = sizeCalculator(),
            width = image.width(),
            height = image.height();

        if (width > height) {
            image.height(height * maxSize / width);
            image.width(maxSize);
        }
        else {
            image.width(width * maxSize / height);
            image.height(maxSize);
        }
    }

    function initialise() {
        image = $("").attr({ "src": sponsorJson.picture,
                                        "title": sponsorJson.name })
                                .load(resizeImage);
    }

    initialise();

    return {
        "getContent": function() { return image; },
        "refresh": resizeImage
    };
};

ORG.NETMELODY.CIEYE.newTargetWidget = function(targetJson) {
    var currentTargetJson = { builds:[] },
        targetDiv = $("

"),
        titleSpan = $(""),
        sponsorDiv = $("

").addClass("sponsors"),
        buildsDiv = $("

"),
        sponsorMugshots = {};

    function sortedSponsors(unsortedSponsors) {
        return unsortedSponsors.sort(function(a, b) {
            return (a.name === b.name) ? 0 : (a.name < b.name) ? -1 : 1;
        });
    }

    function calculateImageSize() {
        return parseInt(titleSpan.css("font-size"), 10) + 5;
    }

    function refresh(newTargetJson) {
        var lastTargetJson = currentTargetJson;

        currentTargetJson = newTargetJson;
        if (lastTargetJson.status !== newTargetJson.status) {
            if (lastTargetJson.status) {
                targetDiv.removeClass(lastTargetJson.status);
            }
            targetDiv.addClass(newTargetJson.status);
        }

        buildsDiv.empty();
        $.each(newTargetJson.builds, function(index, buildJson) {
            buildsDiv.append(ORG.NETMELODY.CIEYE.newBuildWidget(buildJson).getContent());
        });

        if (newTargetJson.builds.length === 0) {
            targetDiv.removeClass("building");
        }
        else {
            targetDiv.addClass("building");
        }

        if (newTargetJson.builds.length === 0 && newTargetJson.status === "GREEN") {
            sponsorDiv.empty();
            return;
        }

        $.each(sortedSponsors(newTargetJson.sponsors), function(index, sponsorJson) {
            if (!sponsorMugshots[sponsorJson.picture]) {
                sponsorMugshots[sponsorJson.picture] = ORG.NETMELODY.CIEYE.newMugshotWidget(sponsorJson, calculateImageSize);
            }
            sponsorDiv.append(sponsorMugshots[sponsorJson.picture].getContent());
        });
    }

    function clickable() {
        return (targetDiv.css("cursor") === "pointer");
    }

    function viewDetails() {
        window.open(targetJson.webUrl);
    }

    function markAsBeingFixed() {
        window.alert("Sorry, not implemented yet.");
    }

    function initialise() {
        titleSpan.text(targetJson.name);
        targetDiv.append(titleSpan);
        targetDiv.append(sponsorDiv);
        targetDiv.append(buildsDiv);
        targetDiv.addClass("target");
        targetDiv.popupMenu([{"label": "View Details", "handler": viewDetails},
                             {"label": "Mark as Being Fixed", "handler": markAsBeingFixed}],
                            clickable);
        refresh(targetJson);
    }

    initialise();

    return {
        "updateFrom": refresh,
        "getContent": function() { return targetDiv; }
    };
};

ORG.NETMELODY.CIEYE.newRadiatorWidget = function() {
    var radiatorDiv = $("

"),
        targetWidgets = {};

    function refresh(targetGroupJson) {
        var targets = targetGroupJson.targets.sort(function(a, b) {
                if (a.status === b.status) {
                    if (a.builds.length === b.builds.length) {
                        return (a.name  b.builds.length) ? -1 : 1;
                }
                return (a.status === "BROKEN" || b.status === "GREEN") ? -1 : 1;
            }),
            deadTargetWidgets = $.extend({}, targetWidgets);

        $.each(targets, function(index, targetJson) {
            if (targetWidgets[targetJson.id]) {
                targetWidgets[targetJson.id].updateFrom(targetJson);
                delete deadTargetWidgets[targetJson.id];
            }
            else {
                targetWidgets[targetJson.id] = ORG.NETMELODY.CIEYE.newTargetWidget(targetJson);
            }
            radiatorDiv.append(targetWidgets[targetJson.id].getContent());
        });
        $.each(deadTargetWidgets, function(index, deadTargetWidget) {
            radiatorDiv.remove(deadTargetWidget.getContent());
        });
    }

    return {
        "updateFrom": refresh,
        "getContent": function() { return radiatorDiv; }
    };
};

ORG.NETMELODY.CIEYE.scheduler = function(browser) {
    var protector;

    function reloadPage() {
        browser.location.reload();
    }

    function safeCallableFor(callback) {
        return function() {
            try {
                callback();
            }
            catch (ex) {
                // ignore
            }
        };
    }

    function repeat(callback, interval) {
        browser.setInterval(safeCallableFor(callback), interval);
    }

    function guard(timeout) {
        if (!protector) {
            protector = browser.setTimeout(reloadPage, timeout);
        }
    }

    function relax() {
        if (protector) {
            browser.clearTimeout(protector);
            protector = null;
        }
    }

    return {
        "repeat": repeat,
        "guard": guard,
        "relax": relax
    };
};

ORG.NETMELODY.CIEYE.newRadiator = function(radiatorDiv, scheduler) {
    var radiatorWidget = ORG.NETMELODY.CIEYE.newRadiatorWidget();

    function refresh() {
        scheduler.guard(30000);
        $.getJSON("landscapeobservation.json", function(targetList) {
            scheduler.relax();
            radiatorWidget.updateFrom(targetList);
        });
    }

    function startup() {
        radiatorDiv.append(radiatorWidget.getContent());
        refresh();
        scheduler.repeat(refresh, 2000);
    }

    return {
        "start": startup
    };
};

$(document).ready(function() {
    var scheduler = ORG.NETMELODY.CIEYE.scheduler(window);
    ORG.NETMELODY.CIEYE.newRadiator($("#radiator"), scheduler).start();
});
<commit_msg>rank similar targets with most recently built first<commit_after>"use strict";
var ORG = window.ORG ? window.ORG : {};
ORG.NETMELODY = ORG.NETMELODY ? ORG.NETMELODY : {};
ORG.NETMELODY.CIEYE = {};

ORG.NETMELODY.CIEYE.newBuildWidget = function(buildJson) {
    var buildDiv = $("

").addClass("progress-bar"),
        barDiv   = $("

");

    function updateProgress(percent) {
        barDiv.attr("style", "width: " + percent + "%");
    }

    function updateStatus(status) {
        barDiv.removeClass();
        barDiv.addClass(status);
    }

    function refresh(newBuildJson) {
        updateProgress(newBuildJson.progress);
        updateStatus(newBuildJson.status);
    }

    function initialise() {
        buildDiv.append(barDiv);
        refresh(buildJson);
    }

    initialise();

    return {
        "updateFrom": refresh,
        "getContent": function() { return buildDiv; }
    };
};

ORG.NETMELODY.CIEYE.newMugshotWidget = function(sponsorJson, sizeCalculator) {
    var image;

    function resizeImage() {
        var maxSize = sizeCalculator(),
            width = image.width(),
            height = image.height();

        if (width > height) {
            image.height(height * maxSize / width);
            image.width(maxSize);
        }
        else {
            image.width(width * maxSize / height);
            image.height(maxSize);
        }
    }

    function initialise() {
        image = $("").attr({ "src": sponsorJson.picture,
                                        "title": sponsorJson.name })
                                .load(resizeImage);
    }

    initialise();

    return {
        "getContent": function() { return image; },
        "refresh": resizeImage
    };
};

ORG.NETMELODY.CIEYE.newTargetWidget = function(targetJson) {
    var currentTargetJson = { builds:[] },
        targetDiv = $("

"),
        titleSpan = $(""),
        sponsorDiv = $("

").addClass("sponsors"),
        buildsDiv = $("

"),
        sponsorMugshots = {};

    function sortedSponsors(unsortedSponsors) {
        return unsortedSponsors.sort(function(a, b) {
            return (a.name === b.name) ? 0 : (a.name < b.name) ? -1 : 1;
        });
    }

    function calculateImageSize() {
        return parseInt(titleSpan.css("font-size"), 10) + 5;
    }

    function refresh(newTargetJson) {
        var lastTargetJson = currentTargetJson;

        currentTargetJson = newTargetJson;
        if (lastTargetJson.status !== newTargetJson.status) {
            if (lastTargetJson.status) {
                targetDiv.removeClass(lastTargetJson.status);
            }
            targetDiv.addClass(newTargetJson.status);
        }

        buildsDiv.empty();
        $.each(newTargetJson.builds, function(index, buildJson) {
            buildsDiv.append(ORG.NETMELODY.CIEYE.newBuildWidget(buildJson).getContent());
        });

        if (newTargetJson.builds.length === 0) {
            targetDiv.removeClass("building");
        }
        else {
            targetDiv.addClass("building");
        }

        if (newTargetJson.builds.length === 0 && newTargetJson.status === "GREEN") {
            sponsorDiv.empty();
            return;
        }

        $.each(sortedSponsors(newTargetJson.sponsors), function(index, sponsorJson) {
            if (!sponsorMugshots[sponsorJson.picture]) {
                sponsorMugshots[sponsorJson.picture] = ORG.NETMELODY.CIEYE.newMugshotWidget(sponsorJson, calculateImageSize);
            }
            sponsorDiv.append(sponsorMugshots[sponsorJson.picture].getContent());
        });
    }

    function clickable() {
        return (targetDiv.css("cursor") === "pointer");
    }

    function viewDetails() {
        window.open(targetJson.webUrl);
    }

    function markAsBeingFixed() {
        window.alert("Sorry, not implemented yet.");
    }

    function initialise() {
        titleSpan.text(targetJson.name);
        targetDiv.append(titleSpan);
        targetDiv.append(sponsorDiv);
        targetDiv.append(buildsDiv);
        targetDiv.addClass("target");
        targetDiv.popupMenu([{"label": "View Details", "handler": viewDetails},
                             {"label": "Mark as Being Fixed", "handler": markAsBeingFixed}],
                            clickable);
        refresh(targetJson);
    }

    initialise();

    return {
        "updateFrom": refresh,
        "getContent": function() { return targetDiv; }
    };
};

ORG.NETMELODY.CIEYE.newRadiatorWidget = function() {
    var radiatorDiv = $("

"),
        targetWidgets = {};

    function refresh(targetGroupJson) {
        var targets = targetGroupJson.targets.sort(function(a, b) {
                if (a.status === b.status) {
                    if (a.builds.length === b.builds.length) {
                        return (a.lastStartTime > b.lastStartTime) ? -1 : 1;
                    }
                    return (a.builds.length > b.builds.length) ? -1 : 1;
                }
                return (a.status === "BROKEN" || b.status === "GREEN") ? -1 : 1;
            }),
            deadTargetWidgets = $.extend({}, targetWidgets);

        $.each(targets, function(index, targetJson) {
            if (targetWidgets[targetJson.id]) {
                targetWidgets[targetJson.id].updateFrom(targetJson);
                delete deadTargetWidgets[targetJson.id];
            }
            else {
                targetWidgets[targetJson.id] = ORG.NETMELODY.CIEYE.newTargetWidget(targetJson);
            }
            radiatorDiv.append(targetWidgets[targetJson.id].getContent());
        });
        $.each(deadTargetWidgets, function(index, deadTargetWidget) {
            radiatorDiv.remove(deadTargetWidget.getContent());
        });
    }

    return {
        "updateFrom": refresh,
        "getContent": function() { return radiatorDiv; }
    };
};

ORG.NETMELODY.CIEYE.scheduler = function(browser) {
    var protector;

    function reloadPage() {
        browser.location.reload();
    }

    function safeCallableFor(callback) {
        return function() {
            try {
                callback();
            }
            catch (ex) {
                // ignore
            }
        };
    }

    function repeat(callback, interval) {
        browser.setInterval(safeCallableFor(callback), interval);
    }

    function guard(timeout) {
        if (!protector) {
            protector = browser.setTimeout(reloadPage, timeout);
        }
    }

    function relax() {
        if (protector) {
            browser.clearTimeout(protector);
            protector = null;
        }
    }

    return {
        "repeat": repeat,
        "guard": guard,
        "relax": relax
    };
};

ORG.NETMELODY.CIEYE.newRadiator = function(radiatorDiv, scheduler) {
    var radiatorWidget = ORG.NETMELODY.CIEYE.newRadiatorWidget();

    function refresh() {
        scheduler.guard(30000);
        $.getJSON("landscapeobservation.json", function(targetList) {
            scheduler.relax();
            radiatorWidget.updateFrom(targetList);
        });
    }

    function startup() {
        radiatorDiv.append(radiatorWidget.getContent());
        refresh();
        scheduler.repeat(refresh, 2000);
    }

    return {
        "start": startup
    };
};

$(document).ready(function() {
    var scheduler = ORG.NETMELODY.CIEYE.scheduler(window);
    ORG.NETMELODY.CIEYE.newRadiator($("#radiator"), scheduler).start();
});
<|endoftext|>


<commit_before>/*!
GPII XML Settings Handler

Copyright 2012 Raising the Floor - International

Licensed under the New BSD license. You may not use this file except in
compliance with this License.

You may obtain a copy of the License at
https://github.com/gpii/universal/LICENSE.txt
*/

/*global require, $ */

(function () {

    "use strict";

    var fluid = require("infusion"),
        fs = require("fs"),
        xm = require("xml-mapping"),
        gpii = fluid.registerNamespace("gpii");

    fluid.registerNamespace("gpii.settingsHandlers.XMLHandler");

    /* -------- Transformation functions -------------------- */

    /**
     * Transforms the given array to an object.
     * Uses the expandSpec.options.key values from each object within the array as new keys.
     *
     * For example, with expandSpec.options.key = "name" and an input object like this:
     *
     * {
     *   b: [
     *     { name: b1, v: v1 },
     *     { name: b2, v: v2 }
     *   ]
     * }
     *
     * The output will be:
     * {
     *   b: {
     *     b1: {
     *       v: v1
     *     }
     *   },
     *   {
     *     b2: {
     *       v: v2
     *     }
     *   }
     * }
     */
    gpii.settingsHandlers.XMLHandler.arrayToObject = function (arr, expander, expandSpec) {
        if (fluid.get(expandSpec, "options.key") === undefined) {
            fluid.fail("arrayToObject requires a 'key' option.", expandSpec);
        }
        if (!fluid.isArrayable(arr)) {
            fluid.fail("arrayToObject didn't find array at inputPath.", expandSpec);
        }
        var newHash = {};
        var pivot = expandSpec.options.key;
        var inputPrefixOp = expander.inputPrefixOp;
        var outputPrefixOp = expander.outputPrefixOp;
        var innerValue = expandSpec.options.innerValue;

        fluid.each(arr, function (v, k) {
            //check that we have a pivot entry in the object and it's a valid type:
            var newKey = v[pivot];
            var keyType = typeof(newKey);
            if (keyType !== "string" && keyType !== "boolean" && keyType !== "number") {
                fluid.fail("arrayToObject encountered untransformable array due to missing or invalid key", v);
            }
            //use the value of the key element as key and use the remaining content as value
            var content = fluid.copy(v);
            delete content[pivot];
            //fix sub Arrays if needed:
            if (innerValue) {
                var expanded = {};

                //build inputPrefix:
                inputPrefixOp.push(expander.outputPrefix);
                inputPrefixOp.push(k.toString()); //push doesn't accept ints
                outputPrefixOp.push(newKey);
                for (var i = 0; i < innerValue.length; ++i) {
                    $.extend(true, expanded, expander.expand(innerValue[i]));
                }
                outputPrefixOp.pop();
                inputPrefixOp.pop();
                inputPrefixOp.pop();
                content = expanded;
            }
            newHash[newKey] = content;
        });
        return newHash;
    };

    gpii.settingsHandlers.XMLHandler.arrayToObject.invertRules = function (expandSpec, expander) {
        var togo = fluid.copy(expandSpec);
        togo.type = "gpii.settingsHandlers.XMLHandler.objectToArray";
        togo.inputPath = fluid.model.composePaths(expander.outputPrefix, expandSpec.outputPath);
        togo.outputPath = fluid.model.composePaths(expander.inputPrefix, expandSpec.inputPath);
        //invert expanders from innerValue as well:
        if (togo.options && togo.options.innerValue) {
            var innerValue = togo.options.innerValue;
            for (var i = 0; i < innerValue.length; ++i) {
                innerValue[i] = fluid.model.transform.invertConfiguration(innerValue[i]);
            }
        }
        return togo;
    };

    fluid.defaults("gpii.settingsHandlers.XMLHandler.arrayToObject", {
        gradeNames: ["fluid.standardTransformFunction", "fluid.lens" ],
        invertConfiguration: "gpii.settingsHandlers.XMLHandler.arrayToObject.invertRules"
    });

    /**
     * Transforms an object into array of objects.
     * This performs the inverse transform of gpii.settingsHandlers.XMLHandler.arrayToObject.
     */
    gpii.settingsHandlers.XMLHandler.objectToArray = function (hash, expander, expandSpec) {
        if (fluid.get(expandSpec, "options.key") === undefined) {
            fluid.fail("objectToArray requires a 'key' option.", expandSpec);
        }
        var newArray = [];
        var pivot = expandSpec.options.key;
        var expanded = {};
        var inputPrefixOp = expander.inputPrefixOp;
        var outputPrefixOp = expander.outputPrefixOp;
        var innerValue = expandSpec.options.innerValue;

        fluid.each(hash, function (v, k) {
            var content = {};
            content[pivot] = k;
            // TODO: factor out this common inner code which also appears in arrayToObject
            if (expandSpec.options.innerValue) {
                inputPrefixOp.push(expandSpec.inputPath);
                inputPrefixOp.push(k);
                outputPrefixOp.push(expandSpec.inputPath);
                outputPrefixOp.push(newArray.length.toString());
                for (var i = 0; i < innerValue.length; ++i) {
                    $.extend(true, expanded, expander.expand(innerValue[i]));
                }
                outputPrefixOp.pop();
                outputPrefixOp.pop();
                inputPrefixOp.pop();
                inputPrefixOp.pop();
                v = expanded;
            }
            // TODO: remove this use of fluid.merge which will not be valid in 1.5 Infusion framework
            fluid.merge("replace", content, v);
            newArray.push(content);
        });
        return newArray;
    };

    fluid.defaults("gpii.settingsHandlers.XMLHandler.objectToArray", {
        gradeNames: "fluid.standardTransformFunction"
    });

    /* ------------------ XML handler specific ---------------------- */
    //Used when fluid.get'ing and set'ing, to allow escaped strings
    // TODO: When FLUID-4852 is fixed, remove these definitions
    var getParser = {
        parser: {
            parse: fluid.pathUtil.parseEL,
            compose: fluid.pathUtil.composePath
        },
        strategies: [fluid.model.defaultFetchStrategy]
    };

    var setParser = {
        parser: {
            parse: fluid.pathUtil.parseEL,
            compose: fluid.pathUtil.composePath
        },
        strategies: [fluid.model.defaultFetchStrategy, fluid.model.defaultCreatorStrategy]
    };

    /**
     * "Pretty-prints" an XML string.
     *
     * This function is derived from sample code posted by Dan Brooks on Stack Overflow:
     * http://stackoverflow.com/questions/376373/pretty-printing-xml-with-javascript
     *
     * @param {String} xml the XML string to reformat
     * @return {String} the reformatted XML document
     */
    gpii.settingsHandlers.XMLHandler.formatXml = function (xml) {
        var formatted = "";
        var reg = /(>)(<)(\/*)/g;
        xml = xml.replace(reg, "$1\r\n$2$3");
        var pad = 0;
        fluid.each(xml.split("\r\n"), function(node) {
            var indent = 0;
            if (node.match( /.+<\/\w[^>]*>$/ )) {
                indent = 0;
            } else if (node.match( /^<\/\w/ )) {
                if (pad !== 0) {
                    pad -= 1;
                }
            } else if (node.match( /^<\w[^>]*[^\/]>.*$/ )) {
                indent = 1;
            } else {
                indent = 0;
            }

            var padding = "";
            for (var i = 0; i < pad; i++) {
                padding += "  ";
            }

            formatted += padding + node + "\r\n";
            pad += indent;
        });
        return formatted;
    };

    //Gets a settings array and a json-ified version of the XML,
    //sets each the relevant settings and returns the settings object with
    //{oldValue: XXXX, newValue: YYYY} as values
    //WARNING: Destructively modifies obj
    gpii.settingsHandlers.XMLHandler.applySettings = function (settings, obj) {
        var returnPayload = {};
        //edit each of the settings
        fluid.each(settings, function(value, el) {
            //store the previous value
            var prev = fluid.get(obj, el, getParser);
            fluid.set(obj, el, value, setParser);

            //create entry in the return payload
            returnPayload[el] = { oldValue: prev, newValue: value };
        });
        return returnPayload;
    };

    /**
     * Reads XML file and returns the equivalent transformed JSON structure
     * (array transformed to objects if given in knownArrays or detected
     * as using 'name' as pivot element)
    */
    gpii.settingsHandlers.XMLHandler.readXMLFile = function (options) {
        if (options === undefined) {
            fluid.fail("readXMLFile: expected an options block defining filename and encoding");
        }
         //TODO check for and handle read errors
        var xmlString = fs.readFileSync(options.filename, options.encoding || "utf-8");
        //parse XML to JSON and apply the settings
        var json = xm.tojson(xmlString);
        return (options && options.rules) ? fluid.model.transformWithRules(json, options.rules) : json;
    };

    gpii.settingsHandlers.XMLHandler.writeXMLFile = function (json, options) {
        //Create XML - first line is the xml-tag from options if set
        var xml = options["xml-tag"] || "";
        //transform back
        var inverseRules = fluid.model.transform.invertConfiguration(options.rules);
        var inversedJSON = fluid.model.transformWithRules(json, inverseRules);

        xml += xm.toxml(inversedJSON);
        //and fix indentation/newlines so it's readable
        var formattedXML = gpii.settingsHandlers.XMLHandler.formatXml(xml);
        //TODO check for and handler write errors
        fs.writeFileSync(options.filename, formattedXML, options.encoding || "utf-8");
    };

    // TODO: For testing purposes, accept additional arguments in "solution.options" to
    // produce data via a callback rather than hardcoded to hit the filesystem

    // TODO: Rescue the algorithm gpii.invokeSettingsHandler from RegistrySettingsHandler.js
    // line 226 and use it to simplify the loops of all settings handlers including this one
    gpii.settingsHandlers.XMLHandler.set = function (data) {
        var returnObj = fluid.copy(data);
        //each solution block
        return fluid.transform(returnObj, function (solution) {
            //each array entry in the solution block
            return fluid.transform(solution, function (solutionEntry) {
                var options = solutionEntry.options;
                var settings = solutionEntry.settings;
                //only valid if a filename is set in options, else ignore this block
                if (options && options.filename) {
                    //parse XML to JSON and apply the settings
                    var json = gpii.settingsHandlers.XMLHandler.readXMLFile(options);
                    //apply settings:
                    var newSettingsResponse = gpii.settingsHandlers.XMLHandler.applySettings(settings, json);
                    //Save to XML file
                    gpii.settingsHandlers.XMLHandler.writeXMLFile(json, options);
                    //save the response from settings handler (ie. with old/new values)
                    solutionEntry.settings = newSettingsResponse;
                }
                return solutionEntry;
            });
        });
    };
}());
<commit_msg>GPII-32: Basic refactoring of duplicate innerValue expansion logic.<commit_after>/*!
GPII XML Settings Handler

Copyright 2012 Raising the Floor - International

Licensed under the New BSD license. You may not use this file except in
compliance with this License.

You may obtain a copy of the License at
https://github.com/gpii/universal/LICENSE.txt
*/

/*global require, $ */

(function () {

    "use strict";

    var fluid = require("infusion"),
        fs = require("fs"),
        xm = require("xml-mapping"),
        gpii = fluid.registerNamespace("gpii");

    fluid.registerNamespace("gpii.settingsHandlers.XMLHandler");

    /* -------- Transformation functions -------------------- */

    gpii.settingsHandlers.XMLHandler.expandInnerValues = function (innerValues, expander) {
        var expanded = {};

        fluid.each(innerValues, function (innerValue) {
            var expandedInner = expander.expand(innerValue);
            $.extend(true, expanded, expandedInner);
        });

        return expanded;
    };

    /**
     * Transforms the given array to an object.
     * Uses the expandSpec.options.key values from each object within the array as new keys.
     *
     * For example, with expandSpec.options.key = "name" and an input object like this:
     *
     * {
     *   b: [
     *     { name: b1, v: v1 },
     *     { name: b2, v: v2 }
     *   ]
     * }
     *
     * The output will be:
     * {
     *   b: {
     *     b1: {
     *       v: v1
     *     }
     *   },
     *   {
     *     b2: {
     *       v: v2
     *     }
     *   }
     * }
     */
    gpii.settingsHandlers.XMLHandler.arrayToObject = function (arr, expander, expandSpec) {
        if (fluid.get(expandSpec, "options.key") === undefined) {
            fluid.fail("arrayToObject requires a 'key' option.", expandSpec);
        }
        if (!fluid.isArrayable(arr)) {
            fluid.fail("arrayToObject didn't find array at inputPath.", expandSpec);
        }
        var newHash = {};
        var pivot = expandSpec.options.key;

        fluid.each(arr, function (v, k) {
            //check that we have a pivot entry in the object and it's a valid type:
            var newKey = v[pivot];
            var keyType = typeof(newKey);
            if (keyType !== "string" && keyType !== "boolean" && keyType !== "number") {
                fluid.fail("arrayToObject encountered untransformable array due to missing or invalid key", v);
            }
            //use the value of the key element as key and use the remaining content as value
            var content = fluid.copy(v);
            delete content[pivot];
            //fix sub Arrays if needed:
            if (expandSpec.options.innerValue) {
                content = gpii.settingsHandlers.XMLHandler.arrayToObject.expandInnerValues(k, newKey, expander, expandSpec);
            }
            newHash[newKey] = content;
        });
        return newHash;
    };

    gpii.settingsHandlers.XMLHandler.arrayToObject.expandInnerValues = function (arrayIdx, key, expander, expandSpec) {
        var inputPrefixOp = expander.inputPrefixOp;
        var outputPrefixOp = expander.outputPrefixOp;

        //build inputPrefix:
        inputPrefixOp.push(expander.outputPrefix);
        inputPrefixOp.push(arrayIdx.toString()); //push doesn't accept ints
        outputPrefixOp.push(key);

        var expanded = gpii.settingsHandlers.XMLHandler.expandInnerValues(expandSpec.options.innerValue, expander)

        outputPrefixOp.pop();
        inputPrefixOp.pop();
        inputPrefixOp.pop();

        return expanded;
    };

    gpii.settingsHandlers.XMLHandler.arrayToObject.invertRules = function (expandSpec, expander) {
        var togo = fluid.copy(expandSpec);
        togo.type = "gpii.settingsHandlers.XMLHandler.objectToArray";
        togo.inputPath = fluid.model.composePaths(expander.outputPrefix, expandSpec.outputPath);
        togo.outputPath = fluid.model.composePaths(expander.inputPrefix, expandSpec.inputPath);
        //invert expanders from innerValue as well:
        if (togo.options && togo.options.innerValue) {
            var innerValue = togo.options.innerValue;
            for (var i = 0; i < innerValue.length; ++i) {
                innerValue[i] = fluid.model.transform.invertConfiguration(innerValue[i]);
            }
        }
        return togo;
    };

    fluid.defaults("gpii.settingsHandlers.XMLHandler.arrayToObject", {
        gradeNames: ["fluid.standardTransformFunction", "fluid.lens" ],
        invertConfiguration: "gpii.settingsHandlers.XMLHandler.arrayToObject.invertRules"
    });

    /**
     * Transforms an object into array of objects.
     * This performs the inverse transform of gpii.settingsHandlers.XMLHandler.arrayToObject.
     */
    gpii.settingsHandlers.XMLHandler.objectToArray = function (hash, expander, expandSpec) {
        if (fluid.get(expandSpec, "options.key") === undefined) {
            fluid.fail("objectToArray requires a 'key' option.", expandSpec);
        }

        var newArray = [];
        var pivot = expandSpec.options.key;

        fluid.each(hash, function (v, k) {
            var content = {};
            content[pivot] = k;
            if (expandSpec.options.innerValue) {
                v = gpii.settingsHandlers.XMLHandler.objectToArray.expandInnerValues(k, newArray, expander, expandSpec);
            }
            // TODO: remove this use of fluid.merge which will not be valid in 1.5 Infusion framework
            fluid.merge("replace", content, v);
            newArray.push(content);
        });
        return newArray;
    };

    gpii.settingsHandlers.XMLHandler.objectToArray.expandInnerValues = function (key, arr, expander, expandSpec) {
        var inputPrefixOp = expander.inputPrefixOp;
        var outputPrefixOp = expander.outputPrefixOp;

        inputPrefixOp.push(expandSpec.inputPath);
        inputPrefixOp.push(key);
        outputPrefixOp.push(expandSpec.inputPath);
        outputPrefixOp.push(arr.length.toString());

        var expanded = gpii.settingsHandlers.XMLHandler.expandInnerValues(expandSpec.options.innerValue, expander);

        outputPrefixOp.pop();
        outputPrefixOp.pop();
        inputPrefixOp.pop();
        inputPrefixOp.pop();

        return expanded;
    };

    fluid.defaults("gpii.settingsHandlers.XMLHandler.objectToArray", {
        gradeNames: "fluid.standardTransformFunction"
    });

    /* ------------------ XML handler specific ---------------------- */
    //Used when fluid.get'ing and set'ing, to allow escaped strings
    // TODO: When FLUID-4852 is fixed, remove these definitions
    var getParser = {
        parser: {
            parse: fluid.pathUtil.parseEL,
            compose: fluid.pathUtil.composePath
        },
        strategies: [fluid.model.defaultFetchStrategy]
    };

    var setParser = {
        parser: {
            parse: fluid.pathUtil.parseEL,
            compose: fluid.pathUtil.composePath
        },
        strategies: [fluid.model.defaultFetchStrategy, fluid.model.defaultCreatorStrategy]
    };

    /**
     * "Pretty-prints" an XML string.
     *
     * This function is derived from sample code posted by Dan Brooks on Stack Overflow:
     * http://stackoverflow.com/questions/376373/pretty-printing-xml-with-javascript
     *
     * @param {String} xml the XML string to reformat
     * @return {String} the reformatted XML document
     */
    gpii.settingsHandlers.XMLHandler.formatXml = function (xml) {
        var formatted = "";
        var reg = /(>)(<)(\/*)/g;
        xml = xml.replace(reg, "$1\r\n$2$3");
        var pad = 0;
        fluid.each(xml.split("\r\n"), function(node) {
            var indent = 0;
            if (node.match( /.+<\/\w[^>]*>$/ )) {
                indent = 0;
            } else if (node.match( /^<\/\w/ )) {
                if (pad !== 0) {
                    pad -= 1;
                }
            } else if (node.match( /^<\w[^>]*[^\/]>.*$/ )) {
                indent = 1;
            } else {
                indent = 0;
            }

            var padding = "";
            for (var i = 0; i < pad; i++) {
                padding += "  ";
            }

            formatted += padding + node + "\r\n";
            pad += indent;
        });
        return formatted;
    };

    //Gets a settings array and a json-ified version of the XML,
    //sets each the relevant settings and returns the settings object with
    //{oldValue: XXXX, newValue: YYYY} as values
    //WARNING: Destructively modifies obj
    gpii.settingsHandlers.XMLHandler.applySettings = function (settings, obj) {
        var returnPayload = {};
        //edit each of the settings
        fluid.each(settings, function(value, el) {
            //store the previous value
            var prev = fluid.get(obj, el, getParser);
            fluid.set(obj, el, value, setParser);

            //create entry in the return payload
            returnPayload[el] = { oldValue: prev, newValue: value };
        });
        return returnPayload;
    };

    /**
     * Reads XML file and returns the equivalent transformed JSON structure
     * (array transformed to objects if given in knownArrays or detected
     * as using 'name' as pivot element)
    */
    gpii.settingsHandlers.XMLHandler.readXMLFile = function (options) {
        if (options === undefined) {
            fluid.fail("readXMLFile: expected an options block defining filename and encoding");
        }
         //TODO check for and handle read errors
        var xmlString = fs.readFileSync(options.filename, options.encoding || "utf-8");
        //parse XML to JSON and apply the settings
        var json = xm.tojson(xmlString);
        return (options && options.rules) ? fluid.model.transformWithRules(json, options.rules) : json;
    };

    gpii.settingsHandlers.XMLHandler.writeXMLFile = function (json, options) {
        //Create XML - first line is the xml-tag from options if set
        var xml = options["xml-tag"] || "";
        //transform back
        var inverseRules = fluid.model.transform.invertConfiguration(options.rules);
        var inversedJSON = fluid.model.transformWithRules(json, inverseRules);

        xml += xm.toxml(inversedJSON);
        //and fix indentation/newlines so it's readable
        var formattedXML = gpii.settingsHandlers.XMLHandler.formatXml(xml);
        //TODO check for and handler write errors
        fs.writeFileSync(options.filename, formattedXML, options.encoding || "utf-8");
    };

    // TODO: For testing purposes, accept additional arguments in "solution.options" to
    // produce data via a callback rather than hardcoded to hit the filesystem

    // TODO: Rescue the algorithm gpii.invokeSettingsHandler from RegistrySettingsHandler.js
    // line 226 and use it to simplify the loops of all settings handlers including this one
    gpii.settingsHandlers.XMLHandler.set = function (data) {
        var returnObj = fluid.copy(data);
        //each solution block
        return fluid.transform(returnObj, function (solution) {
            //each array entry in the solution block
            return fluid.transform(solution, function (solutionEntry) {
                var options = solutionEntry.options;
                var settings = solutionEntry.settings;
                //only valid if a filename is set in options, else ignore this block
                if (options && options.filename) {
                    //parse XML to JSON, apply the settings, and write the file.
                    var json = gpii.settingsHandlers.XMLHandler.readXMLFile(options);
                    var newSettingsResponse = gpii.settingsHandlers.XMLHandler.applySettings(settings, json);
                    gpii.settingsHandlers.XMLHandler.writeXMLFile(json, options);
                    solutionEntry.settings = newSettingsResponse;
                }
                return solutionEntry;
            });
        });
    };
}());
<|endoftext|>


<commit_before>import { getAllTestFromClass } from '../helpers/viewHelpers.js';

var allTestsFromClass = getAllTestsFromClass(1);
console.log(allTestsFromClass);

var master = {};

for (var key in allTestsInClass.answerKeys) {
  master[key] = {id: key,
                 name: key,  // This will be name in the future.
                 correctAnswers: JSON.parse(allTestsInClass.answerKeys[key]),
                 studentAnswers: []
                });
};

allTestsInClass.students.forEach(function(student) {
  var studentId = student.StudentId;
  var studentName = student.StudentName;

  student.tests.forEach(function(item) {
    var test = {};
    // test.testId = item.id;
    test.studentId = studentId;
    test.studentName = studentName;
    test.studentScore = item.result;
    test.studentAnswers = JSON.parse(item.studentAnswers);
    test.imageUrl = item.URL;

    master.forEach(function(exam) {
      if (item.id === exam.id) {
        exam.studentAnswers.push(test);
      }
    });
  });
});

// --------------------------------------------------------------------------------
// All Students' Results from a Single Exam
// --------------------------------------------------------------------------------
var allStudentResults =
  [
    {student: {id: 123456, name: 'Anthony Pecchillo'},
     answers: [ [A], [B], [C,D], [E], [D], [C], [A,B], [B], [A], [D] ],
     score: 95
    },
    {student: {id: 234567, name: 'Benze Gong'},
     answers: [ [D], [C], [A,B], [B], [A], [D], [C,E], [C], [C], [E] ],
     score: 95
    },
    {student: {id: 345678, name: 'Cynthia Bathgate'},
     answers: [ [A], [D], [C,E], [C], [C], [E], [A,B], [B], [A], [D] ],
     score: 95
    },
    {student: {id: 456789, name: 'Kevin Gin'},
     answers: [ [A], [D], [C,E], [C], [C], [E], [A,B], [B], [A], [D] ],
     score: 95
    }
  ]

// --------------------------------------------------------------------------------
// Answer Key from a Single Exam
// --------------------------------------------------------------------------------
var answerKey = [ [A], [B], [C,D], [E], [D], [C], [A,B], [B], [A], [D] ]

// --------------------------------------------------------------------------------
// Formulas for Statistical Variables:
// --------------------------------------------------------------------------------

// Sum
const sum = (arrayOfGrades) => d3.sum(arrayOfGrades, 'Accessor Function Here!');

// Mean
const mean = (arrayOfGrades) => d3.mean(arrayOfGrades, 'Accessor Function Here!');

// Median
const median = (arrayOfGrades) => d3.median(arrayOfGrades, 'Accessor Function Here!');

// Standard Deviation
const stdDev = (arrayOfGrades) => d3.deviation(arrayOfGrades, 'Acessore Function Here!');

// Variance
const variance = (arrayOfGrades) => d3.variance(arrayOfGrades, 'Acessore Function Here!');

// Quantiles, where p is a number in the range [0, 1].
const quantile = (arrayOfGrades) => d3.quantile(arrayOfGrades, p, 'Acessore Function Here!');
// Example: p = 0.25 is the first quantile, Q1.
//          p = 0.75 is the third quantile, Q3.

// Test Item Difficulty
const singleItemDifficulty = (arrayIndivQuesScores) => mean(arrayIndivQuesScores) / arrayIndivQuesScores.length;

// Test Difficulty

const testDifficulty = ()

// Reliability Coeffecient (Chronbach's Alpha)
const alpha = (k, arrayOfArraysOfStudentAnswers, arrayOfGrades) => {'sttuffff'};
// alpha = (k / (k - 1)) * (1 - (sum( sigma2(arrayOfGradesForSignleTestItem))) / sigma2(arrayOfExamGrades) )

<commit_msg>(feat) Create data munging function, processData, for stats analysis<commit_after>import { getAllTestsInClass } from '../helpers/viewHelpers.js';

var objToArray = function(obj) {
  return Object.keys(obj).map(function(key) {
    return obj[key];
  });
};

exports.processData = function(classId) {
  return getAllTestsInClass(classId).then(function(allTestsFromClass) {
    var allTestData = {};
    console.log('allTestsFromClass: ', allTestsFromClass);

    for (var key in allTestsFromClass.data[0].answerKeys) {
      allTestData[key] = {id: allTestsFromClass.data[0].answerKeys[key].keyId,
                          name: allTestsFromClass.data[0].answerKeys[key].keyName,  // This will be name in the future.
                          correctAnswers: objToArray(JSON.parse(allTestsFromClass.data[0].answerKeys[key].answers)),
                          studentTestResults: [],
                          studentTestScores: []
                         };
    };

    allTestsFromClass.data[0].students.forEach(function(student) {
      var studentId = student.StudentId;
      var studentName = student.StudentName;

      student.tests.forEach(function(item) {
        var test = {};
        // test.testId = item.id;
        test.student = {id: studentId, name: studentName};
        test.studentScore = Math.round(item.result * 100);
        test.studentAnswers = objToArray(JSON.parse(item.studentAnswers));
        test.imageUrl = item.URL;
        test.answerKeyId = item.answerKeyId;

        for (var key in allTestData) {
          if (Number(allTestData[key].id) === Number(test.answerKeyId)) {
            allTestData[key].studentTestResults.push(test);
            allTestData[key].studentTestScores.push(test.studentScore);
          }
        }
      });
    });
    console.log('Final allTestData object after processing: ', allTestData);
    return allTestData;
  });
};

// // --------------------------------------------------------------------------------
// // Formulas for Statistical Variables:
// // --------------------------------------------------------------------------------

// // Sum
// const sum = (arrayOfGrades) => d3.sum(arrayOfGrades, 'Accessor Function Here!');

// // Mean
// const mean = (arrayOfGrades) => d3.mean(arrayOfGrades, 'Accessor Function Here!');

// // Median
// const median = (arrayOfGrades) => d3.median(arrayOfGrades, 'Accessor Function Here!');

// // Standard Deviation
// const stdDev = (arrayOfGrades) => d3.deviation(arrayOfGrades, 'Acessore Function Here!');

// // Variance
// const variance = (arrayOfGrades) => d3.variance(arrayOfGrades, 'Acessore Function Here!');

// // Quantiles, where p is a number in the range [0, 1].
// const quantile = (arrayOfGrades) => d3.quantile(arrayOfGrades, p, 'Acessore Function Here!');
// // Example: p = 0.25 is the first quantile, Q1.
// //          p = 0.75 is the third quantile, Q3.

// // Test Item Difficulty
// const singleItemDifficulty = (arrayIndivQuesScores) => mean(arrayIndivQuesScores) / arrayIndivQuesScores.length;

// // Test Difficulty

// const testDifficulty = ()

// // Reliability Coeffecient (Chronbach's Alpha)
// const alpha = (k, arrayOfArraysOfStudentAnswers, arrayOfGrades) => {'sttuffff'};
// // alpha = (k / (k - 1)) * (1 - (sum( sigma2(arrayOfGradesForSignleTestItem))) / sigma2(arrayOfExamGrades) )
<|endoftext|>


<commit_before>var Plane = function(){
    var createGuid = function(){
        var S4 = function(){
            return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
        }
        return (S4() + S4() + "-" + S4() + "-4" + S4().substr(0,3) + "-" + S4() + "-" + S4() + S4() + S4()).toLowerCase();
    }
    this.id = createGuid();

    var plusOrMinus = function(){
        return [-1,1][Math.random()*2|0];
    };

    var getStartPosition = function(){
        return [min, max][Math.random()*2|0];
    };

    var getRandomBetween = function(min, max) {
        return Math.random() * (max - min) + min;
    }

    if(~plusOrMinus()){
        this.x = getRandomBetween(min, max);
        this.y = getStartPosition();
    } else {
        this.y = getRandomBetween(min, max);
        this.x = getStartPosition();
    }

    this.isOutOfBound = false;
    var minAngle = 0.1;
    var maxAngle = 1;
    this.vx = plusOrMinus() * getRandomBetween(minAngle, maxAngle);
    this.vy = plusOrMinus() * getRandomBetween(minAngle, maxAngle);
}

Plane.prototype.draw = function() {
    if(this.x >= min && this.x <= max && this.y >= min && this.y <= max){
        this.x += this.vx;
        this.y += this.vy;
        context.fillRect(this.x, this.y, 10, 10);
    } else {
        this.isOutOfBound = true;
    }
};

var canvas = document.getElementById("radar");
var planeList = document.getElementById("planeList");
var context = canvas.getContext("2d");
var mousePosition = document.getElementById("mousePosition");
var canvasSize = 1000;
var min = canvasSize * (-0.95);
var max = canvasSize * 1.05;
canvas.width = canvasSize;
canvas.height = canvasSize;
var circleInitialPosition = 500;
var planesCount = 35;
var planes = [];

var startAngle = Math.PI;

var createPlane = function(){
    while(planes.length < planesCount){
        var p = new Plane();
        planes.push(p);
        appendPlane(p);
    };
}

var appendPlane = function(p){
    var planeItem = document.createElement("li");
    var id = document.createElement("b");
    id.appendChild(document.createTextNode(p.id));
    var span = document.createElement("span");
    span.appendChild(document.createTextNode(p.x + ", " + p.y));
    planeItem.appendChild(id);
    planeItem.appendChild(span);
    planeItem.setAttribute("id", p.id);
    planeList.appendChild(planeItem);
}

var drawRadar = function(){
    context.lineWidth = 5;
    context.strokeStyle = '#000';
    context.fillStyle = "rgba(52, 152, 219, 0.8)";
    for (var i = 5; i >= 0; i--) {
        drawCircle(circleInitialPosition, circleInitialPosition, i * 100);
    };

    context.moveTo(0, circleInitialPosition);
    context.lineTo(canvasSize, circleInitialPosition);
    context.moveTo(circleInitialPosition, 0);
    context.lineTo(circleInitialPosition, canvasSize);
    context.stroke();
}

var drawLine = function(){
    var center = circleInitialPosition;
    context.lineWidth = 8;
    startAngle += 0.01;
    context.moveTo(center, center);
    context.lineTo(center + center * Math.cos(startAngle), center + center * Math.sin(startAngle));
    context.stroke();
}

var drawPlanes = function(){
    context.fillStyle = "rgb(200, 0, 0)";
    createPlane();
    planes.forEach(function(p, i){
        if(!p.isOutOfBound)
            p.draw();
        else {
            var planeItem = document.getElementById(p.id);
            planeList.removeChild(planeItem);
            planes.splice(i, 1);
        }
    });
}

var draw = function() {
    context.clearRect(0, 0, canvasSize, canvasSize);
    drawRadar();
    drawPlanes();
    drawLine();
}

var drawCircle = function(x, y, rayon){
    context.beginPath();
    context.arc(x, y, rayon, 0, Math.PI*2);
    context.fill();
    context.closePath();
    context.stroke();
}

function writeMessage(message) {
    mousePosition.innerHTML = message
}

function getMousePos(canvas, evt) {
    var rect = canvas.getBoundingClientRect();
    return {
        x: evt.clientX - rect.left,
        y: evt.clientY - rect.top
    };
}

canvas.addEventListener('mousemove', function(evt) {
  var mousePos = getMousePos(canvas, evt);
  var message = 'X: ' + Math.round(mousePos.x) + ' Y: ' + Math.round(mousePos.y);
  writeMessage(message);
}, false);

window.onload = function(){
    setInterval(draw, 1000/60);
}<commit_msg>Plane Selector<commit_after>var Plane = function(){
    var createGuid = function(){
        var S4 = function(){
            return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
        }
        return (S4() + S4() + "-" + S4() + "-4" + S4().substr(0,3) + "-" + S4() + "-" + S4() + S4() + S4()).toLowerCase();
    }
    this.id = createGuid();

    var plusOrMinus = function(){
        return [-1,1][Math.random()*2|0];
    };

    var getStartPosition = function(){
        return [min, max][Math.random()*2|0];
    };

    var getRandomBetween = function(min, max) {
        return Math.random() * (max - min) + min;
    }

    if(~plusOrMinus()){
        this.x = getRandomBetween(min, max);
        this.y = getStartPosition();
    } else {
        this.y = getRandomBetween(min, max);
        this.x = getStartPosition();
    }

    this.isOutOfBound = false;
    var minAngle = 0.1;
    var maxAngle = 1;
    this.vx = plusOrMinus() * getRandomBetween(minAngle, maxAngle);
    this.vy = plusOrMinus() * getRandomBetween(minAngle, maxAngle);
}

Plane.prototype.draw = function() {
    if(this.x >= min && this.x <= max && this.y >= min && this.y <= max){
        this.x += this.vx;
        this.y += this.vy;
        context.fillRect(this.x, this.y, 10, 10);
    } else {
        this.isOutOfBound = true;
    }
};

var canvas = document.getElementById("radar");
var planeList = document.getElementById("planeList");
var context = canvas.getContext("2d");
var mousePosition = document.getElementById("mousePosition");
var canvasSize = 1000;
var min = canvasSize * (-0.95);
var max = canvasSize * 1.05;
canvas.width = canvasSize;
canvas.height = canvasSize;
var circleInitialPosition = 500;
var planesCount = 35;
var planes = [];
var selectedPlanes = [];

var startAngle = Math.PI;

var createPlane = function(){
    while(planes.length < planesCount){
        var p = new Plane();
        planes.push(p);
        appendPlane(p);
    };
}

var appendPlane = function(p){
    var planeItem = document.createElement("li");
    var id = document.createElement("b");
    id.appendChild(document.createTextNode(p.id));
    var span = document.createElement("span");
    span.appendChild(document.createTextNode(p.x + ", " + p.y));
    planeItem.appendChild(id);
    planeItem.appendChild(span);
    planeItem.setAttribute("id", p.id);
    planeList.appendChild(planeItem);
}

var drawRadar = function(){
    context.lineWidth = 5;
    context.strokeStyle = '#000';
    context.fillStyle = "rgba(52, 152, 219, 0.8)";
    for (var i = 5; i >= 0; i--) {
        drawCircle(circleInitialPosition, circleInitialPosition, i * 100);
    };

    context.moveTo(0, circleInitialPosition);
    context.lineTo(canvasSize, circleInitialPosition);
    context.moveTo(circleInitialPosition, 0);
    context.lineTo(circleInitialPosition, canvasSize);
    context.stroke();
}

var drawLine = function(){
    var center = circleInitialPosition;
    context.lineWidth = 8;
    startAngle += 0.01;
    context.moveTo(center, center);
    context.lineTo(center + center * Math.cos(startAngle), center + center * Math.sin(startAngle));
    context.stroke();
}

var drawPlanes = function(){
    createPlane();
    planes.forEach(function(p, i){
        if(!p.isOutOfBound) {
            context.fillStyle = p.isSelected ? "rgb(50, 0, 0)" : "rgb(200, 0, 0)";
            p.draw();
        }
        else {
            var planeItem = document.getElementById(p.id);
            planeList.removeChild(planeItem);
            planes.splice(i, 1);
        }
    });
}

var draw = function() {
    context.clearRect(0, 0, canvasSize, canvasSize);
    drawRadar();
    drawPlanes();
    drawLine();
    drawSelector();
}

var drawCircle = function(x, y, rayon){
    context.beginPath();
    context.arc(x, y, rayon, 0, Math.PI*2);
    context.fill();
    context.closePath();
    context.stroke();
}

function writeMessage(message) {
    mousePosition.innerHTML = message
}

function getMousePos(canvas, evt) {
    var rect = canvas.getBoundingClientRect();
    return {
        x: evt.clientX - rect.left,
        y: evt.clientY - rect.top
    };
}

var initialSelectorPosition = null;
var currentSelectorPosition = null;

canvas.addEventListener('mousemove', function(e) {
  var mousePos = getMousePos(canvas, e);
  var message = 'X: ' + Math.round(mousePos.x) + ' Y: ' + Math.round(mousePos.y);
  writeMessage(message);
}, false);

canvas.addEventListener('mousedown', function(e){
    initialSelectorPosition = getMousePos(canvas, e);
    currentSelectorPosition = initialSelectorPosition;
    canvas.addEventListener('mousemove', setSelector);
    canvas.addEventListener('mouseup', selectPlane);
});

function selectPlane(){
    canvas.removeEventListener('mousemove', setSelector);
    canvas.removeEventListener('mouseup', selectPlane);

    planes.forEach(function(p, i){
        p.isSelected = isPointInRect(initialSelectorPosition, currentSelectorPosition, { x: p.x, y: p.y});
    });

    clearSelector();
}

function clearSelector(){
    initialSelectorPosition = null;
    currentSelectorPosition = null;
}

function setSelector(e){
    currentSelectorPosition = getMousePos(canvas, e);
}

function drawSelector(){
    if(initialSelectorPosition && currentSelectorPosition){
        context.globalAlpha=0.5;
        context.fillStyle = "rgb(200, 0, 0)";
        var lx = currentSelectorPosition.x - initialSelectorPosition.x
        var ly = currentSelectorPosition.y - initialSelectorPosition.y
        context.fillRect(initialSelectorPosition.x, initialSelectorPosition.y, lx, ly);
        context.globalAlpha= 1;
    }
}

function rectArea(a, b, c) {
    return Math.abs((b.x - a.x) * (c.y - a.y));
}

function isPointInRect(ra, rc, p) {
    var minX, maxX, minY, maxY;
    if(ra.x <= rc.x) {
        minX = ra.x;
        maxX = rc.x;
    } else {
        minX = rc.x;
        maxX = ra.x;
    }

    if(ra.y <= rc.y) {
        minY = ra.y;
        maxY = rc.y;
    } else {
        minY = rc.y;
        maxY = ra.y;
    }

    return p.x >= minX && p.x <= maxX && p.y >= minY && p.y <= maxY
}

window.onload = function(){
    setInterval(draw, 1000/60);
}<|endoftext|>


<commit_before>import { default as React, Component } from 'react';
import { render } from 'react-dom';
import Select2 from 'react-select2-wrapper';
import { dataOperation } from '../../service/DataOperation';
import { ErrorModal } from '../../others/ErrorModal';
import { MappingLink } from '../../appLogin/MappingLink';

var Codemirror = require('react-codemirror');
require('codemirror/mode/markdown/markdown');
require('codemirror/addon/search/searchcursor.js');
require('codemirror/addon/search/search.js');
require('codemirror/addon/dialog/dialog.js');
require('codemirror/addon/edit/matchbrackets.js');
require('codemirror/addon/edit/closebrackets.js');
require('codemirror/addon/comment/comment.js');
require('codemirror/addon/display/placeholder');
require('codemirror/addon/fold/foldcode.js');
require('codemirror/addon/fold/foldgutter.js');
require('codemirror/addon/fold/brace-fold.js');
require('codemirror/addon/fold/xml-fold.js');
require('codemirror/addon/fold/markdown-fold.js');
require('codemirror/addon/fold/comment-fold.js');

export class JsonImport extends Component {
  constructor(props) {
    super(props);
    this.sample = null;
  	this.state = {
  		code: '',
      error: {
        title: null,
        message: null
      },
      validFlag: false,
      importType: "data",
      mappingObj: {
        inputFormat: 'data',
        input: {}
      }
  	};
    this.codemirrorOptions = {
      lineNumbers: false,
      mode: "markdown",
      autoCloseBrackets: true,
      matchBrackets: true,
      showCursorWhenSelecting: true,
      tabSize: 2,
      extraKeys: {"Ctrl-Q": function(cm){ cm.foldCode(cm.getCursor()); }},
      foldGutter: true,
      gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
    };
    this.onTypeSelection = this.onTypeSelection.bind(this);
  	this.updateCode = this.updateCode.bind(this);
    this.closeError = this.closeError.bind(this);
    this.submit = this.submit.bind(this);
    this.importTypeChange = this.importTypeChange.bind(this);
  }
  componentWillMount() {
    if(this.props.input_mapping && this.props.input_mapping.inputFormat && this.props.input_mapping.input) {
      let stateObj = {
        mappingObj: this.props.input_mapping,
        importType: this.props.input_mapping.inputFormat,
        code: JSON.stringify(this.props.input_mapping.input, null, 4),
        selectedType: this.props.input_mapping.selectedType ? this.props.input_mapping.selectedType : ''
      };
      this.setState(stateObj, this.submit.bind(this));
    } else {
      this.submit.call(this);
    }
  }
  updateCode(newCode) {
    this.setState({
  	    code: newCode
  	}, this.submit.bind(this));
  }
  submit() {
    if(this.state.selectedType) {
      let isJson = this.isJson(this.state.code);
      let updateObj = {
        validFlag: isJson.validFlag
      };
      if(isJson.validFlag) {
        let parsedJson = isJson.jsonInput;
        this.props.detectMapping(parsedJson, this.state.selectedType, this.state.importType);
        updateObj.mappingObj = {
          inputFormat: this.state.importType,
          input: parsedJson,
          selectedType: this.state.selectedType
        };
      }
      this.setState(updateObj);
    }
  }
  closeError() {
    let error = this.state.error;
    error.title = null;
    error.message = null;
    this.setState({
      error: error
    });
  }
  isJson(jsonInput) {
    let validFlag = true;
    if (jsonInput != "") {
      try {
        jsonInput = JSON.parse(jsonInput);
      } catch (e) {
        validFlag = false;
      }
    } else {
      validFlag = false;
    }
    return {
      validFlag: validFlag,
      jsonInput: jsonInput
    };
  }
  onTypeSelection(select) {
    let selectedType = select.currentTarget.value;
    if(selectedType) {
      this.setState({
        selectedType
      }, this.submit);
    }
  }
  getValidMessage() {
    return this.props.mappings ? (this.props.successMessage ? this.props.successMessage : (this.state.selectedType ? (this.state.validFlag ? 'JSON is valid  ☺.' : 'JSON is invalid  ☹.') : 'Type is not selected')) : 'Appname and url is not preset.';
  }
  importTypeChange(type) {
    this.setState({
      importType: type
    }, this.submit.bind(this));
  }
  radioOptions() {
    return (

            <input type="radio"
              checked={this.state.importType === 'data'}
              onChange={() => this.importTypeChange('data')}
              name="importType" id="importType" value="data" /> Data as JSON

            <input type="radio"
              checked={this.state.importType === 'mapping'}
              onChange={() => this.importTypeChange('mapping')}
              name="importType1" id="importType1" value="mapping" /> Mappings as JSON

    );
  }
  renderComponent(method) {
    let element;
    switch(method) {
      case 'label':
      if(this.state.selectedType && this.state.selectedType != '') {
        element = (Selected Type:);
      }
      break;
    }
    return element;
  }
  render() {
    this.types = [];
    if(this.props.mappings) {
      this.types = Object.keys(this.props.mappings);
      if(this.props.input_mapping && this.props.input_mapping.selectedType && this.types.indexOf(this.props.input_mapping.selectedType) < 0) {
        this.types.push(this.props.input_mapping.selectedType);
      }
      this.types.unshift('');
    } else if(this.props.input_mapping.selectedType) {
      this.types.push(this.props.input_mapping.selectedType);
    }
    return (

            <MappingLink shareAllowed={this.state.validFlag} mappingObj={this.state.mappingObj} />

              {this.radioOptions()}

              {this.renderComponent('label')}

                <Select2
                  multiple={false}
                  data={ this.types }
                  value={this.state.selectedType}
                  options={{
                    placeholder: 'Choose or create a Type',
                    tags: {true}
                  }}
                  onChange={this.onTypeSelection}
                />

          {this.getValidMessage()}

    		<Codemirror ref="editor" value={this.state.code} onChange={this.updateCode}
        placeholder='Add json here' options={this.codemirrorOptions} />
    		<ErrorModal {...this.state.error} closeError={this.closeError} />

    );
  }
}
<commit_msg>Disable share url for if appname and url is not present<commit_after>import { default as React, Component } from 'react';
import { render } from 'react-dom';
import Select2 from 'react-select2-wrapper';
import { dataOperation } from '../../service/DataOperation';
import { ErrorModal } from '../../others/ErrorModal';
import { MappingLink } from '../../appLogin/MappingLink';

var Codemirror = require('react-codemirror');
require('codemirror/mode/markdown/markdown');
require('codemirror/addon/search/searchcursor.js');
require('codemirror/addon/search/search.js');
require('codemirror/addon/dialog/dialog.js');
require('codemirror/addon/edit/matchbrackets.js');
require('codemirror/addon/edit/closebrackets.js');
require('codemirror/addon/comment/comment.js');
require('codemirror/addon/display/placeholder');
require('codemirror/addon/fold/foldcode.js');
require('codemirror/addon/fold/foldgutter.js');
require('codemirror/addon/fold/brace-fold.js');
require('codemirror/addon/fold/xml-fold.js');
require('codemirror/addon/fold/markdown-fold.js');
require('codemirror/addon/fold/comment-fold.js');

export class JsonImport extends Component {
  constructor(props) {
    super(props);
    this.sample = null;
  	this.state = {
  		code: '',
      error: {
        title: null,
        message: null
      },
      validFlag: false,
      importType: "data",
      mappingObj: {
        inputFormat: 'data',
        input: {}
      }
  	};
    this.codemirrorOptions = {
      lineNumbers: false,
      mode: "markdown",
      autoCloseBrackets: true,
      matchBrackets: true,
      showCursorWhenSelecting: true,
      tabSize: 2,
      extraKeys: {"Ctrl-Q": function(cm){ cm.foldCode(cm.getCursor()); }},
      foldGutter: true,
      gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
    };
    this.onTypeSelection = this.onTypeSelection.bind(this);
  	this.updateCode = this.updateCode.bind(this);
    this.closeError = this.closeError.bind(this);
    this.submit = this.submit.bind(this);
    this.importTypeChange = this.importTypeChange.bind(this);
  }
  componentWillMount() {
    if(this.props.input_mapping && this.props.input_mapping.inputFormat && this.props.input_mapping.input) {
      let stateObj = {
        mappingObj: this.props.input_mapping,
        importType: this.props.input_mapping.inputFormat,
        code: JSON.stringify(this.props.input_mapping.input, null, 4),
        selectedType: this.props.input_mapping.selectedType ? this.props.input_mapping.selectedType : ''
      };
      this.setState(stateObj, this.submit.bind(this));
    } else {
      this.submit.call(this);
    }
  }
  updateCode(newCode) {
    this.setState({
  	    code: newCode
  	}, this.submit.bind(this));
  }
  submit() {
    if(this.state.selectedType) {
      let isJson = this.isJson(this.state.code);
      let updateObj = {
        validFlag: isJson.validFlag
      };
      if(isJson.validFlag) {
        let parsedJson = isJson.jsonInput;
        this.props.detectMapping(parsedJson, this.state.selectedType, this.state.importType);
        updateObj.mappingObj = {
          inputFormat: this.state.importType,
          input: parsedJson,
          selectedType: this.state.selectedType
        };
      }
      this.setState(updateObj);
    }
  }
  closeError() {
    let error = this.state.error;
    error.title = null;
    error.message = null;
    this.setState({
      error: error
    });
  }
  isJson(jsonInput) {
    let validFlag = true;
    if (jsonInput != "") {
      try {
        jsonInput = JSON.parse(jsonInput);
      } catch (e) {
        validFlag = false;
      }
    } else {
      validFlag = false;
    }
    return {
      validFlag: validFlag,
      jsonInput: jsonInput
    };
  }
  onTypeSelection(select) {
    let selectedType = select.currentTarget.value;
    if(selectedType) {
      this.setState({
        selectedType
      }, this.submit);
    }
  }
  getValidMessage() {
    return this.props.mappings ? (this.props.successMessage ? this.props.successMessage : (this.state.selectedType ? (this.state.validFlag ? 'JSON is valid  ☺.' : 'JSON is invalid  ☹.') : 'Type is not selected')) : 'Appname and url is not preset.';
  }
  importTypeChange(type) {
    this.setState({
      importType: type
    }, this.submit.bind(this));
  }
  radioOptions() {
    return (

            <input type="radio"
              checked={this.state.importType === 'data'}
              onChange={() => this.importTypeChange('data')}
              name="importType" id="importType" value="data" /> Data as JSON

            <input type="radio"
              checked={this.state.importType === 'mapping'}
              onChange={() => this.importTypeChange('mapping')}
              name="importType1" id="importType1" value="mapping" /> Mappings as JSON

    );
  }
  renderComponent(method) {
    let element;
    switch(method) {
      case 'label':
      if(this.state.selectedType && this.state.selectedType != '') {
        element = (Selected Type:);
      }
      break;
    }
    return element;
  }
  render() {
    this.types = [];
    if(this.props.mappings) {
      this.types = Object.keys(this.props.mappings);
      if(this.props.input_mapping && this.props.input_mapping.selectedType && this.types.indexOf(this.props.input_mapping.selectedType) < 0) {
        this.types.push(this.props.input_mapping.selectedType);
      }
      this.types.unshift('');
    } else if(this.props.input_mapping.selectedType) {
      this.types.push(this.props.input_mapping.selectedType);
    }
    return (

            <MappingLink shareAllowed={this.state.validFlag && this.props.mappings} mappingObj={this.state.mappingObj} />

              {this.radioOptions()}

              {this.renderComponent('label')}

                <Select2
                  multiple={false}
                  data={ this.types }
                  value={this.state.selectedType}
                  options={{
                    placeholder: 'Choose or create a Type',
                    tags: {true}
                  }}
                  onChange={this.onTypeSelection}
                />

          {this.getValidMessage()}

    		<Codemirror ref="editor" value={this.state.code} onChange={this.updateCode}
        placeholder='Add json here' options={this.codemirrorOptions} />
    		<ErrorModal {...this.state.error} closeError={this.closeError} />

    );
  }
}
<|endoftext|>