<commit_before>'use strict'
/**
 * Created by acastillo on 7/1/16.
 */
define([
    'file-saver',
    'src/util/api',
    'src/util/ui',
    'https://www.lactame.com/lib/openchemlib-extended/1.11.0/openchemlib-extended.js',
    'https://www.lactame.com/lib/chemcalc-extended/1.27.0/chemcalc-extended.js',
    'https://www.lactame.com/lib/eln-plugin/0.0.2/eln-plugin.js',
    'https://www.lactame.com/github/cheminfo-js/visualizer-helper/7f9c4d2c296389ed263a43826bafeba1164d13de/rest-on-couch/Roc.js'
], function (fileSaver, API, UI, OCLE, CCE, elnPlugin, Roc) {

    var defaultOptions = {
        varName: 'sample',
        track: true
    };

    class Sample {
        constructor(couchDB, uuid, options) {
            this.options = Object.assign({}, defaultOptions, options);

            var roc = API.cache('roc');
            if (!roc) {
                roc = new Roc({
                    url: couchDB.url,
                    database: couchDB.database,
                    processor: elnPlugin,
                    kind: couchDB.kind
                });
                API.cache('roc', roc);
            }
            this.roc = roc;

            this.uuid = uuid;
            if (!this.uuid) {
                UI.showNotification("Cannot create an editable sample without an uuid", 'error');
                return;
            }
            this._loadInstanceInVisualizer();
        }

        _loadInstanceInVisualizer() {
            this.roc.document(this.uuid, {
                varName: this.options.varName
            }).then(sample => {
                this.sample = sample;
                var sampleVar = API.getVar(this.options.varName);
                API.setVariable('sampleCode', sampleVar, ['$id', 0]);
                API.setVariable('batchCode', sampleVar, ['$id', 1]);
                API.setVariable('creationDate', sampleVar, ['$creationDate']);
                API.setVariable('modificationDate', sampleVar, ['$modificationDate']);
                API.setVariable('content', sampleVar, ['$content']);
                API.setVariable('molfile', sampleVar, ['$content', 'general', 'molfile']);
                API.setVariable('mf', sampleVar, ['$content', 'general', 'mf']);
                API.setVariable('mw', sampleVar, ['$content', 'general', 'mw']);
                API.setVariable('description', sampleVar, ['$content', 'general', 'description']);
                API.setVariable('iupac', sampleVar, ['$content', 'general', 'iupac']);
                API.setVariable('bp', sampleVar, ['$content', 'physical', 'bp']);
                API.setVariable('nd', sampleVar, ['$content', 'physical', 'nd']);
                API.setVariable('mp', sampleVar, ['$content', 'physical', 'mp']);
                API.setVariable('density', sampleVar, ['$content', 'physical', 'density']);
                API.setVariable('nmr', sampleVar, ['$content', 'spectra', 'nmr']);
                API.setVariable('ir', sampleVar, ['$content', 'spectra', 'ir']);
                API.setVariable('mass', sampleVar, ['$content', 'spectra', 'mass']);
                this.updateAttachments(sample);

                var expandableMolecule = new ExpandableMolecule(sample);
                API.cache('expandableMolecule', expandableMolecule);

                sample.onChange((event) => {
                    if (typeof IframeBridge !== 'undefined') {
                        IframeBridge.postMessage('tab.status', {
                            saved: false
                        });
                    }

                    console.log("change event received", event.jpath.join('.'), event);

                    switch (event.jpath.join('.')) {
                        case 'general.molfile':

                            break;
                        case 'general.mf':
                            this._updatedMF();
                            this.sample.$content.general.mw = this.chemcalc.mw;
                            this.sample.$content.general.em = this.chemcalc.em;
                            break;
                    }
                });

                this._initializeNMRAssignment();
                this._updatedMF();
            });
        }

        _updatedMF() {
            this.chemcalc=undefined;
            console.log('updateChemcalc',this.sample);
            if (this.sample['$content'].general && this.sample['$content'].general.mf) {
                try {
                    this.chemcalc=CCE.analyseMF(this.sample['$content'].general.mf+'');
                } catch (e) {
                    UI.showNotification('Could not calculate molecular formula: '+e);
                    console.log(e);
                }
            }

            if (this.chemcalc && this.chemcalc.atoms && this.chemcalc.atoms.H) {
                var nmr1hOptions=API.getData('nmr1hOptions');
                if (nmr1hOptions) nmr1hOptions.integral=this.chemcalc.atoms.H;
            }
        }

        updateAttachments(entry) {
            return this.roc.getAttachmentList(this.uuid).then(function (list) {
                API.createData('sampleAttachments', list);
            })
        }

        handleActionSD(action) {
            switch (action.name) {
                case 'reset1d':
                case 'reset2d':
                    if (this.event !== 'action') return;

                    var type;
                    if (action.name === 'reset1d') type = '1'
                    else if (action.name === 'reset2d') type = '2'
                    else return;

                    var legend = API.cache('legend');
                    if (!legend) {
                        legend = {
                            1: {},
                            2: {}
                        }
                        API.cache('legend', legend);
                    }

                    legend[type] = {};

                    type = type + 'd';
                    API.createData('black', null);
                    API.createData('annot' + type, null);
                    API.createData('legend' + type, {});
                    API.createData('acs', null);

                    break;
                case 'executePeakPicking':
                    //API.doAction("reset1d");
                    // the action may be generated by clicking on a line or clicking on the button to
                    // recalculate the peak picking.
                    var editedNmr;
                    if (action.value.dimension) { // Fired from click on row. We can not take variable because it may not exist yet
                        editedNmr = action.value;
                        if (editedNmr.dimension > 1) {
                            API.createData('black2d', editedNmr.jcamp.data);
                            API.switchToLayer('2D');
                            return;
                        } else {
                            API.switchToLayer('Default layer');
                            API.createData('black1d', editedNmr.jcamp.data);
                        }
                    } else { // we click on the button, show an alert if we want to redo peak picking
                        editedNmr = API.getData('editedNmr');
                        if (editedNmr.dimension > 1) {
                            if (typeof UI != "undefined")
                                UI.showNotification('Peak picking can only be applied on 1D spectra', 'warning');
                            return;
                        }
                    }
                    if (action.value.integral) {//Fired from button
                        doAssignment();
                    } else {
                        if (!editedNmr.range || !editedNmr.range.length) {
                            doAssignment();
                        } else {
                            API.setVariable("editedRange", API.getVariable('editedNmr'), ["range"]);
                        }
                    }
                    API.createData("nmrParams", {
                        "nucleus": editedNmr.nucleus[0],
                        "observe": Math.floor(editedNmr.frequency / 10) * 10
                    });
                    break;
                default:
                    return false;
            }
            return true;
        }

         doAssignment() {
            var jcamp = editedNmr.getChild(['jcamp', 'data']);

            jcamp.then(function(jcamp) {
                jcamp = String(jcamp.get());
                var ppOptions = JSON.parse(JSON.stringify(API.getData("options1H")));
                var integral = ppOptions.integral;
                //console.log(ppOptions);
                if(!ppOptions.noiseFactor){
                    ppOptions = {"noiseFactor":0.8,"clean":true,"compile":true,"optimize":false,"integralFn":"sum", "type":"1H"};
                }

                var spectrum = SD.NMR.fromJcamp(jcamp);
                //spectrum.fillWith(4.7,4.9,0);
                //spectrum.fillWith(-0.1,0.1,0);
                var intFN = 0;
                if(ppOptions.integralFn=="peaks"){
                    intFN=1;
                }
                var peakPicking = spectrum.nmrPeakDetection({"nH":integral,
                    realTop:true,
                    thresholdFactor:ppOptions.noiseFactor,
                    clean:ppOptions.clean,
                    compile:ppOptions.compile,
                    optimize:ppOptions.optimize,
                    integralFn:intFN,
                    idPrefix:spectrum.getNucleus()+"",
                    gsdOptions:{minMaxRatio:0.001, smoothY:false, broadWidth:0},
                    format:"new"
                });
                editedNmr.setChildSync(['range'], peakPicking);
                API.setVariable("editedRange",API.getVariable('editedNmr'),["range"]);
            });

        }

        handleAction(action) {
            if (!action) return;

            if (this.handleActionSD(action)) return;

            switch (action.name) {
                case 'refresh':
                    this.roc.get(this.uuid);
                    break;
                case 'save':
                    this.roc.update(this.sample).then(function () {
                        if (typeof IframeBridge != 'undefined') {
                            IframeBridge.postMessage('tab.status', {
                                saved: true
                            });
                        }
                    });
                    break;

                case 'toggleJSMEEdition':
                    API.cache("expandableMolecule").toggleJSMEEdition();
                    break;
                case 'clearMolfile':
                    var molfile=API.getData('editableMolfile');
                    molfile.setValue('');
                    break;
                case 'swapHydrogens':
                    API.cache("expandableMolecule").setExpandedHydrogens();
                    break;
                case 'toggleNMR1hAdvancedOptions':
                    API.cache('nmr1hAdvancedOptions', ! API.cache('nmr1hAdvancedOptions'));
                case 'createOptions':
                    var advancedOptions1H = API.cache("nmr1hAdvancedOptions");
                    if (advancedOptions1H) {
                        API.createData("nmr1hOndeTemplate", API.getData("nmr1hOndeTemplates").full);
                    } else {
                        API.createData("nmr1hOndeTemplate", API.getData("nmr1hOndeTemplates").short);
                    }
                    break;
                case 'downloadSVG':
                    var blob = new Blob([this.action.value+""], {type: "application/jcamp-dx;charset=utf-8"});
                    fileSaver(blob, 'spectra.svg');
                    break;

                case 'deleteAttachment':
                    var attachment = action.value.name;
                    this.roc.deleteAttachment(sample, attachment).then(this.updateAttachments);
                    break;
                case 'deleteSpectra':
                    this.roc.unattach(sample, action.value).then(this.updateAttachments);
                    break;
                case 'attachNMR':
                case 'attachIR':
                case 'attachMass':
                    var type = action.name.replace("attach", "").toLowerCase();
                    var droppedDatas = data;
                    droppedDatas = droppedDatas.file || droppedDatas.str;
                    var prom = Promise.resolve();
                    for (let i = 0; i < droppedDatas.length; i++) {
                        prom = prom.then(() => {
                            var data = DataObject.resurrect(droppedDatas[i]);
                            return this.roc.attach(type, sample, data);
                        });
                    }

                    prom.then(() => {
                        this.updateAttachments(sample);
                    }).catch(() => {
                        this.updateAttachments(sample);
                    });
                    break;
                default:
                    break
            }
        }

        _initializeNMRAssignment() {
            API.createData('nmr1hOptions', {
                "noiseFactor": 0.8,
                "clean": true,
                "compile": true,
                "optimize": false,
                "integralFn": "sum",
                "integral": 30,
                "type": "1H"
            });

            API.createData('nmr1hOndeTemplates', {
                "full": {
                    "type": "object",
                    "properties": {
                        "integral": {
                            "type": "number",
                            "title": "value to fit the spectrum integral",
                            "label": "Integral"
                        },
                        "noiseFactor": {
                            "type": "number",
                            "title": "Mutiplier of the auto-detected noise level",
                            "label": "noiseFactor"
                        },
                        "clean": {
                            "type": "boolean",
                            "title": "Delete signals with integration less than 0.5",
                            "label": "clean"
                        },
                        "compile": {
                            "type": "boolean",
                            "title": "Compile the multiplets",
                            "label": "compile"
                        },
                        "optimize": {
                            "type": "boolean",
                            "title": "Optimize the peaks to fit the spectrum",
                            "label": "optimize"
                        },
                        "integralFn": {
                            "type": "string",
                            "title": "Type of integration",
                            "label": "Integral type",
                            "enum": [
                                "sum",
                                "peaks"
                            ]
                        },
                        "type": {
                            "type": "string",
                            "title": "Nucleus",
                            "label": "Nucleus",
                            "editable": false
                        }
                    }
                },
                "short": {
                    "type": "object",
                    "properties": {
                        "integral": {
                            "type": "number",
                            "title": "value to fit the spectrum integral",
                            "label": "Integral"
                        }
                    }
                }
            }).then(function(nmr1hOndeTemplates) {
                API.createData('nmr1hOndeTemplate', nmr1hOndeTemplates.short);
            });
        }
    }

    class ExpandableMolecule {
        constructor(sampleIn) {
            this.sample = sampleIn;
            this.molfile = this.sample.$content.general.molfile + '';
            var molecule = OCLE.Molecule.fromMolfile(this.molfile);
            this.idCode = molecule.getIDCode();
            this.expandedHydrogens = false;
            this.jsmeEditionMode = false;
            API.createData('editableMolfile', this.molfile).then(
                (editableMolfile) => {
                    editableMolfile.onChange( (event) => {
                        // us this really a modification ? or a loop event ...
                        // need to compare former oclID with new oclID
                        var idCode = OCLE.Molecule.fromMolfile(event.target + '').getIDCode();
                        if (idCode != this.idCode) {
                            this.idCode = idCode;
                            this.molfile = event.target + '';
                            this.sample.setChildSync('$content.general.molfile', this.molfile);
                        } else {
                            console.log('no update');
                        }

                        // by default we would like the depict mode
                        this.updateMolfiles();
                        this.updateMF();
                    });
                    this.updateMolfiles();
                    this.toggleJSMEEdition(false);
                }
            );
        }

        toggleJSMEEdition(force, noDepictUpdate) {
            if (force !== undefined && force === this.jsmeEditionMode) return;
            if (force === undefined) {
                this.jsmeEditionMode = !this.jsmeEditionMode;
            } else {
                this.jsmeEditionMode = force;
            }
            var prefs = {
                "prefs": [
                    "oldlook",
                    "nozoom"
                ],
                "labelsize": "14",
                "bondwidth": "1",
                "defaultaction": "105",
                "highlightColor": "3",
                "outputResult": [
                    "yes"
                ]
            };

            if (this.jsmeEditionMode) {
                API.getData("editableMolfile").triggerChange();
                this.expandedHydrogens = false;
            } else {
                prefs.prefs.push('depict');
                if (!noDepictUpdate) {
                    this.expandedHydrogens = false;
                    API.createData("viewMolfile", this.viewMolfile);
                }

            }
            API.doAction('setJSMEPreferences', prefs)
        }

        setExpandedHydrogens(force) {
            if (force === undefined) {
                this.expandedHydrogens = !this.expandedHydrogens;
            } else {
                this.expandedHydrogens = force;
            }
            if (this.expandedHydrogens) {
                API.createData("viewMolfileExpandedH", this.viewMolfileExpandedH);
                this.toggleJSMEEdition(false, true);
            } else {
                API.createData("viewMolfile", this.viewMolfile);
            }
        }

        updateMolfiles() {
            // prevent the loop by checking actelionID
            var molecule = OCLE.Molecule.fromMolfile(this.molfile);
            this.viewMolfile = molecule.toVisualizerMolfile();

            molecule.addImplicitHydrogens();
            this.viewMolfileExpandedH = molecule.toVisualizerMolfile();
            this.mf = molecule.getMolecularFormula().formula;
            this.mw = molecule.getMolecularFormula().relativeWeight;
            this.nH = molecule.getNumberOfAtoms('H');
        }

    }

    return Sample;
});

<commit_msg>Add promise<commit_after>'use strict'
/**
 * Created by acastillo on 7/1/16.
 */
define([
    'file-saver',
    'src/util/api',
    'src/util/ui',
    'https://www.lactame.com/lib/openchemlib-extended/1.11.0/openchemlib-extended.js',
    'https://www.lactame.com/lib/chemcalc-extended/1.27.0/chemcalc-extended.js',
    'https://www.lactame.com/lib/eln-plugin/0.0.2/eln-plugin.js',
    'https://www.lactame.com/github/cheminfo-js/visualizer-helper/7f9c4d2c296389ed263a43826bafeba1164d13de/rest-on-couch/Roc.js'
], function (fileSaver, API, UI, OCLE, CCE, elnPlugin, Roc) {

    var defaultOptions = {
        varName: 'sample',
        track: true
    };

    class Sample {
        constructor(couchDB, uuid, options) {
            this.options = Object.assign({}, defaultOptions, options);

            var roc = API.cache('roc');
            if (!roc) {
                roc = new Roc({
                    url: couchDB.url,
                    database: couchDB.database,
                    processor: elnPlugin,
                    kind: couchDB.kind
                });
                API.cache('roc', roc);
            }
            this.roc = roc;

            this.uuid = uuid;
            if (!this.uuid) {
                UI.showNotification("Cannot create an editable sample without an uuid", 'error');
                return;
            }
            this._loadInstanceInVisualizer();
        }

        _loadInstanceInVisualizer() {
            this.roc.document(this.uuid, {
                varName: this.options.varName
            }).then(sample => {
                this.sample = sample;
                var sampleVar = API.getVar(this.options.varName);
                API.setVariable('sampleCode', sampleVar, ['$id', 0]);
                API.setVariable('batchCode', sampleVar, ['$id', 1]);
                API.setVariable('creationDate', sampleVar, ['$creationDate']);
                API.setVariable('modificationDate', sampleVar, ['$modificationDate']);
                API.setVariable('content', sampleVar, ['$content']);
                API.setVariable('molfile', sampleVar, ['$content', 'general', 'molfile']);
                API.setVariable('mf', sampleVar, ['$content', 'general', 'mf']);
                API.setVariable('mw', sampleVar, ['$content', 'general', 'mw']);
                API.setVariable('description', sampleVar, ['$content', 'general', 'description']);
                API.setVariable('iupac', sampleVar, ['$content', 'general', 'iupac']);
                API.setVariable('bp', sampleVar, ['$content', 'physical', 'bp']);
                API.setVariable('nd', sampleVar, ['$content', 'physical', 'nd']);
                API.setVariable('mp', sampleVar, ['$content', 'physical', 'mp']);
                API.setVariable('density', sampleVar, ['$content', 'physical', 'density']);
                API.setVariable('nmr', sampleVar, ['$content', 'spectra', 'nmr']);
                API.setVariable('ir', sampleVar, ['$content', 'spectra', 'ir']);
                API.setVariable('mass', sampleVar, ['$content', 'spectra', 'mass']);
                this.updateAttachments(sample);

                var expandableMolecule = new ExpandableMolecule(sample);
                API.cache('expandableMolecule', expandableMolecule);

                sample.onChange((event) => {
                    if (typeof IframeBridge !== 'undefined') {
                        IframeBridge.postMessage('tab.status', {
                            saved: false
                        });
                    }

                    console.log("change event received", event.jpath.join('.'), event);

                    switch (event.jpath.join('.')) {
                        case 'general.molfile':

                            break;
                        case 'general.mf':
                            this._updatedMF();
                            this.sample.$content.general.mw = this.chemcalc.mw;
                            this.sample.$content.general.em = this.chemcalc.em;
                            break;
                    }
                });

                var promise=new Promise().resolve();
                promise.then(() => this._initializeNMRAssignment());
                promise.then(() => this._updateMF());
            });
        }

        _updatedMF() {
            this.chemcalc=undefined;

            if (this.sample['$content'].general && this.sample['$content'].general.mf) {
                try {
                    this.chemcalc=CCE.analyseMF(this.sample['$content'].general.mf+'');
                } catch (e) {
                    UI.showNotification('Could not calculate molecular formula: '+e);
                    console.log(e);
                }
            }
            console.log('updateChemcalc',this.chemcalc);
            if (this.chemcalc && this.chemcalc.atoms && this.chemcalc.atoms.H) {
                var nmr1hOptions=API.getData('nmr1hOptions');
                if (nmr1hOptions) nmr1hOptions.integral=this.chemcalc.atoms.H;
            }
        }

        updateAttachments(entry) {
            return this.roc.getAttachmentList(this.uuid).then(function (list) {
                API.createData('sampleAttachments', list);
            })
        }

        handleActionSD(action) {
            switch (action.name) {
                case 'reset1d':
                case 'reset2d':
                    if (this.event !== 'action') return;

                    var type;
                    if (action.name === 'reset1d') type = '1'
                    else if (action.name === 'reset2d') type = '2'
                    else return;

                    var legend = API.cache('legend');
                    if (!legend) {
                        legend = {
                            1: {},
                            2: {}
                        }
                        API.cache('legend', legend);
                    }

                    legend[type] = {};

                    type = type + 'd';
                    API.createData('black', null);
                    API.createData('annot' + type, null);
                    API.createData('legend' + type, {});
                    API.createData('acs', null);

                    break;
                case 'executePeakPicking':
                    //API.doAction("reset1d");
                    // the action may be generated by clicking on a line or clicking on the button to
                    // recalculate the peak picking.
                    var editedNmr;
                    if (action.value.dimension) { // Fired from click on row. We can not take variable because it may not exist yet
                        editedNmr = action.value;
                        if (editedNmr.dimension > 1) {
                            API.createData('black2d', editedNmr.jcamp.data);
                            API.switchToLayer('2D');
                            return;
                        } else {
                            API.switchToLayer('Default layer');
                            API.createData('black1d', editedNmr.jcamp.data);
                        }
                    } else { // we click on the button, show an alert if we want to redo peak picking
                        editedNmr = API.getData('editedNmr');
                        if (editedNmr.dimension > 1) {
                            if (typeof UI != "undefined")
                                UI.showNotification('Peak picking can only be applied on 1D spectra', 'warning');
                            return;
                        }
                    }
                    if (action.value.integral) {//Fired from button
                        doAssignment();
                    } else {
                        if (!editedNmr.range || !editedNmr.range.length) {
                            doAssignment();
                        } else {
                            API.setVariable("editedRange", API.getVariable('editedNmr'), ["range"]);
                        }
                    }
                    API.createData("nmrParams", {
                        "nucleus": editedNmr.nucleus[0],
                        "observe": Math.floor(editedNmr.frequency / 10) * 10
                    });
                    break;
                default:
                    return false;
            }
            return true;
        }

         doAssignment() {
            var jcamp = editedNmr.getChild(['jcamp', 'data']);

            jcamp.then(function(jcamp) {
                jcamp = String(jcamp.get());
                var ppOptions = JSON.parse(JSON.stringify(API.getData("options1H")));
                var integral = ppOptions.integral;
                //console.log(ppOptions);
                if(!ppOptions.noiseFactor){
                    ppOptions = {"noiseFactor":0.8,"clean":true,"compile":true,"optimize":false,"integralFn":"sum", "type":"1H"};
                }

                var spectrum = SD.NMR.fromJcamp(jcamp);
                //spectrum.fillWith(4.7,4.9,0);
                //spectrum.fillWith(-0.1,0.1,0);
                var intFN = 0;
                if(ppOptions.integralFn=="peaks"){
                    intFN=1;
                }
                var peakPicking = spectrum.nmrPeakDetection({"nH":integral,
                    realTop:true,
                    thresholdFactor:ppOptions.noiseFactor,
                    clean:ppOptions.clean,
                    compile:ppOptions.compile,
                    optimize:ppOptions.optimize,
                    integralFn:intFN,
                    idPrefix:spectrum.getNucleus()+"",
                    gsdOptions:{minMaxRatio:0.001, smoothY:false, broadWidth:0},
                    format:"new"
                });
                editedNmr.setChildSync(['range'], peakPicking);
                API.setVariable("editedRange",API.getVariable('editedNmr'),["range"]);
            });

        }

        handleAction(action) {
            if (!action) return;

            if (this.handleActionSD(action)) return;

            switch (action.name) {
                case 'refresh':
                    this.roc.get(this.uuid);
                    break;
                case 'save':
                    this.roc.update(this.sample).then(function () {
                        if (typeof IframeBridge != 'undefined') {
                            IframeBridge.postMessage('tab.status', {
                                saved: true
                            });
                        }
                    });
                    break;

                case 'toggleJSMEEdition':
                    API.cache("expandableMolecule").toggleJSMEEdition();
                    break;
                case 'clearMolfile':
                    var molfile=API.getData('editableMolfile');
                    molfile.setValue('');
                    break;
                case 'swapHydrogens':
                    API.cache("expandableMolecule").setExpandedHydrogens();
                    break;
                case 'toggleNMR1hAdvancedOptions':
                    API.cache('nmr1hAdvancedOptions', ! API.cache('nmr1hAdvancedOptions'));
                case 'createOptions':
                    var advancedOptions1H = API.cache("nmr1hAdvancedOptions");
                    if (advancedOptions1H) {
                        API.createData("nmr1hOndeTemplate", API.getData("nmr1hOndeTemplates").full);
                    } else {
                        API.createData("nmr1hOndeTemplate", API.getData("nmr1hOndeTemplates").short);
                    }
                    break;
                case 'downloadSVG':
                    var blob = new Blob([this.action.value+""], {type: "application/jcamp-dx;charset=utf-8"});
                    fileSaver(blob, 'spectra.svg');
                    break;

                case 'deleteAttachment':
                    var attachment = action.value.name;
                    this.roc.deleteAttachment(sample, attachment).then(this.updateAttachments);
                    break;
                case 'deleteSpectra':
                    this.roc.unattach(sample, action.value).then(this.updateAttachments);
                    break;
                case 'attachNMR':
                case 'attachIR':
                case 'attachMass':
                    var type = action.name.replace("attach", "").toLowerCase();
                    var droppedDatas = data;
                    droppedDatas = droppedDatas.file || droppedDatas.str;
                    var prom = Promise.resolve();
                    for (let i = 0; i < droppedDatas.length; i++) {
                        prom = prom.then(() => {
                            var data = DataObject.resurrect(droppedDatas[i]);
                            return this.roc.attach(type, sample, data);
                        });
                    }

                    prom.then(() => {
                        this.updateAttachments(sample);
                    }).catch(() => {
                        this.updateAttachments(sample);
                    });
                    break;
                default:
                    break
            }
        }

        _initializeNMRAssignment() {
            var promise=new Promise.resolve();
            promise=promise.then(() => API.createData('nmr1hOptions', {
                    "noiseFactor": 0.8,
                    "clean": true,
                    "compile": true,
                    "optimize": false,
                    "integralFn": "sum",
                    "integral": 30,
                    "type": "1H"
                })
            );

            promise=promise.then(() => API.createData('nmr1hOndeTemplates', {
                "full": {
                    "type": "object",
                    "properties": {
                        "integral": {
                            "type": "number",
                            "title": "value to fit the spectrum integral",
                            "label": "Integral"
                        },
                        "noiseFactor": {
                            "type": "number",
                            "title": "Mutiplier of the auto-detected noise level",
                            "label": "noiseFactor"
                        },
                        "clean": {
                            "type": "boolean",
                            "title": "Delete signals with integration less than 0.5",
                            "label": "clean"
                        },
                        "compile": {
                            "type": "boolean",
                            "title": "Compile the multiplets",
                            "label": "compile"
                        },
                        "optimize": {
                            "type": "boolean",
                            "title": "Optimize the peaks to fit the spectrum",
                            "label": "optimize"
                        },
                        "integralFn": {
                            "type": "string",
                            "title": "Type of integration",
                            "label": "Integral type",
                            "enum": [
                                "sum",
                                "peaks"
                            ]
                        },
                        "type": {
                            "type": "string",
                            "title": "Nucleus",
                            "label": "Nucleus",
                            "editable": false
                        }
                    }
                },
                "short": {
                    "type": "object",
                    "properties": {
                        "integral": {
                            "type": "number",
                            "title": "value to fit the spectrum integral",
                            "label": "Integral"
                        }
                    }
                }
            });
            promise=promise.then(function(nmr1hOndeTemplates) {
                API.createData('nmr1hOndeTemplate', nmr1hOndeTemplates.short);
            });
            return promise;
        }
    }

    class ExpandableMolecule {
        constructor(sampleIn) {
            this.sample = sampleIn;
            this.molfile = this.sample.$content.general.molfile + '';
            var molecule = OCLE.Molecule.fromMolfile(this.molfile);
            this.idCode = molecule.getIDCode();
            this.expandedHydrogens = false;
            this.jsmeEditionMode = false;
            API.createData('editableMolfile', this.molfile).then(
                (editableMolfile) => {
                    editableMolfile.onChange( (event) => {
                        // us this really a modification ? or a loop event ...
                        // need to compare former oclID with new oclID
                        var idCode = OCLE.Molecule.fromMolfile(event.target + '').getIDCode();
                        if (idCode != this.idCode) {
                            this.idCode = idCode;
                            this.molfile = event.target + '';
                            this.sample.setChildSync('$content.general.molfile', this.molfile);
                        } else {
                            console.log('no update');
                        }

                        // by default we would like the depict mode
                        this.updateMolfiles();
                        this.updateMF();
                    });
                    this.updateMolfiles();
                    this.toggleJSMEEdition(false);
                }
            );
        }

        toggleJSMEEdition(force, noDepictUpdate) {
            if (force !== undefined && force === this.jsmeEditionMode) return;
            if (force === undefined) {
                this.jsmeEditionMode = !this.jsmeEditionMode;
            } else {
                this.jsmeEditionMode = force;
            }
            var prefs = {
                "prefs": [
                    "oldlook",
                    "nozoom"
                ],
                "labelsize": "14",
                "bondwidth": "1",
                "defaultaction": "105",
                "highlightColor": "3",
                "outputResult": [
                    "yes"
                ]
            };

            if (this.jsmeEditionMode) {
                API.getData("editableMolfile").triggerChange();
                this.expandedHydrogens = false;
            } else {
                prefs.prefs.push('depict');
                if (!noDepictUpdate) {
                    this.expandedHydrogens = false;
                    API.createData("viewMolfile", this.viewMolfile);
                }

            }
            API.doAction('setJSMEPreferences', prefs)
        }

        setExpandedHydrogens(force) {
            if (force === undefined) {
                this.expandedHydrogens = !this.expandedHydrogens;
            } else {
                this.expandedHydrogens = force;
            }
            if (this.expandedHydrogens) {
                API.createData("viewMolfileExpandedH", this.viewMolfileExpandedH);
                this.toggleJSMEEdition(false, true);
            } else {
                API.createData("viewMolfile", this.viewMolfile);
            }
        }

        updateMolfiles() {
            // prevent the loop by checking actelionID
            var molecule = OCLE.Molecule.fromMolfile(this.molfile);
            this.viewMolfile = molecule.toVisualizerMolfile();

            molecule.addImplicitHydrogens();
            this.viewMolfileExpandedH = molecule.toVisualizerMolfile();
            this.mf = molecule.getMolecularFormula().formula;
            this.mw = molecule.getMolecularFormula().relativeWeight;
            this.nH = molecule.getNumberOfAtoms('H');
        }

    }

    return Sample;
});

<|endoftext|>


<commit_before>((exports) => {
	typeof module !== `undefined` && module.exports ? module.exports = exports() :
	typeof define === `function` && define.amd ? define(exports) :
	this[`Bite`] = exports();
})(() => {
	const helpers = {};

	const utilities = {
		string : `$ => $ && $.nodeName ? $.outerHTML || [...$.childNodes].map(node => node.outerHTML).join('') : $ || $ === 0 ? $ + '' : ''`,
		escape : `$ => $.replace(/[&<>="\`']/g, c => \`&#\${c.charCodeAt()};\`)`,
		html   : `$ => fragment && $ && $.nodeName ? (nodes.push($), \`
\`) : string($)`,
		repeat : `$ => [...new Array(+$).keys()]`,
		child  : `() => ($.$$ = $$, $$ = $)`,
		parent : `() => ($ = $$, $$ = $.$$, $.$$ = void 0, '')`,
	};

	[
		[``,        [`string`, `escape`], params => `\${escape(string(${params}))}`],
		[`%`,       [`string`, `html`],   params => `\${html(${params})}`],
		[`if`,      [],                   params => `\${${params} ? \``, `\` : ''}`],
		[`elseif`,  [],                   params => `\` : ${params} ? \``],
		[`else`,    [],                   params => `\` : true ? \``],
		[`repeat`,  [`repeat`],           params => `\${repeat(${params}).map(i => \``, `\`).join('')}`],
		[`forEach`, [`child`, `parent`],  params => `\${child(), ${params}.map(($, i) => \``, `\`).join('')} \${parent()}`],
		[`with`,    [`child`, `parent`],  params => `\${child(), $ = ${params}, ''}`, `\${parent()}`],
	].forEach(definition => helper(...definition));

	function helper(helper, deps, begin, end) {
		const standalone   = [``, `%`].includes(helper);
		const clean_helper = helper.replace(/([.*+?^=!:${}()|[\]\/\\])/g, `\\$&`);
		const prefix       = helper ? standalone ? `` : `#` : `(?![#%\/])`;
		const space        = standalone ? `\\s*` : `\\s+`;

		helpers[helper] = {
			deps : deps,
			begin : {
				pattern : new RegExp(`{{${prefix}${clean_helper}(?:${space}([\\s\\S]+?))?\\s*}}(?!})`, `gi`),
				replace : (match, params) => begin(params ? params.replace(/\\`/g, '`').replace(/\\\$\{/g, '${') : null),
			},
			end : end ? {
				pattern : new RegExp(`{{/${clean_helper}}}`, `gi`),
				replace : end,
			} : null,
		};
	}

	function bite(body) {
		body = (body || body === 0 ? body + `` : ``).replace(/`/g, '\\`').replace(/\$\{/g, '\\${');

		const deps_map = {};
		let deps       = ``;

		for(const helper in helpers) {
			const begin  = helpers[helper].begin;
			const end    = helpers[helper].end;
			const begins = (body.match(begin.pattern) || ``).length;
			const ends   = (end && body.match(end.pattern) || ``).length;

			if(end) {
				if(begins > ends) {
					throw new Error(`Unclosed {{#${helper}}}`);
				}
				else if(begins < ends) {
					throw new Error(`Unexpected {{/${helper}}}`);
				}
			}

			if(!begins) {
				continue;
			}

			helpers[helper].deps.forEach((dep) => deps_map[dep] = true);
			body = body.replace(begin.pattern, begin.replace);

			if(end) {
				body = body.replace(end.pattern, end.replace);
			}
		}

		for(const dep in utilities) {
			if(deps_map[dep]) {
				deps += `${dep}=${utilities[dep]}, `;
			}
		}

		body = `
			let $$;
			const ${deps}nodes = [], body = \`${body}\`;

			return fragment ? (
				fragment = new DocumentFragment(),
				$ = document.createElement('div'),
				$.innerHTML = body,
				[...$.childNodes].forEach($ => fragment.appendChild($)),
				nodes.forEach((node, i) => fragment.getElementById(\`bite--\${i}\`).replaceWith(node)),
				fragment
			) : body;
		`;

		const template = new Function(`$`, `fragment`, body);
		template.toString = () => `($, fragment) => {${body}}`;

		return template;
	}

	return bite;
});
<commit_msg>Fixed Edge document fragment error<commit_after>((exports) => {
	typeof module !== `undefined` && module.exports ? module.exports = exports() :
	typeof define === `function` && define.amd ? define(exports) :
	this[`Bite`] = exports();
})(() => {
	const helpers = {};

	const utilities = {
		string : `$ => $ && $.nodeName ? $.outerHTML || [...$.childNodes].map(node => node.outerHTML).join('') : $ || $ === 0 ? $ + '' : ''`,
		escape : `$ => $.replace(/[&<>="\`']/g, c => \`&#\${c.charCodeAt()};\`)`,
		html   : `$ => fragment && $ && $.nodeName ? (nodes.push($), \`
\`) : string($)`,
		repeat : `$ => [...new Array(+$).keys()]`,
		child  : `() => ($.$$ = $$, $$ = $)`,
		parent : `() => ($ = $$, $$ = $.$$, $.$$ = void 0, '')`,
	};

	[
		[``,        [`string`, `escape`], params => `\${escape(string(${params}))}`],
		[`%`,       [`string`, `html`],   params => `\${html(${params})}`],
		[`if`,      [],                   params => `\${${params} ? \``, `\` : ''}`],
		[`elseif`,  [],                   params => `\` : ${params} ? \``],
		[`else`,    [],                   params => `\` : true ? \``],
		[`repeat`,  [`repeat`],           params => `\${repeat(${params}).map(i => \``, `\`).join('')}`],
		[`forEach`, [`child`, `parent`],  params => `\${child(), ${params}.map(($, i) => \``, `\`).join('')} \${parent()}`],
		[`with`,    [`child`, `parent`],  params => `\${child(), $ = ${params}, ''}`, `\${parent()}`],
	].forEach(definition => helper(...definition));

	function helper(helper, deps, begin, end) {
		const standalone   = [``, `%`].includes(helper);
		const clean_helper = helper.replace(/([.*+?^=!:${}()|[\]\/\\])/g, `\\$&`);
		const prefix       = helper ? standalone ? `` : `#` : `(?![#%\/])`;
		const space        = standalone ? `\\s*` : `\\s+`;

		helpers[helper] = {
			deps : deps,
			begin : {
				pattern : new RegExp(`{{${prefix}${clean_helper}(?:${space}([\\s\\S]+?))?\\s*}}(?!})`, `gi`),
				replace : (match, params) => begin(params ? params.replace(/\\`/g, '`').replace(/\\\$\{/g, '${') : null),
			},
			end : end ? {
				pattern : new RegExp(`{{/${clean_helper}}}`, `gi`),
				replace : end,
			} : null,
		};
	}

	function bite(body) {
		body = (body || body === 0 ? body + `` : ``).replace(/`/g, '\\`').replace(/\$\{/g, '\\${');

		const deps_map = {};
		let deps       = ``;

		for(const helper in helpers) {
			const begin  = helpers[helper].begin;
			const end    = helpers[helper].end;
			const begins = (body.match(begin.pattern) || ``).length;
			const ends   = (end && body.match(end.pattern) || ``).length;

			if(end) {
				if(begins > ends) {
					throw new Error(`Unclosed {{#${helper}}}`);
				}
				else if(begins < ends) {
					throw new Error(`Unexpected {{/${helper}}}`);
				}
			}

			if(!begins) {
				continue;
			}

			helpers[helper].deps.forEach((dep) => deps_map[dep] = true);
			body = body.replace(begin.pattern, begin.replace);

			if(end) {
				body = body.replace(end.pattern, end.replace);
			}
		}

		for(const dep in utilities) {
			if(deps_map[dep]) {
				deps += `${dep}=${utilities[dep]}, `;
			}
		}

		body = `
			let $$;
			const ${deps}nodes = [], body = \`${body}\`;

			return fragment ? (
				fragment = document.createDocumentFragment(),
				$ = document.createElement('div'),
				$.innerHTML = body,
				[...$.childNodes].forEach($ => fragment.appendChild($)),
				nodes.forEach((node, i) => fragment.getElementById(\`bite--\${i}\`).replaceWith(node)),
				fragment
			) : body;
		`;

		const template = new Function(`$`, `fragment`, body);
		template.toString = () => `($, fragment) => {${body}}`;

		return template;
	}

	return bite;
});
<|endoftext|>


<commit_before>import Datas from 'src/main/datas';
import API from 'src/util/api';

const DataObject = Datas.DataObject;

const jpaths = {};

jpaths.sampleCode = ['$id', 0];
jpaths.batchCode = ['$id', 1];
jpaths.creationDate = ['$creationDate'];
jpaths.modificationDate = ['$modificationDate'];
jpaths.content = ['$content'];
jpaths.general = ['$content', 'general'];
jpaths.molfile = ['$content', 'general', 'molfile'];
jpaths.mf = ['$content', 'general', 'mf'];
jpaths.mw = ['$content', 'general', 'mw'];
jpaths.em = ['$content', 'general', 'em'];
jpaths.description = ['$content', 'general', 'description'];
jpaths.name = ['$content', 'general', 'name'];
jpaths.physical = ['$content', 'physical'];
jpaths.bp = ['$content', 'physical', 'bp'];
jpaths.nd = ['$content', 'physical', 'nd'];
jpaths.mp = ['$content', 'physical', 'mp'];
jpaths.density = ['$content', 'physical', 'density'];
jpaths.ir = ['$content', 'spectra', 'ir'];
jpaths.mass = ['$content', 'spectra', 'mass'];
jpaths.nmr = ['$content', 'spectra', 'nmr'];
jpaths.chromatogram = ['$content', 'spectra', 'chromatogram'];
jpaths.xray = ['$content', 'spectra', 'xray'];
jpaths.image = ['$content', 'image'];
jpaths.attachments = ['attachmentList'];

export function createVar(variable, varName) {
    check(varName);
    API.setVariable(varName, variable, jpaths[varName]);
}

export function getData(sample, varName) {
    check(varName);
    sample = _getData(sample);
    return sample.getChildSync(jpaths[varName]);
}

export function setData(sample, varName) {
    check(varName);
    // todo fix this
    //sample = get(sample);
    sample.setChildSync(jpaths[varName]);
}

function check(varName) {
    if (!jpaths[varName]) {
        throw new Error(`jpath for ${varName} not defined`);
    }
}

function _getData(variable) {
    if (DataObject.getType(variable) === 'string') {
        return API.getData(variable);
    }
    return variable;
}
<commit_msg>Correct jpath for title<commit_after>import Datas from 'src/main/datas';
import API from 'src/util/api';

const DataObject = Datas.DataObject;

const jpaths = {};

jpaths.sampleCode = ['$id', 0];
jpaths.batchCode = ['$id', 1];
jpaths.creationDate = ['$creationDate'];
jpaths.modificationDate = ['$modificationDate'];
jpaths.content = ['$content'];
jpaths.general = ['$content', 'general'];
jpaths.molfile = ['$content', 'general', 'molfile'];
jpaths.mf = ['$content', 'general', 'mf'];
jpaths.mw = ['$content', 'general', 'mw'];
jpaths.em = ['$content', 'general', 'em'];
jpaths.description = ['$content', 'general', 'description'];
jpaths.title = ['$content', 'general', 'title'];
jpaths.name = ['$content', 'general', 'name'];
jpaths.physical = ['$content', 'physical'];
jpaths.bp = ['$content', 'physical', 'bp'];
jpaths.nd = ['$content', 'physical', 'nd'];
jpaths.mp = ['$content', 'physical', 'mp'];
jpaths.density = ['$content', 'physical', 'density'];
jpaths.ir = ['$content', 'spectra', 'ir'];
jpaths.mass = ['$content', 'spectra', 'mass'];
jpaths.nmr = ['$content', 'spectra', 'nmr'];
jpaths.chromatogram = ['$content', 'spectra', 'chromatogram'];
jpaths.xray = ['$content', 'spectra', 'xray'];
jpaths.image = ['$content', 'image'];
jpaths.attachments = ['attachmentList'];

export function createVar(variable, varName) {
    check(varName);
    API.setVariable(varName, variable, jpaths[varName]);
}

export function getData(sample, varName) {
    check(varName);
    sample = _getData(sample);
    return sample.getChildSync(jpaths[varName]);
}

export function setData(sample, varName) {
    check(varName);
    // todo fix this
    //sample = get(sample);
    sample.setChildSync(jpaths[varName]);
}

function check(varName) {
    if (!jpaths[varName]) {
        throw new Error(`jpath for ${varName} not defined`);
    }
}

function _getData(variable) {
    if (DataObject.getType(variable) === 'string') {
        return API.getData(variable);
    }
    return variable;
}
<|endoftext|>


<commit_before>((exports) => {
	typeof module !== `undefined` && module.exports ? module.exports = exports() :
	typeof define === `function` && define.amd ? define(exports) :
	this[`Bite`] = exports();
})(() => {
	const helpers = {};

	const utilities = {
		string : `$ => $ && $.nodeName ? $.outerHTML || [...$.childNodes].map(node => node.outerHTML).join('') : $ || $ === 0 ? $ + '' : ''`,
		escape : `$ => $.replace(/[&<>="\`']/g, c => \`&#\${c.charCodeAt()};\`)`,
		html   : `$ => fragment && $ && $.nodeName ? (nodes.push($), \`<br id="bite--\${nodes.length - 1}">\`) : string($)`,
		repeat : `$ => [...new Array(+$).keys()]`,
		child  : `() => ($.$$ = $$, $$ = $)`,
		parent : `() => ($ = $$, $$ = $.$$, $.$$ = void 0, '')`,
	};

	[
		[``,        [`string`, `escape`], params => `\${escape(string(${params}))}`],
		[`%`,       [`string`, `html`],   params => `\${html(${params})}`],
		[`if`,      [],                   params => `\${${params} ? \``, `\` : ''}`],
		[`elseif`,  [],                   params => `\` : ${params} ? \``],
		[`else`,    [],                   params => `\` : true ? \``],
		[`repeat`,  [`repeat`],           params => `\${repeat(${params}).map(i => \``, `\`).join('')}`],
		[`forEach`, [`child`, `parent`],  params => `\${child(), ${params}.map(($, i) => \``, `\`).join('')} \${parent()}`],
		[`with`,    [`child`, `parent`],  params => `\${child(), $ = ${params}, ''}`, `\${parent()}`],
	].forEach(definition => helper(...definition));

	function helper(helper, deps, begin, end) {
		const standalone   = [``, `%`].includes(helper);
		const clean_helper = helper.replace(/([.*+?^=!:${}()|[\]\/\\])/g, `\\$&`);
		const prefix       = helper ? standalone ? `` : `#` : `(?![#%\/])`;
		const space        = standalone ? `\\s*` : `\\s+`;

		helpers[helper] = {
			deps : deps,
			begin : {
				pattern : new RegExp(`{{${prefix}${clean_helper}(?:${space}([\\s\\S]+?))?\\s*}}(?!})`, `gi`),
				replace : (match, params) => begin(params ? params.replace(/\\`/g, '`').replace(/\\\$\{/g, '${') : null),
			},
			end : end ? {
				pattern : new RegExp(`{{/${clean_helper}}}`, `gi`),
				replace : end,
			} : null,
		};
	}

	function bite(body) {
		body = (body || body === 0 ? body + `` : ``).replace(/`/g, '\\`').replace(/\$\{/g, '\\${');

		const deps_map = {};
		let deps       = ``;

		for(const helper in helpers) {
			const begin  = helpers[helper].begin;
			const end    = helpers[helper].end;
			const begins = (body.match(begin.pattern) || ``).length;
			const ends   = (end && body.match(end.pattern) || ``).length;

			if(end) {
				if(begins > ends) {
					throw new Error(`Unclosed {{#${helper}}}`);
				}
				else if(begins < ends) {
					throw new Error(`Unexpected {{/${helper}}}`);
				}
			}

			if(!begins) {
				continue;
			}

			helpers[helper].deps.forEach((dep) => deps_map[dep] = true);
			body = body.replace(begin.pattern, begin.replace);

			if(end) {
				body = body.replace(end.pattern, end.replace);
			}
		}

		for(const dep in utilities) {
			if(deps_map[dep]) {
				deps += `${dep}=${utilities[dep]}, `;
			}
		}

		body = `
			let $$;
			const ${deps}nodes = [], body = \`${body}\`;

			return fragment ? (
				fragment = document.createDocumentFragment(),
				$ = document.createElement('div'),
				$.innerHTML = body,
				[...$.childNodes].forEach($ => fragment.appendChild($)),
				nodes.forEach((node, i) => fragment.getElementById(\`bite--\${i}\`).replaceWith(node)),
				fragment
			) : body;
		`;

		const template = new Function(`$`, `fragment`, body);
		template.toString = () => `($, fragment) => {${body}}`;

		return template;
	}

	return bite;
});
<commit_msg>More Edge fixes<commit_after>((exports) => {
	typeof module !== `undefined` && module.exports ? module.exports = exports() :
	typeof define === `function` && define.amd ? define(exports) :
	this[`Bite`] = exports();
})(() => {
	const helpers = {};

	const utilities = {
		string : `$ => $ && $.nodeName ? $.outerHTML || [...$.childNodes].map(node => node.outerHTML).join('') : $ || $ === 0 ? $ + '' : ''`,
		escape : `$ => $.replace(/[&<>="\`']/g, c => \`&#\${c.charCodeAt()};\`)`,
		html   : `$ => fragment && $ && $.nodeName ? (nodes.push($), \`<bite-node id="bite--\${nodes.length - 1}"></bite-node>\`) : string($)`,
		repeat : `$ => [...new Array(+$).keys()]`,
		child  : `() => ($.$$ = $$, $$ = $)`,
		parent : `() => ($ = $$, $$ = $.$$, $.$$ = void 0, '')`,
	};

	[
		[``,        [`string`, `escape`], params => `\${escape(string(${params}))}`],
		[`%`,       [`string`, `html`],   params => `\${html(${params})}`],
		[`if`,      [],                   params => `\${${params} ? \``, `\` : ''}`],
		[`elseif`,  [],                   params => `\` : ${params} ? \``],
		[`else`,    [],                   params => `\` : true ? \``],
		[`repeat`,  [`repeat`],           params => `\${repeat(${params}).map(i => \``, `\`).join('')}`],
		[`forEach`, [`child`, `parent`],  params => `\${child(), ${params}.map(($, i) => \``, `\`).join('')} \${parent()}`],
		[`with`,    [`child`, `parent`],  params => `\${child(), $ = ${params}, ''}`, `\${parent()}`],
	].forEach(definition => helper(...definition));

	function helper(helper, deps, begin, end) {
		const standalone   = [``, `%`].includes(helper);
		const clean_helper = helper.replace(/([.*+?^=!:${}()|[\]\/\\])/g, `\\$&`);
		const prefix       = helper ? standalone ? `` : `#` : `(?![#%\/])`;
		const space        = standalone ? `\\s*` : `\\s+`;

		helpers[helper] = {
			deps : deps,
			begin : {
				pattern : new RegExp(`{{${prefix}${clean_helper}(?:${space}([\\s\\S]+?))?\\s*}}(?!})`, `gi`),
				replace : (match, params) => begin(params ? params.replace(/\\`/g, '`').replace(/\\\$\{/g, '${') : null),
			},
			end : end ? {
				pattern : new RegExp(`{{/${clean_helper}}}`, `gi`),
				replace : end,
			} : null,
		};
	}

	function bite(body) {
		body = (body || body === 0 ? body + `` : ``).replace(/`/g, '\\`').replace(/\$\{/g, '\\${');

		const deps_map = {};
		let deps       = ``;

		for(const helper in helpers) {
			const begin  = helpers[helper].begin;
			const end    = helpers[helper].end;
			const begins = (body.match(begin.pattern) || ``).length;
			const ends   = (end && body.match(end.pattern) || ``).length;

			if(end) {
				if(begins > ends) {
					throw new Error(`Unclosed {{#${helper}}}`);
				}
				else if(begins < ends) {
					throw new Error(`Unexpected {{/${helper}}}`);
				}
			}

			if(!begins) {
				continue;
			}

			helpers[helper].deps.forEach((dep) => deps_map[dep] = true);
			body = body.replace(begin.pattern, begin.replace);

			if(end) {
				body = body.replace(end.pattern, end.replace);
			}
		}

		for(const dep in utilities) {
			if(deps_map[dep]) {
				deps += `${dep}=${utilities[dep]}, `;
			}
		}

		body = `
			let $$;
			const ${deps}nodes = [], body = \`${body}\`;

			return fragment ? (
				fragment = document.createDocumentFragment(),
				$ = document.createElement('div'),
				$.innerHTML = body,
				[...$.childNodes].forEach($ => fragment.appendChild($)),
				nodes.forEach((node, i) => (i = fragment.querySelector(\`bite-node#bite--\${i}\`), i.parentNode.insertBefore(node, i), i.parentNode.removeChild(i))),
				fragment
			) : body;
		`;

		const template = new Function(`$`, `fragment`, body);
		template.toString = () => `($, fragment) => {${body}}`;

		return template;
	}

	return bite;
});
<|endoftext|>


<commit_before>/*#ifndef(UMD)*/
(function () { /* Begin of privacy scope */
    "use strict";
/*#endif*/

    /*
     * Detect host & define global context
     */
    var
        _host,
        _context;

    // Microsoft cscript / wscript
    if ("undefined" !== typeof WScript) {
        _host = "wscript";
        _context = (function () {return this; }).apply(null, []);

        // Define console APIs
        _context.console = {
            log: function (t) {WScript.Echo("    " + t);},
            info: function (t) {WScript.Echo("[?] " + t);},
            warn: function (t) {WScript.Echo("/!\\ " + t);},
            error: function (t) {WScript.Echo("(X) " + t);}
        };

    // Nodejs
    } else if ("undefined" !== typeof module && module.exports) {
        _host = "nodejs";
        _context = global;

    // Browser
    } else if ("undefined" !== typeof window) {
        _host = "browser";
        _context = window;

    // Default: unknown
    } else {
        _host = "unknown";
        _context = this;

    }

/*#ifndef(UMD)*/

    _context.gpf = {};

/*#endif*/

    /**
     * Returns a string identifying the detected host
     *
     * @return {String}
     * - "wscript" for cscript and wscript
     * - "nodejs" for nodejs
     * - "browser" for any browser
     * - "unknown" if not detected
     */
    gpf.host = function () {
        return _host;
    };

    /**
     * Resolve the provided evaluation path and returns the result
     *
     * @param {String|string[]} path Dot separated list of identifier
     * (or identifier array)
     * @return {*|undefined}
     * - when path is empty, it returns the current host higher object
     * - when path is "gpf" it returns the GPF object
     */
    gpf.context = function (path) {
        var
            len,
            idx,
            result;
        if (undefined === path) {
            return _context;
        } else {
            if ("string" === typeof path) {
                path = path.split(".");
            }
            len = path.length;
            idx = 0;
            if (path[0] === "gpf") {
                result = gpf;
                ++idx;
            } else {
                result = _context;
            }
            for (; idx < len; ++idx) {
                result = result[path[idx]];
                if (undefined === result) {
                    break;
                }
            }
            return result;
        }
    };

/*#ifndef(UMD)*/

    var
        _loaded,
        _loadCallbacks = [],
        _finishLoading = function () {
            _loaded = true;
            while (_loadCallbacks.length) {
                _loadCallbacks.shift()();
            }
        };

    gpf.loaded = function (callback) {
        if (callback) {
            if (_loaded) {
                callback();
            } else {
                _loadCallbacks.push(callback);
            }
        }
        return _loaded;
    };

    if(!gpf.loaded) {

/*#else*/

        gpf.loaded = function (callback) {
            if (callback) {
                callback();
            }
            return true;
        };

/*#endif*/

/*#ifndef(UMD)*/

    }

/*#endif*/

    gpf.NOT_IMPLEMENTED = function () {
        console.error("Not implemented");
        throw {
            message: "Not implemented"
        };
    };

    /*
     * Handling external options
     * TODO: provide ways to turn on/off features by adding options
     */

/*#ifdef(DEBUG)*/
    // DEBUG specifics

    gpf.ASSERT = function (condition, message) {
        if (!condition) {
            console.warn("ASSERTION FAILED: " + message);
            throw {
                message: "ASSERTION FAILED: " + message
            };
        }
    };

    if (!gpf.ASSERT) {

/*#else*/

        gpf.ASSERT = function /*gpf:inline*/ () {};

/*#endif*/

/*#ifdef(DEBUG)*/

    }

/*#endif*/

/*#ifndef(UMD)*/

    /*
     * Loading sources occurs here because the release version will have
     * everything embedded.
     */
    if ("wscript" === _host) {
        /*
         * Use FSO and eval
         */
        (function () {
            var
                fso = new ActiveXObject("Scripting.FileSystemObject"),
                include = function (src) {
                    /*global gpfSourcesPath*/ // Tested below
                    if ("undefined" !== typeof gpfSourcesPath) {
                        src = gpfSourcesPath + src;
                    }
                    var srcFile = fso.OpenTextFile(src);
                    /*jslint evil: true*/
                    // No other choice to evaluate in the current context
                    eval(srcFile.ReadAll());
                    /*jslint evil: false*/
                    srcFile.Close();
                },
                sources,
                idx;
            include("sources.js");
            sources = gpf.sources().split(",");
            for (idx = 0; idx < sources.length; ++idx) {
                include(sources[idx] + ".js");
            }
            _finishLoading();
        }());

    } else if ("nodejs" === _host) {
        /*
         * This is probably the simplest part: use require
         */
        require("./sources.js");
        (function () {
            var
                sources = gpf.sources().split(","),
                idx;
            for (idx = 0; idx < sources.length; ++idx) {
                require("./" + sources[idx] + ".js");
            }
            _finishLoading();
        }());

    } else { // "browser" === _host
        /*
         * This one is more tricky and that's why gpf.loaded() has been created
         */
        (function () {
            var
                sources,
                idx = 0,
                loadSources = function () {
                    var src;
                    if (idx < sources.length) {
                        src = sources[idx] + ".js";
                        if ("undefined" !== typeof gpfSourcesPath) {
                            src = gpfSourcesPath + src;
                        }
                        gpf.http.include(src)
                            .onLoad(loadSources);
                        ++idx;
                    } else {
                        _finishLoading();
                    }
                },
                // Ugly but fast way to insert sources
                head = document.getElementsByTagName("head")[0]
                || document.documentElement,

                include = function (src) {
                    if ("undefined" !== typeof gpfSourcesPath) {
                        src = gpfSourcesPath + src;
                    }
                    var script = document.createElement("script");
                    script.language = "javascript";
                    script.src = src;
                    head.insertBefore(script, head.firstChild);
                },
                // Sequence of things to load (followed by test)
                bootList = ["sources", "sources",
                    "base", "each",
                    "events", "events",
                    "http", "http"],
                boot = function () {
                    if (0 === idx % 2) {
                        include(bootList[idx] + ".js");
                        ++idx;
                    } else {
                        if (undefined !== gpf[bootList[idx]]) {
                            ++idx;
                        }
                    }
                    if (idx === bootList.length) {
                        /*
                         * Now that include & sources are loaded,
                         * load the missing sources
                         */
                        sources = gpf.sources().split(",");
                        idx = gpf.test(sources, "http") + 1;
                        loadSources();
                    } else {
                        window.setTimeout(boot, 100);
                    }
                };
            boot();
        }());
    }

}()); /* End of privacy scope */
/*#endif*/
<commit_msg>Documentation fix<commit_after>/*#ifndef(UMD)*/
(function () { /* Begin of privacy scope */
    "use strict";
/*#endif*/

    /*
     * Detect host & define global context
     */
    var
        _host,
        _context;

    // Microsoft cscript / wscript
    if ("undefined" !== typeof WScript) {
        _host = "wscript";
        _context = (function () {return this; }).apply(null, []);

        // Define console APIs
        _context.console = {
            log: function (t) {WScript.Echo("    " + t);},
            info: function (t) {WScript.Echo("[?] " + t);},
            warn: function (t) {WScript.Echo("/!\\ " + t);},
            error: function (t) {WScript.Echo("(X) " + t);}
        };

    // Nodejs
    } else if ("undefined" !== typeof module && module.exports) {
        _host = "nodejs";
        _context = global;

    // Browser
    } else if ("undefined" !== typeof window) {
        _host = "browser";
        _context = window;

    // Default: unknown
    } else {
        _host = "unknown";
        _context = this;

    }

/*#ifndef(UMD)*/

    _context.gpf = {};

/*#endif*/

    /**
     * Returns a string identifying the detected host
     *
     * @return {String}
     * - "wscript" for cscript and wscript
     * - "nodejs" for nodejs
     * - "browser" for any browser
     * - "unknown" if not detected
     */
    gpf.host = function () {
        return _host;
    };

    /**
     * Resolve the provided evaluation path and returns the result
     *
     * @param {String|string[]} [path=undefined] path Dot separated list of
     * identifiers (or identifier array)
     * @return {*|undefined}
     * - when path is empty, it returns the current host higher object
     * - when path is "gpf" it returns the GPF object
     */
    gpf.context = function (path) {
        var
            len,
            idx,
            result;
        if (undefined === path) {
            return _context;
        } else {
            if ("string" === typeof path) {
                path = path.split(".");
            }
            len = path.length;
            idx = 0;
            if (path[0] === "gpf") {
                result = gpf;
                ++idx;
            } else {
                result = _context;
            }
            for (; idx < len; ++idx) {
                result = result[path[idx]];
                if (undefined === result) {
                    break;
                }
            }
            return result;
        }
    };

/*#ifndef(UMD)*/

    var
        _loaded,
        _loadCallbacks = [],
        _finishLoading = function () {
            _loaded = true;
            while (_loadCallbacks.length) {
                _loadCallbacks.shift()();
            }
        };

    gpf.loaded = function (callback) {
        if (callback) {
            if (_loaded) {
                callback();
            } else {
                _loadCallbacks.push(callback);
            }
        }
        return _loaded;
    };

    if(!gpf.loaded) {

/*#else*/

        gpf.loaded = function (callback) {
            if (callback) {
                callback();
            }
            return true;
        };

/*#endif*/

/*#ifndef(UMD)*/

    }

/*#endif*/

    gpf.NOT_IMPLEMENTED = function () {
        console.error("Not implemented");
        throw {
            message: "Not implemented"
        };
    };

    /*
     * Handling external options
     * TODO: provide ways to turn on/off features by adding options
     */

/*#ifdef(DEBUG)*/
    // DEBUG specifics

    gpf.ASSERT = function (condition, message) {
        if (!condition) {
            console.warn("ASSERTION FAILED: " + message);
            throw {
                message: "ASSERTION FAILED: " + message
            };
        }
    };

    if (!gpf.ASSERT) {

/*#else*/

        gpf.ASSERT = function /*gpf:inline*/ () {};

/*#endif*/

/*#ifdef(DEBUG)*/

    }

/*#endif*/

/*#ifndef(UMD)*/

    /*
     * Loading sources occurs here because the release version will have
     * everything embedded.
     */
    if ("wscript" === _host) {
        /*
         * Use FSO and eval
         */
        (function () {
            var
                fso = new ActiveXObject("Scripting.FileSystemObject"),
                include = function (src) {
                    /*global gpfSourcesPath*/ // Tested below
                    if ("undefined" !== typeof gpfSourcesPath) {
                        src = gpfSourcesPath + src;
                    }
                    var srcFile = fso.OpenTextFile(src);
                    /*jslint evil: true*/
                    // No other choice to evaluate in the current context
                    eval(srcFile.ReadAll());
                    /*jslint evil: false*/
                    srcFile.Close();
                },
                sources,
                idx;
            include("sources.js");
            sources = gpf.sources().split(",");
            for (idx = 0; idx < sources.length; ++idx) {
                include(sources[idx] + ".js");
            }
            _finishLoading();
        }());

    } else if ("nodejs" === _host) {
        /*
         * This is probably the simplest part: use require
         */
        require("./sources.js");
        (function () {
            var
                sources = gpf.sources().split(","),
                idx;
            for (idx = 0; idx < sources.length; ++idx) {
                require("./" + sources[idx] + ".js");
            }
            _finishLoading();
        }());

    } else { // "browser" === _host
        /*
         * This one is more tricky and that's why gpf.loaded() has been created
         */
        (function () {
            var
                sources,
                idx = 0,
                loadSources = function () {
                    var src;
                    if (idx < sources.length) {
                        src = sources[idx] + ".js";
                        if ("undefined" !== typeof gpfSourcesPath) {
                            src = gpfSourcesPath + src;
                        }
                        gpf.http.include(src)
                            .onLoad(loadSources);
                        ++idx;
                    } else {
                        _finishLoading();
                    }
                },
                // Ugly but fast way to insert sources
                head = document.getElementsByTagName("head")[0]
                || document.documentElement,

                include = function (src) {
                    if ("undefined" !== typeof gpfSourcesPath) {
                        src = gpfSourcesPath + src;
                    }
                    var script = document.createElement("script");
                    script.language = "javascript";
                    script.src = src;
                    head.insertBefore(script, head.firstChild);
                },
                // Sequence of things to load (followed by test)
                bootList = ["sources", "sources",
                    "base", "each",
                    "events", "events",
                    "http", "http"],
                boot = function () {
                    if (0 === idx % 2) {
                        include(bootList[idx] + ".js");
                        ++idx;
                    } else {
                        if (undefined !== gpf[bootList[idx]]) {
                            ++idx;
                        }
                    }
                    if (idx === bootList.length) {
                        /*
                         * Now that include & sources are loaded,
                         * load the missing sources
                         */
                        sources = gpf.sources().split(",");
                        idx = gpf.test(sources, "http") + 1;
                        loadSources();
                    } else {
                        window.setTimeout(boot, 100);
                    }
                };
            boot();
        }());
    }

}()); /* End of privacy scope */
/*#endif*/
<|endoftext|>


<commit_before>'use strict'

function Boss(root, name){

    var boss = this;

    var loadFileSystem = root => {
        this.FileSystem = eval(root.dirs.sys.files.FileSystem.data);
    }

    var loadEnv = fs => {
        var files = this.fs.get_files('/etc');
        for(var file in files){
            var json = this.fs.get_file('/etc',files[file]).data;
            this.env[files[file]] = JSON.parse(json);
        }
    }

    var loadLibraries = fs => {
        var files = this.fs.get_files('/lib');
        for(var file in files){
            var code = this.fs.get_file('/lib',files[file]).data;
            this.lib[files[file]] = eval(code);
        }
    }

    var loadCommands = fs => {
        var help = [];
        var files = this.fs.get_files('/bin');
        for(var file in files){
            var code = this.fs.get_file('/bin',files[file]).data;
            this.cmd[files[file]] = eval(code);
            if(this.fs.get_file('/bin',files[file]).meta && this.fs.get_file('/bin',files[file]).meta.description){
                help.push(files[file] + ' - ' + this.fs.get_file('/bin',files[file]).meta.description);
            }
        }
        this.cmd['help'] = function(args, client){
            boss.lib.print.log('\n', client);
            for(var opt in help){
                boss.lib.print.log(help[opt], client);
            }
            boss.lib.print.log('\n', client);
        }
    }

    this.reload = function(){
        this.cmd = {};
        this.lib = {};
        this.env = {};
        loadEnv(this.fs);
        loadLibraries(this.fs);
        loadCommands(this.fs);
    }

    loadFileSystem(root);
    this.fs = new this.FileSystem(root, name);
    this.reload();
    this.interpreters = [new this.lib.Login(this).username];
}

var ConsoleClient = function(b){
    var daBoss = b;

    this.toolbar = {
        set_title: function(title){
            //nothing
        },
         set_message: function(message){
            //nothing
        },
         set_notification: function(app){
            //nothing
        }
    }

    this.out = function(text){
        console.log(text);
    }

    this.set_prompt = function(prompt){
        //Do nothing
    }

    this.get_prompt = function(){
        return '';
    }

    this.exec = (command) => {
        daBoss.interpreters[daBoss.interpreters.length - 1](command, this);
    }
}

<commit_msg>add init<commit_after>'use strict'

function Boss(root, name){

    var boss = this;

    var loadFileSystem = root => {
        this.FileSystem = eval(root.dirs.sys.files.FileSystem.data);
    }

    var loadLibraries = fs => {
        var files = this.fs.get_files('/lib');
        for(var file in files){
            var code = this.fs.get_file('/lib',files[file]).data;
            this.lib[files[file]] = eval(code);
        }
    }

    var loadCommands = fs => {
        var help = [];
        var files = this.fs.get_files('/bin');
        for(var file in files){
            var code = this.fs.get_file('/bin',files[file]).data;
            this.cmd[files[file]] = eval(code);
            if(this.fs.get_file('/bin',files[file]).meta && this.fs.get_file('/bin',files[file]).meta.description){
                help.push(files[file] + ' - ' + this.fs.get_file('/bin',files[file]).meta.description);
            }
        }
        this.cmd['help'] = function(args, client){
            boss.lib.print.log('\n', client);
            for(var opt in help){
                boss.lib.print.log(help[opt], client);
            }
            boss.lib.print.log('\n', client);
        }
    }

    var runInit = fs => {
        var files = this.fs.get_files('/etc');
        for(var file in files){
            var code = this.fs.get_file('/etc',files[file]).data;
            var fn = eval(code);
            fn();
        }
    }

    this.reload = function(){
        this.cmd = {};
        this.lib = {};
        loadLibraries(this.fs);
        loadCommands(this.fs);
        runInit();
    }

    loadFileSystem(root);
    this.fs = new this.FileSystem(root, name);
    this.reload();
    this.interpreters = [new this.lib.Login(this).username];
}

var ConsoleClient = function(b){
    var daBoss = b;

    this.toolbar = {
        set_title: function(title){
            //nothing
        },
         set_message: function(message){
            //nothing
        },
         set_notification: function(app){
            //nothing
        }
    }

    this.out = function(text){
        console.log(text);
    }

    this.set_prompt = function(prompt){
        //Do nothing
    }

    this.get_prompt = function(){
        return '';
    }

    this.exec = (command) => {
        daBoss.interpreters[daBoss.interpreters.length - 1](command, this);
    }
}

<|endoftext|>


<commit_before>import { UIDiv, UIButton, UIRow } from './libs/ui.js';

function SidebarGeometryModifiers( editor, object ) {

	const strings = editor.strings;

	const signals = editor.signals;

	const container = new UIDiv().setPaddingLeft( '90px' );

	const geometry = object.geometry;

	// Compute Vertex Normals

	const button = new UIButton( strings.getKey( 'sidebar/geometry/show_vertex_normals' ) );
	button.onClick( function () {

		geometry.computeVertexNormals();

		geometry.attributes.normal.needsUpdate = true;

		signals.geometryChanged.dispatch( object );

	} );

	const row = new UIRow();
	row.add( button );

	container.add( row );

	//

	return container;

}

export { SidebarGeometryModifiers };
<commit_msg>Update Sidebar.Geometry.Modifiers.js<commit_after>import { UIDiv, UIButton, UIRow } from './libs/ui.js';

function SidebarGeometryModifiers( editor, object ) {

	const strings = editor.strings;

	const signals = editor.signals;

	const container = new UIDiv().setPaddingLeft( '90px' );

	const geometry = object.geometry;

	// Compute Vertex Normals

	const button = new UIButton( strings.getKey( 'sidebar/geometry/compute_vertex_normals' ) );
	button.onClick( function () {

		geometry.computeVertexNormals();

		geometry.attributes.normal.needsUpdate = true;

		signals.geometryChanged.dispatch( object );

	} );

	const row = new UIRow();
	row.add( button );

	container.add( row );

	//

	return container;

}

export { SidebarGeometryModifiers };
<|endoftext|>