<commit_before>import { Meteor } from 'meteor/meteor';

import { MeetingSeries } from '/imports/meetingseries'
import { UsersEditConfig } from './meetingSeriesEditUsers'
import { UserRoles } from '/imports/userroles'

Template.meetingSeriesEdit.onCreated(function() {
    let thisMeetingSeriesID = this.data._id;

    // create client-only collection for storage of users attached
    // to this meeting series as input <=> output for the user editor
    let _attachedUsersCollection = new Mongo.Collection(null);

    // build editor config and attach it to the instance of the template
    this.userEditConfig = new UsersEditConfig(
        true,                                               // current user can not be edited
        thisMeetingSeriesID,                                // the meeting series id
        _attachedUsersCollection);                          // collection of attached users

    // Hint: collection will be filled in the "show.bs.modal" event below
});

Template.meetingSeriesEdit.helpers({
    users: function () {
        return Meteor.users.find({});
    },

    userEditConfig: function () {
        return Template.instance().userEditConfig;
    },

    labelsConfig: function() {
        return {
            meetingSeriesId: this._id
        };
    },

    // some responsive CSS tweaking
    useClassWell() {
        if (! Session.get("global.isMobileWidth")) {
            return "well";
        }
    }
});

Template.meetingSeriesEdit.events({

    "click #deleteMeetingSeries": function() {
        console.log("Remove Meeting Series: "+this._id);
        $('#dlgEditMeetingSeries').modal('hide');   // hide underlying modal dialog first, otherwise transparent modal layer is locked!

        let ms = new MeetingSeries(this._id);
        let countMinutes = ms.countMinutes();
        let seriesName = "" + ms.project + ": " + ms.name + "";
        let dialogContent = "
Do you really want to delete the meeting series " + seriesName + "?
";
        if (countMinutes !== 0) {
            let lastMinDate = ms.lastMinutes().date;
            dialogContent += "
This series contains " + countMinutes
                + " meeting minutes (last minutes of " + lastMinDate + ").
";
        }

        confirmationDialog(
            /* callback called if user wants to continue */
            () => {
                MeetingSeries.remove(ms);
                Router.go("/");
            },
            dialogContent
        );
    },

    // "show" event is fired shortly before BootStrap modal dialog will pop up
    // We fill the temp. client-side only user database for the user editor on this event
    "show.bs.modal #dlgEditMeetingSeries": function (evt, tmpl) {
        // Make sure these init values are filled in a close/re-open scenario
        $("#btnMeetingSeriesSave").prop("disabled",false);
        $("#btnMeetinSeriesEditCancel").prop("disabled",false);
        tmpl.find("#id_meetingproject").value = this.project;
        tmpl.find("#id_meetingname").value = this.name;

        Template.instance().userEditConfig.users.remove({});    // first: clean up everything!

        // copy all attached users of this series to the temp. client-side user collection
        // and save their original _ids for later reference
        for (let i in this.visibleFor) {
            let user = Meteor.users.findOne(this.visibleFor[i]);
            user._idOrg = user._id;
            delete user._id;
            Template.instance().userEditConfig.users.insert(user);
        }
    },

    "shown.bs.modal #dlgEditMeetingSeries": function (evt, tmpl) {
        $('#dlgEditMeetingSeries input').trigger("change");   // ensure new values trigger placeholder animation
        tmpl.find("#id_meetingproject").focus();
    },

    "submit #frmDlgEditMeetingSeries": function(evt, tmpl) {
        evt.preventDefault();
        let saveButton = $("#btnMeetingSeriesSave");
        let cancelButton = $("btnMeetinSeriesEditCancel");
        saveButton.prop("disabled",true);
        cancelButton.prop("disabled",true);

        var aProject = tmpl.find("#id_meetingproject").value;
        var aName = tmpl.find("#id_meetingname").value;

        // validate form and show errors - necessary for browsers which do not support form-validation
        let projectNode = tmpl.$("#id_meetingproject");
        let nameNode = tmpl.$("#id_meetingname");
        projectNode.parent().removeClass("has-error");
        nameNode.parent().removeClass("has-error");
        if (aProject == "") {
            projectNode.parent().addClass("has-error");
            projectNode.focus();
            return;
        }
        if (aName == "") {
            nameNode.parent().addClass("has-error");
            nameNode.focus();
            return;
        }

        let usersWithRoles = Template.instance().userEditConfig.users.find().fetch();
        let allVisiblesArray = [];
        let meetingSeriesId = this._id;
        for (let i in usersWithRoles) {
            let usr = usersWithRoles[i];
            let ur = new UserRoles(usr._idOrg);     // Attention: get back to Id of Meteor.users collection
            ur.saveRoleForMeetingSeries(this._id, usr.roles[meetingSeriesId]);
            if (UserRoles.isVisibleRole(usr.roles[this._id])) {
                allVisiblesArray.push(usr._idOrg);  // Attention: get back to Id of Meteor.users collection
            }
        }

        ms = new MeetingSeries(meetingSeriesId);
        ms.project = aProject;
        ms.name = aName;
        ms.setVisibleUsers(allVisiblesArray);
        ms.save();

        // Hide modal dialog
        saveButton.prop("disabled",false);
        cancelButton.prop("disabled",false);
        $('#dlgEditMeetingSeries').modal('hide');
    },

    "click #btnMeetingSeriesSave": function (evt, tmpl) {
        evt.preventDefault();
        // Unfortunately the form.submit()-function does not trigger the
        // validation process
        tmpl.$('#frmDlgEditMeetingSeries').find(':submit').click();
    },

    // Prevent the last open panel to be collapsible
    "click .panel-heading a": function (evt) {
        if($(evt.target).parents('.panel').children('.panel-collapse').hasClass('in')){
            evt.stopPropagation();
        }
        evt.preventDefault();
    }
});
<commit_msg>Remove unused code<commit_after>import { Meteor } from 'meteor/meteor';

import { MeetingSeries } from '/imports/meetingseries'
import { UsersEditConfig } from './meetingSeriesEditUsers'
import { UserRoles } from '/imports/userroles'

Template.meetingSeriesEdit.onCreated(function() {
    let thisMeetingSeriesID = this.data._id;

    // create client-only collection for storage of users attached
    // to this meeting series as input <=> output for the user editor
    let _attachedUsersCollection = new Mongo.Collection(null);

    // build editor config and attach it to the instance of the template
    this.userEditConfig = new UsersEditConfig(
        true,                                               // current user can not be edited
        thisMeetingSeriesID,                                // the meeting series id
        _attachedUsersCollection);                          // collection of attached users

    // Hint: collection will be filled in the "show.bs.modal" event below
});

Template.meetingSeriesEdit.helpers({
    users: function () {
        return Meteor.users.find({});
    },

    userEditConfig: function () {
        return Template.instance().userEditConfig;
    },

    labelsConfig: function() {
        return {
            meetingSeriesId: this._id
        };
    }
});

Template.meetingSeriesEdit.events({

    "click #deleteMeetingSeries": function() {
        console.log("Remove Meeting Series: "+this._id);
        $('#dlgEditMeetingSeries').modal('hide');   // hide underlying modal dialog first, otherwise transparent modal layer is locked!

        let ms = new MeetingSeries(this._id);
        let countMinutes = ms.countMinutes();
        let seriesName = "" + ms.project + ": " + ms.name + "";
        let dialogContent = "
Do you really want to delete the meeting series " + seriesName + "?
";
        if (countMinutes !== 0) {
            let lastMinDate = ms.lastMinutes().date;
            dialogContent += "
This series contains " + countMinutes
                + " meeting minutes (last minutes of " + lastMinDate + ").
";
        }

        confirmationDialog(
            /* callback called if user wants to continue */
            () => {
                MeetingSeries.remove(ms);
                Router.go("/");
            },
            dialogContent
        );
    },

    // "show" event is fired shortly before BootStrap modal dialog will pop up
    // We fill the temp. client-side only user database for the user editor on this event
    "show.bs.modal #dlgEditMeetingSeries": function (evt, tmpl) {
        // Make sure these init values are filled in a close/re-open scenario
        $("#btnMeetingSeriesSave").prop("disabled",false);
        $("#btnMeetinSeriesEditCancel").prop("disabled",false);
        tmpl.find("#id_meetingproject").value = this.project;
        tmpl.find("#id_meetingname").value = this.name;

        Template.instance().userEditConfig.users.remove({});    // first: clean up everything!

        // copy all attached users of this series to the temp. client-side user collection
        // and save their original _ids for later reference
        for (let i in this.visibleFor) {
            let user = Meteor.users.findOne(this.visibleFor[i]);
            user._idOrg = user._id;
            delete user._id;
            Template.instance().userEditConfig.users.insert(user);
        }
    },

    "shown.bs.modal #dlgEditMeetingSeries": function (evt, tmpl) {
        $('#dlgEditMeetingSeries input').trigger("change");   // ensure new values trigger placeholder animation
        tmpl.find("#id_meetingproject").focus();
    },

    "submit #frmDlgEditMeetingSeries": function(evt, tmpl) {
        evt.preventDefault();
        let saveButton = $("#btnMeetingSeriesSave");
        let cancelButton = $("btnMeetinSeriesEditCancel");
        saveButton.prop("disabled",true);
        cancelButton.prop("disabled",true);

        var aProject = tmpl.find("#id_meetingproject").value;
        var aName = tmpl.find("#id_meetingname").value;

        // validate form and show errors - necessary for browsers which do not support form-validation
        let projectNode = tmpl.$("#id_meetingproject");
        let nameNode = tmpl.$("#id_meetingname");
        projectNode.parent().removeClass("has-error");
        nameNode.parent().removeClass("has-error");
        if (aProject == "") {
            projectNode.parent().addClass("has-error");
            projectNode.focus();
            return;
        }
        if (aName == "") {
            nameNode.parent().addClass("has-error");
            nameNode.focus();
            return;
        }

        let usersWithRoles = Template.instance().userEditConfig.users.find().fetch();
        let allVisiblesArray = [];
        let meetingSeriesId = this._id;
        for (let i in usersWithRoles) {
            let usr = usersWithRoles[i];
            let ur = new UserRoles(usr._idOrg);     // Attention: get back to Id of Meteor.users collection
            ur.saveRoleForMeetingSeries(this._id, usr.roles[meetingSeriesId]);
            if (UserRoles.isVisibleRole(usr.roles[this._id])) {
                allVisiblesArray.push(usr._idOrg);  // Attention: get back to Id of Meteor.users collection
            }
        }

        ms = new MeetingSeries(meetingSeriesId);
        ms.project = aProject;
        ms.name = aName;
        ms.setVisibleUsers(allVisiblesArray);
        ms.save();

        // Hide modal dialog
        saveButton.prop("disabled",false);
        cancelButton.prop("disabled",false);
        $('#dlgEditMeetingSeries').modal('hide');
    },

    "click #btnMeetingSeriesSave": function (evt, tmpl) {
        evt.preventDefault();
        // Unfortunately the form.submit()-function does not trigger the
        // validation process
        tmpl.$('#frmDlgEditMeetingSeries').find(':submit').click();
    },

    // Prevent the last open panel to be collapsible
    "click .panel-heading a": function (evt) {
        if($(evt.target).parents('.panel').children('.panel-collapse').hasClass('in')){
            evt.stopPropagation();
        }
        evt.preventDefault();
    }
});
<|endoftext|>


<commit_before>

    var i18n = {
        "en" : {
            "archimedes.experiment": "Archimedes Experiment",
            "time.remaining": "Time remaining",
            "ball.weight.liquid.level" : "Ball weight & Liquid level",
            "close": "Close",
            "hd.picture" : "HD Picture",

            "show": "Show",
            "hide": "Hide",

            "showInstancesHelpTitle": "Show or hide a particular tube",
            "showInstancesHelpContent": "Sometimes you may want to only display some of the available tubes.
This way, the screen can be made less cluttered when not all tubes are needed.
To choose which instances to show or hide, simply click on their button to toggle their state.",

            "sensorsHelpTitle": "Sensor information",
            "sensorsHelpContent": "The sensors tab displays the data that is reported by the physical level and weight sensors.
This data is automatically refreshed.

Due to the nature of physical sensors, you should not necessarily expect this data to be fully accurate.
Particularly, you should notice that, for instance, when the ball is in the water, the weight sensor will often report a number close to zero when the ball is floating.

Likewise, because these sensors are real, if the data were wrong, it would likely be due to some kind of hardware error.",

            "sensors": "Sensors",
            "liquid": "Liquid",
            "liquid/tube": "Liquid/Tube",
            "ball": "Ball",
            "liquid.level": "Liquid Level",
            "ball.weight": "Ball Weight",
            "volume": "Volume",
            "diameter": "Diameter",
            "internal.diameter": "Internal Diameter",
            "density": "Density",
            "mass": "Mass",
            "grams": "gr",
            "cm": "cm",
            "kgm3": "kg/m³",
            "gcm3": "gr/cm³",
            "m3": "m³",
            "cm3": "cm³",

            // For the Weight/Time plot
            "plot.explanation": "Measures the perceived weight of the ball as reported by the sensor. The depicted timeframe is that of the last ball movement.",
            "time.weight.plot" : "Time / Weight Plot",
            "weight.g" : "Weight (g)",
            "seconds.s" : "Seconds (s)",

            // For the instance names.
            "instance1": "1st Tube",
            "instance2": "2nd Tube",
            "instance3": "3rd Tube",
            "instance4": "4th Tube",
            "instance5": "5th Tube",
            "instance6": "6th Tube",
            "instance7": "7th Tube",
            "instance8": "8th Tube",

            "toggle-show-hide": "Toggle to show or hide each tube
"
        }
    };

    $.i18n.load(i18n["en"]);

    var Registry = {
        "archimedes1" : {
            "name": $.i18n._("instance1"),
            "ball_mass": 134, // g
            "ball_diameter": 8.0, // cm
            "ball_density": 0.5,
            "object_density": 0.5,
            "object_volume": 268,
            "object_type": "Ball",
            "liquid_name": "water",
            "liquid_density": 1000, // 1000/m3
            "liquid_diameter": 9.4, // cm
            "webcam": "//cams.weblab.deusto.es/webcam/proxied.py/arquimedes1_rotate"
        },
        "archimedes2" : {
            "name": $.i18n._("instance2"),
            "ball_mass": 56,
            "ball_diameter": 6.0, // cm
            "ball_density": 0.5,
            "object_density": 1.32,
            "object_volume": 113.10,
            "object_type": "Ball",
            "liquid_name": "water",
            "liquid_density": 1000,
            "liquid_diameter": 7, // cm
            "webcam": "//cams.weblab.deusto.es/webcam/proxied.py/arquimedes2_rotate"
        },
        "archimedes3" : {
            "name": $.i18n._("instance3"),
            "ball_mass": 134,
            "ball_diameter": 6, // cm
            "ball_density": 1.18,
            "object_density": 1.18,
            "object_volume": 113.10,
            "object_type": "Ball",
            "liquid_density": 1000, // 1000/m3
            "liquid_diameter": 7, // cm
            "liquid_name": "water",
            "webcam": "//cams.weblab.deusto.es/webcam/proxied.py/arquimedes3_rotate"
        },
        "archimedes4" : {
            "name": $.i18n._("instance4"),
            "ball_mass": 111,
            "ball_diameter": 6, // cm
            "ball_density": 0.98,
            "object_density": 0.98,
            "object_volume": 113.10,
            "object_type": "Ball",
            "liquid_density": 1000, // 1000/m3
            "liquid_diameter": 7, // cm
            "liquid_name": "water",
            "webcam": "//cams.weblab.deusto.es/webcam/proxied.py/arquimedes4_rotate"
        },
        "archimedes5" : {
            "name": $.i18n._("instance5"),
            "ball_mass": 111,
            "ball_diameter": 6.0    , // cm
            "ball_density": 0.98,
            "object_density": 0.98,
            "object_volume": 113.10,
            "object_type": "Ball",
            "liquid_density": 900, // 900/m3
            "liquid_diameter": 7, // cm
            "liquid_name": "oil",
            "webcam": "//cams.weblab.deusto.es/webcam/proxied.py/arquimedes5_rotate"
        },
        "archimedes6" : {
            "name": $.i18n._("instance6"),
            "ball_mass": 89.3,
            "ball_density": 0.79,
            "object_density": 0.79,
            "object_volume": 113.10,
            "object_type": "Ball",
            "ball_diameter": 6, // cm
            "liquid_density": 1000, // 1000/m3
            "liquid_diameter": 7, // cm
            "liquid_name": "water",
            "webcam": "//cams.weblab.deusto.es/webcam/proxied.py/arquimedes6_rotate"
        },
        "archimedes7" : {
            "name": $.i18n._("instance7"),
            "ball_mass": 50.9,
            "ball_density": 0.78,
            "object_density": 0.78,
            "object_volume": 65.45,
            "object_type": "Ball",
            "ball_diameter": 5, // cm
            "liquid_density": 1000, // 1000/m3
            "liquid_diameter": 7, // cm
            "liquid_name": "water",
            "webcam": "//cams.weblab.deusto.es/webcam/proxied.py/arquimedes7_rotate"
        }
    };

    // Possible values:
    // ["controls", "sensor_weight", "sensor_level", "webcam", "hdcam", "plot", "ball_mass", "ball_volume",
    // "ball_diameter", "ball_density", "liquid_density", "liquid_diameter", "liquid_volume"]
    var View = {
        "archimedes1" : ["controls", "sensor_weight",  "sensor_level", "webcam", "hdcam", "plot", "ball_mass",
            "ball_volume", "ball_diameter", "ball_density", "liquid_density", "liquid_diameter"],
        "archimedes2" : "ALL",
        "archimedes3" : ["controls", "sensor_level", "sensor_weight", "webcam", "hdcam", "plot", "ball_mass",
            "ball_volume", "ball_diameter", "ball_density", "liquid_density", "liquid_diameter"], // Fake weight
        "archimedes4" : "ALL",
        "archimedes5" : ["controls", "sensor_level", "sensor_weight", "webcam", "hdcam", "plot", "ball_mass",
            "ball_volume", "ball_diameter", "ball_density", "liquid_density", "liquid_diameter"], // Fake weight
        "archimedes6" : ["controls", "sensor_level", "sensor_weight", "webcam", "hdcam", "plot", "ball_mass",
            "ball_volume", "ball_diameter", "ball_density", "liquid_density", "liquid_diameter"], // Fake weight
        "archimedes7" : ["controls", "sensor_level", "sensor_weight", "webcam", "hdcam", "plot", "ball_mass",
            "ball_volume", "ball_diameter", "ball_density", "liquid_density", "liquid_diameter"]  // Fake weight
    };

    var EDTFilter = {
        //"ball_mass" : 20
    };

    //! Pseudo-class to manage EDT-config filtering.
    //!
    EDT = new function() {

        this.filters = {

            //! @param instance: Instance to check.
            //! @param edtvalue: Specified edtvalue.
            //! @return: True if the instance meets the criteria.
            "ball_mass" : function(instance, grams) {
                return instance["ball_mass"] == grams; // ball_mass expected in grams
            },
            "ball_volume" : function(instance, volcm3) {
                var radius_cm = 0.5 * instance["ball_diameter"];
                var vol_cm3 = (4/3) * Math.PI * radius_cm * radius_cm * radius_cm; // ball_volume expected in cm3
                return vol_cm3 == volcm3;
            },
            "liquid_density" : function(instance, kgm3) {
                return instance["liquid_density"] == kgm3;
            }

        };

        //! Gets the result of filtering the global Registry with the global EDTFilter filter.
        //! (Applying it to the View).
        this.getFilteredView = function() {

            // Clone the view.
            view = JSON.parse(JSON.stringify(View));

            var that = this;
            $.each(Registry, function(name, instance) {
                $.each(EDTFilter, function(variable, value) {
                    if(variable in that.filters)
                        // If the filter check returns false we remove the instance from the list to show.
                        if(!that.filters[variable](instance, value)) {
                            delete view[name];
                        }
                });
            });

            return view;
        }; // !getFilteredRegistry

    }; // !EDT

    //! Global pseudo-class which will be used through the code
    //! to access the current view etc.
    Configuration = new function() {

        //! Returns the current global registry.
        this.getRegistry = function() {
            return Registry;
        };

        //! Returns the current view, filtered by the Registry and the EDTFilter.
        this.getView = function() {
            return EDT.getFilteredView();
        };

    };

<commit_msg>Add basque translation of the archimedes lab<commit_after>

    var i18n = {
        "en" : {
            "archimedes.experiment": "Archimedes Experiment",
            "time.remaining": "Time remaining",
            "ball.weight.liquid.level" : "Ball weight & Liquid level",
            "close": "Close",
            "hd.picture" : "HD Picture",

            "show": "Show",
            "hide": "Hide",

            "showInstancesHelpTitle": "Show or hide a particular tube",
            "showInstancesHelpContent": "Sometimes you may want to only display some of the available tubes.
This way, the screen can be made less cluttered when not all tubes are needed.
To choose which instances to show or hide, simply click on their button to toggle their state.",

            "sensorsHelpTitle": "Sensor information",
            "sensorsHelpContent": "The sensors tab displays the data that is reported by the physical level and weight sensors.
This data is automatically refreshed.

Due to the nature of physical sensors, you should not necessarily expect this data to be fully accurate.
Particularly, you should notice that, for instance, when the ball is in the water, the weight sensor will often report a number close to zero when the ball is floating.

Likewise, because these sensors are real, if the data were wrong, it would likely be due to some kind of hardware error.",

            "sensors": "Sensors",
            "liquid": "Liquid",
            "liquid/tube": "Liquid/Tube",
            "ball": "Ball",
            "liquid.level": "Liquid Level",
            "ball.weight": "Ball Weight",
            "volume": "Volume",
            "diameter": "Diameter",
            "internal.diameter": "Internal Diameter",
            "density": "Density",
            "mass": "Mass",
            "grams": "gr",
            "cm": "cm",
            "kgm3": "kg/m³",
            "gcm3": "gr/cm³",
            "m3": "m³",
            "cm3": "cm³",

            // For the Weight/Time plot
            "plot.explanation": "Measures the perceived weight of the ball as reported by the sensor. The depicted timeframe is that of the last ball movement.",
            "time.weight.plot" : "Time / Weight Plot",
            "weight.g" : "Weight (g)",
            "seconds.s" : "Seconds (s)",

            // For the instance names.
            "instance1": "1st Tube",
            "instance2": "2nd Tube",
            "instance3": "3rd Tube",
            "instance4": "4th Tube",
            "instance5": "5th Tube",
            "instance6": "6th Tube",
            "instance7": "7th Tube",
            "instance8": "8th Tube",

            "toggle-show-hide": "Toggle to show or hide each tube
"
        },
        "eu" : {
            "cm": "cm",
            "instance5": "5. Hodia",
            "close": "Itxi",
            "showInstancesHelpContent": "Batzuetan erabilgarri dauden hodiak bakarrik erakutsi nahi izango dituzu.
Modu horretan, hodi guztiak beharrezkoak ez direnean pantaila argiago agertuko da.
 Ze instantzia erkutsi edo ezkutatuko den aukeratzeko, bere egoera aldatzeko botoia soilik klikatu behar duzu.",
            "plot.explanation": "Bolaren hautemandako balioa sensorearen informazioaren arabera neurtzen du. Deskribatutako denbora tartea bolaren azken mugimenduarena da.",
            "hide": "Ezkutatu",
            "hd.picture": "HD Irudia",
            "density": "Dentsitatea",
            "sensors": "Sentsoreak",
            "show": "Erakutsi",
            "diameter": "Diametroa",
            "seconds.s": "Segunduak (s)",
            "liquid.level": "Likidoaren Maila",
            "m3": "m?",
            "showInstancesHelpTitle": "Hodi jakin bat erakutsi edo ezkutatu",
            "sensorsHelpContent": "Sensorearen fitxak maila fisikoaren eta pisuaren sentsoreak emandako datuak agertzen ditu.
 Datu hauek automatikoki eguneratzen dira.

Sentsoreen izaera fisikoa dela eta, ez zenuke espero behar datu hauek guztiz zehatzak izatea.
Bereziki, konturatu beharko zinateke, adibidez, bola uretan dagoenean, pisuaren sentsorea sarritan zerotik gertu egongo dela bola flotatzen baldin badago.

Era berean, sensoreak erralak direlako, datuak gaizki egongo baziren, seguruenik hardwarearen akatsen bategatik izango zen.",
            "cm3": "cm?",
            "archimedes.experiment": "Archimedes Esperimentua",
            "ball": "Bola",
            "ball.weight.liquid.level": "Bola pisua eta eta likidoaren maila",
            "volume": "Bolumena",
            "instance3": "3. Hodia",
            "instance4": "4. Hodia",
            "instance7": "7. Hodia",
            "sensorsHelpTitle": "Sentsorearen informazioa",
            "internal.diameter": "Barne Diametroa",
            "instance8": "8. Hodia",
            "ball.weight": "Bola pisua",
            "weight.g": "Pisua (g)",
            "instance2": "2. Hodia",
            "grams": "gr",
            "liquid": "Likidoa",
            "time.weight.plot": "Denbora / Pisua Grafikoa",
            "kgm3": "kg/m?",
            "liquid/tube": "Likidoa/ Hodia",
            "instance1": "1. Hodia",
            "mass": "Masa",
            "instance6": "6. Hodia",
            "gcm3": "gr / cm?",
            "toggle-show-hide": "Aldatu -ra erakutsi edo ezkutatu hodi bakoitza
",
            "time.remaining": "Geratzen den denbora"
        }
    };

    // TODO: Improve this mechanism using the WebLab API
    var currentLanguage = "en";
    if (top.window.location.href.search("locale=eu") > 0) {
        currentLanguage = "eu";
    } // Other languages
    $.i18n.load(i18n[currentLanguage]);

    var Registry = {
        "archimedes1" : {
            "name": $.i18n._("instance1"),
            "ball_mass": 134, // g
            "ball_diameter": 8.0, // cm
            "ball_density": 0.5,
            "object_density": 0.5,
            "object_volume": 268,
            "object_type": "Ball",
            "liquid_name": "water",
            "liquid_density": 1000, // 1000/m3
            "liquid_diameter": 9.4, // cm
            "webcam": "//cams.weblab.deusto.es/webcam/proxied.py/arquimedes1_rotate"
        },
        "archimedes2" : {
            "name": $.i18n._("instance2"),
            "ball_mass": 56,
            "ball_diameter": 6.0, // cm
            "ball_density": 0.5,
            "object_density": 1.32,
            "object_volume": 113.10,
            "object_type": "Ball",
            "liquid_name": "water",
            "liquid_density": 1000,
            "liquid_diameter": 7, // cm
            "webcam": "//cams.weblab.deusto.es/webcam/proxied.py/arquimedes2_rotate"
        },
        "archimedes3" : {
            "name": $.i18n._("instance3"),
            "ball_mass": 134,
            "ball_diameter": 6, // cm
            "ball_density": 1.18,
            "object_density": 1.18,
            "object_volume": 113.10,
            "object_type": "Ball",
            "liquid_density": 1000, // 1000/m3
            "liquid_diameter": 7, // cm
            "liquid_name": "water",
            "webcam": "//cams.weblab.deusto.es/webcam/proxied.py/arquimedes3_rotate"
        },
        "archimedes4" : {
            "name": $.i18n._("instance4"),
            "ball_mass": 111,
            "ball_diameter": 6, // cm
            "ball_density": 0.98,
            "object_density": 0.98,
            "object_volume": 113.10,
            "object_type": "Ball",
            "liquid_density": 1000, // 1000/m3
            "liquid_diameter": 7, // cm
            "liquid_name": "water",
            "webcam": "//cams.weblab.deusto.es/webcam/proxied.py/arquimedes4_rotate"
        },
        "archimedes5" : {
            "name": $.i18n._("instance5"),
            "ball_mass": 111,
            "ball_diameter": 6.0    , // cm
            "ball_density": 0.98,
            "object_density": 0.98,
            "object_volume": 113.10,
            "object_type": "Ball",
            "liquid_density": 900, // 900/m3
            "liquid_diameter": 7, // cm
            "liquid_name": "oil",
            "webcam": "//cams.weblab.deusto.es/webcam/proxied.py/arquimedes5_rotate"
        },
        "archimedes6" : {
            "name": $.i18n._("instance6"),
            "ball_mass": 89.3,
            "ball_density": 0.79,
            "object_density": 0.79,
            "object_volume": 113.10,
            "object_type": "Ball",
            "ball_diameter": 6, // cm
            "liquid_density": 1000, // 1000/m3
            "liquid_diameter": 7, // cm
            "liquid_name": "water",
            "webcam": "//cams.weblab.deusto.es/webcam/proxied.py/arquimedes6_rotate"
        },
        "archimedes7" : {
            "name": $.i18n._("instance7"),
            "ball_mass": 50.9,
            "ball_density": 0.78,
            "object_density": 0.78,
            "object_volume": 65.45,
            "object_type": "Ball",
            "ball_diameter": 5, // cm
            "liquid_density": 1000, // 1000/m3
            "liquid_diameter": 7, // cm
            "liquid_name": "water",
            "webcam": "//cams.weblab.deusto.es/webcam/proxied.py/arquimedes7_rotate"
        }
    };

    // Possible values:
    // ["controls", "sensor_weight", "sensor_level", "webcam", "hdcam", "plot", "ball_mass", "ball_volume",
    // "ball_diameter", "ball_density", "liquid_density", "liquid_diameter", "liquid_volume"]
    var View = {
        "archimedes1" : ["controls", "sensor_weight",  "sensor_level", "webcam", "hdcam", "plot", "ball_mass",
            "ball_volume", "ball_diameter", "ball_density", "liquid_density", "liquid_diameter"],
        "archimedes2" : "ALL",
        "archimedes3" : ["controls", "sensor_level", "sensor_weight", "webcam", "hdcam", "plot", "ball_mass",
            "ball_volume", "ball_diameter", "ball_density", "liquid_density", "liquid_diameter"], // Fake weight
        "archimedes4" : "ALL",
        "archimedes5" : ["controls", "sensor_level", "sensor_weight", "webcam", "hdcam", "plot", "ball_mass",
            "ball_volume", "ball_diameter", "ball_density", "liquid_density", "liquid_diameter"], // Fake weight
        "archimedes6" : ["controls", "sensor_level", "sensor_weight", "webcam", "hdcam", "plot", "ball_mass",
            "ball_volume", "ball_diameter", "ball_density", "liquid_density", "liquid_diameter"], // Fake weight
        "archimedes7" : ["controls", "sensor_level", "sensor_weight", "webcam", "hdcam", "plot", "ball_mass",
            "ball_volume", "ball_diameter", "ball_density", "liquid_density", "liquid_diameter"]  // Fake weight
    };

    var EDTFilter = {
        //"ball_mass" : 20
    };

    //! Pseudo-class to manage EDT-config filtering.
    //!
    EDT = new function() {

        this.filters = {

            //! @param instance: Instance to check.
            //! @param edtvalue: Specified edtvalue.
            //! @return: True if the instance meets the criteria.
            "ball_mass" : function(instance, grams) {
                return instance["ball_mass"] == grams; // ball_mass expected in grams
            },
            "ball_volume" : function(instance, volcm3) {
                var radius_cm = 0.5 * instance["ball_diameter"];
                var vol_cm3 = (4/3) * Math.PI * radius_cm * radius_cm * radius_cm; // ball_volume expected in cm3
                return vol_cm3 == volcm3;
            },
            "liquid_density" : function(instance, kgm3) {
                return instance["liquid_density"] == kgm3;
            }

        };

        //! Gets the result of filtering the global Registry with the global EDTFilter filter.
        //! (Applying it to the View).
        this.getFilteredView = function() {

            // Clone the view.
            view = JSON.parse(JSON.stringify(View));

            var that = this;
            $.each(Registry, function(name, instance) {
                $.each(EDTFilter, function(variable, value) {
                    if(variable in that.filters)
                        // If the filter check returns false we remove the instance from the list to show.
                        if(!that.filters[variable](instance, value)) {
                            delete view[name];
                        }
                });
            });

            return view;
        }; // !getFilteredRegistry

    }; // !EDT

    //! Global pseudo-class which will be used through the code
    //! to access the current view etc.
    Configuration = new function() {

        //! Returns the current global registry.
        this.getRegistry = function() {
            return Registry;
        };

        //! Returns the current view, filtered by the Registry and the EDTFilter.
        this.getView = function() {
            return EDT.getFilteredView();
        };

    };

<|endoftext|>


<commit_before>// limit results and instant results
var maxResults = 20;
// minimum song length
// 120000 = 2 minutes
var minSongLength = 120000;
// maximum song length
// 600000 = 10 minutes
var maxSongLength = 600000;

// collection for results. only a local collection
SearchResults = new Meteor.Collection(null);
// to track adds to the playlist
PlaylistTracker = new Meteor.Stream("playlistTracker");
PlaylistTracker.on("songAdded", function() {
  if (!Session.equals("selectedTab", "playlist")) {
    Session.set("missedPlaylist", Session.get("missedPlaylist") + 1);
  }
});

var processSearchResults = function(tracks, query) {
  // clear the results
  SearchResults.remove({});
  $(".searching").hide();
  if (_.size(tracks)) {
    $(".results-message").show();
  } else {
    $(".no-results").show();
  }
  _.each(tracks, function(track, key, list) {
    if (track.streamable) {
      if (Playlist.find({
        id: track.id,
        boxname: Meteor.user().profile.boxname
      }).count()) {
        track.inPlaylist = true;
      } else {
        track.inPlaylist = false;
      }
      SearchResults.insert({
        id: track.id,
        duration: track.duration,
        original_content_size: track.original_content_size,
        tag_list: track.tag_list,
        purchase_title: track.purchase_title,
        genre: track.genre,
        title: track.title,
        description: track.description,
        track_type: track.track_type,
        video_url: track.video_url,
        uri: track.uri,
        permalink_url: track.permalink_url,
        artwork_url: track.artwork_url,
        stream_url: track.stream_url,
        inPlaylist: track.inPlaylist,
      });
    }
  });
  // highlight the instant search results
  $(".search-results tbody").highlight(query.split(" "));
}

var getSearchResults = function(event) {
  var query = $(".search input[type=search]").val().trim();
  if (query) {
    $(".query").html(query);
    SC.get("/tracks", {
      limit: maxResults,
      q: query,
      // there is a bug in the soundcloud api where the filter option
      // is ignored when there is a query option. i'm including it
      // anyway so when it's fixed it'll work
      filter: {streamable: true},
      duration: {from: minSongLength, to: maxSongLength}
    }, function(tracks, error) {
      if (error) {
        $(".searching").hide();
        $(".error").show();
        return;
      }
      processSearchResults(tracks, query);
    });
  }
}

Template.search.events({
  "submit .search form": function(event) {
    $(".results-message").hide();
    $(".no-results").hide();
    $(".error").hide();
    $(".searching").show();
    event.preventDefault();
    getSearchResults(event);
  },
  "click .add-to-playlist": function(event) {
    event.preventDefault();
    OJPlayer.addSongToPlaylist(this);
    if (!Session.equals("selectedTab", "playlist")) {
      Session.set("missedPlaylist", Session.get("missedPlaylist") + 1);
    }
    PlaylistTracker.emit("songAdded");
    $(event.currentTarget).parent().addClass("in-playlist");
    $(".added").fadeIn("fast").delay(1000).fadeOut("slow");
  }
});

Template.search.helpers({
  searchResults: function() {
    return SearchResults.find({inPlaylist: false});
  },
});

Template.searchResult.helpers({
  inPlaylist: function() {
    if (Playlist.find({
      id: this.id,
      boxname: Meteor.user().profile.boxname
    }).count()) {
      if (!this.inPlaylist) {
        SearchResults.update(this._id, {
          $set: {inPlaylist: true}
        });
      }
      return "in-playlist";
    }
    if (this.inPlaylist) {
      SearchResults.update(this._id, {
        $set: {inPlaylist: false}
      });
    }
    return "";
  },
});
<commit_msg>blank search queries no longer say searching<commit_after>// limit results and instant results
var maxResults = 20;
// minimum song length
// 120000 = 2 minutes
var minSongLength = 120000;
// maximum song length
// 600000 = 10 minutes
var maxSongLength = 600000;

// collection for results. only a local collection
SearchResults = new Meteor.Collection(null);
// to track adds to the playlist
PlaylistTracker = new Meteor.Stream("playlistTracker");
PlaylistTracker.on("songAdded", function() {
  if (!Session.equals("selectedTab", "playlist")) {
    Session.set("missedPlaylist", Session.get("missedPlaylist") + 1);
  }
});

var processSearchResults = function(tracks, query) {
  // clear the results
  SearchResults.remove({});
  $(".searching").hide();
  if (_.size(tracks)) {
    $(".results-message").show();
  } else {
    $(".no-results").show();
  }
  _.each(tracks, function(track, key, list) {
    if (track.streamable) {
      if (Playlist.find({
        id: track.id,
        boxname: Meteor.user().profile.boxname
      }).count()) {
        track.inPlaylist = true;
      } else {
        track.inPlaylist = false;
      }
      SearchResults.insert({
        id: track.id,
        duration: track.duration,
        original_content_size: track.original_content_size,
        tag_list: track.tag_list,
        purchase_title: track.purchase_title,
        genre: track.genre,
        title: track.title,
        description: track.description,
        track_type: track.track_type,
        video_url: track.video_url,
        uri: track.uri,
        permalink_url: track.permalink_url,
        artwork_url: track.artwork_url,
        stream_url: track.stream_url,
        inPlaylist: track.inPlaylist,
      });
    }
  });
  // highlight the instant search results
  $(".search-results tbody").highlight(query.split(" "));
}

var getSearchResults = function(query) {
  if (!query) {
    return;
  }
  $(".query").html(query);
  SC.get("/tracks", {
    limit: maxResults,
    q: query,
    // there is a bug in the soundcloud api where the filter option
    // is ignored when there is a query option. i'm including it
    // anyway so when it's fixed it'll work
    filter: {streamable: true},
    duration: {from: minSongLength, to: maxSongLength}
  }, function(tracks, error) {
    if (error) {
      $(".searching").hide();
      $(".error").show();
      return;
    }
    processSearchResults(tracks, query);
  });
}

Template.search.events({
  "submit .search form": function(event) {
    event.preventDefault();
    var query = $(".search input[type=search]").val().trim();
    if (query) {
      $(".results-message").hide();
      $(".no-results").hide();
      $(".error").hide();
      $(".searching").show();
      getSearchResults(query);
    }
  },
  "click .add-to-playlist": function(event) {
    event.preventDefault();
    OJPlayer.addSongToPlaylist(this);
    if (!Session.equals("selectedTab", "playlist")) {
      Session.set("missedPlaylist", Session.get("missedPlaylist") + 1);
    }
    PlaylistTracker.emit("songAdded");
    $(event.currentTarget).parent().addClass("in-playlist");
    $(".added").fadeIn("fast").delay(1000).fadeOut("slow");
  }
});

Template.search.helpers({
  searchResults: function() {
    return SearchResults.find({inPlaylist: false});
  },
});

Template.searchResult.helpers({
  inPlaylist: function() {
    if (Playlist.find({
      id: this.id,
      boxname: Meteor.user().profile.boxname
    }).count()) {
      if (!this.inPlaylist) {
        SearchResults.update(this._id, {
          $set: {inPlaylist: true}
        });
      }
      return "in-playlist";
    }
    if (this.inPlaylist) {
      SearchResults.update(this._id, {
        $set: {inPlaylist: false}
      });
    }
    return "";
  },
});
<|endoftext|>


<commit_before>import React from 'react';
import Textarea from "react-textarea-autosize";
import _ from "lodash";

import ModalRenderUtils from "./ModalRenderUtils";
import TestResultUtils from "../../common/TestResultUtils";

export function wrapWithTestResult(fieldName, testResultsToShow, testResultsToHide, toggleTestResult, field) {
  const testValue = fieldName ? (testResultsToShow && testResultsToShow.expressionResults[fieldName]) : null
  const shouldHideTestResults = testResultsToHide.has(fieldName)
  const hiddenClassPart = (shouldHideTestResults ? " partly-hidden" : "")
  const showIconClass = shouldHideTestResults ? "glyphicon glyphicon-eye-close" : "glyphicon glyphicon-eye-open"
  if (testValue) {
    return (

        {field}

{ModalRenderUtils.renderInfo('Value evaluated in test case')}
            {testValue.pretty ?  toggleTestResult(fieldName)}/> : null}

            {testValue.original ? <Textarea className="node-input" readOnly={true} value={testValue.original}/> : null}
            <Textarea rows={1} cols={50} className="node-input" value={testValue.pretty || testValue} readOnly={true}/>
            {shouldHideTestResults ?

 : null}

    )
  } else {
    return field
  }
}

function prettyPrint(obj) {
  return JSON.stringify(obj, null, 2);
}

export function testResults(nodeId, testResultsToShow) {
  if (testResultsToShow && !_.isEmpty(testResultsToShow.context.variables)) {
    const ctx = testResultsToShow.context.variables;
    return (

{ModalRenderUtils.renderInfo('Variables in test case')}

        {Object.keys(ctx).map((key, ikey) =>

{key}:

              {(ctx[key] || {}).original ? <Textarea className="node-input" readOnly={true} value={ctx[key].original}/> : null}
              <Textarea className="node-input" readOnly={true}
                        value={ctx[key] !== null ? prettyPrint(ctx[key].pretty) : "null"}/>

        )}
        {testResultsToShow && !_.isEmpty(testResultsToShow.mockedResultsForCurrentContext) ?
          (testResultsToShow.mockedResultsForCurrentContext).map((mockedValue, index) =>

               Results for this input
          ) : null
        }
        {testResultsToShow && !_.isEmpty(testResultsToShow.mockedResultsForEveryContext) ?

             Results for all inputs
          : null
        }

)
  } else {
    return null;
  }
}

function mergedMockedResults(mockedResults) {
  return _.join(mockedResults.map((mockedValue) => mockedValue.value), "\n\n")
}

function downloadableHref(content) {
  return "data:application/octet-stream;charset=utf-8," + encodeURIComponent(content)
}

export function testResultsSelect(testResults, testResultsIdToShow, selectTestResults) {
  if (hasTestResults(testResults)) {
    return (

Test case:

          <select className="node-input selectTestResults" onChange={(e) => selectTestResults(e.target.value, testResults)}
                  value={testResultsIdToShow}>
            { TestResultUtils.availableContexts(testResults).map((ctx, idx) =>
              (<option key={idx} value={ctx.id}>{ctx.id} ({ctx.display})</option>)
            )}
          </select>

    )
  } else {
    return null;
  }

}

export function stateForSelectTestResults(id, testResults) {
  if (hasTestResults(testResults)) {
    const chosenId = id || _.get(_.head(TestResultUtils.availableContexts(testResults)), "id")
    return {
      testResultsToShow: TestResultUtils.nodeResultsForContext(testResults, chosenId),
      testResultsIdToShow: chosenId
    }
  } else {
    return null;
  }
}

function hasTestResults(testResults) {
  return testResults && TestResultUtils.availableContexts(testResults).length > 0
}

export function testErrors(testResultsToShow) {
  if (testResultsToShow && testResultsToShow.error) {
    var error = testResultsToShow.error

    return (

{ ModalRenderUtils.renderWarning('Test case error')}

{`${error.message} (${error.class})`}

    );
  } else {
    return null;
  }
}

<commit_msg>[ITDEVESP-741] - pretty print in expressions<commit_after>import React from 'react';
import Textarea from "react-textarea-autosize";
import _ from "lodash";

import ModalRenderUtils from "./ModalRenderUtils";
import TestResultUtils from "../../common/TestResultUtils";

export function wrapWithTestResult(fieldName, testResultsToShow, testResultsToHide, toggleTestResult, field) {
  const testValue = fieldName ? (testResultsToShow && testResultsToShow.expressionResults[fieldName]) : null
  const shouldHideTestResults = testResultsToHide.has(fieldName)
  const showIconClass = shouldHideTestResults ? "glyphicon glyphicon-eye-close" : "glyphicon glyphicon-eye-open"
  if (testValue) {
    return (

        {field}

{ModalRenderUtils.renderInfo('Value evaluated in test case')}
            {testValue.pretty ?  toggleTestResult(fieldName)}/> : null}

          {showTestValue(testValue, shouldHideTestResults)}

    )
  } else {
    return field
  }
}

function prettyPrint(obj) {
  return JSON.stringify(obj, null, 2);
}

function showTestValue(testValue, shouldHideTestResults) {
  const hiddenClassPart = (shouldHideTestResults ? " partly-hidden" : "");
  return (

    {(testValue || {}).original ? <Textarea className="node-input" readOnly={true} value={testValue.original}/> : null}
    <Textarea className="node-input" readOnly={true}
              value={testValue !== null ? prettyPrint(testValue.pretty) : "null"}/>
    {shouldHideTestResults ?

 : null}

);
}

export function testResults(nodeId, testResultsToShow) {
  if (testResultsToShow && !_.isEmpty(testResultsToShow.context.variables)) {
    const ctx = testResultsToShow.context.variables;
    return (

{ModalRenderUtils.renderInfo('Variables in test case')}

        {Object.keys(ctx).map((key, ikey) =>

{key}:

            {showTestValue(ctx[key], false)}

        )}
        {testResultsToShow && !_.isEmpty(testResultsToShow.mockedResultsForCurrentContext) ?
          (testResultsToShow.mockedResultsForCurrentContext).map((mockedValue, index) =>

               Results for this input
          ) : null
        }
        {testResultsToShow && !_.isEmpty(testResultsToShow.mockedResultsForEveryContext) ?

             Results for all inputs
          : null
        }

)
  } else {
    return null;
  }
}

function mergedMockedResults(mockedResults) {
  return _.join(mockedResults.map((mockedValue) => mockedValue.value), "\n\n")
}

function downloadableHref(content) {
  return "data:application/octet-stream;charset=utf-8," + encodeURIComponent(content)
}

export function testResultsSelect(testResults, testResultsIdToShow, selectTestResults) {
  if (hasTestResults(testResults)) {
    return (

Test case:

          <select className="node-input selectTestResults" onChange={(e) => selectTestResults(e.target.value, testResults)}
                  value={testResultsIdToShow}>
            { TestResultUtils.availableContexts(testResults).map((ctx, idx) =>
              (<option key={idx} value={ctx.id}>{ctx.id} ({ctx.display})</option>)
            )}
          </select>

    )
  } else {
    return null;
  }

}

export function stateForSelectTestResults(id, testResults) {
  if (hasTestResults(testResults)) {
    const chosenId = id || _.get(_.head(TestResultUtils.availableContexts(testResults)), "id")
    return {
      testResultsToShow: TestResultUtils.nodeResultsForContext(testResults, chosenId),
      testResultsIdToShow: chosenId
    }
  } else {
    return null;
  }
}

function hasTestResults(testResults) {
  return testResults && TestResultUtils.availableContexts(testResults).length > 0
}

export function testErrors(testResultsToShow) {
  if (testResultsToShow && testResultsToShow.error) {
    var error = testResultsToShow.error

    return (

{ ModalRenderUtils.renderWarning('Test case error')}

{`${error.message} (${error.class})`}

    );
  } else {
    return null;
  }
}

<|endoftext|>


<commit_before>define(function () {

    var kernelSpecs = requirejs.s.contexts._.config.paths.kernelspecs;
    var staticFolder = kernelSpecs + "/ifsharp/static/";

    var link = document.createElement("link");
    link.type = "text/css";
    link.rel = "stylesheet";
    link.href = staticFolder + "custom/fsharp.css";
    document.getElementsByTagName("head")[0].appendChild(link);

    var changedSinceTypecheck = true;
    var changedRecently = false;
    var kernelIdledSinceTypeCheck = false;
    var kernelIdledRecently = false

    var onload = function () {

        var md = IPython.notebook.metadata;
        if (md.language) {
            console.log('language already defined and is :', md.language);
        }
        else {
            md.language = 'fsharp';
            console.log('add metadata hint that language is fsharp...');
        }

        IPython.CodeCell.options_default.cm_config.mode = 'fsharp';

        // callback called by the end-user
        function updateMarkers(data) {
            // applies intellisense hooks onto all cells
            var cells = getCodeCells();

            // clear old error marks
            cells.cells.forEach(function (cell) {
                cell.code_mirror.doc.getAllMarks().forEach(function (m) {
                    if (m.className === 'br-errormarker') {
                        m.clear();
                    }
                });
            });

            // apply new error marks
            data.forEach(function (err) {
                var editor = cells.cells[err.CellNumber].code_mirror;
                var from = { line: err.StartLine, ch: err.StartColumn };
                var to = { line: err.EndLine, ch: err.EndColumn };
                editor.doc.markText(from, to, { title: err.Message, className: 'br-errormarker' });
            });
        }

        function getCodeCells() {
            var results = { codes: [], cells: [], selectedCell: null, selectedIndex: 0 };
            IPython.notebook.get_cells()
                .forEach(function (c) {
                    if (c.cell_type === 'code') {
                        if (c.selected === true) {
                            results.selectedCell = c;
                            results.selectedIndex = results.cells.length;
                        }
                        results.cells.push(c);
                        results.codes.push(c.code_mirror.getValue());
                    }
                });

            return results;
        }

        function intellisenseRequest(item) {
            var cells = getCodeCells();
            var editor = cells.selectedCell != null ? cells.selectedCell.code_mirror : null
            var cursor = editor != null ? editor.doc.getCursor() : { ch: 0, line: 0 }
            var callbacks = { shell: {}, iopub: {} };

            if (editor != null) {
                var line = editor.getLine(cursor.line);
                var isSlash = item.keyCode === 191 || item.keyCode === 220;
                var isQuote = item.keyCode === 222;

                var isLoadOrRef = line.indexOf('#load') === 0
                    || line.indexOf('#r') === 0;

                var isStartLoadOrRef = line === '#load "'
                    || line === '#r "'
                    || line === '#load @"'
                    || line === '#r @"';

                if (isSlash && !isLoadOrRef) {
                    return;
                }

                if (isQuote && !isStartLoadOrRef) {
                    return;
                }
            }

            callbacks.shell.reply = function (msg) {
                if (editor != null && item.keyCode !== 0) {
                    editor.intellisense.setDeclarations(msg.content.matches);
                    editor.intellisense.setStartColumnIndex(msg.content.cursor_start);
                }
            };

            callbacks.iopub.output = function (msg) {
                updateMarkers(msg.content.data.errors);
            };

            var content = {
                text: JSON.stringify(cells.codes),
                line: '',
                block: JSON.stringify({ selectedIndex: cells.selectedIndex, ch: cursor.ch, line: cursor.line }),
                cursor_pos: cursor.ch
            };

            IPython.notebook.kernel.send_shell_message("intellisense_request", content, callbacks, null, null);
        }

        //There are dependencies in the lazy loading
        require(['codemirror/addon/mode/loadmode'], function () {
            require([staticFolder + 'custom/webintellisense.js', staticFolder + 'custom/webintellisense-codemirror.js'], function () {
                // applies intellisense hooks onto a cell
                function applyIntellisense(cell) {
                    if (cell.cell_type !== 'code') { return; }

                    var editor = cell.code_mirror;
                    if (editor.intellisense == null) {
                        var intellisense = new CodeMirrorIntellisense(editor);
                        editor.setOption('theme', 'neat');
                        editor.intellisense = intellisense;

                        editor.on('changes', function (cm, changes) {
                            changedSinceTypecheck = true;
                            changedRecently = true;
                        });

                        intellisense.addDeclarationTrigger({ keyCode: 190 }); // `.`
                        intellisense.addDeclarationTrigger({ keyCode: 32, ctrlKey: true, preventDefault: true, type: 'down' }); // `ctrl+space`
                        intellisense.addDeclarationTrigger({ keyCode: 191 }); // `/`
                        intellisense.addDeclarationTrigger({ keyCode: 220 }); // `\`
                        intellisense.addDeclarationTrigger({ keyCode: 222 }); // `"`
                        intellisense.addDeclarationTrigger({ keyCode: 222, shiftKey: true }); // `"`
                        intellisense.addMethodsTrigger({ keyCode: 57, shiftKey: true }); // `(`
                        intellisense.addMethodsTrigger({ keyCode: 48, shiftKey: true });// `)`
                        intellisense.onMethod(function (item) { });
                        intellisense.onDeclaration(intellisenseRequest);
                    }
                }

                // applies intellisense hooks onto all cells
                IPython.notebook.get_cells().forEach(function (cell) {
                    applyIntellisense(cell);
                });

                // applies intellisense hooks onto cells that are selected
                $([IPython.events]).on('create.Cell', function (event, data) {
                    applyIntellisense(data.cell);
                });

                $([IPython.events]).on('delete.Cell', function (event, data) {
                    data.cell.code_mirror.intellisense.setDeclarations([])
                });

                $([IPython.events]).on('kernel_idle.Kernel', function (event, data) {
                    kernelIdledSinceTypeCheck = true;
                    kernelIdledRecently = true;
                });

                window.setInterval(function () {
                    if (!changedSinceTypecheck && !kernelIdledSinceTypeCheck)
                        return;

                    if (changedRecently || kernelIdledRecently) {
                        changedRecently = false;
                        kernelIdledRecently = false;
                        return;
                    }

                    changedSinceTypecheck = false;
                    changedRecently = false;
                    kernelIdledSinceTypeCheck = false;
                    kernelIdledRecently = false;
                    intellisenseRequest({ keyCode: 0 })
                }, 1000);

            });
        });
    }

    return { onload: onload }
})<commit_msg>Mark new cells as F# so they get syntax highlighted with the same mechanism.<commit_after>define(function () {

    var kernelSpecs = requirejs.s.contexts._.config.paths.kernelspecs;
    var staticFolder = kernelSpecs + "/ifsharp/static/";

    var link = document.createElement("link");
    link.type = "text/css";
    link.rel = "stylesheet";
    link.href = staticFolder + "custom/fsharp.css";
    document.getElementsByTagName("head")[0].appendChild(link);

    var changedSinceTypecheck = true;
    var changedRecently = false;
    var kernelIdledSinceTypeCheck = false;
    var kernelIdledRecently = false

    var onload = function () {

        var md = IPython.notebook.metadata;
        if (md.language) {
            console.log('language already defined and is :', md.language);
        }
        else {
            md.language = 'fsharp';
            console.log('add metadata hint that language is fsharp...');
        }

        IPython.CodeCell.options_default.cm_config.mode = 'fsharp';

        // callback called by the end-user
        function updateMarkers(data) {
            // applies intellisense hooks onto all cells
            var cells = getCodeCells();

            // clear old error marks
            cells.cells.forEach(function (cell) {
                cell.code_mirror.doc.getAllMarks().forEach(function (m) {
                    if (m.className === 'br-errormarker') {
                        m.clear();
                    }
                });
            });

            // apply new error marks
            data.forEach(function (err) {
                var editor = cells.cells[err.CellNumber].code_mirror;
                var from = { line: err.StartLine, ch: err.StartColumn };
                var to = { line: err.EndLine, ch: err.EndColumn };
                editor.doc.markText(from, to, { title: err.Message, className: 'br-errormarker' });
            });
        }

        function getCodeCells() {
            var results = { codes: [], cells: [], selectedCell: null, selectedIndex: 0 };
            IPython.notebook.get_cells()
                .forEach(function (c) {
                    if (c.cell_type === 'code') {
                        if (c.selected === true) {
                            results.selectedCell = c;
                            results.selectedIndex = results.cells.length;
                        }
                        results.cells.push(c);
                        results.codes.push(c.code_mirror.getValue());
                    }
                });

            return results;
        }

        function intellisenseRequest(item) {
            var cells = getCodeCells();
            var editor = cells.selectedCell != null ? cells.selectedCell.code_mirror : null
            var cursor = editor != null ? editor.doc.getCursor() : { ch: 0, line: 0 }
            var callbacks = { shell: {}, iopub: {} };

            if (editor != null) {
                var line = editor.getLine(cursor.line);
                var isSlash = item.keyCode === 191 || item.keyCode === 220;
                var isQuote = item.keyCode === 222;

                var isLoadOrRef = line.indexOf('#load') === 0
                    || line.indexOf('#r') === 0;

                var isStartLoadOrRef = line === '#load "'
                    || line === '#r "'
                    || line === '#load @"'
                    || line === '#r @"';

                if (isSlash && !isLoadOrRef) {
                    return;
                }

                if (isQuote && !isStartLoadOrRef) {
                    return;
                }
            }

            callbacks.shell.reply = function (msg) {
                if (editor != null && item.keyCode !== 0) {
                    editor.intellisense.setDeclarations(msg.content.matches);
                    editor.intellisense.setStartColumnIndex(msg.content.cursor_start);
                }
            };

            callbacks.iopub.output = function (msg) {
                updateMarkers(msg.content.data.errors);
            };

            var content = {
                text: JSON.stringify(cells.codes),
                line: '',
                block: JSON.stringify({ selectedIndex: cells.selectedIndex, ch: cursor.ch, line: cursor.line }),
                cursor_pos: cursor.ch
            };

            IPython.notebook.kernel.send_shell_message("intellisense_request", content, callbacks, null, null);
        }

        //There are dependencies in the lazy loading
        require(['codemirror/addon/mode/loadmode'], function () {
            require([staticFolder + 'custom/webintellisense.js', staticFolder + 'custom/webintellisense-codemirror.js'], function () {
                // applies intellisense hooks onto a cell
                function applyIntellisense(cell) {
                    if (cell.cell_type !== 'code') { return; }

                    var editor = cell.code_mirror;
                    if (editor.intellisense == null) {
                        var intellisense = new CodeMirrorIntellisense(editor);
                        editor.setOption('theme', 'neat');
                        editor.intellisense = intellisense;

                        editor.on('changes', function (cm, changes) {
                            changedSinceTypecheck = true;
                            changedRecently = true;
                        });

                        intellisense.addDeclarationTrigger({ keyCode: 190 }); // `.`
                        intellisense.addDeclarationTrigger({ keyCode: 32, ctrlKey: true, preventDefault: true, type: 'down' }); // `ctrl+space`
                        intellisense.addDeclarationTrigger({ keyCode: 191 }); // `/`
                        intellisense.addDeclarationTrigger({ keyCode: 220 }); // `\`
                        intellisense.addDeclarationTrigger({ keyCode: 222 }); // `"`
                        intellisense.addDeclarationTrigger({ keyCode: 222, shiftKey: true }); // `"`
                        intellisense.addMethodsTrigger({ keyCode: 57, shiftKey: true }); // `(`
                        intellisense.addMethodsTrigger({ keyCode: 48, shiftKey: true });// `)`
                        intellisense.onMethod(function (item) { });
                        intellisense.onDeclaration(intellisenseRequest);
                    }
                }

                // applies intellisense hooks onto all cells
                IPython.notebook.get_cells().forEach(function (cell) {
                    applyIntellisense(cell);
                });

                // applies intellisense hooks onto cells that are selected
                $([IPython.events]).on('create.Cell', function (event, data) {
                    data.cell.cm_config.mode = 'text/x-fsharp'
                    applyIntellisense(data.cell);
                });

                $([IPython.events]).on('delete.Cell', function (event, data) {
                    data.cell.code_mirror.intellisense.setDeclarations([])
                });

                $([IPython.events]).on('kernel_idle.Kernel', function (event, data) {
                    kernelIdledSinceTypeCheck = true;
                    kernelIdledRecently = true;
                });

                window.setInterval(function () {
                    if (!changedSinceTypecheck && !kernelIdledSinceTypeCheck)
                        return;

                    if (changedRecently || kernelIdledRecently) {
                        changedRecently = false;
                        kernelIdledRecently = false;
                        return;
                    }

                    changedSinceTypecheck = false;
                    changedRecently = false;
                    kernelIdledSinceTypeCheck = false;
                    kernelIdledRecently = false;
                    intellisenseRequest({ keyCode: 0 })
                }, 1000);

            });
        });
    }

    return { onload: onload }
})<|endoftext|>


<commit_before>'use strict';

var _        = require('lodash');
var moment   = require('moment');

var api      = require('data/api');
var dateUtil = require('util/date');

function campaignComparator(a, b) {
	if (!b.campaign) {
		return a.campaign ? -1 : 0;
	}

	return (a.campaign.start_date < b.campaign.start_date) ? -1 :
		(a.campaign.start_date > b.campaign.start_date) ? 1 : 0;
}

function dataError(err) {
	/* jshint validthis:true */
	console.log(err);

	this.loading = false;
	this.error   = true;
}

function parseData(data) {
	/* jshint validthis:true */
	var loaded = _.omit(data, 'objects');

	// Convert the data from an array of unique (region, campaign) objects
	// with multiple indicators into an array of objects for each
	// (region, campaign, indicator) set. This is is identical to the form in
	// which the data is stored in the datapoint table on the server, and is
	// more flexible for plotting because it's easier to access values and
	// facet on properties like indicator for creating multiple series.
	loaded.objects = _(data.objects).map(function (o) {
		var datapoints = [];
		var indicators = o.indicators;
		var props      = _.omit(o, 'indicators');

		for (var i = indicators.length - 1; i >= 0; i--) {
			var datum = indicators[i];

			datapoints.push(_.assign({
				indicator: datum.indicator,
				value    : datum.value
			}, props));
		}

		return datapoints;
	})
		.flatten()
		.sortBy(campaignComparator)
		.value();

	this.datapoints = loaded.objects;
	this.loading    = false;
}

function _loadIndicator () {
	/* jshint validthis:true */

	console.debug('with-indicator::loadIndicator', this.indicator);

	var self = this;

	if (!this.indicators) {
		return;
	}

	var indicators = this.indicators;

	if (_.isString(indicators)) {
		indicators = JSON.parse(indicators);
	}

	if (!_.isArray(indicators)) {
		indicators = [indicators];
	}

	indicators = indicators.filter(function (d) {
		return _.isNumber(d) || _.isString(d);
	});

	if (indicators.length < 1) {
		// All indicators have been loaded. Begin loading the datapoints.
		this._loadDatapoints();
		return;
	}

	this.loading = true;

	api.indicators({ id__in: indicators })
		.then(function (data) {
			self.indicators = data.objects;
		}, dataError.bind(this));

	console.debug('with-indicator::loadIndicator', 'exit');
}

function _loadDatapoints () {
	/* jshint validthis:true */

	console.info('with-indicator::loadDatapoints', 'enter');

	if (!this.indicators || !this.campaign || !this.region) {
		console.info('with-indicator::loadDatapoints', 'exit', 'missing parameters');
		return;
	}

	this.loading = true;

	var q = this.query;

	console.debug('with-indicator::data-load', 'q', q);

	api.datapoints(q).then(parseData.bind(this), dataError.bind(this));

	console.info('with-indicator::loadDatapoints', 'exit');
}

module.exports = {

	paramAttributes: [
		'data-indicators',
		'data-period'
	],

	data: function () {
		return {
			campaign  : null,
			datapoints: [],
			error     : false,
			indicators: null,
			loading   : true,
			region    : null,
			period    : null
		};
	},

	created: function () {
		// Initialize private methods
		this._loadIndicator  = _loadIndicator.bind(this);
		this._loadDatapoints = _loadDatapoints.bind(this);

		this.$watch('campaign', this._loadDatapoints);
		this.$watch('region', this._loadDatapoints);

		this.$watch('indicators', this._loadIndicator);
		this._loadIndicator();
	},

	computed: {

		campaign_start: function () {
			if (!this.period) {
				return null;
			}

			var start = moment(this.campaign.date, 'YYYYMMDD');

			return start.subtract.apply(
					start,
					dateUtil.parseDuration(this.period)
				).format('YYYY-MM-DD');
		},

		length: function () {
			var datapoints = this.datapoints;

			return (datapoints && datapoints.length) || 0;
		},

		empty: function () {
			return this.length < 1;
		},

		query: function () {
			var q = {
				indicator__in: _.pluck(this.indicators, 'id'),
				campaign_end : this.campaign.end,
				region__in   : [this.region]
			};

			var start = this.campaign_start;
			if (start) {
				q.campaign_start = start;
			}

			return q;
		}

	}

};
<commit_msg>Remove console statements<commit_after>'use strict';

var _        = require('lodash');
var moment   = require('moment');

var api      = require('data/api');
var dateUtil = require('util/date');

function campaignComparator(a, b) {
	if (!b.campaign) {
		return a.campaign ? -1 : 0;
	}

	return (a.campaign.start_date < b.campaign.start_date) ? -1 :
		(a.campaign.start_date > b.campaign.start_date) ? 1 : 0;
}

function dataError(err) {
	/* jshint validthis:true */
	console.error(err);

	this.loading = false;
	this.error   = true;
}

function parseData(data) {
	/* jshint validthis:true */
	var loaded = _.omit(data, 'objects');

	// Convert the data from an array of unique (region, campaign) objects
	// with multiple indicators into an array of objects for each
	// (region, campaign, indicator) set. This is is identical to the form in
	// which the data is stored in the datapoint table on the server, and is
	// more flexible for plotting because it's easier to access values and
	// facet on properties like indicator for creating multiple series.
	loaded.objects = _(data.objects).map(function (o) {
		var datapoints = [];
		var indicators = o.indicators;
		var props      = _.omit(o, 'indicators');

		for (var i = indicators.length - 1; i >= 0; i--) {
			var datum = indicators[i];

			datapoints.push(_.assign({
				indicator: datum.indicator,
				value    : datum.value
			}, props));
		}

		return datapoints;
	})
		.flatten()
		.sortBy(campaignComparator)
		.value();

	this.datapoints = loaded.objects;
	this.loading    = false;
}

function _loadIndicator () {
	/* jshint validthis:true */
	var self = this;

	if (!this.indicators) {
		return;
	}

	var indicators = this.indicators;

	if (_.isString(indicators)) {
		indicators = JSON.parse(indicators);
	}

	if (!_.isArray(indicators)) {
		indicators = [indicators];
	}

	indicators = indicators.filter(function (d) {
		return _.isNumber(d) || _.isString(d);
	});

	if (indicators.length < 1) {
		// All indicators have been loaded. Begin loading the datapoints.
		this._loadDatapoints();
		return;
	}

	this.loading = true;

	api.indicators({ id__in: indicators })
		.then(function (data) {
			self.indicators = data.objects;
		}, dataError.bind(this));
}

function _loadDatapoints () {
	/* jshint validthis:true */

	if (!this.indicators || !this.campaign || !this.region) {
		return;
	}

	this.loading = true;

	var q = this.query;

	api.datapoints(q).then(parseData.bind(this), dataError.bind(this));
}

module.exports = {

	paramAttributes: [
		'data-indicators',
		'data-period'
	],

	data: function () {
		return {
			campaign  : null,
			datapoints: [],
			error     : false,
			indicators: null,
			loading   : true,
			region    : null,
			period    : null
		};
	},

	created: function () {
		// Initialize private methods
		this._loadIndicator  = _loadIndicator.bind(this);
		this._loadDatapoints = _loadDatapoints.bind(this);

		this.$watch('campaign', this._loadDatapoints);
		this.$watch('region', this._loadDatapoints);

		this.$watch('indicators', this._loadIndicator);
		this._loadIndicator();
	},

	computed: {

		campaign_start: function () {
			if (!this.period) {
				return null;
			}

			var start = moment(this.campaign.date, 'YYYYMMDD');

			return start.subtract.apply(
					start,
					dateUtil.parseDuration(this.period)
				).format('YYYY-MM-DD');
		},

		length: function () {
			var datapoints = this.datapoints;

			return (datapoints && datapoints.length) || 0;
		},

		empty: function () {
			return this.length < 1;
		},

		query: function () {
			var q = {
				indicator__in: _.pluck(this.indicators, 'id'),
				campaign_end : this.campaign.end,
				region__in   : [this.region]
			};

			var start = this.campaign_start;
			if (start) {
				q.campaign_start = start;
			}

			return q;
		}

	}

};
<|endoftext|>


<commit_before>var gulp = require('gulp');
var config = require('../config').nodeCopy;
var pkg = require('../../package.json');
var browserSync = require('browser-sync');

gulp.task('node-copy', function() {
  if (pkg['node-copy']) {
    return gulp.src(pkg['node-copy'], {base: 'node_modules/'})
      .pipe(gulp.dest(config.dest))
      .pipe(browserSync.reload({stream:true}));
  } else {
    return void 0;
  }
});
<commit_msg>fix base for nodeCopy<commit_after>var gulp = require('gulp');
var config = require('../config').nodeCopy;
var pkg = require('../../package.json');
var browserSync = require('browser-sync');

gulp.task('node-copy', function() {
  if (pkg['node-copy']) {
    return gulp.src(pkg['node-copy'], {base: '.'})
      .pipe(gulp.dest(config.dest))
      .pipe(browserSync.reload({stream:true}));
  } else {
    return void 0;
  }
});
<|endoftext|>


<commit_before>/*
*
* Author: Eric Douglas
* Finished:
*
* Paying Debt Off In a Year
*
* - interest is compounded monthly according to the balance at
*     the start of the month
* - monthly payment must be a multiple of $10 and is the same for all months
* -  it is possible for the balance to become negative using this scheme
*/

var prompt = require( 'prompt' );

prompt.start();
prompt.get([
  {
    name : 'balance',
    description : 'Enter the outstanding balance on your credit card'
  },
  {
    name : 'interest',
    description : 'Enter the annual credit card interest rate as a decimal'
  }
], function( err, results ) {

 // constants
 var PERIOD = 12;

 // input variables
 var initialBalance = parseFloat( results.balance );
 var interest       = parseFloat( results.interest );

 // helper variables
 var monthsNeeded  = 0;
 var totalBalance  = initialBalance;
 var monthInterest = interest / 12;
 var monthPayment  = Math.ceil( initialBalance * ( 1 + interest ) / 120 ) * 10;
 // (( balance * ( interest ) / 12 ) / 10 ) * 10

 while ( totalBalance > 0 ) {

  totalBalance = ( totalBalance * ( 1 + monthInterest ) - monthPayment ).toFixed( 2 );
  monthsNeeded += 1;

 }

 console.log( '======= RESULT =======');
 console.log( 'Monthly payment to pay off debt in 1 year:', monthPayment );
 console.log( 'Number of months needed:', monthsNeeded );
 console.log( 'Balance', totalBalance );

});
<commit_msg>Intro to CS - v02 problem set 01.02 - final<commit_after>/*
*
* Author: Eric Douglas
* Finished:
*
* Paying Debt Off In a Year
*
* - interest is compounded monthly according to the balance at
*     the start of the month
* - monthly payment must be a multiple of $10 and is the same for all months
* -  it is possible for the balance to become negative using this scheme
*/

var prompt = require( 'prompt' );

prompt.start();
prompt.get([
  {
    name : 'balance',
    description : 'Enter the outstanding balance on your credit card'
  },
  {
    name : 'interest',
    description : 'Enter the annual credit card interest rate as a decimal'
  }
], function( err, results ) {

 // constants
 var PERIOD = 12;

 // input variables
 var initialBalance = parseFloat( results.balance );
 var interest       = parseFloat( results.interest );

 // helper variables
 var monthsNeeded  = 0;
 var totalBalance  = initialBalance;
 var monthInterest = interest / 12;
 var monthPayment  = 10;

 while ( totalBalance > 0 ) {

  totalBalance = ( totalBalance * ( 1 + monthInterest ) - monthPayment );
  monthsNeeded += 1;

  if ( monthsNeeded >= 12 ) {
    monthPayment += 10;
    totalBalance = initialBalance;
    monthsNeeded = 0;
  }

 }

 console.log( '======= RESULT =======');
 console.log( 'Monthly payment to pay off debt in 1 year:', monthPayment );
 console.log( 'Number of months needed:', monthsNeeded );
 console.log( 'Balance', totalBalance.toFixed( 2 ));

});
<|endoftext|>


<commit_before>angular.module('hadouken.filesystem', [
    'hadouken.jsonrpc'
])
.directive('directoryBrowser', [ '$document', 'jsonrpc', function($document, jsonrpc) {
    var browser = '
' +
                    '
' +
                      '
' +
                        '' +
                        '<select class="form-control drive-list"></select>' +
                      '
' +
                      '
' +
                      '
' +
                    '
' +
                  '
';

    var parentItem = '';
    var item = ' ';

    var originalDirectory = '';

    function bytes(bytes, precision) {
        if (isNaN(parseFloat(bytes)) || !isFinite(bytes) || bytes <= 0) return '-';
        if (typeof precision === 'undefined') precision = 1;
        var units = ['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'],
            number = Math.floor(Math.log(bytes) / Math.log(1024));
        return (bytes / Math.pow(1024, Math.floor(number))).toFixed(precision) +  ' ' + units[number];
    }

    function getDirectories(selected, cb) {
        jsonrpc.request('fileSystem.getDirectories', {
            params: [selected],
            success: function(d) {
                cb(d.result);
            }
        });
    }

    function getDrives(cb) {
        jsonrpc.request('fileSystem.getDrives', {
            params: [],
            success: function(d) {
                cb(d.result);
            }
        });
    }

    function getParent(selected, cb) {
        jsonrpc.request('fileSystem.getParent', {
            params: [selected],
            success: function(d) {
                cb(d.result);
            }
        });
    }

    // Go up one level
    function up($scope, element, currentDirectory) {
        getParent(currentDirectory, function(parent) {
            getDirectories(parent, function(directories) {
                render($scope, element, parent, directories);
            });
        });
    }

    function down($scope, element, currentDirectory) {
        getDirectories(currentDirectory, function(directories) {
            render($scope, element, currentDirectory, directories);
        });
    }

    function render($scope, element, currentDirectory, directories) {
        element.find('.list-group-item').remove();

        var parent = angular.element(parentItem);
        parent.bind('click', function(e) {
            e.preventDefault();
            up($scope, element, currentDirectory);
        });

        element.find('.list-group').append(parent);

        for(var i = 0; i < directories.length; i++) {

            (function(directory) {
                var el = angular.element(item);
                var parts = directory.split('/');

                el.find('.text').text(parts[parts.length - 1]);
                el.bind('click', function(e) {
                    e.preventDefault();
                    down($scope, element, directory);
                });

                element.find('.list-group').append(el);
            })(directories[i]);
        }

        $scope.directory = currentDirectory.replace(/\//g, '\\');

        if($scope.directory.split('\\').filter(function(e){return e;}).length <= 1) {
            parent.hide();
        }
    }

    return {
        scope: {
            directory: '='
        },
        link: function($scope, element, attrs) {
            $document.bind('click', function(e) {
                if(e.target === element[0]
                    || e.target.matches('.directoryBrowser, .directoryBrowser *')) {
                    return;
                }

                element.parent().find('.directoryBrowser').remove();
            });

            element.bind('click', function() {
                originalDirectory = $scope.directory;

                var container = angular.element(browser);
                var driveList = container.find('.drive-list');

                container.width(element.outerWidth());
                driveList.hide();

                element.after(container);

                getDrives(function(drives) {
                    for(var i = 0; i < drives.length; i++) {
                        var drive = drives[i];
                        var opt = angular.element('<option></option>');

                        opt.val(drive.Name);
                        opt.text(drive.Name + ' (' + bytes(drive.TotalFreeSpace) + ' free)');

                        driveList.append(opt);
                    }

                    container.find('.drive-loader').hide();
                    driveList.show();

                    // On drive change
                    driveList.bind('change', function(e) {
                        var drive = driveList.val();

                        getDirectories(drive, function(result) {
                            render($scope, container, drive, result);
                        });
                    });
                });

                getDirectories(originalDirectory, function(result) {
                    render($scope, container, originalDirectory, result);
                });
            });
        }
    }
}]);<commit_msg>Removed matches-selector and implemented it old school for IE.<commit_after>angular.module('hadouken.filesystem', [
    'hadouken.jsonrpc'
])
.directive('directoryBrowser', [ '$document', 'jsonrpc', function($document, jsonrpc) {
    var browser = '
' +
                    '
' +
                      '
' +
                        '' +
                        '<select class="form-control drive-list"></select>' +
                      '
' +
                      '
' +
                      '
' +
                    '
' +
                  '
';

    var parentItem = '';
    var item = ' ';

    var originalDirectory = '';

    function bytes(bytes, precision) {
        if (isNaN(parseFloat(bytes)) || !isFinite(bytes) || bytes <= 0) return '-';
        if (typeof precision === 'undefined') precision = 1;
        var units = ['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'],
            number = Math.floor(Math.log(bytes) / Math.log(1024));
        return (bytes / Math.pow(1024, Math.floor(number))).toFixed(precision) +  ' ' + units[number];
    }

    function $anyParentHasClass(element, classname) {
        if (element.className && element.className.split(' ').indexOf(classname)>=0) return true;
        return element.parentNode && $anyParentHasClass(element.parentNode, classname);
    }

    function getDirectories(selected, cb) {
        jsonrpc.request('fileSystem.getDirectories', {
            params: [selected],
            success: function(d) {
                cb(d.result);
            }
        });
    }

    function getDrives(cb) {
        jsonrpc.request('fileSystem.getDrives', {
            params: [],
            success: function(d) {
                cb(d.result);
            }
        });
    }

    function getParent(selected, cb) {
        jsonrpc.request('fileSystem.getParent', {
            params: [selected],
            success: function(d) {
                cb(d.result);
            }
        });
    }

    // Go up one level
    function up($scope, element, currentDirectory) {
        getParent(currentDirectory, function(parent) {
            getDirectories(parent, function(directories) {
                render($scope, element, parent, directories);
            });
        });
    }

    function down($scope, element, currentDirectory) {
        getDirectories(currentDirectory, function(directories) {
            render($scope, element, currentDirectory, directories);
        });
    }

    function render($scope, element, currentDirectory, directories) {
        element.find('.list-group-item').remove();

        var parent = angular.element(parentItem);
        parent.bind('click', function(e) {
            e.preventDefault();
            up($scope, element, currentDirectory);
        });

        element.find('.list-group').append(parent);

        for(var i = 0; i < directories.length; i++) {

            (function(directory) {
                var el = angular.element(item);
                var parts = directory.split('/');

                el.find('.text').text(parts[parts.length - 1]);
                el.bind('click', function(e) {
                    e.preventDefault();
                    down($scope, element, directory);
                });

                element.find('.list-group').append(el);
            })(directories[i]);
        }

        $scope.directory = currentDirectory.replace(/\//g, '\\');

        if($scope.directory.split('\\').filter(function(e){return e;}).length <= 1) {
            parent.hide();
        }
    }

    return {
        scope: {
            directory: '='
        },
        link: function($scope, element, attrs) {
            $document.bind('click', function(e) {
                if(e.target === element[0]
                    || $anyParentHasClass(e.target, 'directoryBrowser')) {
                    return;
                }

                element.parent().find('.directoryBrowser').remove();
            });

            element.bind('click', function() {
                originalDirectory = $scope.directory;

                var container = angular.element(browser);
                var driveList = container.find('.drive-list');

                container.width(element.outerWidth());
                driveList.hide();

                element.after(container);

                getDrives(function(drives) {
                    for(var i = 0; i < drives.length; i++) {
                        var drive = drives[i];
                        var opt = angular.element('<option></option>');

                        opt.val(drive.Name);
                        opt.text(drive.Name + ' (' + bytes(drive.TotalFreeSpace) + ' free)');

                        driveList.append(opt);
                    }

                    container.find('.drive-loader').hide();
                    driveList.show();

                    // On drive change
                    driveList.bind('change', function(e) {
                        var drive = driveList.val();

                        getDirectories(drive, function(result) {
                            render($scope, container, drive, result);
                        });
                    });
                });

                getDirectories(originalDirectory, function(result) {
                    render($scope, container, originalDirectory, result);
                });
            });
        }
    }
}]);<|endoftext|>