<commit_before>/**
 * SaveLoadEngine is responsible for automatic and manual save and load operations.
 *
 * @class SaveLoadEngine
 * @constructor
 */
var SaveLoadEngine = Class.create({

    initialize: function () {
        this._saveInProgress = false;
    },

    /**
     * Saves the state of the pedigree (including any user preferences and current color scheme)
     *
     * @return Serialization data for the entire graph
     */
    serialize: function () {
        var jsonObject = editor.getGraph().toJSONObject();

        jsonObject["settings"] = editor.getView().getSettings();

        return JSON.stringify(jsonObject);
    },

    createGraphFromSerializedData: function (JSONString, noUndo, centerAround0) {
        console.log("---- load: parsing data ----");
        document.fire("pedigree:load:start");

        try {
            var jsonObject = JSON.parse(JSONString);

            // load the graph model of the pedigree & node data
            var changeSet = editor.getGraph().fromJSONObject(jsonObject);

            //The following is added for GEL(GenomicsEngland) by Soheil ................................................
            //This will make remove all unRenderedNode from unRenderedNodeLegend and adds the new one if any exists
            editor._unRenderedLegend.removeAllNodes();
            var unRenderedNodes = changeSet.unRendered;
            editor._unRenderedLegend.addAllNodes(unRenderedNodes);
            editor.getWorkspace().clearMenuText();
            //..........................................................................................................

            // load/process metadata such as pedigree options and color choices
            if (jsonObject.hasOwnProperty("settings")) {
                editor.getView().loadSettings(jsonObject.settings);
            }
        }
        catch (err) {
            console.log("ERROR loading the graph: " + err);
            alert("Error loading the graph");
            document.fire("pedigree:graph:clear");
            document.fire("pedigree:load:finish");
            return;
        }

        if (!noUndo) {
            var probandJSONObject = editor.getProbandDataFromPhenotips();
            var genderOk = editor.getGraph().setProbandData(probandJSONObject);
            if (!genderOk)
                alert("Proband gender defined in Phenotips is incompatible with this pedigree. Setting proband gender to 'Unknown'");
            JSONString = this.serialize();
        }

        if (editor.getView().applyChanges(changeSet, false)) {
            editor.getWorkspace().adjustSizeToScreen();
        }

        if (centerAround0) {
            editor.getWorkspace().centerAroundNode(0);
        }

        if (!noUndo && !editor.isReadOnlyMode()) {
            editor.getUndoRedoManager().addState(null, null, JSONString);
        }

        document.fire("pedigree:load:finish");
    },

    createGraphFromImportData: function (importString, importType, importOptions, noUndo, centerAround0) {
        console.log("---- import: parsing data ----");
        document.fire("pedigree:load:start");

        try {
            var changeSet = editor.getGraph().fromImport(importString, importType, importOptions);

            //The following is added for GEL(GenomicsEngland) by Soheil ................................................
            //This will make remove all unRenderedNode from unRenderedNodeLegend and adds the new one if any exists
            editor._unRenderedLegend.removeAllNodes();
            var unRenderedNodes = changeSet.unRendered;
            editor._unRenderedLegend.addAllNodes(unRenderedNodes);
            editor.getWorkspace().clearMenuText();
            //..........................................................................................................

            if (changeSet == null) throw "unable to create a pedigree from imported data";
        }
        catch (err) {
            alert("Error importing pedigree: " + err);
            document.fire("pedigree:load:finish");
            return;
        }

        if (!noUndo) {
            var probandJSONObject = editor.getProbandDataFromPhenotips();
            var genderOk = editor.getGraph().setProbandData(probandJSONObject);
            if (!genderOk)
                alert("Proband gender defined in Phenotips is incompatible with the imported pedigree. Setting proband gender to 'Unknown'");
            JSONString = this.serialize();
        }

        if (editor.getView().applyChanges(changeSet, false)) {
            editor.getWorkspace().adjustSizeToScreen();
        }

        if (centerAround0) {
            editor.getWorkspace().centerAroundNode(0);
        }

        if (!noUndo && !editor.isReadOnlyMode()) {
            editor.getUndoRedoManager().addState(null, null, JSONString);
        }

        document.fire("pedigree:load:finish");
    },

    save: function (callback) {
        if (this._saveInProgress) {
            return;   // Don't send parallel save requests
        }

        editor.getView().unmarkAll();

        //Added by Soheil for GEL(GenomicsEngland)
        //the following line will export the diagram as JSON and pass the param as all
        var privacySetting = "all";
        var exportString = PedigreeExport.exportAsSimpleJSON(editor.getGraph().DG, privacySetting);

        var me = this;

        var jsonData = this.serialize();

        console.log("[SAVE] data: " + Helpers.stringifyObject(jsonData));

        var svg = editor.getWorkspace().getSVGCopy(false);
        var svgText = svg.getSVGText();

//		var image = $('canvas');
//		var background = image.getElementsByClassName('panning-background')[0];
//		var backgroundPosition = background.nextSibling;
//		var backgroundParent =  background.parentNode;
//		backgroundParent.removeChild(background);
//		var bbox = image.down().getBBox();

        var savingNotification = new XWiki.widgets.Notification("Saving", "inprogress");
        //The line is commented by Soheil for GEL(GenomicEngland)
        //instead of using XWiki rest end point for saving the value into XML
        //we pass it the backend Webservice URL
        //new Ajax.Request(XWiki.currentDocument.getRestURL('objects/PhenoTips.PedigreeClass/0.xml', 'method=PUT').substring(1), {
        var webservice = new WebService();
        var href = webservice.saveDiagramEndpointPath();
        new Ajax.Request(href, {
            method: 'POST',
            onCreate: function () {
                me._saveInProgress = true;
                // Disable save and close buttons during a save
                var closeButton = $('action-close');
                var saveButton = $('action-save');
                var saveAndExitButton = $('action-saveAndExit');

                Element.addClassName(saveButton, "disabled-menu-item");
                Element.removeClassName(saveButton, "menu-item");
                Element.addClassName(saveButton, "no-mouse-interaction");
                Element.addClassName(closeButton, "disabled-menu-item");
                Element.removeClassName(closeButton, "menu-item");
                Element.addClassName(closeButton, "no-mouse-interaction");

                Element.addClassName(saveAndExitButton, "disabled-menu-item");
                Element.removeClassName(saveAndExitButton, "menu-item");
                Element.addClassName(saveAndExitButton, "no-mouse-interaction");

                // IE9 & IE10 do not support "no-mouse-interaction", so add JS to handle this
                if (closeButton != null && closeButton != undefined) {
                    Helpers.disableMouseclicks(closeButton);
                }
                if (saveButton != null && saveButton != undefined) {
                    Helpers.disableMouseclicks(saveButton);
                }
                if (saveAndExitButton != null && saveAndExitButton != undefined) {
                    Helpers.disableMouseclicks(saveAndExitButton);
                }

            },
            onComplete: function (response) {
                me._saveInProgress = false;
                var actionAfterSave = editor.getAfterSaveAction();
                actionAfterSave && actionAfterSave();
                // Enable save and close buttons after a save
                var closeButton = $('action-close');
                var saveButton = $('action-save');
                var saveAndExitButton = $('action-saveAndExit');

                Element.addClassName(saveButton, "menu-item");
                Element.removeClassName(saveButton, "disabled-menu-item");
                Element.removeClassName(saveButton, "no-mouse-interaction");

                Element.addClassName(closeButton, "menu-item");
                Element.removeClassName(closeButton, "disabled-menu-item");
                Element.removeClassName(closeButton, "no-mouse-interaction");

                Element.addClassName(saveAndExitButton, "menu-item");
                Element.removeClassName(saveAndExitButton, "disabled-menu-item");
                Element.removeClassName(saveAndExitButton, "no-mouse-interaction");

                // remove IE9/IE10 specific handlers
                if (closeButton != null && closeButton != undefined) {
                    Helpers.enableMouseclicks(closeButton);
                }
                if (saveButton != null && saveButton != undefined) {
                    Helpers.enableMouseclicks(saveButton);
                }
                if (saveAndExitButton != null && saveAndExitButton != undefined) {
                    Helpers.enableMouseclicks(saveAndExitButton);
                }

                //Added for GEL(GenomicsEngland) ...............................................................
                //if it has successfully saved the result
                if (response.status == 200 || response.status == 201) {
                    //Added by Soheil for GEL(GenomicsEngland)
                    //If the backend is OpenClinica and it is in adminEdit mode
                    //Show the following message after each save ................................................
                    var settings = new Settings();
                    var config = settings.getSetting('diagramEndpoint');
                    if (config.service == "openclinica") {
                        var webService = new WebService();
                        var isAdminEdit = webService.getUrlParameter("adminEdit", true);
                        if (isAdminEdit != null && isAdminEdit != undefined && isAdminEdit == "true") {
                            var closeFunction = function () {
                                this.dialog.show();
                                if (callback) {
                                    callback();
                                }
                            };
                            editor.getOkCancelDialogue().showCustomized('Your data will be saved for later but not resubmitted to Genomics England.
When you are ready, please resubmit the Pedigree CRF.',
                                "Genomics England",
                                "Close", closeFunction,
                                null, null,
                                null, null, true);
                        } else {
                            if (callback) {
                                callback();
                            }
                        }
                    } else {
                        if (callback) {
                            callback();
                        }
                    }
                }
                //............................................................................................

            },
            onFailure: function (response) {
                //Added for GEL(GenomicsEngland), if an error occurs while saving, then show error message
                me._saveInProgress = false;
                editor.getUndoRedoManager().addSaveEvent();

                switch (response.status) {
                    case 404:
                        savingNotification.replace(new XWiki.widgets.Notification("Participant not found"));
                        break;
                    case 403:
                        savingNotification.replace(new XWiki.widgets.Notification("Not Authorized!"));
                        break;
                    default:
                        savingNotification.replace(new XWiki.widgets.Notification("An error occurred! Please try again later."));
                        break;
                }

            },
            onSuccess: function (response) {

                if (response.status != 200 && response.status != 201) {
                    me._saveInProgress = false;
                    editor.getUndoRedoManager().addSaveEvent();
                    savingNotification.replace(new XWiki.widgets.Notification("An error occurred! Please try again later."));
                    return;
                }

                me._saveInProgress = false;
                editor.getUndoRedoManager().addSaveEvent();
                savingNotification.replace(new XWiki.widgets.Notification("Successfully saved"));
            },
            parameters: {
                "jsonDiagram": exportString,
                "svgDiagram": svgText//image.innerHTML.replace(/xmlns:xlink=".*?"/, '').replace(/width=".*?"/, '').replace(/height=".*?"/, '').replace(/viewBox=".*?"/, "viewBox=\"" + bbox.x + " " + bbox.y + " " + bbox.width + " " + bbox.height + "\" width=\"" + bbox.width + "\" height=\"" + bbox.height + "\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"")
            }

        });
    },

    //probandDataObj passed to set  the probandData from the result content returned by the webservice
    load: function (probandDataObj) {
        console.log("initiating load process");

        //CALL OpenClinica service to load it ******************************************
        //******************************************************************************
        //******************************************************************************

        //This line is commented by Soheil for GEL(GenomicsEngland)
        //we load the pedigree diagram JSON from backend webservice instead of xWiki XML
        //new Ajax.Request(XWiki.currentDocument.getRestURL('objects/PhenoTips.PedigreeClass/0.xml').substring(1), {
        var webservice = new WebService();
        var path = webservice.getDiagramEndpointPath();
        var _this = this;
        new Ajax.Request(path, {
            method: 'GET',
            requestHeaders: {Accept: "application/json text/json"},
            contentType: "application/x-www-form-urlencoded",
            onCreate: function (response) {
                document.fire("pedigree:load:start");

                //Added for GEL(GenomicsEngland).............
                //We need to stop sending Pre-flight OPTIONS request
                //http://stackoverflow.com/questions/13814739/prototype-ajax-request-being-sent-as-options-rather-than-get-results-in-501-err
                var SEND_OPTION_REQUEST = false;
                if (!SEND_OPTION_REQUEST) {
                    var t = response.transport;
                    t.setRequestHeader = t.setRequestHeader.wrap(function (original, k, v) {
                        if (/^(accept|accept-language|content-language)$/i.test(k))
                            return original(k, v);
                        if (/^content-type$/i.test(k) &&
                            /^(application\/x-www-form-urlencoded|multipart\/form-data|text\/plain)(;.+)?$/i.test(v))
                            return original(k, v);
                        return;
                    });
                }
            },
            on401:function (response) {
                var message = response.statusText;
                if (response.responseJSON != null) {
                    message = response.responseJSON.message;
                }
                _this.showUnauthorisedError(message);
            },
            onFailure: function (response) {
                var message = response.statusText;
                if (response.responseJSON != null) {
                    message = response.responseJSON.message;
                }
                _this.showLoadError(message);
            },
            onSuccess: function (response) {
                if (response.status == 0) {
                    _this.showLoadError("Unknown failure reason");
                    return;
                }

                //These lines are added by Soheil for GEL(GenomicsEngland)
                //These will set the proband details into probandDataObj
                probandDataObj.probandData = {};
                var pedigreeJSON = response.responseJSON;
                if (config.service == "openclinica") {
                    pedigreeJSON = response.responseJSON.pedigreeJSON
                }

                for (var i = 0; i < pedigreeJSON.length; i++) {
                    var node = pedigreeJSON[i];
                    if (node.proband != undefined && node.proband == true) {
                        probandDataObj.probandData = node;
                        var genderString = probandDataObj.probandData.sex.toLowerCase();
                        if (genderString == "female" || genderString == "f" || genderString == "2")
                            probandDataObj.probandData.gender = "F";
                        else if (genderString == "male" || genderString == "m" || genderString == "1")
                            probandDataObj.probandData.gender = "M";
                        else if (genderString == "other" || genderString == "o" || genderString == "9")
                            probandDataObj.probandData.gender = "O";
                        break;
                    }
                }

                var jsonContentString = JSON.stringify(pedigreeJSON);

                var importType = "simpleJSON";
                var importOptions = {
                    "acceptUnknownPhenotypes": true,
                    "externalIdMark": true,
                    "markEvaluated": false
                };
                var noUndo = false;
                var centerAround0 = true;
                this.createGraphFromImportData(jsonContentString, importType, importOptions, noUndo, centerAround0);
                return;

                //console.log("Data from LOAD: >>" + response.responseText + "<<");
                if (response.responseJSON) {
                    console.log("[LOAD] recived JSON: " + Helpers.stringifyObject(response.responseJSON));

                    var updatedJSONData = editor.getVersionUpdater().updateToCurrentVersion(response.responseText);

                    this.createGraphFromSerializedData(updatedJSONData);

                    // since we just loaded data from disk data in memory is equivalent to data on disk
                    editor.getUndoRedoManager().addSaveEvent();
                } else {
                    new TemplateSelector(true);
                }
            }.bind(this)
        })
    },
    showLoadError: function(reason){
        this.showError("Failed to load pedigree model",reason);
    },
    showUnauthorisedError: function(reason){
        this.showError("User is not allowed to load pedigree model",reason);
    },
    showError: function(message, reason){
        editor.getOkCancelDialogue().showCustomized(message + "

-- " + reason +
            " --

Please choose a base template.", "Error Loading Model", "Choose Template", function () {
                new TemplateSelector(true);
            },
            null, null,
            null, null, true);
    }
});<commit_msg>Read application config from right parameter<commit_after>/**
 * SaveLoadEngine is responsible for automatic and manual save and load operations.
 *
 * @class SaveLoadEngine
 * @constructor
 */
var SaveLoadEngine = Class.create({

    initialize: function () {
        this._saveInProgress = false;
    },

    /**
     * Saves the state of the pedigree (including any user preferences and current color scheme)
     *
     * @return Serialization data for the entire graph
     */
    serialize: function () {
        var jsonObject = editor.getGraph().toJSONObject();

        jsonObject["settings"] = editor.getView().getSettings();

        return JSON.stringify(jsonObject);
    },

    createGraphFromSerializedData: function (JSONString, noUndo, centerAround0) {
        console.log("---- load: parsing data ----");
        document.fire("pedigree:load:start");

        try {
            var jsonObject = JSON.parse(JSONString);

            // load the graph model of the pedigree & node data
            var changeSet = editor.getGraph().fromJSONObject(jsonObject);

            //The following is added for GEL(GenomicsEngland) by Soheil ................................................
            //This will make remove all unRenderedNode from unRenderedNodeLegend and adds the new one if any exists
            editor._unRenderedLegend.removeAllNodes();
            var unRenderedNodes = changeSet.unRendered;
            editor._unRenderedLegend.addAllNodes(unRenderedNodes);
            editor.getWorkspace().clearMenuText();
            //..........................................................................................................

            // load/process metadata such as pedigree options and color choices
            if (jsonObject.hasOwnProperty("settings")) {
                editor.getView().loadSettings(jsonObject.settings);
            }
        }
        catch (err) {
            console.log("ERROR loading the graph: " + err);
            alert("Error loading the graph");
            document.fire("pedigree:graph:clear");
            document.fire("pedigree:load:finish");
            return;
        }

        if (!noUndo) {
            var probandJSONObject = editor.getProbandDataFromPhenotips();
            var genderOk = editor.getGraph().setProbandData(probandJSONObject);
            if (!genderOk)
                alert("Proband gender defined in Phenotips is incompatible with this pedigree. Setting proband gender to 'Unknown'");
            JSONString = this.serialize();
        }

        if (editor.getView().applyChanges(changeSet, false)) {
            editor.getWorkspace().adjustSizeToScreen();
        }

        if (centerAround0) {
            editor.getWorkspace().centerAroundNode(0);
        }

        if (!noUndo && !editor.isReadOnlyMode()) {
            editor.getUndoRedoManager().addState(null, null, JSONString);
        }

        document.fire("pedigree:load:finish");
    },

    createGraphFromImportData: function (importString, importType, importOptions, noUndo, centerAround0) {
        console.log("---- import: parsing data ----");
        document.fire("pedigree:load:start");

        try {
            var changeSet = editor.getGraph().fromImport(importString, importType, importOptions);

            //The following is added for GEL(GenomicsEngland) by Soheil ................................................
            //This will make remove all unRenderedNode from unRenderedNodeLegend and adds the new one if any exists
            editor._unRenderedLegend.removeAllNodes();
            var unRenderedNodes = changeSet.unRendered;
            editor._unRenderedLegend.addAllNodes(unRenderedNodes);
            editor.getWorkspace().clearMenuText();
            //..........................................................................................................

            if (changeSet == null) throw "unable to create a pedigree from imported data";
        }
        catch (err) {
            alert("Error importing pedigree: " + err);
            document.fire("pedigree:load:finish");
            return;
        }

        if (!noUndo) {
            var probandJSONObject = editor.getProbandDataFromPhenotips();
            var genderOk = editor.getGraph().setProbandData(probandJSONObject);
            if (!genderOk)
                alert("Proband gender defined in Phenotips is incompatible with the imported pedigree. Setting proband gender to 'Unknown'");
            JSONString = this.serialize();
        }

        if (editor.getView().applyChanges(changeSet, false)) {
            editor.getWorkspace().adjustSizeToScreen();
        }

        if (centerAround0) {
            editor.getWorkspace().centerAroundNode(0);
        }

        if (!noUndo && !editor.isReadOnlyMode()) {
            editor.getUndoRedoManager().addState(null, null, JSONString);
        }

        document.fire("pedigree:load:finish");
    },

    save: function (callback) {
        if (this._saveInProgress) {
            return;   // Don't send parallel save requests
        }

        editor.getView().unmarkAll();

        //Added by Soheil for GEL(GenomicsEngland)
        //the following line will export the diagram as JSON and pass the param as all
        var privacySetting = "all";
        var exportString = PedigreeExport.exportAsSimpleJSON(editor.getGraph().DG, privacySetting);

        var me = this;

        var jsonData = this.serialize();

        console.log("[SAVE] data: " + Helpers.stringifyObject(jsonData));

        var svg = editor.getWorkspace().getSVGCopy(false);
        var svgText = svg.getSVGText();

//		var image = $('canvas');
//		var background = image.getElementsByClassName('panning-background')[0];
//		var backgroundPosition = background.nextSibling;
//		var backgroundParent =  background.parentNode;
//		backgroundParent.removeChild(background);
//		var bbox = image.down().getBBox();

        var savingNotification = new XWiki.widgets.Notification("Saving", "inprogress");
        //The line is commented by Soheil for GEL(GenomicEngland)
        //instead of using XWiki rest end point for saving the value into XML
        //we pass it the backend Webservice URL
        //new Ajax.Request(XWiki.currentDocument.getRestURL('objects/PhenoTips.PedigreeClass/0.xml', 'method=PUT').substring(1), {
        var webservice = new WebService();
        var href = webservice.saveDiagramEndpointPath();
        new Ajax.Request(href, {
            method: 'POST',
            onCreate: function () {
                me._saveInProgress = true;
                // Disable save and close buttons during a save
                var closeButton = $('action-close');
                var saveButton = $('action-save');
                var saveAndExitButton = $('action-saveAndExit');

                Element.addClassName(saveButton, "disabled-menu-item");
                Element.removeClassName(saveButton, "menu-item");
                Element.addClassName(saveButton, "no-mouse-interaction");
                Element.addClassName(closeButton, "disabled-menu-item");
                Element.removeClassName(closeButton, "menu-item");
                Element.addClassName(closeButton, "no-mouse-interaction");

                Element.addClassName(saveAndExitButton, "disabled-menu-item");
                Element.removeClassName(saveAndExitButton, "menu-item");
                Element.addClassName(saveAndExitButton, "no-mouse-interaction");

                // IE9 & IE10 do not support "no-mouse-interaction", so add JS to handle this
                if (closeButton != null && closeButton != undefined) {
                    Helpers.disableMouseclicks(closeButton);
                }
                if (saveButton != null && saveButton != undefined) {
                    Helpers.disableMouseclicks(saveButton);
                }
                if (saveAndExitButton != null && saveAndExitButton != undefined) {
                    Helpers.disableMouseclicks(saveAndExitButton);
                }

            },
            onComplete: function (response) {
                me._saveInProgress = false;
                var actionAfterSave = editor.getAfterSaveAction();
                actionAfterSave && actionAfterSave();
                // Enable save and close buttons after a save
                var closeButton = $('action-close');
                var saveButton = $('action-save');
                var saveAndExitButton = $('action-saveAndExit');

                Element.addClassName(saveButton, "menu-item");
                Element.removeClassName(saveButton, "disabled-menu-item");
                Element.removeClassName(saveButton, "no-mouse-interaction");

                Element.addClassName(closeButton, "menu-item");
                Element.removeClassName(closeButton, "disabled-menu-item");
                Element.removeClassName(closeButton, "no-mouse-interaction");

                Element.addClassName(saveAndExitButton, "menu-item");
                Element.removeClassName(saveAndExitButton, "disabled-menu-item");
                Element.removeClassName(saveAndExitButton, "no-mouse-interaction");

                // remove IE9/IE10 specific handlers
                if (closeButton != null && closeButton != undefined) {
                    Helpers.enableMouseclicks(closeButton);
                }
                if (saveButton != null && saveButton != undefined) {
                    Helpers.enableMouseclicks(saveButton);
                }
                if (saveAndExitButton != null && saveAndExitButton != undefined) {
                    Helpers.enableMouseclicks(saveAndExitButton);
                }

                //Added for GEL(GenomicsEngland) ...............................................................
                //if it has successfully saved the result
                if (response.status == 200 || response.status == 201) {
                    //Added by Soheil for GEL(GenomicsEngland)
                    //If the backend is OpenClinica and it is in adminEdit mode
                    //Show the following message after each save ................................................
                    var settings = new Settings();
                    var config = settings.getSetting('diagramEndpoint');
                    if (config.service == "openclinica") {
                        var webService = new WebService();
                        var isAdminEdit = webService.getUrlParameter("adminEdit", true);
                        if (isAdminEdit != null && isAdminEdit != undefined && isAdminEdit == "true") {
                            var closeFunction = function () {
                                this.dialog.show();
                                if (callback) {
                                    callback();
                                }
                            };
                            editor.getOkCancelDialogue().showCustomized('Your data will be saved for later but not resubmitted to Genomics England.
When you are ready, please resubmit the Pedigree CRF.',
                                "Genomics England",
                                "Close", closeFunction,
                                null, null,
                                null, null, true);
                        } else {
                            if (callback) {
                                callback();
                            }
                        }
                    } else {
                        if (callback) {
                            callback();
                        }
                    }
                }
                //............................................................................................

            },
            onFailure: function (response) {
                //Added for GEL(GenomicsEngland), if an error occurs while saving, then show error message
                me._saveInProgress = false;
                editor.getUndoRedoManager().addSaveEvent();

                switch (response.status) {
                    case 404:
                        savingNotification.replace(new XWiki.widgets.Notification("Participant not found"));
                        break;
                    case 403:
                        savingNotification.replace(new XWiki.widgets.Notification("Not Authorized!"));
                        break;
                    default:
                        savingNotification.replace(new XWiki.widgets.Notification("An error occurred! Please try again later."));
                        break;
                }

            },
            onSuccess: function (response) {

                if (response.status != 200 && response.status != 201) {
                    me._saveInProgress = false;
                    editor.getUndoRedoManager().addSaveEvent();
                    savingNotification.replace(new XWiki.widgets.Notification("An error occurred! Please try again later."));
                    return;
                }

                me._saveInProgress = false;
                editor.getUndoRedoManager().addSaveEvent();
                savingNotification.replace(new XWiki.widgets.Notification("Successfully saved"));
            },
            parameters: {
                "jsonDiagram": exportString,
                "svgDiagram": svgText//image.innerHTML.replace(/xmlns:xlink=".*?"/, '').replace(/width=".*?"/, '').replace(/height=".*?"/, '').replace(/viewBox=".*?"/, "viewBox=\"" + bbox.x + " " + bbox.y + " " + bbox.width + " " + bbox.height + "\" width=\"" + bbox.width + "\" height=\"" + bbox.height + "\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"")
            }

        });
    },

    //probandDataObj passed to set  the probandData from the result content returned by the webservice
    load: function (probandDataObj) {
        console.log("initiating load process");

        //CALL OpenClinica service to load it ******************************************
        //******************************************************************************
        //******************************************************************************

        //This line is commented by Soheil for GEL(GenomicsEngland)
        //we load the pedigree diagram JSON from backend webservice instead of xWiki XML
        //new Ajax.Request(XWiki.currentDocument.getRestURL('objects/PhenoTips.PedigreeClass/0.xml').substring(1), {
        var webservice = new WebService();
        var path = webservice.getDiagramEndpointPath();
        var _this = this;
        new Ajax.Request(path, {
            method: 'GET',
            requestHeaders: {Accept: "application/json text/json"},
            contentType: "application/x-www-form-urlencoded",
            onCreate: function (response) {
                document.fire("pedigree:load:start");

                //Added for GEL(GenomicsEngland).............
                //We need to stop sending Pre-flight OPTIONS request
                //http://stackoverflow.com/questions/13814739/prototype-ajax-request-being-sent-as-options-rather-than-get-results-in-501-err
                var SEND_OPTION_REQUEST = false;
                if (!SEND_OPTION_REQUEST) {
                    var t = response.transport;
                    t.setRequestHeader = t.setRequestHeader.wrap(function (original, k, v) {
                        if (/^(accept|accept-language|content-language)$/i.test(k))
                            return original(k, v);
                        if (/^content-type$/i.test(k) &&
                            /^(application\/x-www-form-urlencoded|multipart\/form-data|text\/plain)(;.+)?$/i.test(v))
                            return original(k, v);
                        return;
                    });
                }
            },
            on401:function (response) {
                var message = response.statusText;
                if (response.responseJSON != null) {
                    message = response.responseJSON.message;
                }
                _this.showUnauthorisedError(message);
            },
            onFailure: function (response) {
                var message = response.statusText;
                if (response.responseJSON != null) {
                    message = response.responseJSON.message;
                }
                _this.showLoadError(message);
            },
            onSuccess: function (response) {
                if (response.status == 0) {
                    _this.showLoadError("Unknown failure reason");
                    return;
                }

                //These lines are added by Soheil for GEL(GenomicsEngland)
                //These will set the proband details into probandDataObj
                probandDataObj.probandData = {};
                var pedigreeJSON = response.responseJSON;
                var settings = new Settings();
                var config = settings.getSetting('diagramEndpoint');
                if (config.service == "openclinica") {
                    pedigreeJSON = response.responseJSON.pedigreeJSON
                }

                for (var i = 0; i < pedigreeJSON.length; i++) {
                    var node = pedigreeJSON[i];
                    if (node.proband != undefined && node.proband == true) {
                        probandDataObj.probandData = node;
                        var genderString = probandDataObj.probandData.sex.toLowerCase();
                        if (genderString == "female" || genderString == "f" || genderString == "2")
                            probandDataObj.probandData.gender = "F";
                        else if (genderString == "male" || genderString == "m" || genderString == "1")
                            probandDataObj.probandData.gender = "M";
                        else if (genderString == "other" || genderString == "o" || genderString == "9")
                            probandDataObj.probandData.gender = "O";
                        break;
                    }
                }

                var jsonContentString = JSON.stringify(pedigreeJSON);

                var importType = "simpleJSON";
                var importOptions = {
                    "acceptUnknownPhenotypes": true,
                    "externalIdMark": true,
                    "markEvaluated": false
                };
                var noUndo = false;
                var centerAround0 = true;
                this.createGraphFromImportData(jsonContentString, importType, importOptions, noUndo, centerAround0);
                return;

                //console.log("Data from LOAD: >>" + response.responseText + "<<");
                if (response.responseJSON) {
                    console.log("[LOAD] recived JSON: " + Helpers.stringifyObject(response.responseJSON));

                    var updatedJSONData = editor.getVersionUpdater().updateToCurrentVersion(response.responseText);

                    this.createGraphFromSerializedData(updatedJSONData);

                    // since we just loaded data from disk data in memory is equivalent to data on disk
                    editor.getUndoRedoManager().addSaveEvent();
                } else {
                    new TemplateSelector(true);
                }
            }.bind(this)
        })
    },
    showLoadError: function(reason){
        this.showError("Failed to load pedigree model",reason);
    },
    showUnauthorisedError: function(reason){
        this.showError("User is not allowed to load pedigree model",reason);
    },
    showError: function(message, reason){
        editor.getOkCancelDialogue().showCustomized(message + "

-- " + reason +
            " --

Please choose a base template.", "Error Loading Model", "Choose Template", function () {
                new TemplateSelector(true);
            },
            null, null,
            null, null, true);
    }
});<|endoftext|>


<commit_before>define(['js/core/DomElement'], function(DomElement) {

    var SvgElement = DomElement.inherit("js/svg/SvgElement", {

        ctor: function() {
            // default namespace
            this.$namespace = SvgElement.SVG_NAMESPACE;
            this.$transformations = [];

            this.callBase();
        },

        resetTransform: function() {
            if (this.$transformation.length) {
                this.$transformation = [];
                this._refreshTransform();
            }
        },

        addTransform: function(transform) {
            if (transform) {
                this.$transformations.push(transform);
                this._refreshTransform();
            }
        },

        translate: function(x, y) {
            if (x && y) {
                this.addTransform(new SvgElement.Translate(x, y));
            }
            return this;
        },

        rotate: function(r, x, y) {
            this.addTransform(new SvgElement.Rotate(r, x, y));
            return this;
        },

        _refreshTransform: function() {

            var transformations = [];
            for (var i = 0; i < this.$transformations.length; i++) {
                var t = this.$transformations[i];

                if (t instanceof SvgElement.Transform) {
                    transformations.push(t.toString());
                } else {
                    transformations.push(t);
                }
            }

            this.set('transform', transformations.join(" "));
        },

        // render each href Element in xlink namespace
        _renderHref: function(href, oldHref) {
            this._setAttribute("href", href, SvgElement.XLINK_NAMESPACE);
        }
    });

    SvgElement.XLINK_NAMESPACE = "http://www.w3.org/1999/xlink";
    SvgElement.SVG_NAMESPACE = "http://www.w3.org/2000/svg";

    SvgElement.Matrix = function(a, b, c, d, e, f) {
        if (arguments.length) {
            this.a = a;
            this.b = b;
            this.c = c;
            this.d = d;
            this.e = e;
            this.f = f;
        } else {
            this.a = 1;
            this.b = 0;
            this.c = 0;
            this.d = 1;
            this.e = 0;
            this.f = 0;
        }
    };

    SvgElement.Transform = function() {
    };

    SvgElement.Translate = SvgElement.Transform.inherit({
        ctor: function(x, y) {
            this.x = x;
            this.y = y;
        },
        toString: function() {
            return "translate(" + this.x + "," + this.y + ")";
        }
    });

    SvgElement.Rotate = SvgElement.Transform.inherit({
        ctor: function(r, x, y) {
            this.r = r || 0;
            this.x = x || 0;
            this.y = y || 0;
        },
        toString: function() {
            return "rotate(" + this.r + "," + this.x + "," + this.y + ")"
        }
    });

    return SvgElement;
});<commit_msg>fixed rendering of svg element class<commit_after>define(['js/core/DomElement'], function(DomElement) {

    var SvgElement = DomElement.inherit("js/svg/SvgElement", {

        ctor: function() {
            // default namespace
            this.$namespace = SvgElement.SVG_NAMESPACE;
            this.$transformations = [];

            this.callBase();
        },

        resetTransform: function() {
            if (this.$transformation.length) {
                this.$transformation = [];
                this._refreshTransform();
            }
        },

        addTransform: function(transform) {
            if (transform) {
                this.$transformations.push(transform);
                this._refreshTransform();
            }
        },

        translate: function(x, y) {
            if (x && y) {
                this.addTransform(new SvgElement.Translate(x, y));
            }
            return this;
        },

        rotate: function(r, x, y) {
            this.addTransform(new SvgElement.Rotate(r, x, y));
            return this;
        },

        _refreshTransform: function() {

            var transformations = [];
            for (var i = 0; i < this.$transformations.length; i++) {
                var t = this.$transformations[i];

                if (t instanceof SvgElement.Transform) {
                    transformations.push(t.toString());
                } else {
                    transformations.push(t);
                }
            }

            this.set('transform', transformations.join(" "));
        },

        // render each href Element in xlink namespace
        _renderHref: function(href, oldHref) {
            this._setAttribute("href", href, SvgElement.XLINK_NAMESPACE);
        },

        _renderClass: function(value) {
            this._setAttribute('class', value);
        }
    });

    SvgElement.XLINK_NAMESPACE = "http://www.w3.org/1999/xlink";
    SvgElement.SVG_NAMESPACE = "http://www.w3.org/2000/svg";

    SvgElement.Matrix = function(a, b, c, d, e, f) {
        if (arguments.length) {
            this.a = a;
            this.b = b;
            this.c = c;
            this.d = d;
            this.e = e;
            this.f = f;
        } else {
            this.a = 1;
            this.b = 0;
            this.c = 0;
            this.d = 1;
            this.e = 0;
            this.f = 0;
        }
    };

    SvgElement.Transform = function() {
    };

    SvgElement.Translate = SvgElement.Transform.inherit({
        ctor: function(x, y) {
            this.x = x;
            this.y = y;
        },
        toString: function() {
            return "translate(" + this.x + "," + this.y + ")";
        }
    });

    SvgElement.Rotate = SvgElement.Transform.inherit({
        ctor: function(r, x, y) {
            this.r = r || 0;
            this.x = x || 0;
            this.y = y || 0;
        },
        toString: function() {
            return "rotate(" + this.r + "," + this.x + "," + this.y + ")"
        }
    });

    return SvgElement;
});<|endoftext|>


<commit_before>//Translated from test_stone.rb using babyruby2js
'use strict';

var inherits = require('util').inherits;
var Stone = require('../Stone');
var main = require('../main');
var assertEqual = main.assertEqual;

var Goban = require('../Goban');
// NB: for debugging think of using @goban.console_display
TestStone.prototype.init_board = function () {
    this.goban = new Goban(5);
};

/** @class */
function TestStone(test_name) {
    main.TestCase.call(this, test_name);
    return this.init_board();
}
inherits(TestStone, main.TestCase);
module.exports = main.tests.add(TestStone);

TestStone.prototype.how_many_lives = function (i, j) {
    var s = this.goban.stone_at(i, j);
    var lives_before = s.empties().size;
    // we test the play/undo too
    s = Stone.play_at(this.goban, i, j, main.WHITE);
    var lives = s.empties().size;
    assertEqual(lives_before, lives);
    Stone.undo(this.goban);
    var lives_after = s.empties().size;
    assertEqual(lives_after, lives);
    return lives;
};

// Not very useful anymore for stones
TestStone.prototype.test_how_many_lives = function () {
    assertEqual(2, this.how_many_lives(1, 1));
    assertEqual(2, this.how_many_lives(this.goban.size, this.goban.size));
    assertEqual(2, this.how_many_lives(1, this.goban.size));
    assertEqual(2, this.how_many_lives(this.goban.size, 1));
    assertEqual(4, this.how_many_lives(2, 2));
    assertEqual(4, this.how_many_lives(this.goban.size - 1, this.goban.size - 1));
    var s = Stone.play_at(this.goban, 2, 2, main.BLACK); // we will try white stones around this one
    var g = s.group;
    assertEqual(2, this.how_many_lives(1, 1));
    assertEqual(4, g.lives);
    assertEqual(2, this.how_many_lives(1, 2));
    assertEqual(4, g.lives); // verify the live count did not change
    assertEqual(2, this.how_many_lives(2, 1));
    assertEqual(3, this.how_many_lives(2, 3));
    assertEqual(3, this.how_many_lives(3, 2));
    return assertEqual(4, this.how_many_lives(3, 3));
};

TestStone.prototype.test_play_at = function () {
    // single stone
    var s = Stone.play_at(this.goban, 5, 4, main.BLACK);
    assertEqual(s, this.goban.stone_at(5, 4));
    assertEqual(this.goban, s.goban);
    assertEqual(main.BLACK, s.color);
    assertEqual(5, s.i);
    return assertEqual(4, s.j);
};

TestStone.prototype.test_suicide = function () {
    // a2 b2 b1 a3 pass c1
    Stone.play_at(this.goban, 1, 2, main.BLACK);
    Stone.play_at(this.goban, 2, 2, main.WHITE);
    Stone.play_at(this.goban, 2, 1, main.BLACK);
    assertEqual(false, Stone.valid_move(this.goban, 1, 1, main.WHITE)); // suicide invalid
    Stone.play_at(this.goban, 1, 3, main.WHITE);
    assertEqual(true, Stone.valid_move(this.goban, 1, 1, main.WHITE)); // now this would be a kill
    assertEqual(true, Stone.valid_move(this.goban, 1, 1, main.BLACK)); // black could a1 too (merge)
    Stone.play_at(this.goban, 3, 1, main.WHITE); // now 2 black stones share a last life
    return assertEqual(false, Stone.valid_move(this.goban, 1, 1, main.BLACK)); // so this would be a suicide with merge
};

TestStone.prototype.test_ko = function () {
    // pass b2 a2 a3 b1 a1
    Stone.play_at(this.goban, 2, 2, main.WHITE);
    Stone.play_at(this.goban, 1, 2, main.BLACK);
    Stone.play_at(this.goban, 1, 3, main.WHITE);
    Stone.play_at(this.goban, 2, 1, main.BLACK);
    Stone.play_at(this.goban, 1, 1, main.WHITE); // kill!
    assertEqual(false, Stone.valid_move(this.goban, 1, 2, main.BLACK)); // now this is a ko
    Stone.play_at(this.goban, 4, 4, main.BLACK); // play once anywhere else
    Stone.play_at(this.goban, 4, 5, main.WHITE);
    assertEqual(true, Stone.valid_move(this.goban, 1, 2, main.BLACK)); // ko can be taken by black
    Stone.play_at(this.goban, 1, 2, main.BLACK); // black takes the ko
    assertEqual(false, Stone.valid_move(this.goban, 1, 1, main.WHITE)); // white cannot take the ko
    Stone.play_at(this.goban, 5, 5, main.WHITE); // play once anywhere else
    Stone.play_at(this.goban, 5, 4, main.BLACK);
    assertEqual(true, Stone.valid_move(this.goban, 1, 1, main.WHITE)); // ko can be taken back by white
    Stone.play_at(this.goban, 1, 1, main.WHITE); // white takes the ko
    return assertEqual(false, Stone.valid_move(this.goban, 1, 2, main.BLACK)); // and black cannot take it now
};
<commit_msg>moved back init_board in testStone<commit_after>//Translated from test_stone.rb using babyruby2js
'use strict';

var inherits = require('util').inherits;
var Stone = require('../Stone');
var main = require('../main');
var assertEqual = main.assertEqual;

var Goban = require('../Goban');

/** @class */
function TestStone(test_name) {
    main.TestCase.call(this, test_name);
    return this.init_board();
}
inherits(TestStone, main.TestCase);
module.exports = main.tests.add(TestStone);

// NB: for debugging think of using @goban.console_display
TestStone.prototype.init_board = function () {
    this.goban = new Goban(5);
};

TestStone.prototype.how_many_lives = function (i, j) {
    var s = this.goban.stone_at(i, j);
    var lives_before = s.empties().size;
    // we test the play/undo too
    s = Stone.play_at(this.goban, i, j, main.WHITE);
    var lives = s.empties().size;
    assertEqual(lives_before, lives);
    Stone.undo(this.goban);
    var lives_after = s.empties().size;
    assertEqual(lives_after, lives);
    return lives;
};

// Not very useful anymore for stones
TestStone.prototype.test_how_many_lives = function () {
    assertEqual(2, this.how_many_lives(1, 1));
    assertEqual(2, this.how_many_lives(this.goban.size, this.goban.size));
    assertEqual(2, this.how_many_lives(1, this.goban.size));
    assertEqual(2, this.how_many_lives(this.goban.size, 1));
    assertEqual(4, this.how_many_lives(2, 2));
    assertEqual(4, this.how_many_lives(this.goban.size - 1, this.goban.size - 1));
    var s = Stone.play_at(this.goban, 2, 2, main.BLACK); // we will try white stones around this one
    var g = s.group;
    assertEqual(2, this.how_many_lives(1, 1));
    assertEqual(4, g.lives);
    assertEqual(2, this.how_many_lives(1, 2));
    assertEqual(4, g.lives); // verify the live count did not change
    assertEqual(2, this.how_many_lives(2, 1));
    assertEqual(3, this.how_many_lives(2, 3));
    assertEqual(3, this.how_many_lives(3, 2));
    return assertEqual(4, this.how_many_lives(3, 3));
};

TestStone.prototype.test_play_at = function () {
    // single stone
    var s = Stone.play_at(this.goban, 5, 4, main.BLACK);
    assertEqual(s, this.goban.stone_at(5, 4));
    assertEqual(this.goban, s.goban);
    assertEqual(main.BLACK, s.color);
    assertEqual(5, s.i);
    return assertEqual(4, s.j);
};

TestStone.prototype.test_suicide = function () {
    // a2 b2 b1 a3 pass c1
    Stone.play_at(this.goban, 1, 2, main.BLACK);
    Stone.play_at(this.goban, 2, 2, main.WHITE);
    Stone.play_at(this.goban, 2, 1, main.BLACK);
    assertEqual(false, Stone.valid_move(this.goban, 1, 1, main.WHITE)); // suicide invalid
    Stone.play_at(this.goban, 1, 3, main.WHITE);
    assertEqual(true, Stone.valid_move(this.goban, 1, 1, main.WHITE)); // now this would be a kill
    assertEqual(true, Stone.valid_move(this.goban, 1, 1, main.BLACK)); // black could a1 too (merge)
    Stone.play_at(this.goban, 3, 1, main.WHITE); // now 2 black stones share a last life
    return assertEqual(false, Stone.valid_move(this.goban, 1, 1, main.BLACK)); // so this would be a suicide with merge
};

TestStone.prototype.test_ko = function () {
    // pass b2 a2 a3 b1 a1
    Stone.play_at(this.goban, 2, 2, main.WHITE);
    Stone.play_at(this.goban, 1, 2, main.BLACK);
    Stone.play_at(this.goban, 1, 3, main.WHITE);
    Stone.play_at(this.goban, 2, 1, main.BLACK);
    Stone.play_at(this.goban, 1, 1, main.WHITE); // kill!
    assertEqual(false, Stone.valid_move(this.goban, 1, 2, main.BLACK)); // now this is a ko
    Stone.play_at(this.goban, 4, 4, main.BLACK); // play once anywhere else
    Stone.play_at(this.goban, 4, 5, main.WHITE);
    assertEqual(true, Stone.valid_move(this.goban, 1, 2, main.BLACK)); // ko can be taken by black
    Stone.play_at(this.goban, 1, 2, main.BLACK); // black takes the ko
    assertEqual(false, Stone.valid_move(this.goban, 1, 1, main.WHITE)); // white cannot take the ko
    Stone.play_at(this.goban, 5, 5, main.WHITE); // play once anywhere else
    Stone.play_at(this.goban, 5, 4, main.BLACK);
    assertEqual(true, Stone.valid_move(this.goban, 1, 1, main.WHITE)); // ko can be taken back by white
    Stone.play_at(this.goban, 1, 1, main.WHITE); // white takes the ko
    return assertEqual(false, Stone.valid_move(this.goban, 1, 2, main.BLACK)); // and black cannot take it now
};
<|endoftext|>


<commit_before>/*global $,app,esri,accounting,google*/

app.views.property = function (accountNumber) {
  var alreadyGettingOpaData, opaRendered, opaDetailsRendered;

  app.hooks.ownerSearchDisclaimer.addClass('hide');

  // Search area prep
  app.hooks.propertyTitle.find('h1').html(' ');
  app.hooks.propertyTitle.find('.small-text').empty();
  // Reset the search forms when showing details
  app.hooks.searchFormContainer.find('form').each(function(i, form) {
    form.reset();
  });
  app.hooks.searchLeft.removeClass('medium-4').addClass('medium-14')
    .empty().append(app.hooks.propertyTitle);
    app.hooks.searchRight.html('');
  app.hooks.searchBox.removeClass('medium-16').addClass('medium-10 right');

  // Clear existing elements out of the way
  app.hooks.content.children().detach();

  if (!history.state) history.replaceState({}, '');

  if (history.state.error) return renderError();

  if (history.state.opa) {
    renderOpa();
  } else {
    app.hooks.content.append(app.hooks.loading);
    getOpaData();
  }

  // The less-detailed search result contains address_match
  if (hasOpaDetails()) {
    renderOpaDetails();
  } else {
    if (!alreadyGettingOpaData) getOpaData();
  }

  if (history.state.sa) {
    renderSa();
  } else if (history.state.address) {
    getSaData();
  }

  function hasOpaDetails() {
    // ownership.mailing_address is only included in detailed results, not the
    // basic stuff that comes back from the geocode.
    return history.state.opa && history.state.opa.ownership.mailing_address;
  }

  function getOpaData () {
    alreadyGettingOpaData = true;
    $.ajax('https://api.phila.gov/opa/v1.1/account/' + accountNumber + '?format=json',
      {dataType: app.settings.ajaxType})
      .done(function (data) {
        var state = $.extend({}, history.state);
        var property = data.data.property;
        state.opa = property;
        state.address = app.util.addressWithUnit(property);
        history.replaceState(state, ''); // Second param not optional in IE10
        if (!opaRendered) renderOpa();
        if (!opaDetailsRendered) renderOpaDetails();
        if (!state.sa) getSaData();
      })
      .fail(function () {
        history.replaceState({error: true}, '');
        renderError();
      });
  }

  function getSaData () {
    $.ajax('https://api.phila.gov/ulrs/v3/addresses/' + encodeURIComponent(history.state.address) +
      '/service-areas?format='+app.settings.ajaxType, {dataType: app.settings.ajaxType})
      .done(function (data) {
        var state = $.extend({}, history.state);
        state.sa = data.serviceAreaValues;
        history.replaceState(state, '');
        renderSa();
      })
      .fail(function () {
        var state = $.extend({}, history.state);
        state.sa = {error: true};
        history.replaceState(state, '');
      });
  }

  function renderOpa () {
    var state = history.state;

    // Breadcrumbs
    app.hooks.propertyCrumb.text(state.address);
    app.hooks.crumbs.update(app.hooks.propertyCrumb);

    // Search area
    app.hooks.propertyTitle.find('h1').text(state.address);
    app.hooks.propertyTitle.find('.small-text').text('Philadelphia, PA ' + state.opa.zip);

    // Clear loading...
    app.hooks.content.empty();

    // Render owners
    app.hooks.propertyOwners.empty();
    state.opa.ownership.owners.forEach(function (owner) {
      app.hooks.propertyOwners.append($('<div>').text(owner));
    });

    app.hooks.opaAccount.text(state.opa.account_number);

    // Render improvement stuff
    app.hooks.improvementDescription.text(state.opa.characteristics.description);
    app.hooks.landArea.text(accounting.formatNumber(state.opa.characteristics.land_area));
    app.hooks.improvementArea.text(accounting.formatNumber(state.opa.characteristics.improvement_area));

    // Empty zoning in prep for details
    app.hooks.zoning.empty();

    // Render sales details
    app.hooks.salesPrice.text(accounting.formatMoney(state.opa.sales_information.sales_price));
    app.hooks.salesDate.text(app.util.formatSalesDate(state.opa.sales_information.sales_date));

    // Empty mailing address in prep for details
    app.hooks.propertyMailingHeader.detach();
    app.hooks.propertyMailing.empty();

    // Empty valuation history
    app.hooks.valuation.empty();

    app.hooks.content.append(app.hooks.propertyMain);
    app.hooks.content.append(app.hooks.propertySide);
    app.hooks.belowContent.append(app.hooks.propertySecondary);

    // Render map stuff
    renderMap();
    setStreetViewLink();

    opaRendered = true;
  }

  function renderMap() {
    var state = history.state;

    require(['esri/map', 'esri/layers/ArcGISTiledMapServiceLayer',
      'esri/graphic', 'esri/geometry/Point', 'esri/symbols/SimpleMarkerSymbol', 'dojo/domReady!'],
      function(Map, Tiled, Graphic, Point, SimpleMarkerSymbol) {

        function initMapView() {
          var point, markerSymbol, markerGraphic, fillSymbol, fillGraphic;

          // Because you apparently can't do this through the setup properties.
          app.globals.map.disableScrollWheelZoom();

          // Set center
          app.globals.map.centerAndZoom([state.opa.geometry.x, state.opa.geometry.y], 8);

          // Clear any existing markers
          app.globals.map.graphics.clear();

          // Create a new marker
          point = new Point(state.opa.geometry.x, state.opa.geometry.y);

          // Marker with a hole
          markerSymbol = new SimpleMarkerSymbol({
            "color": [242, 186, 19, 190],
            "size": 20,
            "xoffset": 0,
            "yoffset": 10,
            "type": "esriSMS",
            "style": "esriSMSPath",
            "path": "M16,3.5c-4.142,0-7.5,3.358-7.5,7.5c0,4.143,7.5,18.121,7.5,18.121S23.5,15.143,23.5,11C23.5,6.858,20.143,3.5,16,3.5z M16,14.584c-1.979,0-3.584-1.604-3.584-3.584S14.021,7.416,16,7.416S19.584,9.021,19.584,11S17.979,14.584,16,14.584z",
            "outline": {
              "color": [53, 53, 53, 255],
              "width": 0.5,
              "type": "esriSLS",
              "style": "esriSLSSolid"
            }
          });

          // Fill the hole
          fillSymbol = new SimpleMarkerSymbol({
            "color": [53, 53, 53, 255],
            "size": 5,
            "xoffset": 0,
            "yoffset": 14,
            "type": "esriSMS",
            "style": "esriSMSCircle",
            "outline": null
          });

          // Fill in the hole in the marker (there must be a better way)
          fillGraphic = new Graphic(point, fillSymbol);
          app.globals.map.graphics.add(fillGraphic);
          // Add marker to the map
          markerGraphic = new Graphic(point, markerSymbol);
          app.globals.map.graphics.add(markerGraphic);
        }

        // If the map is already constructed
        if (app.globals.map) {
          initMapView();
        } else {
          // Construct the map
          app.globals.map = new Map(app.hooks.map[0], {
            center: [state.opa.geometry.x, state.opa.geometry.y],
            zoom: 8,
            smartNavigation: false
          });

          app.globals.layer = new Tiled('https://tiles.arcgis.com/tiles/fLeGjb7u4uXqeF9q/arcgis/rest/services/CityBasemap/MapServer');
          app.globals.map.addLayer(app.globals.layer);

          app.globals.map.on('load', initMapView);
        }
      }
    );
  }

  function setStreetViewLink() {
    var state = history.state,
        sv, addressLatLng;

    // Fetch StreetView data
    sv = new google.maps.StreetViewService();
    addressLatLng = new google.maps.LatLng(
      state.opa.geometry.y, state.opa.geometry.x);

    sv.getPanoramaByLocation(addressLatLng, 50, function(panoData, status) {
      var cbp = '',
          heading;

      if (status === google.maps.StreetViewStatus.OK) {
        heading = google.maps.geometry.spherical.computeHeading(
                    panoData.location.latLng, addressLatLng);

        cbp = '&cbp=12,'+heading+',0,1,0';
      }

      // Set the street view url
      app.hooks.streetViewUrl.attr('href', 'http://maps.google.com/maps?q=loc:'+
        state.opa.geometry.y + ',' + state.opa.geometry.x + '&layer=c&cbll='+
        state.opa.geometry.y + ',' + state.opa.geometry.x + cbp);
    });
  }

  function renderOpaDetails () {
    var state = history.state;

    // Render mailing address
    var pm = app.hooks.propertyMailing;
    var ma = state.opa.ownership.mailing_address;
    app.hooks.propertyMailingHeader.insertBefore(pm);
    pm.append($('<div>').text(state.opa.ownership.liaison));
    pm.append($('<div>').text(ma.street));
    pm.append($('<div>').text(ma.city + ', ' + ma.state));
    pm.append($('<div>').text(ma.zip));

    // Render zoning
    app.hooks.zoning.html(state.opa.characteristics.zoning + '<br>' +
      state.opa.characteristics.zoning_description);

    // Render valuation history
    state.opa.valuation_history.forEach(function (vh) {
      var row = $('<tr>');
      row.append($('<td>').text(vh.certification_year));
      row.append($('<td>').text(accounting.formatMoney(vh.market_value)));
      row.append($('<td>').text(accounting.formatMoney(vh.land_taxable)));
      row.append($('<td>').text(accounting.formatMoney(vh.improvement_taxable)));
      row.append($('<td>').text(accounting.formatMoney(vh.land_exempt)));
      row.append($('<td>').text(accounting.formatMoney(vh.improvement_exempt)));
      app.hooks.valuation.append(row);
    });

    opaDetailsRendered = true;
  }

  function renderSa () {
    var state = history.state;

    // No use rendering if there's been a data error
    if (state.error || state.sa.error) return;

    // Wait for both OPA render and SA data
    if (!opaRendered || !state.sa) return;

    // Render service areas
    state.sa.forEach(function (sa) {
      switch (sa.serviceAreaId) {
        // Sidebox
        case 'SA_STREETS_Rubbish_Recyc':
          return app.hooks.rubbishDay.text(app.util.abbrevToFullDay(sa.value));

        // School catchment
        case 'SA_SCHOOLS_Elementary_School_Catchment':
          return app.hooks.elementarySchool.text(sa.value);
        case 'SA_SCHOOLS_Middle_School_Catchment':
          return app.hooks.middleSchool.text(sa.value);
        case 'SA_SCHOOLS_High_School_Catchment':
          return app.hooks.highSchool.text(sa.value);

        // Political
        case 'SA_PLANNING_2016Councilmanic':
          return app.hooks.councilDistrict.text(sa.value);
        case 'SA_PLANNING_Ward':
          return app.hooks.ward.text(sa.value);
        case 'SA_PLANNING_Ward_Divisions':
          return app.hooks.wardDivisions.text(sa.value);

        // Public safety
        case 'SA_POLICE_PSA':
          return app.hooks.policePsa.text(sa.value);
        case 'SA_POLICE_District':
          return app.hooks.policeDistrict.text(sa.value);
        case 'SA_POLICE_Sector':
          return app.hooks.policeSector.text(sa.value);
        case 'SA_POLICE_Division':
          return app.hooks.policeDivision.text(sa.value);
        case 'SA_POLICE_FireDistricts':
          return app.hooks.fireDistrict.text(sa.value);

        // Streets
        case 'SA_STREETS_Highway_District':
          return app.hooks.highwayDistrict.text(sa.value);
        case 'SA_STREETS_Highway_Section':
          return app.hooks.highwaySection.text(sa.value);
        case 'SA_STREETS_Highway_Subsection':
          return app.hooks.highwaySubsection.text(sa.value);
        case 'SA_STREETS_Street_Lights_Routes':
          return app.hooks.streetLightRoutes.text(sa.value);
        case 'SA_Streets_Traffic_District':
          return app.hooks.trafficDistrict.text(sa.value);
        case 'SA_STREETS_Recycling_Diversion_Rate':
          return app.hooks.recyclingDiversion.text(sa.value);
        case 'SA_STREETS_Sanitation_Area':
          return app.hooks.sanitationArea.text(sa.value);
        case 'SA_STREETS_Sanitation_Districts':
          return app.hooks.sanitationDistrict.text(sa.value);
        case 'SA_STREETS_Leaf':
          return app.hooks.leafCollection.text(sa.value);
        case 'SA_Streets_Traffic_PM_District':
          return app.hooks.trafficPmDistrict.text(sa.value);

        // Districts
        case 'SA_PLANNING_Planning_Districts':
          return app.hooks.planning.text(sa.value);
        case 'SA_LNI_DISTRICT':
          return app.hooks.liDistrict.text(sa.value);
        case 'SA_RECREATION_Recreation_District':
          return app.hooks.recreation.text(sa.value);

        // Water
        case 'PWD_MAINT_DIST':
          return app.hooks.pwdMaintenance.text(sa.value);
        case 'PWD_PRES_DIST':
          return app.hooks.pwdPressure.text(sa.value);
        case 'PWD_WTPSA':
          return app.hooks.waterTreatment.text(sa.value);
        case 'SA_WATER_Water_Plate_Index':
          return app.hooks.waterPlate.text(sa.value);
      }
    });
  }

  function renderError () {
    // TODO Display an error message that looks nice
  }

  // // TODO Get L&I data
  // // Tim also pointed at http://api.phila.gov/ULRS311/Data/LIAddressKey/340%20n%2012th%20st
  // var topicsUrl = 'https://api.phila.gov/ulrs/v3/addresses/' + encodeURIComponent(params.p) + '/topics?format=json';
  // $.ajax(topicsUrl)
  //   .done(function (data) {
  //     var addressKey;
  //     data.topics.some(function (topic) {
  //       if (topic.topicName === 'AddressKeys') {
  //         return topic.keys.some(function (key) {
  //           if (key.topicId) {
  //             addressKey = key.topicId;
  //             return true;
  //           }
  //         });
  //       }
  //     });
  //     if (!addressKey) {
  //       propertyData.li = {error: 'No L&I key found at ' + topicsUrl + '.'};
  //       return --pending || app.views.address(propertyData);
  //     }
  //     $.ajax('https://services.phila.gov/PhillyApi/Data/v1.0/locations(' + addressKey + ')?$format=json')
  //       .done(function (data) {
  //         propertyData.li = data.d;
  //         --pending || app.views.property(propertyData);
  //       })
  //       .fail(function () {
  //         propertyData.li = {error: 'Failed to retrieve L&I address data.'};
  //         --pending || app.views.property(propertyData);
  //       });
  //   })
  //   .fail(function () {
  //     propertyData.li = {error: 'Failed to retrieve address topics.'};
  //     --pending || app.views.property(propertyData);
  //   });
  //
  // function renderLi () {
  // }
};
<commit_msg>Lookup service areas from Socrata. - The best data is now here. Do a lookup via the standardized address.<commit_after>/*global $,app,esri,accounting,google*/

app.views.property = function (accountNumber) {
  var alreadyGettingOpaData, opaRendered, opaDetailsRendered;

  app.hooks.ownerSearchDisclaimer.addClass('hide');

  // Search area prep
  app.hooks.propertyTitle.find('h1').html(' ');
  app.hooks.propertyTitle.find('.small-text').empty();
  // Reset the search forms when showing details
  app.hooks.searchFormContainer.find('form').each(function(i, form) {
    form.reset();
  });
  app.hooks.searchLeft.removeClass('medium-4').addClass('medium-14')
    .empty().append(app.hooks.propertyTitle);
    app.hooks.searchRight.html('');
  app.hooks.searchBox.removeClass('medium-16').addClass('medium-10 right');

  // Clear existing elements out of the way
  app.hooks.content.children().detach();

  if (!history.state) history.replaceState({}, '');

  if (history.state.error) return renderError();

  if (history.state.opa) {
    renderOpa();
  } else {
    app.hooks.content.append(app.hooks.loading);
    getOpaData();
  }

  // The less-detailed search result contains address_match
  if (hasOpaDetails()) {
    renderOpaDetails();
  } else {
    if (!alreadyGettingOpaData) getOpaData();
  }

  if (history.state.sa) {
    renderSa();
  } else if (history.state.address) {
    getSaData();
  }

  function hasOpaDetails() {
    // ownership.mailing_address is only included in detailed results, not the
    // basic stuff that comes back from the geocode.
    return history.state.opa && history.state.opa.ownership.mailing_address;
  }

  function getOpaData () {
    alreadyGettingOpaData = true;
    $.ajax('https://api.phila.gov/opa/v1.1/account/' + accountNumber + '?format=json',
      {dataType: app.settings.ajaxType})
      .done(function (data) {
        var state = $.extend({}, history.state);
        var property = data.data.property;
        state.opa = property;
        state.address = app.util.addressWithUnit(property);
        history.replaceState(state, ''); // Second param not optional in IE10
        if (!opaRendered) renderOpa();
        if (!opaDetailsRendered) renderOpaDetails();
        if (!state.sa) getSaData();
      })
      .fail(function () {
        history.replaceState({error: true}, '');
        renderError();
      });
  }

  function getSaData () {
    $.ajax('https://data.phila.gov/resource/bz79-67af.json?address_id=' + encodeURIComponent(history.state.address),
        {dataType: app.settings.ajaxType})
      .done(function (data) {
        var state = $.extend({}, history.state);
        state.sa = data.length > 0 ? data[0] : null;
        history.replaceState(state, '');
        renderSa();
      })
      .fail(function () {
        var state = $.extend({}, history.state);
        state.sa = {error: true};
        history.replaceState(state, '');
      });
  }

  function renderOpa () {
    var state = history.state;

    // Breadcrumbs
    app.hooks.propertyCrumb.text(state.address);
    app.hooks.crumbs.update(app.hooks.propertyCrumb);

    // Search area
    app.hooks.propertyTitle.find('h1').text(state.address);
    app.hooks.propertyTitle.find('.small-text').text('Philadelphia, PA ' + state.opa.zip);

    // Clear loading...
    app.hooks.content.empty();

    // Render owners
    app.hooks.propertyOwners.empty();
    state.opa.ownership.owners.forEach(function (owner) {
      app.hooks.propertyOwners.append($('<div>').text(owner));
    });

    app.hooks.opaAccount.text(state.opa.account_number);

    // Render improvement stuff
    app.hooks.improvementDescription.text(state.opa.characteristics.description);
    app.hooks.landArea.text(accounting.formatNumber(state.opa.characteristics.land_area));
    app.hooks.improvementArea.text(accounting.formatNumber(state.opa.characteristics.improvement_area));

    // Empty zoning in prep for details
    app.hooks.zoning.empty();

    // Render sales details
    app.hooks.salesPrice.text(accounting.formatMoney(state.opa.sales_information.sales_price));
    app.hooks.salesDate.text(app.util.formatSalesDate(state.opa.sales_information.sales_date));

    // Empty mailing address in prep for details
    app.hooks.propertyMailingHeader.detach();
    app.hooks.propertyMailing.empty();

    // Empty valuation history
    app.hooks.valuation.empty();

    app.hooks.content.append(app.hooks.propertyMain);
    app.hooks.content.append(app.hooks.propertySide);
    app.hooks.belowContent.append(app.hooks.propertySecondary);

    // Render map stuff
    renderMap();
    setStreetViewLink();

    opaRendered = true;
  }

  function renderMap() {
    var state = history.state;

    require(['esri/map', 'esri/layers/ArcGISTiledMapServiceLayer',
      'esri/graphic', 'esri/geometry/Point', 'esri/symbols/SimpleMarkerSymbol', 'dojo/domReady!'],
      function(Map, Tiled, Graphic, Point, SimpleMarkerSymbol) {

        function initMapView() {
          var point, markerSymbol, markerGraphic, fillSymbol, fillGraphic;

          // Because you apparently can't do this through the setup properties.
          app.globals.map.disableScrollWheelZoom();

          // Set center
          app.globals.map.centerAndZoom([state.opa.geometry.x, state.opa.geometry.y], 8);

          // Clear any existing markers
          app.globals.map.graphics.clear();

          // Create a new marker
          point = new Point(state.opa.geometry.x, state.opa.geometry.y);

          // Marker with a hole
          markerSymbol = new SimpleMarkerSymbol({
            "color": [242, 186, 19, 190],
            "size": 20,
            "xoffset": 0,
            "yoffset": 10,
            "type": "esriSMS",
            "style": "esriSMSPath",
            "path": "M16,3.5c-4.142,0-7.5,3.358-7.5,7.5c0,4.143,7.5,18.121,7.5,18.121S23.5,15.143,23.5,11C23.5,6.858,20.143,3.5,16,3.5z M16,14.584c-1.979,0-3.584-1.604-3.584-3.584S14.021,7.416,16,7.416S19.584,9.021,19.584,11S17.979,14.584,16,14.584z",
            "outline": {
              "color": [53, 53, 53, 255],
              "width": 0.5,
              "type": "esriSLS",
              "style": "esriSLSSolid"
            }
          });

          // Fill the hole
          fillSymbol = new SimpleMarkerSymbol({
            "color": [53, 53, 53, 255],
            "size": 5,
            "xoffset": 0,
            "yoffset": 14,
            "type": "esriSMS",
            "style": "esriSMSCircle",
            "outline": null
          });

          // Fill in the hole in the marker (there must be a better way)
          fillGraphic = new Graphic(point, fillSymbol);
          app.globals.map.graphics.add(fillGraphic);
          // Add marker to the map
          markerGraphic = new Graphic(point, markerSymbol);
          app.globals.map.graphics.add(markerGraphic);
        }

        // If the map is already constructed
        if (app.globals.map) {
          initMapView();
        } else {
          // Construct the map
          app.globals.map = new Map(app.hooks.map[0], {
            center: [state.opa.geometry.x, state.opa.geometry.y],
            zoom: 8,
            smartNavigation: false
          });

          app.globals.layer = new Tiled('https://tiles.arcgis.com/tiles/fLeGjb7u4uXqeF9q/arcgis/rest/services/CityBasemap/MapServer');
          app.globals.map.addLayer(app.globals.layer);

          app.globals.map.on('load', initMapView);
        }
      }
    );
  }

  function setStreetViewLink() {
    var state = history.state,
        sv, addressLatLng;

    // Fetch StreetView data
    sv = new google.maps.StreetViewService();
    addressLatLng = new google.maps.LatLng(
      state.opa.geometry.y, state.opa.geometry.x);

    sv.getPanoramaByLocation(addressLatLng, 50, function(panoData, status) {
      var cbp = '',
          heading;

      if (status === google.maps.StreetViewStatus.OK) {
        heading = google.maps.geometry.spherical.computeHeading(
                    panoData.location.latLng, addressLatLng);

        cbp = '&cbp=12,'+heading+',0,1,0';
      }

      // Set the street view url
      app.hooks.streetViewUrl.attr('href', 'http://maps.google.com/maps?q=loc:'+
        state.opa.geometry.y + ',' + state.opa.geometry.x + '&layer=c&cbll='+
        state.opa.geometry.y + ',' + state.opa.geometry.x + cbp);
    });
  }

  function renderOpaDetails () {
    var state = history.state;

    // Render mailing address
    var pm = app.hooks.propertyMailing;
    var ma = state.opa.ownership.mailing_address;
    app.hooks.propertyMailingHeader.insertBefore(pm);
    pm.append($('<div>').text(state.opa.ownership.liaison));
    pm.append($('<div>').text(ma.street));
    pm.append($('<div>').text(ma.city + ', ' + ma.state));
    pm.append($('<div>').text(ma.zip));

    // Render zoning
    app.hooks.zoning.html(state.opa.characteristics.zoning + '<br>' +
      state.opa.characteristics.zoning_description);

    // Render valuation history
    state.opa.valuation_history.forEach(function (vh) {
      var row = $('<tr>');
      row.append($('<td>').text(vh.certification_year));
      row.append($('<td>').text(accounting.formatMoney(vh.market_value)));
      row.append($('<td>').text(accounting.formatMoney(vh.land_taxable)));
      row.append($('<td>').text(accounting.formatMoney(vh.improvement_taxable)));
      row.append($('<td>').text(accounting.formatMoney(vh.land_exempt)));
      row.append($('<td>').text(accounting.formatMoney(vh.improvement_exempt)));
      app.hooks.valuation.append(row);
    });

    opaDetailsRendered = true;
  }

  function renderSa () {
    var state = history.state;
    var sa = state.sa;

    // No use rendering if there's been a data error
    if (state.error || state.sa.error) return;

    // Wait for both OPA render and SA data
    if (!opaRendered || !state.sa) return;

    // Render service areas
    // Sidebox
    app.hooks.rubbishDay.text(app.util.abbrevToFullDay(sa.rubbish));

    // School catchment
    app.hooks.elementarySchool.text(sa.elementary_school);
    app.hooks.middleSchool.text(sa.middle_school);
    app.hooks.highSchool.text(sa.high_school);

    // Political
    app.hooks.councilDistrict.text(sa.council_2016);
    app.hooks.ward.text(sa.ward);
    app.hooks.wardDivisions.text(sa.ward_div);

    // Public safety
    app.hooks.policePsa.text(sa.psa);
    app.hooks.policeDistrict.text(sa.ppd_district);
    app.hooks.policeSector.text(sa.ppd_sector);
    app.hooks.policeDivision.text(sa.ppd_div);
    app.hooks.fireDistrict.text(sa.fire_district);

    // Streets
    app.hooks.highwayDistrict.text(sa.highway_district);
    app.hooks.highwaySection.text(sa.highway_section);
    app.hooks.highwaySubsection.text(sa.highway_subsection);
    app.hooks.streetLightRoutes.text(sa.street_light_route);
    app.hooks.trafficDistrict.text(sa.traffic_district);
    app.hooks.recyclingDiversion.text(sa.recycling_diversion_rate_score);
    app.hooks.sanitationArea.text(sa.sanitation_area);
    app.hooks.sanitationDistrict.text(sa.sanitation_district);
    app.hooks.leafCollection.text(sa.leaf);
    app.hooks.trafficPmDistrict.text(sa.traffic_pm_district);

    // Districts
    app.hooks.planning.text(sa.planning_district);
    app.hooks.liDistrict.text(sa.lni_district);
    app.hooks.recreation.text(sa.rec_district);

    // Water
    app.hooks.pwdMaintenance.text(sa.pwd_maint_dist);
    app.hooks.pwdPressure.text(sa.pwd_pres_dist);
    app.hooks.waterTreatment.text(sa.pwd_wtpsa);
    app.hooks.waterPlate.text(sa.water_plate);
  }

  function renderError () {
    // TODO Display an error message that looks nice
  }

  // // TODO Get L&I data
  // // Tim also pointed at http://api.phila.gov/ULRS311/Data/LIAddressKey/340%20n%2012th%20st
  // var topicsUrl = 'https://api.phila.gov/ulrs/v3/addresses/' + encodeURIComponent(params.p) + '/topics?format=json';
  // $.ajax(topicsUrl)
  //   .done(function (data) {
  //     var addressKey;
  //     data.topics.some(function (topic) {
  //       if (topic.topicName === 'AddressKeys') {
  //         return topic.keys.some(function (key) {
  //           if (key.topicId) {
  //             addressKey = key.topicId;
  //             return true;
  //           }
  //         });
  //       }
  //     });
  //     if (!addressKey) {
  //       propertyData.li = {error: 'No L&I key found at ' + topicsUrl + '.'};
  //       return --pending || app.views.address(propertyData);
  //     }
  //     $.ajax('https://services.phila.gov/PhillyApi/Data/v1.0/locations(' + addressKey + ')?$format=json')
  //       .done(function (data) {
  //         propertyData.li = data.d;
  //         --pending || app.views.property(propertyData);
  //       })
  //       .fail(function () {
  //         propertyData.li = {error: 'Failed to retrieve L&I address data.'};
  //         --pending || app.views.property(propertyData);
  //       });
  //   })
  //   .fail(function () {
  //     propertyData.li = {error: 'Failed to retrieve address topics.'};
  //     --pending || app.views.property(propertyData);
  //   });
  //
  // function renderLi () {
  // }
};
<|endoftext|>


<commit_before>var version = require('./package.json').version;

// Custom webpack loaders are generally the same for all webpack bundles, hence
// stored in a separate local variable.
var loaders = [
    {test: /\.glsl$/, loader: 'raw-loader'},
    { test: /\.json$/, loader: 'json-loader' },
    {
    test: /\.png$/,
    loader: 'url-loader?limit=10000000'
}
];

module.exports = [
    {// Notebook extension
     //
     // This bundle only contains the part of the JavaScript that is run on
     // load of the notebook. This section generally only performs
     // some configuration for requirejs, and provides the legacy
     // "load_ipython_extension" function which is required for any notebook
     // extension.
     //
        entry: './src/extension.js',
        output: {
            filename: 'extension.js',
            path: '../ipyvolume/static',
            libraryTarget: 'amd'
        }
    },
    {// Bundle for the notebook containing the custom widget views and models
     //
     // This bundle contains the implementation for the custom widget views and
     // custom widget.
     // It must be an amd module
     //
        entry: './src/index.js',
        output: {
            filename: 'index.js',
            path: '../ipyvolume/static',
            libraryTarget: 'amd'
        },
        devtool: 'source-map',
        module: {
            loaders: loaders
        },
        externals: ['jupyter-js-widgets', 'three']
    },
    {// Embeddable ipyvolume bundle
     //
     // This bundle is generally almost identical to the notebook bundle
     // containing the custom widget views and models.
     //
     // The only difference is in the configuration of the webpack public path
     // for the static assets.
     //
     // It will be automatically distributed by unpkg to work with the static
     // widget embedder.
     //
     // The target bundle is always `dist/index.js`, which is the path required
     // by the custom widget embedder.
     //
        entry: './src/embed.js',
        output: {
            filename: 'index.js',
            path: './dist/',
            libraryTarget: 'amd',
            publicPath: 'https://unpkg.com/ipyvolume@' + version + '/dist/'
        },
        devtool: 'source-map',
        module: {
            loaders: loaders
        },
        externals: ['jupyter-js-widgets']
    },
    {
        entry: 'three',
        output: {
            filename: 'three.js',
            path: '../ipyvolume/static',
            libraryTarget: 'amd'
        },
        devtool: 'source-map',
        module: {
            loaders: loaders
        }
    },
];
<commit_msg>fix: new widget packages are external<commit_after>var version = require('./package.json').version;

// Custom webpack loaders are generally the same for all webpack bundles, hence
// stored in a separate local variable.
var loaders = [
    {test: /\.glsl$/, loader: 'raw-loader'},
    { test: /\.json$/, loader: 'json-loader' },
    {
    test: /\.png$/,
    loader: 'url-loader?limit=10000000'
}
];

module.exports = [
    {// Notebook extension
     //
     // This bundle only contains the part of the JavaScript that is run on
     // load of the notebook. This section generally only performs
     // some configuration for requirejs, and provides the legacy
     // "load_ipython_extension" function which is required for any notebook
     // extension.
     //
        entry: './src/extension.js',
        output: {
            filename: 'extension.js',
            path: '../ipyvolume/static',
            libraryTarget: 'amd'
        }
    },
    {// Bundle for the notebook containing the custom widget views and models
     //
     // This bundle contains the implementation for the custom widget views and
     // custom widget.
     // It must be an amd module
     //
        entry: './src/index.js',
        output: {
            filename: 'index.js',
            path: '../ipyvolume/static',
            libraryTarget: 'amd'
        },
        devtool: 'source-map',
        module: {
            loaders: loaders
        },
        externals: ['three', 'jupyter-js-widgets', '@jupyter-widgets/base', '@jupyter-widgets/controls']
    },
    {// Embeddable ipyvolume bundle
     //
     // This bundle is generally almost identical to the notebook bundle
     // containing the custom widget views and models.
     //
     // The only difference is in the configuration of the webpack public path
     // for the static assets.
     //
     // It will be automatically distributed by unpkg to work with the static
     // widget embedder.
     //
     // The target bundle is always `dist/index.js`, which is the path required
     // by the custom widget embedder.
     //
        entry: './src/embed.js',
        output: {
            filename: 'index.js',
            path: './dist/',
            libraryTarget: 'amd',
            publicPath: 'https://unpkg.com/ipyvolume@' + version + '/dist/'
        },
        devtool: 'source-map',
        module: {
            loaders: loaders
        },
        externals: ['jupyter-js-widgets', '@jupyter-widgets/base', '@jupyter-widgets/controls']
    },
    {
        entry: 'three',
        output: {
            filename: 'three.js',
            path: '../ipyvolume/static',
            libraryTarget: 'amd'
        },
        devtool: 'source-map',
        module: {
            loaders: loaders
        }
    },
];
<|endoftext|>


<commit_before>require('jsio', ['getEnvironment', 'log', 'bind', 'test']);

function getObj(objectName, transportName, envName) {
	envName = envName || getEnvironment();
	try {
		var what = {};
		what[objectName] = 'result';
		require('.' + envName + '.' + transportName, what);
	} catch(e) {
		throw new Error('No ' + objectName + ' found for ' + transportName + ' in ' + envName);
	}
	return result;
}

exports.getListener = bind(this, getObj, 'Listener');
exports.getConnector = bind(this, getObj, 'Connector');
<commit_msg>don't need to require 'test'<commit_after>require('jsio', ['getEnvironment', 'log', 'bind']);

function getObj(objectName, transportName, envName) {
	envName = envName || getEnvironment();
	try {
		var what = {};
		what[objectName] = 'result';
		require('.' + envName + '.' + transportName, what);
	} catch(e) {
		throw new Error('No ' + objectName + ' found for ' + transportName + ' in ' + envName);
	}
	return result;
}

exports.getListener = bind(this, getObj, 'Listener');
exports.getConnector = bind(this, getObj, 'Connector');
<|endoftext|>


<commit_before>
jmol_isReady = function(applet) {
    // initialize the plugin
    $('.jmolInline').jmolTools({
        showStereoId: 'stereo',
        showNeighborhoodId: 'neighborhood',
        showNumbersId: 'showNtNums',
        showNextId: 'next',
        showPrevId: 'prev',
        showAllId: 'all',
        clearId: 'clear',
        insertionsId: 'insertions'
    });
    // run the plugin
    $('.jmolInline').first().jmolToggle();
};

var Info = {
    width: 340,
    height: 340,
    debug: false,
    color: 'white',
    addSelectionOptions: false,
    use: 'HTML5',
    j2sPath: 'file:///Users/apetrov/Desktop/jmolTools/jsmol/j2s',
    readyFunction: jmol_isReady,
    disableInitialConsole: true
};

var jmolApplet0 = Jmol.getApplet('jmolApplet0', Info);

// these are conveniences that mimic behavior of Jmol.js
function jmolCheckbox(script1, script0,text,ischecked) {Jmol.jmolCheckbox(jmolApplet0,script1, script0, text, ischecked)};
function jmolButton(script, text) {Jmol.jmolButton(jmolApplet0, script,text)};
function jmolHtml(s) { document.write(s) };
function jmolBr() { jmolHtml("
") };
function jmolMenu(a) {Jmol.jmolMenu(jmolApplet0, a)};
function jmolScript(cmd) {Jmol.script(jmolApplet0, cmd)};
function jmolScriptWait(cmd) {Jmol.scriptWait(jmolApplet0, cmd)};
<commit_msg>Use relative path for j2sPath<commit_after>
jmol_isReady = function(applet) {
    // initialize the plugin
    $('.jmolInline').jmolTools({
        showStereoId: 'stereo',
        showNeighborhoodId: 'neighborhood',
        showNumbersId: 'showNtNums',
        showNextId: 'next',
        showPrevId: 'prev',
        showAllId: 'all',
        clearId: 'clear',
        insertionsId: 'insertions'
    });
    // run the plugin
    $('.jmolInline').first().jmolToggle();
};

var Info = {
    width: 340,
    height: 340,
    debug: false,
    color: 'white',
    addSelectionOptions: false,
    use: 'HTML5',
    j2sPath: './jsmol/j2s',
    readyFunction: jmol_isReady,
    disableInitialConsole: true
};

var jmolApplet0 = Jmol.getApplet('jmolApplet0', Info);

// these are conveniences that mimic behavior of Jmol.js
function jmolCheckbox(script1, script0,text,ischecked) {Jmol.jmolCheckbox(jmolApplet0,script1, script0, text, ischecked)};
function jmolButton(script, text) {Jmol.jmolButton(jmolApplet0, script,text)};
function jmolHtml(s) { document.write(s) };
function jmolBr() { jmolHtml("
") };
function jmolMenu(a) {Jmol.jmolMenu(jmolApplet0, a)};
function jmolScript(cmd) {Jmol.script(jmolApplet0, cmd)};
function jmolScriptWait(cmd) {Jmol.scriptWait(jmolApplet0, cmd)};
<|endoftext|>