<commit_before>/*
 @author Zakai Hamilton
 @component KabStyle
 */

package.kab.style = function KabStyle(me) {
    me.process = function (session, instance, replacement, expansion) {
        var styles = instance.item.style;
        var html = "";
        var phase = null, heading = null, tooltip = null, descriptions = {};
        var term = instance.item.source ? instance.item.source : instance.target;
        if (typeof styles === "string") {
            if (session.json.style) {
                styles = session.json.style[styles];
            } else {
                styles = null;
            }
        }
        if (styles && styles.bold) {
            html += "";
        }
        if (styles && styles.phase) {
            phase = styles.phase;
            if (styles && styles.heading && session.options.headings) {
                heading = styles.heading;
            }
            if (!session.options.keepSource && !expansion && session.options.doTranslation && term !== replacement) {
                if (instance.item.source) {
                    term = instance.item.source;
                }
                tooltip = term;
            }
        } else if (!session.options.keepSource && !expansion) {
            phase = "none";
            if (term !== replacement) {
                tooltip = term;
            }
            if (styles && styles.heading && session.options.headings) {
                heading = styles.heading;
            }
        }
        if(styles) {
            if(session.options.prioritizeExplanation) {
                if(styles.explanation) {
                    descriptions["explanation"] = styles.explanation;
                }
                if(styles.technical) {
                    descriptions["technical"] = styles.technical;
                }
            }
            else {
                if(styles.technical) {
                    descriptions["technical"] = styles.technical;
                }
                if(styles.explanation) {
                    descriptions["explanation"] = styles.explanation;
                }
            }
        }
        descriptions["related"] = {};
        var numDescriptions = Object.keys(descriptions).length;
        if (styles && styles.tooltip) {
            tooltip = styles.tooltip;
        }
        if (phase) {
            html += "<span class=\"kab-term-phase-inline kab-term-phase-" + phase + " kab-term-phase-" + phase + "-outline\"";
            if (numDescriptions) {
                html += " kab-term-toast";
            }
            if (tooltip) {
                html += " kab-term-tooltip=\"" + tooltip + "\"";
            }
            var diagram = me.package.kab.diagram.matchingDiagram(session, instance.target);
            if(diagram && session.options.diagramCallback) {
                html += " onload=\"" + session.options.diagramCallback + "(this," + diagram + ")\"";
            }
            if(session.options.hoverCallback) {
                html += " onmouseover=\"" + session.options.hoverCallback + "(this,true)\" onmouseout=\"" + session.options.hoverCallback + "(this,false)\"";
            }
            if(session.options.toggleCallback) {
                html += " onclick=\"" + session.options.toggleCallback + "(this)\"";
            }
            html += ">";
            if (phase !== "none" && session.options.phaseNumbers && session.json.phaseNumber) {
                var phaseNumber = session.json.phaseNumber[phase];
                if (phaseNumber) {
                    html += "";
                }
            }
            if (heading) {
                html += "";
            }
            if (numDescriptions) {
                if (phase === "none") {
                    phase = "root";
                }
                for(var descriptionType in descriptions) {
                    var description = descriptions[descriptionType];
                    html += "";
                    var short = description.short;
                    if (!short) {
                        short = "";
                    }
                    html += "" + replacement + ": " + short + "";
                    html += "" + descriptionType + "";
                    var long = description.long;
                    if (long) {
                        html += "" + long + "";
                    }
                    html += "";
                }
            }
        }
        html += replacement;
        if (phase) {
            html += "";
        }
        if (styles && styles.bold) {
            html += "";
        }
        return html;
    };
};
<commit_msg>both term and its translation are displayed in popup<commit_after>/*
 @author Zakai Hamilton
 @component KabStyle
 */

package.kab.style = function KabStyle(me) {
    me.process = function (session, instance, replacement, expansion) {
        var styles = instance.item.style;
        var html = "";
        var phase = null, heading = null, tooltip = null, descriptions = {};
        var term = instance.item.source ? instance.item.source : instance.target;
        if (typeof styles === "string") {
            if (session.json.style) {
                styles = session.json.style[styles];
            } else {
                styles = null;
            }
        }
        if (styles && styles.bold) {
            html += "";
        }
        if (styles && styles.phase) {
            phase = styles.phase;
            if (styles && styles.heading && session.options.headings) {
                heading = styles.heading;
            }
            if (!session.options.keepSource && !expansion && session.options.doTranslation && term !== replacement) {
                if (instance.item.source) {
                    term = instance.item.source;
                }
                tooltip = term;
            }
        } else if (!session.options.keepSource && !expansion) {
            phase = "none";
            if (term !== replacement) {
                tooltip = term;
            }
            if (styles && styles.heading && session.options.headings) {
                heading = styles.heading;
            }
        }
        if(styles) {
            if(session.options.prioritizeExplanation) {
                if(styles.explanation) {
                    descriptions["explanation"] = styles.explanation;
                }
                if(styles.technical) {
                    descriptions["technical"] = styles.technical;
                }
            }
            else {
                if(styles.technical) {
                    descriptions["technical"] = styles.technical;
                }
                if(styles.explanation) {
                    descriptions["explanation"] = styles.explanation;
                }
            }
        }
        descriptions["related"] = {};
        var numDescriptions = Object.keys(descriptions).length;
        if (styles && styles.tooltip) {
            tooltip = styles.tooltip;
        }
        if (phase) {
            html += "<span class=\"kab-term-phase-inline kab-term-phase-" + phase + " kab-term-phase-" + phase + "-outline\"";
            if (numDescriptions) {
                html += " kab-term-toast";
            }
            if (tooltip) {
                html += " kab-term-tooltip=\"" + tooltip + "\"";
            }
            var diagram = me.package.kab.diagram.matchingDiagram(session, instance.target);
            if(diagram && session.options.diagramCallback) {
                html += " onload=\"" + session.options.diagramCallback + "(this," + diagram + ")\"";
            }
            if(session.options.hoverCallback) {
                html += " onmouseover=\"" + session.options.hoverCallback + "(this,true)\" onmouseout=\"" + session.options.hoverCallback + "(this,false)\"";
            }
            if(session.options.toggleCallback) {
                html += " onclick=\"" + session.options.toggleCallback + "(this)\"";
            }
            html += ">";
            if (phase !== "none" && session.options.phaseNumbers && session.json.phaseNumber) {
                var phaseNumber = session.json.phaseNumber[phase];
                if (phaseNumber) {
                    html += "";
                }
            }
            if (heading) {
                html += "";
            }
            if (numDescriptions) {
                if (phase === "none") {
                    phase = "root";
                }
                for(var descriptionType in descriptions) {
                    var description = descriptions[descriptionType];
                    html += "";
                    var short = description.short;
                    if (!short) {
                        short = "";
                    }
                    html += "" + term + " [" + replacement + "]: " + short + "";
                    html += "" + descriptionType + "";
                    var long = description.long;
                    if (long) {
                        html += "" + long + "";
                    }
                    html += "";
                }
            }
        }
        html += replacement;
        if (phase) {
            html += "";
        }
        if (styles && styles.bold) {
            html += "";
        }
        return html;
    };
};
<|endoftext|>


<commit_before>define([
    'jquery',
    'base/utils',
    'base/component',
    'base/model',
    'smartpicker'
], function($, utils, Component, Model, SmartPicker) {

    var picker,
        countries;

    var PickerGeo = Component.extend({
        init: function(parent, options) {
            this._super(parent, options);
            this.data = options.data;
        },

        postRender: function() {
            var _this = this;

            //load countries and then initialize pickers
            this.loadCountries().then(function(country_list) {
                _this.initializePicker(country_list);
            });
        },

        //load list of countries
        loadCountries: function() {
            var _this = this,
                defer = $.Deferred(),
                language = this.model.get("language"),
                state = this.model.get("state"),
                query = this.getQuery(),
                countries = new Model();

            //set the correct source
            countries.setSource(this.data);

            //load data and resolve the defer when it's done
            $.when(
                countries.load(query, language, _this.events)
            ).done(function() {
                country_list = countries.get()[0];

                // TODO: remove hard-coded filtering for indicators
                country_list = country_list.filter(function(row) {
                    return (row["geo.category"] == "country" &&
                        row.time === "2000" && row.lex && row.pop && row.gdp);
                });

                country_list = country_list.map(function (country) {
                    return {
                        value: country["geo"],
                        name: country["geo.name"]
                    };
                });

                defer.resolve(country_list);
            });

            return defer;

        },

        //initialize picker with list of countries
        initializePicker: function(country_list) {
            var _this = this;
            //instantiate a new geoMult picker
            picker = new SmartPicker('mult', 'geo-picker', {
                contentData: {
                    text: "Select the countries",
                    options: country_list || []
                },
                width: 320,
                confirmButton: "OK",
                //what to do after user selects a country
                onSet: function(selected) {
                    //extract the value only
                    var countries = _.map(selected.selected, function(country) {
                        return country.value;
                    });
                    //pass the selected countries to state
                    _this.selectCountries(countries);
                }
            });
        },

        //pass a list of countries to the state
        selectCountries: function(countriesArr) {
            var state = {
                show: {
                    'geo': countriesArr,
                    'geo.categories': ['country']
                },
            };

            this.setState(state);
        },

        show: function() {
            if (picker && picker.show) {
                picker.show();
            }
        },

        update: function() {

        },

        getQuery: function() {
          var query = [{
                    select: [
                        'geo',
                        'geo.name',
                    ],
                    where: {
                        geo: ["*"]
                    }}];

            return query;
        }

    });

    return PickerGeo;
});<commit_msg>remove old geo-picker button<commit_after><|endoftext|>


<commit_before>(function(exports) {
  const randInt = (min, max) => {
    const range = max - min;
    return Math.round(
      min + Math.random() * range
    );
  };

  function generateStocks({minPrice, maxPrice}) {
    const symbols = [
      'Amazon',
      'Google',
      'Facebook',
      'Microsoft',
      'Facebook',
      'McDonald\'s',
      'ExxonMobil'
    ].sort();

    const stocks = symbols.map(symbol =>
      new Stock({
        symbol,
        price: randInt(minPrice, maxPrice)
      })
    );

    return stocks;
  }

  function StockFactory() {
    let stocks = Db.get('stocks');
    if (typeof stocks !== 'object' || stocks === null) {
      stocks = generateStocks({
        minPrice: 100,
        maxPrice: 1000
      });
    }

    stocks.forEach(stock => {
      if (stock.shouldUpdatePrice()) {
        stock.updatePrice();
      }
    });

    return stocks;
  }

  exports.StockFactory = StockFactory;
})(window);<commit_msg>Save stocks when prices change<commit_after>(function(exports) {
  const randInt = (min, max) => {
    const range = max - min;
    return Math.round(
      min + Math.random() * range
    );
  };

  function generateStocks({minPrice, maxPrice}) {
    const symbols = [
      'Amazon',
      'Google',
      'Facebook',
      'Microsoft',
      'Facebook',
      'McDonald\'s',
      'ExxonMobil'
    ].sort();

    const stocks = symbols.map(symbol =>
      new Stock({
        symbol,
        price: randInt(minPrice, maxPrice)
      })
    );

    return stocks;
  }

  function StockFactory() {
    let stocks = Db.get('stocks');
    if (typeof stocks !== 'object' || stocks === null) {
      stocks = generateStocks({
        minPrice: 100,
        maxPrice: 1000
      });
    }

    let pricesChanged = false;
    stocks.forEach(stock => {
      if (stock.shouldUpdatePrice()) {
        stock.updatePrice();
        pricesChanged = true;
      }
    });

    if (pricesChanged) {
      Db.save('stocks', stocks);
    }

    return stocks;
  }

  exports.StockFactory = StockFactory;
})(window);<|endoftext|>


<commit_before>module.exports = {
    publicPath: './',
    productionSourceMap: false,
    chainWebpack: config => {
        config.plugins.delete('prefetch')
    }
}<commit_msg>Add metrics eventcount support<commit_after>module.exports = {
    publicPath: './',
    productionSourceMap: false,
    chainWebpack: config => {
        config.plugins.delete('prefetch')
    },
    devServer: {
        proxy: {
            '/cap/api': {
                target: 'http://localhost:5000',
                changeOrigin: true
            }
        }
    }
}<|endoftext|>


<commit_before>'use strict';

const R = require('ramda');

const EnumFromObject = Object.freeze;
const EnumFromArray = R.reduce((acc, value) => EnumValue(value)(acc), {});
const EnumFromPairs = R.reduce((acc, pair) => EnumPairValue(pair)(acc), {});

const EnumKeyValue = (key, value) => R.assoc(
    R.ifElse(
        R.is(String),
        R.identity,
        String
    )(key), value
);
const EnumValue = value => EnumKeyValue(value, value);
const EnumPairValue = pair => EnumKeyValue(pair[0], pair[1]);

const excludeEmpty = R.filter(R.pipe(R.length, R.gte(R.__, 1)));
const debug = R.tap(console.log);
const isSingleArg = R.pipe(R.length, R.equals(1));
const isPair = R.both(
    R.is(Array),
    R.pipe(R.length, R.equals(2))
);
const arePairs = R.both(R.is(Array), R.pipe(R.head, isPair));
const extend = [[R.T, R.identity]];
const EnumSingle = R.pipe(R.cond(extend), R.cond([
    [arePairs, EnumFromPairs],
    [R.is(Array), EnumFromArray],
    [R.is(Map), R.pipe(Array.from, EnumFromPairs)],
    [R.is(Set), R.pipe(Array.from, EnumFromArray)],
    [R.is(String), R.pipe(R.split(/[\s]+/ig), excludeEmpty, EnumFromArray)],
    [R.is(Number), R.pipe(EnumValue, R.apply(R.__, [{}]))],
    [R.is(Boolean), R.pipe(EnumValue, R.apply(R.__, [{}]))],
    [R.T, R.identity],
]));

const EnumMultiple = R.cond([
    [R.pipe(R.head, R.is(String)), EnumFromArray],
    [R.T, R.identity],
]);

/**
 * @param {Object|Array|Map|Set|...String} values Input arguments.
 * @return {Object} Frozen object corresponding to given arguments.
 */
const Enum = R.unapply(R.ifElse(
    isSingleArg,
    R.pipe(R.head, EnumSingle, EnumFromObject),
    R.pipe(R.reduce((acc, value) => R.merge(acc, EnumSingle(value)), {}), EnumFromObject)
));

const isValidCondition = R.both(R.is(Function), R.pipe(R.prop('length'), R.equals(1)));
const isValidOperator = R.both(R.is(Function), R.pipe(R.prop('length'), R.gte(R.__, 0)));
const addExtend = R.invoker(3, 'splice')(0, 0, R.__, extend);

Enum.extend = R.unapply(R.ifElse(
    R.both(
        R.pipe(R.length, R.equals(2)),
        R.both(
            R.pipe(R.head, isValidCondition),
            R.pipe(R.last, isValidOperator)
        )
    ),
    addExtend,
    R.F
));

exports = module.exports = Enum;
<commit_msg>remove unused code<commit_after>'use strict';

const R = require('ramda');

const EnumFromObject = Object.freeze;
const EnumFromArray = R.reduce((acc, value) => EnumValue(value)(acc), {});
const EnumFromPairs = R.reduce((acc, pair) => EnumPairValue(pair)(acc), {});

const EnumKeyValue = (key, value) => R.assoc(
    R.ifElse(
        R.is(String),
        R.identity,
        String
    )(key), value
);
const EnumValue = value => EnumKeyValue(value, value);
const EnumPairValue = pair => EnumKeyValue(pair[0], pair[1]);

const excludeEmpty = R.filter(R.pipe(R.length, R.gte(R.__, 1)));
const debug = R.tap(console.log);
const isSingleArg = R.pipe(R.length, R.equals(1));
const isPair = R.both(
    R.is(Array),
    R.pipe(R.length, R.equals(2))
);
const arePairs = R.both(R.is(Array), R.pipe(R.head, isPair));
const extend = [[R.T, R.identity]];
const EnumSingle = R.pipe(R.cond(extend), R.cond([
    [arePairs, EnumFromPairs],
    [R.is(Array), EnumFromArray],
    [R.is(Map), R.pipe(Array.from, EnumFromPairs)],
    [R.is(Set), R.pipe(Array.from, EnumFromArray)],
    [R.is(String), R.pipe(R.split(/[\s]+/ig), excludeEmpty, EnumFromArray)],
    [R.is(Number), R.pipe(EnumValue, R.apply(R.__, [{}]))],
    [R.is(Boolean), R.pipe(EnumValue, R.apply(R.__, [{}]))],
    [R.T, R.identity],
]));

/**
 * @param {Object|Array|Map|Set|...String} values Input arguments.
 * @return {Object} Frozen object corresponding to given arguments.
 */
const Enum = R.unapply(R.ifElse(
    isSingleArg,
    R.pipe(R.head, EnumSingle, EnumFromObject),
    R.pipe(R.reduce((acc, value) => R.merge(acc, EnumSingle(value)), {}), EnumFromObject)
));

const isValidCondition = R.both(R.is(Function), R.pipe(R.prop('length'), R.equals(1)));
const isValidOperator = R.both(R.is(Function), R.pipe(R.prop('length'), R.gte(R.__, 0)));
const addExtend = R.invoker(3, 'splice')(0, 0, R.__, extend);

Enum.extend = R.unapply(R.ifElse(
    R.both(
        R.pipe(R.length, R.equals(2)),
        R.both(
            R.pipe(R.head, isValidCondition),
            R.pipe(R.last, isValidOperator)
        )
    ),
    addExtend,
    R.F
));

exports = module.exports = Enum;
<|endoftext|>


<commit_before>'use string'

var nock = require('nock')
var config = require('../../config')
var fs = require('fs')

module.exports.dataPackage = require('./demo-package/datapackage.json')
module.exports.readme = fs.readFileSync('tests/fixtures/demo-package/README.md').toString()

module.exports.initMocks = function() {
  var data = module.exports
  nock(config.get('BITSTORE_URL'))
    .persist()
    .get('/metadata/admin/demo-package/_v/latest/datapackage.json')
    .reply(200, data.dataPackage, {'access-control-allow-origin': '*'})
    .get('/metadata/admin/demo-package/_v/latest/README.md')
    .reply(200, data.readme, {'access-control-allow-origin': '*'})
    .get('/metadata/core/s-and-p-500-companies/_v/latest/datapackage.json')
    .reply(200, data.dataPackage, {'access-control-allow-origin': '*'})
    .get('/metadata/core/s-and-p-500-companies/_v/latest/README.md')
    .reply(200, data.readme, {'access-control-allow-origin': '*'})
    .get('/metadata/core/house-prices-us/_v/latest/datapackage.json')
    .reply(200, data.dataPackage, {'access-control-allow-origin': '*'})
    .get('/metadata/core/house-prices-us/_v/latest/README.md')
    .reply(200, data.readme, {'access-control-allow-origin': '*'})
    .get('/metadata/core/gold-prices/_v/latest/datapackage.json')
    .reply(200, data.dataPackage, {'access-control-allow-origin': '*'})
    .get('/metadata/core/gold-prices/_v/latest/README.md')
    .reply(200, data.readme, {'access-control-allow-origin': '*'})
    .get('/metadata/examples/simple-graph-spec/_v/latest/datapackage.json')
    .reply(200, data.dataPackage, {'access-control-allow-origin': '*'})
    .get('/metadata/examples/simple-graph-spec/_v/latest/README.md')
    .reply(200, data.readme, {'access-control-allow-origin': '*'})
    .get('/metadata/examples/vega-views-tutorial-lines/_v/latest/datapackage.json')
    .reply(200, data.dataPackage, {'access-control-allow-origin': '*'})
    .get('/metadata/examples/vega-views-tutorial-lines/_v/latest/README.md')
    .reply(200, data.readme, {'access-control-allow-origin': '*'})
    .get('/metadata/examples/geojson-tutorial/_v/latest/datapackage.json')
    .reply(200, data.dataPackage, {'access-control-allow-origin': '*'})
    .get('/metadata/examples/geojson-tutorial/_v/latest/README.md')
    .reply(200, data.readme, {'access-control-allow-origin': '*'})

  // Mock api calls for authentication
  // Not authenticated returns urls for login
  process.stdout.write(config.get('BITSTORE_URL'))
  nock(config.get('API_URL'))
    .persist()
    .get(`/auth/check?jwt=undefined&next=${config.get('SITE_URL')}/success`)
    .reply(200, {
      "authenticated": false,
      "providers": {
        "github": {
          "url": "https://github.com/login/"
        },
        "google": {
          "url": "https://accounts.google.com/o/oauth2/auth"
        }
      }
    })
  // GitHub
  nock(config.get('API_URL'))
    .persist()
    .get(`/auth/check?jwt=1a2b3c&next=${config.get('SITE_URL')}/success`)
    .reply(200, {
      "authenticated": true,
      "profile": {
        "avatar_url": "https://avatars2.githubusercontent.com/u/000000?v=3",
        "email": "test_username_but_not_email",
        "id": "123456abc",
        "join_date": "Tue, 27 Jun 2017 10:15:05 GMT",
        "name": "Firstname Secondname",
        "provider_id": "github:17809581",
        "username": null
      }
    })
  // GOOGLE
  nock(config.get('API_URL'))
    .persist()
    .get(`/auth/check?jwt=1a2b3c4d&next=${config.get('SITE_URL')}/success`)
    .reply(200, {
      "authenticated": true,
      "profile": {
        "avatar_url": "https://lh4.googleusercontent.com/photo.jpg",
        "email": "actual_email@gmail.com",
        "id": "123456abc",
        "join_date": "Tue, 27 Jun 2017 10:58:08 GMT",
        "name": "Firstname Secondname",
        "provider_id": "google:117985331094635516621",
        "username": null
      }
    })
}
<commit_msg>[tests][s]: fixed brocken links for nock<commit_after>'use string'

var nock = require('nock')
var config = require('../../config')
var fs = require('fs')

module.exports.dataPackage = require('./demo-package/datapackage.json')
module.exports.readme = fs.readFileSync('tests/fixtures/demo-package/README.md').toString()

module.exports.initMocks = function() {
  var data = module.exports
  nock(config.get('BITSTORE_URL'))
    .persist()
    .get('/admin/demo-package/latest/datapackage.json')
    .reply(200, data.dataPackage, {'access-control-allow-origin': '*'})
    .get('/admin/demo-package/latest/README.md')
    .reply(200, data.readme, {'access-control-allow-origin': '*'})
    .get('/core/s-and-p-500-companies/latest/datapackage.json')
    .reply(200, data.dataPackage, {'access-control-allow-origin': '*'})
    .get('/core/s-and-p-500-companies/latest/README.md')
    .reply(200, data.readme, {'access-control-allow-origin': '*'})
    .get('/core/house-prices-us/latest/datapackage.json')
    .reply(200, data.dataPackage, {'access-control-allow-origin': '*'})
    .get('/core/house-prices-us/latest/README.md')
    .reply(200, data.readme, {'access-control-allow-origin': '*'})
    .get('/core/gold-prices/latest/datapackage.json')
    .reply(200, data.dataPackage, {'access-control-allow-origin': '*'})
    .get('/core/gold-prices/latest/README.md')
    .reply(200, data.readme, {'access-control-allow-origin': '*'})
    .get('/examples/simple-graph-spec/latest/datapackage.json')
    .reply(200, data.dataPackage, {'access-control-allow-origin': '*'})
    .get('/examples/simple-graph-spec/latest/README.md')
    .reply(200, data.readme, {'access-control-allow-origin': '*'})
    .get('/examples/vega-views-tutorial-lines/latest/datapackage.json')
    .reply(200, data.dataPackage, {'access-control-allow-origin': '*'})
    .get('/examples/vega-views-tutorial-lines/latest/README.md')
    .reply(200, data.readme, {'access-control-allow-origin': '*'})
    .get('/examples/geojson-tutorial/latest/datapackage.json')
    .reply(200, data.dataPackage, {'access-control-allow-origin': '*'})
    .get('/examples/geojson-tutorial/latest/README.md')
    .reply(200, data.readme, {'access-control-allow-origin': '*'})

  // Mock api calls for authentication
  // Not authenticated returns urls for login
  process.stdout.write(config.get('BITSTORE_URL'))
  nock(config.get('API_URL'))
    .persist()
    .get(`/auth/check?jwt=undefined&next=${config.get('SITE_URL')}/success`)
    .reply(200, {
      "authenticated": false,
      "providers": {
        "github": {
          "url": "https://github.com/login/"
        },
        "google": {
          "url": "https://accounts.google.com/o/oauth2/auth"
        }
      }
    })
  // GitHub
  nock(config.get('API_URL'))
    .persist()
    .get(`/auth/check?jwt=1a2b3c&next=${config.get('SITE_URL')}/success`)
    .reply(200, {
      "authenticated": true,
      "profile": {
        "avatar_url": "https://avatars2.githubusercontent.com/u/000000?v=3",
        "email": "test_username_but_not_email",
        "id": "123456abc",
        "join_date": "Tue, 27 Jun 2017 10:15:05 GMT",
        "name": "Firstname Secondname",
        "provider_id": "github:17809581",
        "username": null
      }
    })
  // GOOGLE
  nock(config.get('API_URL'))
    .persist()
    .get(`/auth/check?jwt=1a2b3c4d&next=${config.get('SITE_URL')}/success`)
    .reply(200, {
      "authenticated": true,
      "profile": {
        "avatar_url": "https://lh4.googleusercontent.com/photo.jpg",
        "email": "actual_email@gmail.com",
        "id": "123456abc",
        "join_date": "Tue, 27 Jun 2017 10:58:08 GMT",
        "name": "Firstname Secondname",
        "provider_id": "google:117985331094635516621",
        "username": null
      }
    })
}
<|endoftext|>


<commit_before>// model.js - A mongoose model
// https://www.edu-apps.org/code.html - LTI Parameters
// See http://mongoosejs.com/docs/models.html
// for more of what you can do here.

const mongoose = require('mongoose');
const { enableAuditLog } = require('../../utils/database');

const { Schema } = mongoose;

const ltiToolSchema = new Schema({
	name: { type: String },
	url: { type: String, required: true },
	key: { type: String },
	secret: { type: String, required: true },
	logo_url: { type: String },
	lti_message_type: { type: String },
	lti_version: { type: String },
	resource_link_id: { type: String },
	roles: {
		type: [{
			type: String,
			enum: ['Learner', 'Instructor', 'ContentDeveloper', 'Administrator', 'Mentor', 'TeachingAssistant'],
		}],
	},
	privacy_permission: {
		type: String,
		enum: ['anonymous', 'e-mail', 'name', 'public', 'pseudonymous'],
		default: 'anonymous',
	},
	customs: { type: [{ key: { type: String }, value: { type: String } }] },
	isTemplate: { type: Boolean },
	isLocal: { type: Boolean },
	createdAt: { type: Date, default: Date.now },
	updatedAt: { type: Date, default: Date.now },
	originTool: { type: Schema.Types.ObjectId, ref: 'ltiTool' },
	oAuthClientId: { type: String },
	friendlyUrl: { type: String, unique: true, sparse: true },
	skipConsent: { type: Boolean },
});

function validateKey(value) {
	if (this.lti_version === 'LTI-1p0') return !!value;
	return true;
}

ltiToolSchema.path('key').validate(validateKey);

enableAuditLog(ltiToolSchema);

const ltiToolModel = mongoose.model('ltiTool', ltiToolSchema);

module.exports = ltiToolModel;
<commit_msg>add field for new tab configuration of tools<commit_after>// model.js - A mongoose model
// https://www.edu-apps.org/code.html - LTI Parameters
// See http://mongoosejs.com/docs/models.html
// for more of what you can do here.

const mongoose = require('mongoose');
const { enableAuditLog } = require('../../utils/database');

const { Schema } = mongoose;

const ltiToolSchema = new Schema({
	name: { type: String },
	url: { type: String, required: true },
	key: { type: String },
	secret: { type: String, required: true },
	logo_url: { type: String },
	lti_message_type: { type: String },
	lti_version: { type: String },
	resource_link_id: { type: String },
	roles: {
		type: [{
			type: String,
			enum: ['Learner', 'Instructor', 'ContentDeveloper', 'Administrator', 'Mentor', 'TeachingAssistant'],
		}],
	},
	privacy_permission: {
		type: String,
		enum: ['anonymous', 'e-mail', 'name', 'public', 'pseudonymous'],
		default: 'anonymous',
	},
	customs: { type: [{ key: { type: String }, value: { type: String } }] },
	isTemplate: { type: Boolean },
	isLocal: { type: Boolean },
	createdAt: { type: Date, default: Date.now },
	updatedAt: { type: Date, default: Date.now },
	originTool: { type: Schema.Types.ObjectId, ref: 'ltiTool' },
	oAuthClientId: { type: String },
	friendlyUrl: { type: String, unique: true, sparse: true },
	skipConsent: { type: Boolean },
	openNewTab: { type: Boolean, default: false },
});

function validateKey(value) {
	if (this.lti_version === 'LTI-1p0') return !!value;
	return true;
}

ltiToolSchema.path('key').validate(validateKey);

enableAuditLog(ltiToolSchema);

const ltiToolModel = mongoose.model('ltiTool', ltiToolSchema);

module.exports = ltiToolModel;
<|endoftext|>


<commit_before>'use strict';

// MODULES //

var bench = require( '@stdlib/bench' );
var isString = require( '@stdlib/assert/is-string' ).isPrimitive;
var pkg = require( './../package.json' ).name;
var replace = require( './../lib' );

// MAIN //

bench( pkg+'::string', function benchmark( b ) {
	var out;
	var str;
	var i;

	str = 'To be, or not to be, that is the question.';

	b.tic();
	for ( i = 0; i < b.iterations; i++ ) {
		out = replace( str, 'be', String.fromCharCode( i%126 ) );
		if ( !isString( out ) ) {
			b.fail( 'should return a string' );
		}
	}
	b.toc();
	if ( !isString( out ) ) {
		b.fail( 'should return a string' );
	}
	b.pass( 'benchmark finished' );
	b.end();
});

bench( pkg+'::regexp', function benchmark( b ) {
	var out;
	var str;
	var re;
	var i;

	str = 'To be, or not to be, that is the question.';
	re = /be/g;

	b.tic();
	for ( i = 0; i < b.iterations; i++ ) {
		out = replace( str, re, String.fromCharCode( i%126 ) );
		if ( !isString( out ) ) {
			b.fail( 'should return a string' );
		}
	}
	b.toc();
	if ( isString( out ) ) {
		b.pass( 'benchmark finished' );
	} else {
		b.fail( 'should return a string' );
	}
	b.end();
});

bench( pkg+'::replacer', function benchmark( b ) {
	var out;
	var str;
	var i;

	str = 'To be, or not to be, that is the question.';

	b.tic();
	for ( i = 0; i < b.iterations; i++ ) {
		out = replace( str, 'be', replacer );
		if ( !isString( out ) ) {
			b.fail( 'should return a string' );
		}
	}
	b.toc();
	if ( !isString( out ) ) {
		b.fail( 'should return a string' );
	}
	b.pass( 'benchmark finished' );
	b.end();

	function replacer( match, p1 ) {
		return '/' + p1 + '/';
	}
});
<commit_msg>Use string utility<commit_after>'use strict';

// MODULES //

var bench = require( '@stdlib/bench' );
var isString = require( '@stdlib/assert/is-string' ).isPrimitive;
var fromCodePoint = require( '@stdlib/string/from-code-point' );
var pkg = require( './../package.json' ).name;
var replace = require( './../lib' );

// MAIN //

bench( pkg+'::string', function benchmark( b ) {
	var out;
	var str;
	var i;

	str = 'To be, or not to be, that is the question.';

	b.tic();
	for ( i = 0; i < b.iterations; i++ ) {
		out = replace( str, 'be', fromCodePoint( i%126 ) );
		if ( !isString( out ) ) {
			b.fail( 'should return a string' );
		}
	}
	b.toc();
	if ( !isString( out ) ) {
		b.fail( 'should return a string' );
	}
	b.pass( 'benchmark finished' );
	b.end();
});

bench( pkg+'::regexp', function benchmark( b ) {
	var out;
	var str;
	var re;
	var i;

	str = 'To be, or not to be, that is the question.';
	re = /be/g;

	b.tic();
	for ( i = 0; i < b.iterations; i++ ) {
		out = replace( str, re, fromCodePoint( i%126 ) );
		if ( !isString( out ) ) {
			b.fail( 'should return a string' );
		}
	}
	b.toc();
	if ( !isString( out ) ) {
		b.fail( 'should return a string' );
	}
	b.pass( 'benchmark finished' );
	b.end();
});

bench( pkg+'::replacer', function benchmark( b ) {
	var out;
	var str;
	var i;

	str = 'To be, or not to be, that is the question.';

	b.tic();
	for ( i = 0; i < b.iterations; i++ ) {
		out = replace( str, 'be', replacer );
		if ( !isString( out ) ) {
			b.fail( 'should return a string' );
		}
	}
	b.toc();
	if ( !isString( out ) ) {
		b.fail( 'should return a string' );
	}
	b.pass( 'benchmark finished' );
	b.end();

	function replacer( match, p1 ) {
		return '/' + p1 + '/';
	}
});
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2014 Google Inc. All Rights Reserved
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var touchManager = TouchManager.create({});
touchManager.install(document);
var gestureManager = GestureManager.create();

DEBUG = true;

MODEL({
  name: 'ModelListController',
  properties: [
    {
      name: 'search',
    },
    {
      name: 'searchView',
      factory: function() {
        return this.X.mdTextFieldView.create({ data$: this.search$, label:'Search', onKeyMode: true, displayWidth: 20 });
      }
    },
    {
      name: 'dao',
      factory: function() {
        var newDAO = this.X.MDAO.create({model:Model});

        // This is to make sure getPrototype is called, even if the model object
        // has been created without a .create or .getPrototype having been called
        // yet.
        for ( var key in UNUSED_MODELS ) {
          var modl = FOAM.lookup(key, this.X);
          modl.getPrototype && modl.getPrototype();
        }
        for ( var key in USED_MODELS ) {
          var modl = FOAM.lookup(key, this.X);
          modl.getPrototype && modl.getPrototype();
        }

        // All models are now in USED_MODELS
        for ( var key in USED_MODELS ) {
          var m = FOAM.lookup(key, this.X);
          if ( ! m.getPrototype ) continue;
          m.getPrototype();
          newDAO.put(m);
        };

        // Add in non-model things like Interfaces
        for ( var key in NONMODEL_INSTANCES ) {
          var m = FOAM.lookup(key, this.X);
          newDAO.put(m);
        };

        // load up books
        for (var key in this.X.developerDocs) {
          newDAO.put(this.X.developerDocs[key]);
        }

        return newDAO;
      }
    },
    {
      name: 'filteredDAO',
      model_: 'DAOProperty',

      dynamicValue: function() {
        return this.dao.orderBy(this.order)
            .where(OR(CONTAINS_IC(Model.NAME, this.search), CONTAINS_IC(Model.PACKAGE, this.search)));
      }
    },
    {
      name: 'filteredDAOView',
      factory: function() {
        return this.X.DAOListView.create({ data$: this.filteredDAO$, rowView: 'ModelDescriptionRowView' });
      }
    }
  ]
});

MODEL({
  name: 'ModelDescriptionRowView',
  extendsModel: 'View',

  properties: [
    {
      name: 'data',
      help: 'The Model to describe',
      postSet: function() {
        this.modelRef = this.data.package? this.data.package + "." + this.data.name : this.data.name;
        this.modelName = this.data.package? "["+this.data.package + "] " + this.data.name : this.data.name;
      }
    },
    {
      name: 'modelName',
      help: 'The Model package and name.'
    },
    {
      name: 'modelRef'
    }
  ],

  methods: {
    init: function() {
      // set up context // TODO: template is compile before we create subcontext
      this.X = this.X.sub({name:'ModelDescriptionRowView_X'});
      this.X.documentationViewParentModel = SimpleValue.create();

      this.SUPER();
    }
  },
  templates: [ // TODO: the data gets set on the modelNameView... screws it up
    function toInnerHTML() {/*

$$modelName{model_:'DocRefView', ref$: this.modelRef$, text$: this.modelName$}

    */}
  ]
});

MODEL({
  name: 'ControllerView',
  extendsModel: 'DetailView',

  methods: {
    initHTML: function() {
      this.data.searchView.initHTML();
      this.data.filteredDAOView.initHTML();
    }
  },

  templates: [
    function toHTML() {/*

<%=this.data.searchView.toHTML()%>

<%=this.data.filteredDAOView.toHTML()%>

    */}
  ]
});

MODEL({
  name: 'DocBrowserController',

  documentation: function() {  /*

Some documentation for the $$DOC{ref:'.'} model.

This should be expaneded to explain some of the interesting properties found here, such as $$DOC{ref:'.modelList'}.

We can also mention how invalid references are caught $$DOC{ref:'modelList'}.

And here's a normal property view in the same template: $$data{ mode: 'read-only' }

Though you'd often want to link to related models, like $$DOC{ref:'DocModelBodyView'}, or even specific features on them, like $$DOC{ref:'DocModelView.data', text:'DocModelView's data property'}.

Reference to a method argument: $$DOC{ref:'DocBrowserController.testMethod.args.testy'}

This won't work since 'properties' here will resolve to the DocBrowserController.PROPERTIES feature: $$DOC{ref:'DocBrowserController.properties.modelListView'}. Only use direct access for layers below Model.feature.

Linking to a $$DOC{ref:'Model'} property value of a $$DOC{ref:'Model'} (rather than a feature): $$DOC{ref:'DocBrowserController'}

  */},

  models: [
    {
      model_: 'Model',
      name: 'NamedInnerModel',
      documentation: function() { /* Docs for named inner model. $$DOC{ref:"."} */ },
      models: [
        {
          model_: 'Model',
          name: 'InnyInner',
          documentation: function() { /* Inny Inner! $$DOC{ref:"."} */ },
        }
      ]

    },
//    {
//      model_: 'Model',

//    }
  ],

  methods: {
    init: function() {
      /* This is a method documentation comment: spawn and populate sub contexts. */

      // load developer guides
      RegisterDevDocs(this.X);

      // search context uses a selection value to indicate the chosen Model to display
      this.SearchContext = this.X.sub({}, 'searchX');
      this.SearchContext.selection$ = this.SearchContext.SimpleValue.create(); // holds a Model definition

      // detail context needs a documentViewRef.get().resolvedRoot to indicate what model it is rooted at
      this.DetailContext = this.X.sub({}, 'detailX');
      this.DetailContext.documentViewRef = this.DetailContext.SimpleValue.create();// this.DetailContext.DocRef.create();

      this.X.documentViewRequestNavigation = this.requestNavigation.bind(this);

      /////////////////////////// Context setup ^
      this.SUPER();
      /////////////////////////// this.init v

      // when the hash changes set the documentViewRef and this.selection
      window.addEventListener('hashchange', this.setReferenceFromHash.bind(this));

      // initialization from hash
      this.setReferenceFromHash();

      var testArg = this.X.Arg.create({name: 'testy'});
      testArg.documentation = this.X.Documentation.create({
        body: function() { /*
          Argument $$DOC{ref:'.'} documentation.
          */ }
      });
      this.model_.methods[1].args.push(testArg);
    },

    testMethod: function(a1, b2) {
      return a1 + b2;
    },

    setReferenceFromHash: function() {
      if (location.hash === '#' || location.hash === '#undefined' || location.hash.length === 0) {
        location.hash = 'developerDocs.Welcome';
        return;
      }
      // don't respond if we are already at the location desired
      if (location.hash.substring(1) === this.DetailContext.documentViewRef.get().ref) return;

      var newRef = this.DetailContext.DocRef.create({ref:location.hash.substring(1)});
      if (newRef.valid) {
        this.DetailContext.documentViewRef.set(newRef);
        this.SearchContext.selection$.set(newRef.resolvedRoot.resolvedModelChain[0]); // selection wants a Model object

      }
    },

    requestNavigation: function(ref) {
      if (ref.valid) {
        this.selection = ref.resolvedModelChain[0];
        this.DetailContext.documentViewRef.set(ref);
        this.SearchContext.selection$.set(ref.resolvedRoot.resolvedModelChain[0]); // selection wants a Model object
        location.hash = "#" + ref.resolvedRef;
      }
    }

  },

  listeners: [
    {
      name: 'onReadyToScroll',
      code: function(evt) {

      }
    }
  ],

  properties: [
    {
      name: 'modelList',
      factory: function() {
        return this.SearchContext.ModelListController.create();
      }
    },
    {
      name: 'modelListView',
      factory: function() {
        return this.SearchContext.ControllerView.create({ model: ModelListController,
                                                          data$: this.modelList$ });
      }
    },
    {
      name: 'selectionView',
      factory: function() {
        return this.DetailContext.DocModelView.create({ model: Model, data$: this.DetailContext.documentViewRef });
      }
    },
  ]

});

MODEL({
  name: 'DocBrowserView',
  extendsModel: 'DetailView',

  methods: {
   initHTML: function() {
     this.data.modelListView.initHTML();
     this.data.selectionView.initHTML();
   }
  },

  templates: [
    function CSS() {/*
      body {
        margin: 0px;
        font-family: 'Roboto', sans-serif;
        font-size: inherit;

        background-color: #e0e0e0;
        position: relative;

      }

      .outermost {
        width: 100%;
        height: 100%;
        display: flex;
        flex-direction: column;
      }

      .docbrowser-header {
        height: 90px;
        position: relative;
        color: #fff;
        z-index: 1;
        flex-shrink: 0;
      }

      .docbrowser-header-inner {
        background-color: #5555FF;
        position: absolute;
        height: 120px;
        width: 100%;
        flex-shrink: 0;
      }

      .docbrowser-header-flex-container {
        display: flex;
        flex-shrink: 0;
        justify-content: space-around;
        margin: 0 50px;
      }
      .docbrowser-header-contents {
        flex-grow: 1;
        flex-shrink: 0;
        max-width: 1280px;

        display: flex;
        justify-content: space-between;
      }

      .docbrowser-title {
        font-weight: lighter;
        font-size: 250%;
        margin-top: 20px;
      }
      .docbrowser-tabs {
        font-size: 120%;
        font-weight: lighter;
        margin-top: 40px;
        margin-right: 20px;
      }
      .docbrowser-tab {
        margin-left: 50px;
      }
      .docbrowser-tab.enabled {
        font-weight: normal;
      }

      .outer-container {
        margin: 0 30px;
        z-index: 2;
        position: relative;
        display:flex;
        flex-direction: column;

        flex-shrink: 1;
        flex-basis: 10000px;
      }
      .outer-flex-container {
        display: flex;
        flex-direction: column;
        justify-content: space-around;
        margin-bottom: 60px;
        width: 100%;
        flex-grow: 1;
 //       height: 83%;
      }
      .inner-container {
        background-color: #fff;
        border: 1px solid #888;
        border-radius: 12px;
        flex-grow: 1000;
        flex-shrink: 1;
        flex-basis: 1px;
        max-width: 1280px;
        padding: 15px;
        box-shadow: 0px 5px 5px #888888;
        display:flex;
      }

      input {
        font-family: inherit;
        font-size: inherit;
      }

      p {
        padding-bottom: 0.5em;
      }
      li {
        padding-bottom: 0.5em;
      }

      div.listPane {
        min-width: 200px;
        flex-basis: 200px;
        order: 1;
        padding: 1em;
        flex-grow: 0;
        overflow-x: hidden;

        display: flex;
        flex-direction: column;
      }

      div.detailPane {
        order: 2;
        flex-grow: 10;
        overflow-y: scroll;
        padding: 1em;
      }

      div.detailPane div.chapters h2 {
        font-size: 110%;
      }

      div.search-field-container {
        flex-grow: 0;
        flex-shrink: 0;
        order: 1;
        padding: 0;
        margin-left: -15;
      }

      div.list-container {
        order: 2;
        flex-grow: 1;
        overflow-y:scroll;
        overflow-x:hidden;
      }
      div.list-container span.docLink {
        border-bottom: none;
      }

      div.members {
        padding-left: 2em;
      }
      div.memberList {
        padding-left: 2em;
      }

      div.chapters div.memberList {
        padding-left: 0;
      }

      div.inherited {
        color: #333333;
      }

      p.browse-list-entry {
        font-size:100%;
        font-weight: bold;
        line-height: 150%
      }

      span.docLink {
        cursor: pointer;
        color: #000077;
        border-bottom: 0.1em dotted #999;
      }

      span.docLinkNoDocumentation {
        color: #770000;

      }

      div.model-info-block {
        padding: 1em;
        margin: 1em 0 1em 0;
        border-top: 0.1em solid black;
        border-bottom: 0.1em solid black;
      }
      div.model-info-block p.note {
        font-size:105%;
      }
      div.model-info-block p.important {
        font-size:105%;
        font-weight:bold;
      }

      .feature-row {
        //border-top: 0.1em solid grey;
        margin-top: 1em;
        margin-bottom: 1em;
      }

      p.inheritance-info {
        font-size: 90%;
        padding-left: 1em;
      }

      .feature-type-heading {
        font-weight: bold;
        font-size: 150%;
      }
      .feature-heading {
        font-weight: bold;
        font-size: 125%;
      }
      .feature-sub-heading {
        font-weight: bold;
        font-size: 100%;
      }
      .feature-type {
        float:right;
      }

      .light {
        color: #444;
      }
    */},
    function toHTML() {/*
      <div class="outermost" id="<%= this.id %>">

        <div id="<%= this.id %>-outer-container" class="outer-container">

            <div id="<%= this.id %>-inner-container" class="inner-container">

<%=this.data.modelListView.toHTML()%>

<%=this.data.selectionView.toHTML()%>

    */}
  ]

});

<commit_msg>Docs CSS update<commit_after>/**
 * @license
 * Copyright 2014 Google Inc. All Rights Reserved
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var touchManager = TouchManager.create({});
touchManager.install(document);
var gestureManager = GestureManager.create();

DEBUG = true;

MODEL({
  name: 'ModelListController',
  properties: [
    {
      name: 'search',
    },
    {
      name: 'searchView',
      factory: function() {
        return this.X.mdTextFieldView.create({ data$: this.search$, label:'Search', onKeyMode: true, displayWidth: 20 });
      }
    },
    {
      name: 'dao',
      factory: function() {
        var newDAO = this.X.MDAO.create({model:Model});

        // This is to make sure getPrototype is called, even if the model object
        // has been created without a .create or .getPrototype having been called
        // yet.
        for ( var key in UNUSED_MODELS ) {
          var modl = FOAM.lookup(key, this.X);
          modl.getPrototype && modl.getPrototype();
        }
        for ( var key in USED_MODELS ) {
          var modl = FOAM.lookup(key, this.X);
          modl.getPrototype && modl.getPrototype();
        }

        // All models are now in USED_MODELS
        for ( var key in USED_MODELS ) {
          var m = FOAM.lookup(key, this.X);
          if ( ! m.getPrototype ) continue;
          m.getPrototype();
          newDAO.put(m);
        };

        // Add in non-model things like Interfaces
        for ( var key in NONMODEL_INSTANCES ) {
          var m = FOAM.lookup(key, this.X);
          newDAO.put(m);
        };

        // load up books
        for (var key in this.X.developerDocs) {
          newDAO.put(this.X.developerDocs[key]);
        }

        return newDAO;
      }
    },
    {
      name: 'filteredDAO',
      model_: 'DAOProperty',

      dynamicValue: function() {
        return this.dao.orderBy(this.order)
            .where(OR(CONTAINS_IC(Model.NAME, this.search), CONTAINS_IC(Model.PACKAGE, this.search)));
      }
    },
    {
      name: 'filteredDAOView',
      factory: function() {
        return this.X.DAOListView.create({ data$: this.filteredDAO$, rowView: 'ModelDescriptionRowView' });
      }
    }
  ]
});

MODEL({
  name: 'ModelDescriptionRowView',
  extendsModel: 'View',

  properties: [
    {
      name: 'data',
      help: 'The Model to describe',
      postSet: function() {
        this.modelRef = this.data.package? this.data.package + "." + this.data.name : this.data.name;
        this.modelName = this.data.package? "["+this.data.package + "] " + this.data.name : this.data.name;
      }
    },
    {
      name: 'modelName',
      help: 'The Model package and name.'
    },
    {
      name: 'modelRef'
    }
  ],

  methods: {
    init: function() {
      // set up context // TODO: template is compile before we create subcontext
      this.X = this.X.sub({name:'ModelDescriptionRowView_X'});
      this.X.documentationViewParentModel = SimpleValue.create();

      this.SUPER();
    }
  },
  templates: [ // TODO: the data gets set on the modelNameView... screws it up
    function toInnerHTML() {/*

$$modelName{model_:'DocRefView', ref$: this.modelRef$, text$: this.modelName$}

    */}
  ]
});

MODEL({
  name: 'ControllerView',
  extendsModel: 'DetailView',

  methods: {
    initHTML: function() {
      this.data.searchView.initHTML();
      this.data.filteredDAOView.initHTML();
    }
  },

  templates: [
    function toHTML() {/*

<%=this.data.searchView.toHTML()%>

<%=this.data.filteredDAOView.toHTML()%>

    */}
  ]
});

MODEL({
  name: 'DocBrowserController',

  documentation: function() {  /*

Some documentation for the $$DOC{ref:'.'} model.

This should be expaneded to explain some of the interesting properties found here, such as $$DOC{ref:'.modelList'}.

We can also mention how invalid references are caught $$DOC{ref:'modelList'}.

And here's a normal property view in the same template: $$data{ mode: 'read-only' }

Though you'd often want to link to related models, like $$DOC{ref:'DocModelBodyView'}, or even specific features on them, like $$DOC{ref:'DocModelView.data', text:'DocModelView's data property'}.

Reference to a method argument: $$DOC{ref:'DocBrowserController.testMethod.args.testy'}

This won't work since 'properties' here will resolve to the DocBrowserController.PROPERTIES feature: $$DOC{ref:'DocBrowserController.properties.modelListView'}. Only use direct access for layers below Model.feature.

Linking to a $$DOC{ref:'Model'} property value of a $$DOC{ref:'Model'} (rather than a feature): $$DOC{ref:'DocBrowserController'}

  */},

  models: [
    {
      model_: 'Model',
      name: 'NamedInnerModel',
      documentation: function() { /* Docs for named inner model. $$DOC{ref:"."} */ },
      models: [
        {
          model_: 'Model',
          name: 'InnyInner',
          documentation: function() { /* Inny Inner! $$DOC{ref:"."} */ },
        }
      ]

    },
//    {
//      model_: 'Model',

//    }
  ],

  methods: {
    init: function() {
      /* This is a method documentation comment: spawn and populate sub contexts. */

      // load developer guides
      RegisterDevDocs(this.X);

      // search context uses a selection value to indicate the chosen Model to display
      this.SearchContext = this.X.sub({}, 'searchX');
      this.SearchContext.selection$ = this.SearchContext.SimpleValue.create(); // holds a Model definition

      // detail context needs a documentViewRef.get().resolvedRoot to indicate what model it is rooted at
      this.DetailContext = this.X.sub({}, 'detailX');
      this.DetailContext.documentViewRef = this.DetailContext.SimpleValue.create();// this.DetailContext.DocRef.create();

      this.X.documentViewRequestNavigation = this.requestNavigation.bind(this);

      /////////////////////////// Context setup ^
      this.SUPER();
      /////////////////////////// this.init v

      // when the hash changes set the documentViewRef and this.selection
      window.addEventListener('hashchange', this.setReferenceFromHash.bind(this));

      // initialization from hash
      this.setReferenceFromHash();

      var testArg = this.X.Arg.create({name: 'testy'});
      testArg.documentation = this.X.Documentation.create({
        body: function() { /*
          Argument $$DOC{ref:'.'} documentation.
          */ }
      });
      this.model_.methods[1].args.push(testArg);
    },

    testMethod: function(a1, b2) {
      return a1 + b2;
    },

    setReferenceFromHash: function() {
      if (location.hash === '#' || location.hash === '#undefined' || location.hash.length === 0) {
        location.hash = 'developerDocs.Welcome';
        return;
      }
      // don't respond if we are already at the location desired
      if (location.hash.substring(1) === this.DetailContext.documentViewRef.get().ref) return;

      var newRef = this.DetailContext.DocRef.create({ref:location.hash.substring(1)});
      if (newRef.valid) {
        this.DetailContext.documentViewRef.set(newRef);
        this.SearchContext.selection$.set(newRef.resolvedRoot.resolvedModelChain[0]); // selection wants a Model object

      }
    },

    requestNavigation: function(ref) {
      if (ref.valid) {
        this.selection = ref.resolvedModelChain[0];
        this.DetailContext.documentViewRef.set(ref);
        this.SearchContext.selection$.set(ref.resolvedRoot.resolvedModelChain[0]); // selection wants a Model object
        location.hash = "#" + ref.resolvedRef;
      }
    }

  },

  listeners: [
    {
      name: 'onReadyToScroll',
      code: function(evt) {

      }
    }
  ],

  properties: [
    {
      name: 'modelList',
      factory: function() {
        return this.SearchContext.ModelListController.create();
      }
    },
    {
      name: 'modelListView',
      factory: function() {
        return this.SearchContext.ControllerView.create({ model: ModelListController,
                                                          data$: this.modelList$ });
      }
    },
    {
      name: 'selectionView',
      factory: function() {
        return this.DetailContext.DocModelView.create({ model: Model, data$: this.DetailContext.documentViewRef });
      }
    },
  ]

});

MODEL({
  name: 'DocBrowserView',
  extendsModel: 'DetailView',

  methods: {
   initHTML: function() {
     this.data.modelListView.initHTML();
     this.data.selectionView.initHTML();
   }
  },

  templates: [
    function CSS() {/*
      body {
        margin: 0px;
        font-family: 'Roboto', sans-serif;
        font-size: inherit;

        background-color: #e0e0e0;
        position: relative;

      }

      .outermost {
        width: 100%;
        height: 100%;
        display: flex;
        flex-direction: column;
      }

      .docbrowser-header {
        height: 90px;
        position: relative;
        color: #fff;
        z-index: 1;
        flex-shrink: 0;
      }

      .docbrowser-header-inner {
        background-color: #5555FF;
        position: absolute;
        height: 120px;
        width: 100%;
        flex-shrink: 0;
      }

      .docbrowser-header-flex-container {
        display: flex;
        flex-shrink: 0;
        justify-content: space-around;
        margin: 0 50px;
      }
      .docbrowser-header-contents {
        flex-grow: 1;
        flex-shrink: 0;
        max-width: 1280px;

        display: flex;
        justify-content: space-between;
      }

      .docbrowser-title {
        font-weight: lighter;
        font-size: 250%;
        margin-top: 20px;
      }
      .docbrowser-tabs {
        font-size: 120%;
        font-weight: lighter;
        margin-top: 40px;
        margin-right: 20px;
      }
      .docbrowser-tab {
        margin-left: 50px;
      }
      .docbrowser-tab.enabled {
        font-weight: normal;
      }

      .outer-container {
        margin: 0 30px;
        z-index: 2;
        position: relative;
        display:flex;
        flex-direction: column;

        flex-shrink: 1;
        flex-basis: 10000px;
      }
      .outer-flex-container {
        display: flex;
        flex-direction: column;
        justify-content: space-around;
        margin-bottom: 60px;
        width: 100%;
        flex-grow: 1;
 //       height: 83%;
      }
      .inner-container {
        background-color: #fff;
        border: 1px solid #888;
        border-radius: 12px;
        flex-grow: 1000;
        flex-shrink: 1;
        flex-basis: 1px;
        max-width: 1280px;
        padding: 15px;
        box-shadow: 0px 5px 5px #888888;
        display:flex;
      }

      input {
        font-family: inherit;
        font-size: inherit;
      }

      p {
        padding-bottom: 0.5em;
      }
      li {
        padding-bottom: 0.5em;
      }

      div.listPane {
        min-width: 200px;
        flex-basis: 200px;
        order: 1;
        padding: 1em;
        flex-grow: 0;
        overflow-x: hidden;

        display: flex;
        flex-direction: column;
      }

      div.detailPane {
        order: 2;
        flex-grow: 10;
        overflow-y: scroll;
        padding: 1em;
      }

      div.detailPane div.chapters h2 {
        font-size: 110%;
      }

      div.search-field-container {
        flex-grow: 0;
        flex-shrink: 0;
        order: 1;
        padding: 0;
        margin-left: -15;
      }

      div.list-container {
        order: 2;
        flex-grow: 1;
        overflow-y:scroll;
        overflow-x:hidden;
      }
      div.list-container span.docLink {
        border-bottom: none;
      }

      div.members {
        margin-top: 1em;
        padding-left: 2em;
      }
      div.memberList {
        padding-left: 2em;
      }

      div.chapters div.memberList {
        padding-left: 0;
      }

      div.inherited {
        color: #333333;
      }

      p.browse-list-entry {
        font-size:100%;
        font-weight: bold;
        line-height: 150%
      }

      span.docLink {
        cursor: pointer;
        color: #000077;
        border-bottom: 0.1em dotted #999;
      }

      span.docLinkNoDocumentation {
        color: #770000;

      }

      div.model-info-block {
        padding: 1em;
        margin: 1em 0 1em 0;
        border-top: 0.1em solid black;
        border-bottom: 0.1em solid black;
      }
      div.model-info-block p.note {
        font-size:105%;
      }
      div.model-info-block p.important {
        font-size:105%;
        font-weight:bold;
      }

      .feature-row {
        //border-top: 0.1em solid grey;
        margin-top: 1em;
        margin-bottom: 1em;
      }

      p.inheritance-info {
        font-size: 90%;
        padding-left: 1em;
      }

      .feature-type-heading {
        font-weight: bold;
        font-size: 150%;
      }
      .feature-heading {
        font-weight: bold;
        font-size: 125%;
      }
      .feature-sub-heading {
        font-weight: bold;
        font-size: 100%;
      }
      .feature-type {
        float:right;
      }

      .light {
        color: #444;
      }
    */},
    function toHTML() {/*
      <div class="outermost" id="<%= this.id %>">

        <div id="<%= this.id %>-outer-container" class="outer-container">

            <div id="<%= this.id %>-inner-container" class="inner-container">

<%=this.data.modelListView.toHTML()%>

<%=this.data.selectionView.toHTML()%>

    */}
  ]

});

<|endoftext|>


<commit_before>app = ap || {};

app.User = Backbone.Model.extend({
})<commit_msg>Add potential defaults to user model -these aren't meant to sync up with db, but be representative of a user's relation to the current page<commit_after>app = ap || {};

app.User = Backbone.Model.extend({

  defaults: {
    user_id: null,
    voteData = null,
    questionOwner = null
  },

  initialize: function(){

  },

})<|endoftext|>


<commit_before>/*
 * Share Snippet plugin:

<Plugin id="ShareSnippet" width="1" height="1"
path="/content/uiconf/ps/cornell/kdp_3.5.32/plugins/ShareSnippetPlugin4.swf"
visible="false" includeInLayout="false"
landingPagePrefix="http://www.cornell.edu/video/?videoID="
generatorEmbedPrefix="http://www.cornell.edu/video/embed.js?videoID="
uuidType="customField" uuidFieldName="CCVideoID"
customSnippetBefore="%3Cscript%20src%3D'"
customSnippetAfter="' type%3D'text%2Fjavascript'%3E%3C%2Fscript%3E%3Cnoscript%3EEmbedded%20video%20from%20%3Ca%20href%3D'http%3A%2F%2Fwww.cornell.edu%2Fvideo'%3ECornell%20University%3C%2Fa%3E%3C%2Fnoscript%3E" />

*
* Share Button:
*

<Button id="shareBtnEndScreen"
kClick="sendNotification('showShareSnippets')"
buttonType="onScreenButton" minWidth="60"
labelPlacement="top" label="Share"
styleName="onScreenBtn" upIcon="shareIcon"
k_buttonType="buttonIconControllerArea" color1="14540253"
color2="16777215" color3="3355443" color4="0x58A1E0"
color5="16777215" font="Arial" />

*
*/

( function( mw, $ ) {
	// Bind to new player event
	$( mw ).bind( 'newEmbedPlayerEvent', function( event, embedPlayer ){
		$( embedPlayer ).bind( 'KalturaSupport_CheckUiConf', function( event, $uiConf, callback ){

			// Check if plugin exists
			if( embedPlayer.getKalturaConfig( 'ShareSnippet', 'plugin' ) ) {
				window['shareSnippet'].init( embedPlayer );
			}

			// Continue player build-out
			callback();
		});
	});

	// Share snippet
	window['shareSnippet'] = {

		init: function( embedPlayer ) {
			this.embedPlayer = embedPlayer;
			this.setupConfig();
			this.addPlayerBindings();
			this.addShareButton();
		},

		setupConfig: function() {

			var shareConfig = [
				'landingPagePrefix',
				'uuidType',
				'uuidFieldName',
				'generatorEmbedPrefix',
				'customSnippetBefore',
				'customSnippetAfter'
			];

			this.config = this.embedPlayer.getKalturaConfig('ShareSnippet', shareConfig);
		},

		addPlayerBindings: function() {
			var _this = this;
			$( this.embedPlayer ).unbind('showShareSnippets').bind('showShareSnippets', function() {
				_this.drawModal();
			});
		},

		addShareButton: function() {
			var _this = this;
			var embedPlayer = this.embedPlayer;
			var shareButtonClick = embedPlayer.getKalturaConfig('shareBtnControllerScreen', 'kClick');
			// TODO: We should have better support for kClick attribute [ sendNotification('showShareSnippets') ]
			if( shareButtonClick.indexOf('showShareSnippets') ) {

				mw.log('shareSnippet :: add share button');
				$( embedPlayer ).bind( 'addControlBarComponent', function(event, controlBar ){

					var $shareButton = {
						'w': 28,
						'o': function( ctrlObj ) {

							var $textButton = $( '<div />' )
								.attr( 'title', gM( 'mwe-embedplayer-share' ) )
								.addClass( "ui-state-default ui-corner-all ui-icon_link rButton" )
								.append( $( '<span />' ).addClass( "ui-icon ui-icon-link" ) )
								.buttonHover()
								.click(function() {
									$( embedPlayer ).trigger('showShareSnippets');
								});

							return $textButton;
						}
					};

					// Add the button to control bar
					controlBar.supportedComponents['shareLink'] = true;
					controlBar.components['shareLink'] = $shareButton;

				});

			}
		},

		getUniqueId: function() {
			if( this.config['uuidType'] == 'entryId' ) {
				return this.embedPlayer.evaluate('{mediaProxy.entry.id}');
			} else {
				return this.embedPlayer.evaluate('{mediaProxy.entryMetadata.' + this.config['uuidFieldName'] + '}');
			}
		},

		drawModal: function() {

			var embedPlayer = this.embedPlayer,
				config = this.config,
				showError = false,
				videoId = this.getUniqueId(),
				shareUrl,
				generatorPageUrl,
				customSnippet;

			// Generate Share URL
			if( config['landingPagePrefix'] ) {
				// Custom share URL
				shareUrl = config['landingPagePrefix'] + videoId;
			} else {
				// Default KMC preview page
				var partnerId = embedPlayer.kwidgetid.substr(1,embedPlayer.kwidgetid.length);
				shareUrl = mw.getConfig('Kaltura.ServiceUrl') + '/index.php/kmc/preview/';
				shareUrl += 'partner_id/' + partnerId + '/entry_id/' + embedPlayer.kentryid + '/uiconf_id/' + embedPlayer.kuiconfid;
			}

			// Genrate Embed Code
			if( config['generatorEmbedPrefix'] ) {
				generatorPageUrl = config['generatorEmbedPrefix'] + videoId;
			} else {
				showError = true;
				generatorPageUrl = "Plugin is not configured correctly. Generator page prefix is not set";
			}

			if( showError ) {
				customSnippet = generatorPageUrl;
			} else {
				customSnippet = unescape(config['customSnippetBefore']) + generatorPageUrl + unescape(config['customSnippetAfter']);
			}

			var $title = $('<h2 />').text('Share');
			var $shareLink = $('<div />').append(
				$('<span />').text('Email or IM this to your friends:'),
				$('<textarea />')
				.css({'width': '95%', 'height': '15px'})
				.text(shareUrl)
				.click( function() {
					this.select();
				})
			);
			var $shareCode = $('<div />').append(
				$('<span />').text('Copy this code to your website or blog:'),
				$('<textarea />')
				.css({'width': '95%', 'height': '30px'})
				.text(customSnippet)
			).css({'margin-top': '20px', 'clear': 'both'});

			var $selectLinkButton = false;
			var $selectCodeButton = false;
			if( ! mw.isIpad() ) {
				// Share Link Button
				$selectLinkButton = $('<button />')
				.addClass( 'ui-state-default ui-corner-all copycode' )
				.text( gM( 'mwe-embedplayer-copy-code' ) )
				.click(function() {
					$shareLink.find( 'textarea' ).focus().select();
					// Copy the text if supported:
					if ( document.selection ) {
						CopiedTxt = document.selection.createRange();
						CopiedTxt.execCommand( "Copy" );
					}
				} );

				$shareLink.append( $selectLinkButton );

				// Share Code Button
				$selectCodeButton = $('<button />')
				.addClass( 'ui-state-default ui-corner-all copycode' )
				.text( gM( 'mwe-embedplayer-copy-code' ) )
				.click(function() {
					$shareCode.find( 'textarea' ).focus().select();
					// Copy the text if supported:
					if ( document.selection ) {
						CopiedTxt = document.selection.createRange();
						CopiedTxt.execCommand( "Copy" );
					}
				} );

				$shareCode.append( $selectCodeButton );
			}

			var $shareScreen = $('<div />').append(
				$title, $shareLink, $shareCode
			);

			embedPlayer.controlBuilder.displayMenuOverlay( $shareScreen );
		}
	};

})( window.mw, window.jQuery );<commit_msg>Used isPluginEnabled instead of getKalturaConfig<commit_after>/*
 * Share Snippet plugin:

<Plugin id="ShareSnippet" width="1" height="1"
path="/content/uiconf/ps/cornell/kdp_3.5.32/plugins/ShareSnippetPlugin4.swf"
visible="false" includeInLayout="false"
landingPagePrefix="http://www.cornell.edu/video/?videoID="
generatorEmbedPrefix="http://www.cornell.edu/video/embed.js?videoID="
uuidType="customField" uuidFieldName="CCVideoID"
customSnippetBefore="%3Cscript%20src%3D'"
customSnippetAfter="' type%3D'text%2Fjavascript'%3E%3C%2Fscript%3E%3Cnoscript%3EEmbedded%20video%20from%20%3Ca%20href%3D'http%3A%2F%2Fwww.cornell.edu%2Fvideo'%3ECornell%20University%3C%2Fa%3E%3C%2Fnoscript%3E" />

*
* Share Button:
*

<Button id="shareBtnEndScreen"
kClick="sendNotification('showShareSnippets')"
buttonType="onScreenButton" minWidth="60"
labelPlacement="top" label="Share"
styleName="onScreenBtn" upIcon="shareIcon"
k_buttonType="buttonIconControllerArea" color1="14540253"
color2="16777215" color3="3355443" color4="0x58A1E0"
color5="16777215" font="Arial" />

*
*/

( function( mw, $ ) {
	// Bind to new player event
	$( mw ).bind( 'newEmbedPlayerEvent', function( event, embedPlayer ){
		$( embedPlayer ).bind( 'KalturaSupport_CheckUiConf', function( event, $uiConf, callback ){

			// Check if plugin exists
			if( embedPlayer.isPluginEnabled( 'ShareSnippet' ) ) {
				window['shareSnippet'].init( embedPlayer );
			}

			// Continue player build-out
			callback();
		});
	});

	// Share snippet
	window['shareSnippet'] = {

		init: function( embedPlayer ) {
			this.embedPlayer = embedPlayer;
			this.setupConfig();
			this.addPlayerBindings();
			this.addShareButton();
		},

		setupConfig: function() {

			var shareConfig = [
				'landingPagePrefix',
				'uuidType',
				'uuidFieldName',
				'generatorEmbedPrefix',
				'customSnippetBefore',
				'customSnippetAfter'
			];

			this.config = this.embedPlayer.getKalturaConfig('ShareSnippet', shareConfig);
		},

		addPlayerBindings: function() {
			var _this = this;
			$( this.embedPlayer ).unbind('showShareSnippets').bind('showShareSnippets', function() {
				_this.drawModal();
			});
		},

		addShareButton: function() {
			var _this = this;
			var embedPlayer = this.embedPlayer;
			var shareButtonClick = embedPlayer.getKalturaConfig('shareBtnControllerScreen', 'kClick');
			// TODO: We should have better support for kClick attribute [ sendNotification('showShareSnippets') ]
			if( shareButtonClick.indexOf('showShareSnippets') ) {

				mw.log('shareSnippet :: add share button');
				$( embedPlayer ).bind( 'addControlBarComponent', function(event, controlBar ){

					var $shareButton = {
						'w': 28,
						'o': function( ctrlObj ) {

							var $textButton = $( '<div />' )
								.attr( 'title', gM( 'mwe-embedplayer-share' ) )
								.addClass( "ui-state-default ui-corner-all ui-icon_link rButton" )
								.append( $( '<span />' ).addClass( "ui-icon ui-icon-link" ) )
								.buttonHover()
								.click(function() {
									$( embedPlayer ).trigger('showShareSnippets');
								});

							return $textButton;
						}
					};

					// Add the button to control bar
					controlBar.supportedComponents['shareLink'] = true;
					controlBar.components['shareLink'] = $shareButton;

				});

			}
		},

		getUniqueId: function() {
			if( this.config['uuidType'] == 'entryId' ) {
				return this.embedPlayer.evaluate('{mediaProxy.entry.id}');
			} else {
				return this.embedPlayer.evaluate('{mediaProxy.entryMetadata.' + this.config['uuidFieldName'] + '}');
			}
		},

		drawModal: function() {

			var embedPlayer = this.embedPlayer,
				config = this.config,
				showError = false,
				videoId = this.getUniqueId(),
				shareUrl,
				generatorPageUrl,
				customSnippet;

			// Generate Share URL
			if( config['landingPagePrefix'] ) {
				// Custom share URL
				shareUrl = config['landingPagePrefix'] + videoId;
			} else {
				// Default KMC preview page
				var partnerId = embedPlayer.kwidgetid.substr(1,embedPlayer.kwidgetid.length);
				shareUrl = mw.getConfig('Kaltura.ServiceUrl') + '/index.php/kmc/preview/';
				shareUrl += 'partner_id/' + partnerId + '/entry_id/' + embedPlayer.kentryid + '/uiconf_id/' + embedPlayer.kuiconfid;
			}

			// Genrate Embed Code
			if( config['generatorEmbedPrefix'] ) {
				generatorPageUrl = config['generatorEmbedPrefix'] + videoId;
			} else {
				showError = true;
				generatorPageUrl = "Plugin is not configured correctly. Generator page prefix is not set";
			}

			if( showError ) {
				customSnippet = generatorPageUrl;
			} else {
				customSnippet = unescape(config['customSnippetBefore']) + generatorPageUrl + unescape(config['customSnippetAfter']);
			}

			var $title = $('<h2 />').text('Share');
			var $shareLink = $('<div />').append(
				$('<span />').text('Email or IM this to your friends:'),
				$('<textarea />')
				.css({'width': '95%', 'height': '15px'})
				.text(shareUrl)
				.click( function() {
					this.select();
				})
			);
			var $shareCode = $('<div />').append(
				$('<span />').text('Copy this code to your website or blog:'),
				$('<textarea />')
				.css({'width': '95%', 'height': '30px'})
				.text(customSnippet)
			).css({'margin-top': '20px', 'clear': 'both'});

			var $selectLinkButton = false;
			var $selectCodeButton = false;
			if( ! mw.isIpad() ) {
				// Share Link Button
				$selectLinkButton = $('<button />')
				.addClass( 'ui-state-default ui-corner-all copycode' )
				.text( gM( 'mwe-embedplayer-copy-code' ) )
				.click(function() {
					$shareLink.find( 'textarea' ).focus().select();
					// Copy the text if supported:
					if ( document.selection ) {
						CopiedTxt = document.selection.createRange();
						CopiedTxt.execCommand( "Copy" );
					}
				} );

				$shareLink.append( $selectLinkButton );

				// Share Code Button
				$selectCodeButton = $('<button />')
				.addClass( 'ui-state-default ui-corner-all copycode' )
				.text( gM( 'mwe-embedplayer-copy-code' ) )
				.click(function() {
					$shareCode.find( 'textarea' ).focus().select();
					// Copy the text if supported:
					if ( document.selection ) {
						CopiedTxt = document.selection.createRange();
						CopiedTxt.execCommand( "Copy" );
					}
				} );

				$shareCode.append( $selectCodeButton );
			}

			var $shareScreen = $('<div />').append(
				$title, $shareLink, $shareCode
			);

			embedPlayer.controlBuilder.displayMenuOverlay( $shareScreen );
		}
	};

})( window.mw, window.jQuery );<|endoftext|>


<commit_before>(function() {
    'use strict';

    var gulp        = require('gulp'),
        mocha       = require('gulp-mocha');

    gulp.task('test', function() {
       gulp.src('test/test.js')
           .pipe(mocha({reporter: 'min'}))
           .on('error', onError);
    });

    function onError(params) {
        console.log(params.message);
    }
})();
<commit_msg>chore(gulpfile) onError: params -> error<commit_after>(function() {
    'use strict';

    var gulp        = require('gulp'),
        mocha       = require('gulp-mocha');

    gulp.task('test', function() {
       gulp.src('test/test.js')
           .pipe(mocha({reporter: 'min'}))
           .on('error', onError);
    });

    function onError(error) {
        console.log(error.message);
    }
})();
<|endoftext|>


<commit_before>(function() {
	"use strict";

	var Router = function() {
		this.regExpRelativeUrl = /^\/[^\/]?/;

		this.routes = {};

		// onRouteChange is called when the route changes.
		this.onRouteChange = function() {};

		window.addEventListener("click", this.onWindowClick.bind(this));
		window.addEventListener("popstate", this.onHistoryPopState);
	};

	// dispatchRequest dispatches an internal request to load the page specified
	// by relativeUrl. If no route is registered to handle relativeUrl, nothing
	// will happen.
	Router.prototype.dispatchRequest = function(relativeUrl) {
		for (var route in this.routes) {
			if (!this.routes.hasOwnProperty(route)) {
				continue;
			}

			var finalRoute = "^" + route + "$";
			var routeRegExp = new RegExp(finalRoute);
			var match = routeRegExp.exec(relativeUrl);

			if (match === null) {
				continue;
			}

			if (typeof(this.onRouteChange) === "function") {
				this.onRouteChange();
			}

			var params = [];

			if (match.length > 1) {
				params = match.slice(1);
			}

			this.routes[route](params);
			return;
		}
	};

	Router.prototype.onHistoryPopState = function(event) {
		// console.debug("popstate", event);
	};

	// onWindowClick triggers a new page request if the user clicked on a link
	// with a relative URL, e.g. “/settings”. If the link’s “target” attribute
	// is set to a non-empty string, no “href” attribute exists or the URL is
	// absolute, Router lets the browser handle the click.
	Router.prototype.onWindowClick = function(event) {
		if (event.target.tagName === "A") {
			var element = event.target;

			// If link opens in new tab or window
			if (element.hasAttribute("target") && element.getAttribute("target") !== "") {
				return;
			}

			// If link doesn’t have a URL
			var url = element.getAttribute("href");
			if (!url) {
				return;
			}

			// If URL is not relative
			if (!this.regExpRelativeUrl.test(url)) {
				return;
			}

			event.preventDefault();
			event.stopPropagation();

			this.dispatchRequest(url);
			window.history.pushState(null, "", url);
		}
	};

	// registerRoute registers a route and its handleFunc.
	Router.prototype.registerRoute = function(route, handleFunc) {
		this.routes[route] = handleFunc;
	};

	sprinkles.Router = Router;
})();
<commit_msg>Going back in browser history, e.g. by using browser back button, works now.<commit_after>(function() {
	"use strict";

	var Router = function() {
		this.regExpRelativeUrl = /^\/[^\/]?/;

		// dispatchedFirstRequest indicates whether the Router dispatched its
		// first request. It is used to prevent Safari from triggering the
		// popstate event on page load.
		this.dispatchedFirstRequest = false;

		this.routes = {};

		// onRouteChange is called when the route changes.
		this.onRouteChange = function() {};

		window.addEventListener("click", this.onWindowClick.bind(this));
		window.addEventListener("popstate", this.onHistoryPopState.bind(this));
	};

	// dispatchRequest dispatches an internal request to load the page specified
	// by relativeUrl. If no route is registered to handle relativeUrl, nothing
	// will happen.
	Router.prototype.dispatchRequest = function(relativeUrl) {
		for (var route in this.routes) {
			if (!this.routes.hasOwnProperty(route)) {
				continue;
			}

			var finalRoute = "^" + route + "$";
			var routeRegExp = new RegExp(finalRoute);
			var match = routeRegExp.exec(relativeUrl);

			if (match === null) {
				continue;
			}

			if (typeof(this.onRouteChange) === "function") {
				this.onRouteChange();
			}

			var params = [];

			if (match.length > 1) {
				params = match.slice(1);
			}

			this.routes[route](params);
			return;
		}

		this.dispatchedFirstRequest = true;
	};

	Router.prototype.onHistoryPopState = function(event) {
		// Prevent Safari from triggering popstate event on page load
		if (!this.dispatchedFirstRequest) {
			return;
		}

		this.dispatchRequest(location.pathname);
	};

	// onWindowClick triggers a new page request if the user clicked on a link
	// with a relative URL, e.g. “/settings”. If the link’s “target” attribute
	// is set to a non-empty string, no “href” attribute exists or the URL is
	// absolute, Router lets the browser handle the click.
	Router.prototype.onWindowClick = function(event) {
		if (event.target.tagName === "A") {
			var element = event.target;

			// If link opens in new tab or window
			if (element.hasAttribute("target") && element.getAttribute("target") !== "") {
				return;
			}

			// If link doesn’t have a URL
			var url = element.getAttribute("href");
			if (!url) {
				return;
			}

			// If URL is not relative
			if (!this.regExpRelativeUrl.test(url)) {
				return;
			}

			event.preventDefault();
			event.stopPropagation();

			this.dispatchRequest(url);
			window.history.pushState(null, "", url);
		}
	};

	// registerRoute registers a route and its handleFunc.
	Router.prototype.registerRoute = function(route, handleFunc) {
		this.routes[route] = handleFunc;
	};

	sprinkles.Router = Router;
})();
<|endoftext|>


<commit_before>import React from 'react';

export default class MouseMoveActionLayer extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isAction: false,
      startPoint: {x: 0, y: 0},
    };
    this.canvas = null;
    this.ctx = null;
    this.canvasStartPosition = null;
  }
  componentDidMount() {
    this.ctx = this.canvas.getContext('2d');
    const {x, y} = this.canvas.getBoundingClientRect();
    this.canvasStartPosition = {x, y};
    this.props.callbackDidMount({
      canvas: this.canvas,
      ctx: this.ctx,
    });
  }
  setStartPoint(mouseEventPageX, mouseEventPageY) {
    this.setState({
      startPoint: {
        x: mouseEventPageX - this.canvasStartPosition.x,
        y: mouseEventPageY - this.canvasStartPosition.y,
      },
    });
  }
  getCurrentPoint(mouseEventPageX, mouseEventPageY) {
    const {canvasStartPosition} = this;
    return {
      x: mouseEventPageX - canvasStartPosition.x,
      y: mouseEventPageY - canvasStartPosition.y,
    };
  }
  startAction() {
    this.setState({isAction: true});
  }
  stopAction() {
    this.setState({isAction: false});
  }
  switchCurrentPointToStartPoint(currentPoint) {
    this.setState({
      startPoint: currentPoint,
    });
  }
  render() {
    const {width, height} = this.props.imageData;
    return (
      <canvas
        className="action-layer"
        width={width}
        height={height}
        ref={ref => {
          this.canvas = ref;
        }}
        onMouseDown={e => {
          this.startAction();
          this.setStartPoint(e.pageX, e.pageY);
        }}
        onMouseMove={e => {
          if (!this.state.isAction) return;
          const currentPoint = this.getCurrentPoint(e.pageX, e.pageY);
          this.props.executeAction({
            canvas: this.canvas,
            ctx: this.ctx,
            startPoint: this.state.startPoint,
            currentPoint,
          });
          this.switchCurrentPointToStartPoint(currentPoint);
        }}
        onMouseUp={() => {
          this.stopAction();
        }}
        onMouseLeave={() => {
          this.stopAction();
        }}
      />
    );
  }
}
<commit_msg>add Flow MouseMoveActionLayer.js<commit_after>// @flow
import React from 'react';

type Point = {x: number, y: number};

type Props = {
  callbackDidMount: ({ctx: CanvasRenderingContext2D}) => void,
  executeAction: ({
    canvas: HTMLCanvasElement,
    ctx: CanvasRenderingContext2D,
    startPoint: Point,
    currentPoint: Point,
  }) => void,
  imageData: ImageData,
};

type State = {
  isAction: boolean,
  startPoint: Point,
};

export default class MouseMoveActionLayer extends React.Component<
  Props,
  State
> {
  constructor(props: Props) {
    super(props);
    this.state = {
      isAction: false,
      startPoint: {x: 0, y: 0},
    };
    this.canvas = null;
    this.ctx = null;
    this.canvasStartPosition = null;
  }
  componentDidMount() {
    const {canvas} = this;
    if (!canvas) throw new Error('canvas is null.');
    this.ctx = canvas.getContext('2d');
    const {x, y} = ((canvas.getBoundingClientRect(): any): DOMRect);
    this.canvasStartPosition = {x, y};
    if (!this.ctx) throw new Error('this.ctx is null.');
    this.props.callbackDidMount({
      canvas,
      ctx: this.ctx,
    });
  }
  setStartPoint(mouseEventPageX: number, mouseEventPageY: number) {
    const {canvasStartPosition} = this;
    if (!canvasStartPosition) throw new Error('canvasStartPosition is null.');
    this.setState({
      startPoint: {
        x: mouseEventPageX - canvasStartPosition.x,
        y: mouseEventPageY - canvasStartPosition.y,
      },
    });
  }
  getCurrentPoint(mouseEventPageX: number, mouseEventPageY: number): Point {
    const {canvasStartPosition} = this;
    if (!canvasStartPosition) throw new Error('canvasStartPosition is null.');
    return {
      x: mouseEventPageX - canvasStartPosition.x,
      y: mouseEventPageY - canvasStartPosition.y,
    };
  }

  canvas: HTMLCanvasElement | null;
  ctx: CanvasRenderingContext2D | null;
  canvasStartPosition: Point | null;

  startAction() {
    this.setState({isAction: true});
  }
  stopAction() {
    this.setState({isAction: false});
  }
  switchCurrentPointToStartPoint(currentPoint: Point) {
    this.setState({
      startPoint: currentPoint,
    });
  }
  render() {
    const {width, height} = this.props.imageData;
    return (
      <canvas
        className="action-layer"
        width={width}
        height={height}
        ref={ref => {
          this.canvas = ref;
        }}
        onMouseDown={e => {
          this.startAction();
          this.setStartPoint(e.pageX, e.pageY);
        }}
        onMouseMove={e => {
          if (!this.state.isAction) return;
          const currentPoint = this.getCurrentPoint(e.pageX, e.pageY);
          if (!this.canvas) throw new Error('this.canvas is null.');
          if (!this.ctx) throw new Error('this.ctx is null.');
          this.props.executeAction({
            canvas: this.canvas,
            ctx: this.ctx,
            startPoint: this.state.startPoint,
            currentPoint,
          });
          this.switchCurrentPointToStartPoint(currentPoint);
        }}
        onMouseUp={() => {
          this.stopAction();
        }}
        onMouseLeave={() => {
          this.stopAction();
        }}
      />
    );
  }
}
<|endoftext|>


<commit_before>
<commit_msg>Delete empty<commit_after><|endoftext|>


<commit_before>define([ 'dojo/_base/declare',
         'dojo/_base/array',
         'JBrowse/View/Export'
       ],
       function( declare, array, ExportBase ) {

return declare( ExportBase,
 /**
  * @lends JBrowse.View.Export.GFF3.prototype
  */
{

    /**
     * Data export driver for GFF3 format.
     * @constructs
     */
    constructor: function( args ) {
        this._idCounter = 0;

        this.print( "##gff-version 3\n");
        if( this.refSeq )
            this.print("##sequence-region "+this.refSeq.name+" "+(this.refSeq.start+1)+" "+this.refSeq.end+"\n");
    },

    gff3_field_names: [
        'seq_id',
        'source',
        'type',
        'start',
        'end',
        'score',
        'strand',
        'phase',
        'attributes'
    ],

    gff3_reserved_attributes: [
        'ID',
        'Name',
        'Alias',
        'Parent',
        'Target',
        'Gap',
        'Derives_from',
        'Note',
        'Dbxref',
        'Ontology_term',
        'Is_circular'
    ],

    /**
     * @returns false if the field goes in tabular portion of gff3, true otherwise
     * @private
     */
    _is_not_gff3_tab_field: function( fieldname ) {
        if( ! this._gff3_fields_by_name ) {
            var fields = {};
            dojo.forEach( this.gff3_field_names, function(f) {
                              fields[f] = true;
                          });
            this._gff3_fields_by_name = fields;
        }

        return ! this._gff3_fields_by_name[ fieldname.toLowerCase() ];
    },

    /**
     * @returns the capitalized attribute name if the given field name
     * corresponds to a GFF3 reserved attribute
     * @private
     */
    _gff3_reserved_attribute: function( fieldname ) {
        if( ! this._gff3_reserved_attributes_by_lcname ) {
            var fields = {};
            dojo.forEach( this.gff3_reserved_attributes, function(f) {
                              fields[f.toLowerCase()] = f;
                          });
            this._gff3_reserved_attributes_by_lcname = fields;
        }

        return this._gff3_reserved_attributes_by_lcname[ fieldname.toLowerCase() ];
    },

    /**
     * Format a feature into a string.
     * @param {Object} feature feature object (like those returned from JBrowse/Store/SeqFeature/*)
     * @returns {String} GFF3 string representation of the feature
     */
    formatFeature: function( feature, parentID ) {
        var fields = dojo.map(
                [ feature.get('seq_id') || this.refSeq.name ]
                .concat( dojo.map( this.gff3_field_names.slice(1,7), function(field) {
                                       return feature.get( field );
                                   },this)
                       ),
            function( data ) {
                return this._gff3_escape( data || '.' );
            },
            this
        );

        // convert back from interbase
        if( typeof parseInt(fields[3]) == 'number' )
            fields[3]++;
        // normalize the strand field
        fields[6] = { '1': '+', '-1': '-', '0': '.' }[ fields[6] ] || fields[6];

        // format the attributes
        var attr = this._gff3_attributes( feature );
        if( parentID )
            attr.Parent = parentID;

        var subfeatures = array.map(
            feature.get('subfeatures') || [],
            function(feat) {
                if( ! attr.ID ) {
                    attr.ID = ++this._idCounter;
                }
                return this.formatFeature( feat, attr.ID );
            }, this);

        fields[8] = this._gff3_format_attributes( attr );
        return fields.join("\t")+"\n" + subfeatures.join('');
    },

    /**
     * Write the feature to the GFF3 under construction.
     * @returns nothing
     */
    writeFeature: function(feature) {
        this.print( this.formatFeature(feature)+"###\n" );
    },

    /**
     * Extract a key-value object of gff3 attributes from the given
     * feature.  Attribute names will have proper capitalization.
     * @private
     */
    _gff3_attributes: function(feature) {
        var tags = array.filter( feature.tags(), dojo.hitch(this, function(f) {
            f = f.toLowerCase();
            return this._is_not_gff3_tab_field(f) && f != 'subfeatures';
        }));
        var attrs = {};
        array.forEach( tags, function(tag) {
            var val = feature.get(tag);
            if( typeof val != 'string' && typeof val != 'number' )
                return;
            tag = this._gff3_reserved_attribute(tag) || tag.toLowerCase();
            attrs[tag] = val;
        },this);
        return attrs;
    },

    /**
     * @private
     * @returns {String} formatted attribute string
     */
    _gff3_format_attributes: function( attrs ) {
        var attrOrder = [];
        for( var tag in attrs ) {
            attrOrder.push( this._gff3_escape( tag )+'='+this._gff3_escape( attrs[tag] ) );
        }
        return attrOrder.join(';');
    },

    /**
     * @returns always an escaped string representation of the passed value
     * @private
     */
    _gff3_escape: function( val ) {
        return (''+val).replace(/[\n\r\t\;\=%&,\x00-\x1f\x7f-\xff]+/g, escape );
    }
});

});
<commit_msg>in gff3 export, delete Parent attr if we don't actually have the feature's Parent<commit_after>define([ 'dojo/_base/declare',
         'dojo/_base/array',
         'JBrowse/View/Export'
       ],
       function( declare, array, ExportBase ) {

return declare( ExportBase,
 /**
  * @lends JBrowse.View.Export.GFF3.prototype
  */
{

    /**
     * Data export driver for GFF3 format.
     * @constructs
     */
    constructor: function( args ) {
        this._idCounter = 0;

        this.print( "##gff-version 3\n");
        if( this.refSeq )
            this.print("##sequence-region "+this.refSeq.name+" "+(this.refSeq.start+1)+" "+this.refSeq.end+"\n");
    },

    gff3_field_names: [
        'seq_id',
        'source',
        'type',
        'start',
        'end',
        'score',
        'strand',
        'phase',
        'attributes'
    ],

    gff3_reserved_attributes: [
        'ID',
        'Name',
        'Alias',
        'Parent',
        'Target',
        'Gap',
        'Derives_from',
        'Note',
        'Dbxref',
        'Ontology_term',
        'Is_circular'
    ],

    /**
     * @returns false if the field goes in tabular portion of gff3, true otherwise
     * @private
     */
    _is_not_gff3_tab_field: function( fieldname ) {
        if( ! this._gff3_fields_by_name ) {
            var fields = {};
            dojo.forEach( this.gff3_field_names, function(f) {
                              fields[f] = true;
                          });
            this._gff3_fields_by_name = fields;
        }

        return ! this._gff3_fields_by_name[ fieldname.toLowerCase() ];
    },

    /**
     * @returns the capitalized attribute name if the given field name
     * corresponds to a GFF3 reserved attribute
     * @private
     */
    _gff3_reserved_attribute: function( fieldname ) {
        if( ! this._gff3_reserved_attributes_by_lcname ) {
            var fields = {};
            dojo.forEach( this.gff3_reserved_attributes, function(f) {
                              fields[f.toLowerCase()] = f;
                          });
            this._gff3_reserved_attributes_by_lcname = fields;
        }

        return this._gff3_reserved_attributes_by_lcname[ fieldname.toLowerCase() ];
    },

    /**
     * Format a feature into a string.
     * @param {Object} feature feature object (like those returned from JBrowse/Store/SeqFeature/*)
     * @returns {String} GFF3 string representation of the feature
     */
    formatFeature: function( feature, parentID ) {
        var fields = dojo.map(
                [ feature.get('seq_id') || this.refSeq.name ]
                .concat( dojo.map( this.gff3_field_names.slice(1,7), function(field) {
                                       return feature.get( field );
                                   },this)
                       ),
            function( data ) {
                return this._gff3_escape( data || '.' );
            },
            this
        );

        // convert back from interbase
        if( typeof parseInt(fields[3]) == 'number' )
            fields[3]++;
        // normalize the strand field
        fields[6] = { '1': '+', '-1': '-', '0': '.' }[ fields[6] ] || fields[6];

        // format the attributes
        var attr = this._gff3_attributes( feature );
        if( parentID )
            attr.Parent = parentID;
        else
            delete attr.Parent;

        var subfeatures = array.map(
            feature.get('subfeatures') || [],
            function(feat) {
                if( ! attr.ID ) {
                    attr.ID = ++this._idCounter;
                }
                return this.formatFeature( feat, attr.ID );
            }, this);

        fields[8] = this._gff3_format_attributes( attr );
        return fields.join("\t")+"\n" + subfeatures.join('');
    },

    /**
     * Write the feature to the GFF3 under construction.
     * @returns nothing
     */
    writeFeature: function(feature) {
        this.print( this.formatFeature(feature)+"###\n" );
    },

    /**
     * Extract a key-value object of gff3 attributes from the given
     * feature.  Attribute names will have proper capitalization.
     * @private
     */
    _gff3_attributes: function(feature) {
        var tags = array.filter( feature.tags(), dojo.hitch(this, function(f) {
            f = f.toLowerCase();
            return this._is_not_gff3_tab_field(f) && f != 'subfeatures';
        }));
        var attrs = {};
        array.forEach( tags, function(tag) {
            var val = feature.get(tag);
            if( typeof val != 'string' && typeof val != 'number' )
                return;
            tag = this._gff3_reserved_attribute(tag) || tag.toLowerCase();
            attrs[tag] = val;
        },this);
        return attrs;
    },

    /**
     * @private
     * @returns {String} formatted attribute string
     */
    _gff3_format_attributes: function( attrs ) {
        var attrOrder = [];
        for( var tag in attrs ) {
            attrOrder.push( this._gff3_escape( tag )+'='+this._gff3_escape( attrs[tag] ) );
        }
        return attrOrder.join(';');
    },

    /**
     * @returns always an escaped string representation of the passed value
     * @private
     */
    _gff3_escape: function( val ) {
        return (''+val).replace(/[\n\r\t\;\=%&,\x00-\x1f\x7f-\xff]+/g, escape );
    }
});

});
<|endoftext|>