<commit_before>var path = require('path');
var markdown = require('markdown').markdown;
var nunjucks = require('nunjucks');
var util = require('util');

exports.buildEnvironment = function buildEnvironment(options) {
  var themeDir = options.themeDir;
  var staticMiddleware = options.staticMiddleware;
  var paths = [__dirname + '/views'];

  if (themeDir) paths.splice(0, 0, path.join(themeDir, 'views'));

  var loaders = paths.map(function(path) {
    return new nunjucks.FileSystemLoader(path);
  });
  var env = new nunjucks.Environment(loaders);

  env.express = function(app) {
    nunjucks.Environment.prototype.express.apply(this, arguments);
    if (themeDir) {
      var staticDir = path.join(themeDir, 'public');
      app.use(staticMiddleware(staticDir));
    }
    app.use(staticMiddleware(path.join(__dirname, 'public')));
  };

  env.addFilter('undef', function (thing) {
    return thing || '';
  });
  env.addFilter('activize', function (actual, expect) {
    if (expect === actual)
      return 'class="active"';
    return '';
  });
  env.addFilter('markdown', function (string) {
    return markdown.toHTML(string);
  });
  env.addFilter('imageForBadge', function (badge) {
    if (!badge || !badge.relativeUrl)
      return '';
    return util.format(
      '',
      badge.relativeUrl('image'));
  });

  env.addFilter('stupidSafe', function (html) {
    return (
      html
      .replace(/</g, '<')
      .replace(/>/g, '>')
    );
  });
  env.addFilter('list', function (list, prop, sep) {
    return list.map(util.prop(prop)).join(sep);
  });

  env.addFilter('userHome', function (access) {
    return {
      super: '/admin',
      issuer: '/issuer'
    }[access];
  });

  env.addFilter('dateInput', function (date) {
    return date.toISOString().split('T')[0];
  });

  env.addFilter('selected', function (value, expected) {
    if (value === expected)
      return 'selected';
    return '';
  });

  return env;
};
<commit_msg>Protect against nulls.<commit_after>var path = require('path');
var markdown = require('markdown').markdown;
var nunjucks = require('nunjucks');
var util = require('util');

exports.buildEnvironment = function buildEnvironment(options) {
  var themeDir = options.themeDir;
  var staticMiddleware = options.staticMiddleware;
  var paths = [__dirname + '/views'];

  if (themeDir) paths.splice(0, 0, path.join(themeDir, 'views'));

  var loaders = paths.map(function(path) {
    return new nunjucks.FileSystemLoader(path);
  });
  var env = new nunjucks.Environment(loaders);

  env.express = function(app) {
    nunjucks.Environment.prototype.express.apply(this, arguments);
    if (themeDir) {
      var staticDir = path.join(themeDir, 'public');
      app.use(staticMiddleware(staticDir));
    }
    app.use(staticMiddleware(path.join(__dirname, 'public')));
  };

  env.addFilter('undef', function (thing) {
    return thing || '';
  });
  env.addFilter('activize', function (actual, expect) {
    if (expect === actual)
      return 'class="active"';
    return '';
  });
  env.addFilter('markdown', function (string) {
    return markdown.toHTML(string);
  });
  env.addFilter('imageForBadge', function (badge) {
    if (!badge || !badge.relativeUrl)
      return '';
    return util.format(
      '',
      badge.relativeUrl('image'));
  });

  env.addFilter('stupidSafe', function (html) {
    return (
      html
      .replace(/</g, '<')
      .replace(/>/g, '>')
    );
  });
  env.addFilter('list', function (list, prop, sep) {
    return list.map(util.prop(prop)).join(sep);
  });

  env.addFilter('userHome', function (access) {
    return {
      super: '/admin',
      issuer: '/issuer'
    }[access];
  });

  env.addFilter('dateInput', function (date) {
    return date && date.toISOString().split('T')[0] || '';
  });

  env.addFilter('selected', function (value, expected) {
    if (value === expected)
      return 'selected';
    return '';
  });

  return env;
};
<|endoftext|>


<commit_before>import $ from 'jquery';
import { saveAs } from 'file-saver';

import { download as downloadEOWCS, getDownloadInfos as getDownloadInfosEOWCS, downloadFullResolution } from './eowcs';
import { getDownloadInfos as getDownloadInfosUrl } from './url';
import { getDownloadInfos as getDownloadInfosS3 } from './s3';
import rewrite from './rewrite';

export function isRecordDownloadable(layerModel, recordModel) {
  if (layerModel.get('download.protocol') === 'EO-WCS') {
    return true;
  }
  const properties = recordModel.get('properties');
  if (properties && properties.links) {
    const url = properties.links.find(link => link.rel === 'enclosure');
    if (url) {
      return true;
    }
  }
  return false;
}

function downloadUrl(url) {
  const a = document.createElement('a');
  // This works in Chrome and Firefox
  if (typeof a.download !== 'undefined') {
    const ia = document.createElement('a');
    ia.style.display = 'none';
    ia.setAttribute('target', '_blank');
    ia.setAttribute('href', url);

    // Needed for multiple downloads in Chrome.
    // Adding 'noreferrer' breaks multiple downloads in Firefox
    ia.setAttribute('rel', 'noopener');

    document.body.appendChild(ia);
    ia.click();

    setTimeout(() => document.body.removeChild(ia), 10000);
  } else {
    // This works in IE11, but not for SSO
    const $iframe = $('');
    $('body').append($iframe);
    const content = $iframe[0].contentDocument;
    const form = `<form action="${url}" method="GET"></form>`;
    content.write(form);
    $('form', content).submit();
    setTimeout(() => {
      $iframe.remove();
    }, 20000);
  }
}

export function downloadRecord(layerModel, filtersModel, recordModel, options) {
  const rewriteRule = layerModel.get('download.rewrite');

  if (layerModel.get('download.protocol') === 'EO-WCS') {
    const urlOrElement = downloadEOWCS(layerModel, filtersModel, recordModel, options);
    if (urlOrElement) {
      if (layerModel.get('download.method') === 'GET') {
        downloadUrl(rewrite(urlOrElement, rewriteRule, recordModel));
      } else {
        const xmlRewritten = rewrite(urlOrElement, rewriteRule, recordModel);
        const urlRewritten = rewrite(layerModel.get('download.url'), rewriteRule, recordModel);
        const form = $(`<form method="post" action="${urlRewritten}" enctype="text/plain" target="_blank">
          <input type="hidden" name='<?xml version' value='"1.0"?>${xmlRewritten}'></input>
        </form>`);
        if (form) {
          const elem = form[0];
          document.body.appendChild(elem);
          elem.submit();
          setTimeout(() => elem.remove(), 10000);
        }
      }
    }
  } else {
    getDownloadInfosUrl(recordModel).then(infos => infos.forEach((info) => {
      downloadUrl(rewrite(info.href, rewriteRule, recordModel));
    }));
  }
}

export function downloadFullResolutionWCS(layerModel, mapModel, filtersModel, options) {
  const url = downloadFullResolution(layerModel, mapModel, filtersModel, options);
  downloadUrl(rewrite(url, layerModel.get('download.rewrite')));
}

export function downloadCustom(filename, mediaType, content) {
  saveAs(new Blob([content], { type: mediaType }), filename);
}

export function getDownloadInfos(layerModel, filtersModel, recordModel, options) {
  let downloadInfos;
  if (layerModel.get('download.protocol') === 'EO-WCS') {
    downloadInfos = getDownloadInfosEOWCS(layerModel, filtersModel, recordModel, options);
  } else if (layerModel.get('download.protocol') === 'S3') {
    downloadInfos = getDownloadInfosS3(layerModel, recordModel);
  } else {
    downloadInfos = getDownloadInfosUrl(recordModel);
  }

  return downloadInfos.then(infos => infos.map(item => Object.assign({}, item, {
    href: rewrite(item.href, layerModel.get('download.rewrite'), recordModel)
  })));
}
<commit_msg>fix downloadinfo hrefs - if href starts with // use current instead<commit_after>import $ from 'jquery';
import { saveAs } from 'file-saver';

import { download as downloadEOWCS, getDownloadInfos as getDownloadInfosEOWCS, downloadFullResolution } from './eowcs';
import { getDownloadInfos as getDownloadInfosUrl } from './url';
import { getDownloadInfos as getDownloadInfosS3 } from './s3';
import rewrite from './rewrite';

export function isRecordDownloadable(layerModel, recordModel) {
  if (layerModel.get('download.protocol') === 'EO-WCS') {
    return true;
  }
  const properties = recordModel.get('properties');
  if (properties && properties.links) {
    const url = properties.links.find(link => link.rel === 'enclosure');
    if (url) {
      return true;
    }
  }
  return false;
}

function downloadUrl(url) {
  const a = document.createElement('a');
  // This works in Chrome and Firefox
  if (typeof a.download !== 'undefined') {
    const ia = document.createElement('a');
    ia.style.display = 'none';
    ia.setAttribute('target', '_blank');
    ia.setAttribute('href', url);

    // Needed for multiple downloads in Chrome.
    // Adding 'noreferrer' breaks multiple downloads in Firefox
    ia.setAttribute('rel', 'noopener');

    document.body.appendChild(ia);
    ia.click();

    setTimeout(() => document.body.removeChild(ia), 10000);
  } else {
    // This works in IE11, but not for SSO
    const $iframe = $('');
    $('body').append($iframe);
    const content = $iframe[0].contentDocument;
    const form = `<form action="${url}" method="GET"></form>`;
    content.write(form);
    $('form', content).submit();
    setTimeout(() => {
      $iframe.remove();
    }, 20000);
  }
}

export function downloadRecord(layerModel, filtersModel, recordModel, options) {
  const rewriteRule = layerModel.get('download.rewrite');

  if (layerModel.get('download.protocol') === 'EO-WCS') {
    const urlOrElement = downloadEOWCS(layerModel, filtersModel, recordModel, options);
    if (urlOrElement) {
      if (layerModel.get('download.method') === 'GET') {
        downloadUrl(rewrite(urlOrElement, rewriteRule, recordModel));
      } else {
        const xmlRewritten = rewrite(urlOrElement, rewriteRule, recordModel);
        const urlRewritten = rewrite(layerModel.get('download.url'), rewriteRule, recordModel);
        const form = $(`<form method="post" action="${urlRewritten}" enctype="text/plain" target="_blank">
          <input type="hidden" name='<?xml version' value='"1.0"?>${xmlRewritten}'></input>
        </form>`);
        if (form) {
          const elem = form[0];
          document.body.appendChild(elem);
          elem.submit();
          setTimeout(() => elem.remove(), 10000);
        }
      }
    }
  } else {
    getDownloadInfosUrl(recordModel).then(infos => infos.forEach((info) => {
      downloadUrl(rewrite(info.href, rewriteRule, recordModel));
    }));
  }
}

export function downloadFullResolutionWCS(layerModel, mapModel, filtersModel, options) {
  const url = downloadFullResolution(layerModel, mapModel, filtersModel, options);
  downloadUrl(rewrite(url, layerModel.get('download.rewrite')));
}

export function downloadCustom(filename, mediaType, content) {
  saveAs(new Blob([content], { type: mediaType }), filename);
}

export function getDownloadInfos(layerModel, filtersModel, recordModel, options) {
  let downloadInfos;
  if (layerModel.get('download.protocol') === 'EO-WCS') {
    downloadInfos = getDownloadInfosEOWCS(layerModel, filtersModel, recordModel, options);
  } else if (layerModel.get('download.protocol') === 'S3') {
    downloadInfos = getDownloadInfosS3(layerModel, recordModel);
  } else {
    downloadInfos = getDownloadInfosUrl(recordModel);
  }

  return downloadInfos.then(infos => infos.map(item => Object.assign({}, item, {
    href: rewrite(item.href, layerModel.get('download.rewrite'), recordModel)
  })).map(item => Object.assign({}, item, {
    href: item.href.startsWith('//') ? location.protocol + item.href : item.href
  }))
  );
}
<|endoftext|>


<commit_before>/*!
 * <%= _.slugify(appname) %> <https://github.com/<%= username %>/<%= _.slugify(appname) %>>
 *
 * Copyright (c) <%= (new Date).getFullYear() %> <%= authorname %>.
 * Licensed under the MIT license.
 */

'use strict';

var assert = require('assert');
var should = require('should');
var <%= _.namify(appname) %> = require('./');

describe('<%= _.namify(appname) %>', function () {
  it('should:', function () {
    <%= _.namify(appname) %>('a').should.equal({a: 'b'});
    <%= _.namify(appname) %>('a').should.eql('a');
  });

  it('should throw an error:', function () {
    (function () {
      <%= _.namify(appname) %>();
    }).should.throw('<%= _.namify(appname) %> expects valid arguments');
  });
});
<commit_msg>fix tests<commit_after>/*!
 * <%= _.slugify(appname) %> <https://github.com/<%= username %>/<%= _.slugify(appname) %>>
 *
 * Copyright (c) <%= (new Date).getFullYear() %> <%= authorname %>.
 * Licensed under the MIT license.
 */

'use strict';

/* deps:mocha */
var assert = require('assert');
var should = require('should');
var <%= _.namify(appname) %> = require('./');

describe('<%= _.namify(appname) %>', function () {
  it('should:', function () {
    <%= _.namify(appname) %>('a').should.eql({a: 'b'});
    <%= _.namify(appname) %>('a').should.equal('a');
  });

  it('should throw an error:', function () {
    (function () {
      <%= _.namify(appname) %>();
    }).should.throw('<%= _.namify(appname) %> expects valid arguments');
  });
});
<|endoftext|>


<commit_before>import { assign, attr, bind, camelize, coerce, data as getData, hasAttr, hasOwn, hyphenate, includes, isArray, isFunction, isPlainObject, isString, isUndefined, mergeOptions, Observer, on, startsWith } from '../util/index';

export default function (UIkit) {

    var uid = 0;

    UIkit.prototype.props = {};

    UIkit.prototype._init = function (options) {

        options = options || {};
        options = this.$options = mergeOptions(this.constructor.options, options, this);

        this.$el = null;
        this.$name = UIkit.prefix + hyphenate(this.$options.name);
        this.$props = {};

        this._frames = {reads: {}, writes: {}};
        this._events = [];

        this._uid = uid++;
        this._initData();
        this._initMethods();
        this._initComputeds();
        this._callHook('created');

        if (options.el) {
            this.$mount(options.el);
        }
    };

    UIkit.prototype._initData = function () {

        var {defaults, data = {}, args = [], props = {}, el} = this.$options;

        if (args.length && isArray(data)) {
            data = data.slice(0, args.length).reduce((data, value, index) => {
                if (isPlainObject(value)) {
                    assign(data, value);
                } else {
                    data[args[index]] = value;
                }
                return data;
            }, {});
        }

        for (var key in assign({}, defaults, props)) {
            this.$props[key] = this[key] = hasOwn(data, key) && !isUndefined(data[key])
                ? coerce(props[key], data[key], el)
                : defaults
                    ? defaults[key] && isArray(defaults[key])
                        ? defaults[key].concat()
                        : defaults[key]
                    : null;
        }
    };

    UIkit.prototype._initMethods = function () {

        var methods = this.$options.methods;

        if (methods) {
            for (var key in methods) {
                this[key] = bind(methods[key], this);
            }
        }
    };

    UIkit.prototype._initComputeds = function () {

        var computed = this.$options.computed;

        this._resetComputeds();

        if (computed) {
            for (var key in computed) {
                registerComputed(this, key, computed[key]);
            }
        }
    };

    UIkit.prototype._resetComputeds = function () {
        this._computeds = {};
    };

    UIkit.prototype._initProps = function (props) {

        var key;

        this._resetComputeds();

        props = props || getProps(this.$options, this.$name);

        for (key in props) {
            if (!isUndefined(props[key])) {
                this.$props[key] = props[key];
            }
        }

        var exclude = [this.$options.computed, this.$options.methods];
        for (key in this.$props) {
            if (key in props && notIn(exclude, key)) {
                this[key] = this.$props[key];
            }
        }
    };

    UIkit.prototype._initEvents = function () {

        var events = this.$options.events;

        if (events) {

            events.forEach(event => {

                if (!hasOwn(event, 'handler')) {
                    for (var key in event) {
                        registerEvent(this, event[key], key);
                    }
                } else {
                    registerEvent(this, event);
                }

            });
        }
    };

    UIkit.prototype._unbindEvents = function () {
        this._events.forEach(unbind => unbind());
        this._events = [];
    };

    UIkit.prototype._initObserver = function () {

        var {attrs, props, el} = this.$options;
        if (this._observer || !props || !attrs || !Observer) {
            return;
        }

        attrs = isArray(attrs) ? attrs : Object.keys(props).map(key => hyphenate(key));

        this._observer = new Observer(() => {

            var data = getProps(this.$options, this.$name);
            if (attrs.some(key => !isUndefined(data[key]) && data[key] !== this.$props[key])) {
                this.$reset(data);
            }

        });

        this._observer.observe(el, {attributes: true, attributeFilter: attrs.concat([this.$name, `data-${this.$name}`])});
    };

    function getProps(opts, name) {

        var data = {},
            {args = [], props = {}, el} = opts,
            key, prop;

        if (!props) {
            return data;
        }

        for (key in props) {
            prop = hyphenate(key);
            if (hasAttr(el, prop)) {

                var value = coerce(props[key], attr(el, prop), el);

                if (prop === 'target' && (!value || startsWith(value, '_'))) {
                    continue;
                }

                data[key] = value;
            }
        }

        var options = parseOptions(getData(el, name), args);

        for (key in options) {
            prop = camelize(key);
            if (props[prop] !== undefined) {
                data[prop] = coerce(props[prop], options[key], el);
            }
        }

        return data;
    }

    function parseOptions(options, args = []) {

        try {

            return !options
                ? {}
                : startsWith(options, '{')
                    ? JSON.parse(options)
                    : args.length && !includes(options, ':')
                        ? ({[args[0]]: options})
                        : options.split(';').reduce((options, option) => {
                            var [key, value] = option.split(/:(.+)/);
                            if (key && value) {
                                options[key.trim()] = value.trim();
                            }
                            return options;
                        }, {});

        } catch (e) {
            return {};
        }

    }

    function registerComputed(component, key, cb) {
        Object.defineProperty(component, key, {

            enumerable: true,

            get() {

                var {_computeds, $props, $el} = component;

                if (!hasOwn(_computeds, key)) {
                    _computeds[key] = cb.call(component, $props, $el);
                }

                return _computeds[key];
            },

            set(value) {
                component._computeds[key] = value;
            }

        });
    }

    function registerEvent(component, event, key) {

        if (!isPlainObject(event)) {
            event = ({name: key, handler: event});
        }

        var {name, el, delegate, self, filter, handler} = event;
        el = isFunction(el)
            ? el.call(component)
            : el || component.$el;

        if (isArray(el)) {
            el.forEach(el => registerEvent(component, assign({}, event, {el}), key));
            return;
        }

        if (!el || filter && !filter.call(component)) {
            return;
        }

        handler = detail(isString(handler) ? component[handler] : bind(handler, component));

        if (self) {
            handler = selfFilter(handler);
        }

        component._events.push(
            on(
                el,
                name,
                !delegate
                    ? null
                    : isString(delegate)
                        ? delegate
                        : delegate.call(component),
                handler
            )
        );

    }

    function selfFilter(handler) {
        return function selfHandler(e) {
            if (e.target === e.currentTarget || e.target === e.current) {
                return handler.call(null, e);
            }
        };
    }

    function notIn(options, key) {
        return options.every(arr => !arr || !hasOwn(arr, key));
    }

    function detail(listener) {
        return e => isArray(e.detail) ? listener.apply(listener, [e].concat(e.detail)) : listener(e);
    }

}
<commit_msg>allow to register events in capture phase<commit_after>import { assign, attr, bind, camelize, coerce, data as getData, hasAttr, hasOwn, hyphenate, includes, isArray, isFunction, isPlainObject, isString, isUndefined, mergeOptions, Observer, on, startsWith } from '../util/index';

export default function (UIkit) {

    var uid = 0;

    UIkit.prototype.props = {};

    UIkit.prototype._init = function (options) {

        options = options || {};
        options = this.$options = mergeOptions(this.constructor.options, options, this);

        this.$el = null;
        this.$name = UIkit.prefix + hyphenate(this.$options.name);
        this.$props = {};

        this._frames = {reads: {}, writes: {}};
        this._events = [];

        this._uid = uid++;
        this._initData();
        this._initMethods();
        this._initComputeds();
        this._callHook('created');

        if (options.el) {
            this.$mount(options.el);
        }
    };

    UIkit.prototype._initData = function () {

        var {defaults, data = {}, args = [], props = {}, el} = this.$options;

        if (args.length && isArray(data)) {
            data = data.slice(0, args.length).reduce((data, value, index) => {
                if (isPlainObject(value)) {
                    assign(data, value);
                } else {
                    data[args[index]] = value;
                }
                return data;
            }, {});
        }

        for (var key in assign({}, defaults, props)) {
            this.$props[key] = this[key] = hasOwn(data, key) && !isUndefined(data[key])
                ? coerce(props[key], data[key], el)
                : defaults
                    ? defaults[key] && isArray(defaults[key])
                        ? defaults[key].concat()
                        : defaults[key]
                    : null;
        }
    };

    UIkit.prototype._initMethods = function () {

        var methods = this.$options.methods;

        if (methods) {
            for (var key in methods) {
                this[key] = bind(methods[key], this);
            }
        }
    };

    UIkit.prototype._initComputeds = function () {

        var computed = this.$options.computed;

        this._resetComputeds();

        if (computed) {
            for (var key in computed) {
                registerComputed(this, key, computed[key]);
            }
        }
    };

    UIkit.prototype._resetComputeds = function () {
        this._computeds = {};
    };

    UIkit.prototype._initProps = function (props) {

        var key;

        this._resetComputeds();

        props = props || getProps(this.$options, this.$name);

        for (key in props) {
            if (!isUndefined(props[key])) {
                this.$props[key] = props[key];
            }
        }

        var exclude = [this.$options.computed, this.$options.methods];
        for (key in this.$props) {
            if (key in props && notIn(exclude, key)) {
                this[key] = this.$props[key];
            }
        }
    };

    UIkit.prototype._initEvents = function () {

        var events = this.$options.events;

        if (events) {

            events.forEach(event => {

                if (!hasOwn(event, 'handler')) {
                    for (var key in event) {
                        registerEvent(this, event[key], key);
                    }
                } else {
                    registerEvent(this, event);
                }

            });
        }
    };

    UIkit.prototype._unbindEvents = function () {
        this._events.forEach(unbind => unbind());
        this._events = [];
    };

    UIkit.prototype._initObserver = function () {

        var {attrs, props, el} = this.$options;
        if (this._observer || !props || !attrs || !Observer) {
            return;
        }

        attrs = isArray(attrs) ? attrs : Object.keys(props).map(key => hyphenate(key));

        this._observer = new Observer(() => {

            var data = getProps(this.$options, this.$name);
            if (attrs.some(key => !isUndefined(data[key]) && data[key] !== this.$props[key])) {
                this.$reset(data);
            }

        });

        this._observer.observe(el, {attributes: true, attributeFilter: attrs.concat([this.$name, `data-${this.$name}`])});
    };

    function getProps(opts, name) {

        var data = {},
            {args = [], props = {}, el} = opts,
            key, prop;

        if (!props) {
            return data;
        }

        for (key in props) {
            prop = hyphenate(key);
            if (hasAttr(el, prop)) {

                var value = coerce(props[key], attr(el, prop), el);

                if (prop === 'target' && (!value || startsWith(value, '_'))) {
                    continue;
                }

                data[key] = value;
            }
        }

        var options = parseOptions(getData(el, name), args);

        for (key in options) {
            prop = camelize(key);
            if (props[prop] !== undefined) {
                data[prop] = coerce(props[prop], options[key], el);
            }
        }

        return data;
    }

    function parseOptions(options, args = []) {

        try {

            return !options
                ? {}
                : startsWith(options, '{')
                    ? JSON.parse(options)
                    : args.length && !includes(options, ':')
                        ? ({[args[0]]: options})
                        : options.split(';').reduce((options, option) => {
                            var [key, value] = option.split(/:(.+)/);
                            if (key && value) {
                                options[key.trim()] = value.trim();
                            }
                            return options;
                        }, {});

        } catch (e) {
            return {};
        }

    }

    function registerComputed(component, key, cb) {
        Object.defineProperty(component, key, {

            enumerable: true,

            get() {

                var {_computeds, $props, $el} = component;

                if (!hasOwn(_computeds, key)) {
                    _computeds[key] = cb.call(component, $props, $el);
                }

                return _computeds[key];
            },

            set(value) {
                component._computeds[key] = value;
            }

        });
    }

    function registerEvent(component, event, key) {

        if (!isPlainObject(event)) {
            event = ({name: key, handler: event});
        }

        var {name, el, handler, capture, delegate, filter, self} = event;
        el = isFunction(el)
            ? el.call(component)
            : el || component.$el;

        if (isArray(el)) {
            el.forEach(el => registerEvent(component, assign({}, event, {el}), key));
            return;
        }

        if (!el || filter && !filter.call(component)) {
            return;
        }

        handler = detail(isString(handler) ? component[handler] : bind(handler, component));

        if (self) {
            handler = selfFilter(handler);
        }

        component._events.push(
            on(
                el,
                name,
                !delegate
                    ? null
                    : isString(delegate)
                        ? delegate
                        : delegate.call(component),
                handler,
                capture
            )
        );

    }

    function selfFilter(handler) {
        return function selfHandler(e) {
            if (e.target === e.currentTarget || e.target === e.current) {
                return handler.call(null, e);
            }
        };
    }

    function notIn(options, key) {
        return options.every(arr => !arr || !hasOwn(arr, key));
    }

    function detail(listener) {
        return e => isArray(e.detail) ? listener.apply(listener, [e].concat(e.detail)) : listener(e);
    }

}
<|endoftext|>


<commit_before>(function (<bridge>, document) {
    if (document.readyState == "loaded" || document.readyState == "complete") {
        document.__creammonkeyed__ = true;
    } else {
        return;
    }
    with ({ location: window.location, unsafeWindow: window }) {
        // define GM functions
        var GM_log = function (s) {
            window.console.log('GM_log: ' + s);
            return <bridge>.gmLog_(s);
        };
        var GM_getValue = function (k, d) {
            return <bridge>.gmValueForKey_defaultValue_scriptName_namespace_(k, d, "<name>", "<namespace>");
        };
        var GM_setValue = function (k, v) {
            return <bridge>.gmSetValue_forKey_scriptName_namespace_(v, k, "<name>", "<namespace>");
        };
        /* Not implemented yet
        var GM_registerMenuCommand = function (t, c) {
            <bridge>.gmRegisterMenuCommand_callback_(t, c);
        }
        */
        var GM_xmlhttpRequest = function (d) {
            return <bridge>.gmXmlhttpRequest_(d);
        };

        <body>;
    }
});
<commit_msg>add GM_addStyle.<commit_after>(function (<bridge>, document) {
    if (document.readyState == "loaded" || document.readyState == "complete") {
        document.__creammonkeyed__ = true;
    } else {
        return;
    }
    with ({ location: window.location, unsafeWindow: window }) {
        // define GM functions
       var GM_addStyle = function (s) {
	  var style = document.createElement('style');
	  style.setAttribute('type', 'text/css');
	  style.appendChild(document.createTextNode(s));
	  document.getElementsByTagName('head')[0].appendChild(style);
       }
        var GM_log = function (s) {
            window.console.log('GM_log: ' + s);
            return <bridge>.gmLog_(s);
        };
        var GM_getValue = function (k, d) {
            return <bridge>.gmValueForKey_defaultValue_scriptName_namespace_(k, d, "<name>", "<namespace>");
        };
        var GM_setValue = function (k, v) {
            return <bridge>.gmSetValue_forKey_scriptName_namespace_(v, k, "<name>", "<namespace>");
        };
        /* Not implemented yet
        var GM_registerMenuCommand = function (t, c) {
            <bridge>.gmRegisterMenuCommand_callback_(t, c);
        }
        */
        var GM_xmlhttpRequest = function (d) {
            return <bridge>.gmXmlhttpRequest_(d);
        };

        <body>;
    }
});
<|endoftext|>


<commit_before>(function(window, undefined) {
	var LazyFingers = window.LazyFingers = function(options) {
		options = options || {};

		this.options = {
			idAttribute: options.idAttribute || 'id',
			indexAttribute: options.indexAttribute || 'name'
		};

		this._index = [];
		this._documentsById = {};
	};

	LazyFingers.fn = LazyFingers.prototype;

	LazyFingers.fn.add = function(docs) {
		var docsIndex = 0;
		var docsLength = docs.length;
		var indexAttribute = this.options.indexAttribute;
		var idAttribute = this.options.idAttribute;
		var doc;
		var docData;
		var docsById = this._documentsById;
		var index = this._index;

		//Iterate over all documents we want to add to the index.
		for(; docsIndex < docsLength; docsIndex++) {
			doc = docs[docsIndex];
			docData = doc[indexAttribute];

			docsById[doc[idAttribute]] = doc;

			//Does the document have any data to index?
			if(docData === undefined || docData === null) {
				continue;
			}

			docData = ('' + docData);

			index.push({
				data: docData,
				doc: doc
			});
		}
	};

	LazyFingers.fn.find = function(input) {
		input = input.replace(/\s+/g, '');
		input = escapeRegExp(input);

		var rx = new RegExp('(' + input.split('').join(').*(') + ')', 'i');
		var results = [];
		var index = this._index;
		var indexIndex = 0;
		var indexLength = index.length;
		var indexEntry;
		var indexEntryData;
		var isMatch;
		var matchedPositions;
		var argumentsIndex;
		var argumentsLength;

		for(; indexIndex < indexLength; indexIndex++) {
			indexEntry = index[indexIndex];
			indexEntryData = indexEntry.data;

			isMatch = false;

			indexEntryData.replace(rx, function() {
				isMatch = true;

				matchedPositions = [];

				argumentsIndex = 1;
				//-3 because we only want the group, not the full string or the index.
				argumentsLength = arguments.length - 2;

				for(; argumentsIndex < argumentsLength; argumentsIndex++) {
					matchedPositions.push(indexEntryData.indexOf(arguments[argumentsIndex]));
				}
			});

			if(isMatch) {
				results.push({
					doc: indexEntry.doc,
					positions: matchedPositions
				});
			}
		}

		return results;
	};

	var escapeRegExp = function(text) {
		return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
	};
}(window));<commit_msg>added wrap method to highlight matches. also fixed issue with duplicate character in query<commit_after>(function(window, undefined) {
	var LazyFingers = window.LazyFingers = function(options) {
		options = options || {};

		this.options = {
			idAttribute: options.idAttribute || 'id',
			indexAttribute: options.indexAttribute || 'name'
		};

		this._index = [];
		this._documentsById = {};
	};

	LazyFingers.fn = LazyFingers.prototype;

	LazyFingers.fn.add = function(docs) {
		var docsIndex = 0;
		var docsLength = docs.length;
		var indexAttribute = this.options.indexAttribute;
		var idAttribute = this.options.idAttribute;
		var doc;
		var docData;
		var docsById = this._documentsById;
		var index = this._index;

		//Iterate over all documents we want to add to the index.
		for(; docsIndex < docsLength; docsIndex++) {
			doc = docs[docsIndex];
			docData = doc[indexAttribute];

			docsById[doc[idAttribute]] = doc;

			//Does the document have any data to index?
			if(docData === undefined || docData === null) {
				continue;
			}

			docData = ('' + docData).toLowerCase();

			index.push({
				data: docData,
				doc: doc
			});
		}
	};

	LazyFingers.fn.find = function(input, options) {
		input = input.replace(/\s+/g, '').toLowerCase();

		if(!input.length) {
			return [];
		}

		input = escapeRegExp(input);

		options = options || {};

		var rx = new RegExp('(' + input.split('').join(').*(') + ')');
		var results = [];
		var index = this._index;
		var indexIndex = 0;
		var indexLength = index.length;
		var indexEntry;
		var indexEntryData;
		var isMatch;
		var matchedPositions;
		var argumentsIndex;
		var argumentsLength;
		var character;
		var characterIndex ;
		var limit = options.limit;

		for(; indexIndex < indexLength; indexIndex++) {
			indexEntry = index[indexIndex];
			indexEntryData = indexEntry.data;

			isMatch = false;

			indexEntryData.replace(rx, function() {
				isMatch = true;

				matchedPositions = [];

				argumentsIndex = 1;
				//-3 because we only want the group, not the full string or the index.
				argumentsLength = arguments.length - 2;

				characterIndex = 0;

				for(; argumentsIndex < argumentsLength; argumentsIndex++) {
					character = arguments[argumentsIndex];
					characterIndex = indexEntryData.indexOf(character, characterIndex);
					matchedPositions.push(characterIndex);
					characterIndex++;
				}
			});

			if(isMatch) {
				results.push({
					doc: indexEntry.doc,
					positions: matchedPositions
				});

				if(limit && results.length >= limit) {
					break;
				}
			}
		}

		return results;
	};

	LazyFingers.wrap = function(input, positions, fn) {
		var inputIndex = 0;
		var inputLength = input.length;
		var offset = 0;
		var replacementString;
		var positionsIndex = 0;
		var positionsLength = positions.length;
		var index;

		for(; positionsIndex < positionsLength; positionsIndex++) {
			index = positions[positionsIndex] + offset;
			replacementString = fn(input.charAt(index));

			input = input.slice(0, index) + replacementString + input.slice(index + 1);

			offset += replacementString.length - 1;
		}

		return input;
	};

	var escapeRegExp = function(text) {
		return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
	};
}(window));<|endoftext|>


<commit_before>//Math.random() devuelve numero aleatorio entre 0 y 1
var numero = Math.random();
//Inicio la operacion if
if (numero <= 0.5) {
  console.log('n' + numero + 'MENOR que 0.5 n');
} else {
  console.log('n' + numero + 'MAYOR que 0.5 n');
}
<commit_msg>Primera Version<commit_after>//Math.random() devuelve numero aleatorio entre 0 y 1
var numero = Math.random();
//Inicio la operacion if
if (numero <= 0.5) {
  console.log('n' + numero + 'MENOR que 0.5 n');//menor
} else {
  console.log('n' + numero + 'MAYOR que 0.5 n');//mayor
}
<|endoftext|>


<commit_before>// Global Ajax Setup
var globalAjaxOptions = {};
$.ajaxSetup = function (options) {
    if (options.type) options.method = options.type;
    $.each(options, function (optionName, optionValue) {
        globalAjaxOptions[optionName]  = optionValue;
    });
};

// Ajax
var _jsonpRequests = 0;
$.ajax = function (options) {
    var defaults = {
        method: 'GET',
        data: false,
        async: true,
        cache: true,
        user: '',
        password: '',
        headers: {},
        xhrFields: {},
        statusCode: {},
        processData: true,
        dataType: 'text',
        contentType: 'application/x-www-form-urlencoded',
        timeout: 0
    };
    var callbacks = ['beforeSend', 'error', 'complete', 'success', 'statusCode'];

    //For jQuery guys
    if (options.type) options.method = options.type;

    // Merge global and defaults
    $.each(globalAjaxOptions, function (globalOptionName, globalOptionValue) {
        if (callbacks.indexOf(globalOptionName) < 0) defaults[globalOptionName] = globalOptionValue;
    });

    // Function to run XHR callbacks and events
    function fireAjaxCallback (eventName, eventData, callbackName) {
        var a = arguments;
        if (eventName) $(document).trigger(eventName, eventData);
        if (callbackName) {
            // Global callback
            if (callbackName in globalAjaxOptions) globalAjaxOptions[callbackName](a[3], a[4], a[5], a[6]);
            // Options callback
            if (options[callbackName]) options[callbackName](a[3], a[4], a[5], a[6]);
        }
    }

    // Merge options and defaults
    $.each(defaults, function (prop, defaultValue) {
        if (!(prop in options)) options[prop] = defaultValue;
    });

    // Default URL
    if (!options.url) {
        options.url = window.location.toString();
    }
    // Parameters Prefix
    var paramsPrefix = options.url.indexOf('?') >= 0 ? '&' : '?';

    // UC method
    var _method = options.method.toUpperCase();
    // Data to modify GET URL
    if ((_method === 'GET' || _method === 'HEAD') && options.data) {
        var stringData;
        if (typeof options.data === 'string') {
            // Should be key=value string
            if (options.data.indexOf('?') >= 0) stringData = options.data.split('?')[1];
            else stringData = options.data;
        }
        else {
            // Should be key=value object
            stringData = $.serializeObject(options.data);
        }
        if (stringData.length) {
            options.url += paramsPrefix + stringData;
            if (paramsPrefix === '?') paramsPrefix = '&';
        }
    }
    // JSONP
    if (options.dataType === 'json' && options.url.indexOf('callback=') >= 0) {

        var callbackName = 'f7jsonp_' + Date.now() + (_jsonpRequests++);
        var abortTimeout;
        var callbackSplit = options.url.split('callback=');
        var requestUrl = callbackSplit[0] + 'callback=' + callbackName;
        if (callbackSplit[1].indexOf('&') >= 0) {
            var addVars = callbackSplit[1].split('&').filter(function (el) { return el.indexOf('=') > 0; }).join('&');
            if (addVars.length > 0) requestUrl += '&' + addVars;
        }

        // Create script
        var script = document.createElement('script');
        script.type = 'text/javascript';
        script.onerror = function() {
            clearTimeout(abortTimeout);
            fireAjaxCallback(undefined, undefined, 'error', null, 'scripterror');
        };
        script.src = requestUrl;

        // Handler
        window[callbackName] = function (data) {
            clearTimeout(abortTimeout);
            fireAjaxCallback(undefined, undefined, 'success', data);
            script.parentNode.removeChild(script);
            script = null;
            delete window[callbackName];
        };
        document.querySelector('head').appendChild(script);

        if (options.timeout > 0) {
            abortTimeout = setTimeout(function () {
                script.parentNode.removeChild(script);
                script = null;
                fireAjaxCallback(undefined, undefined, 'error', null, 'timeout');
            }, options.timeout);
        }

        return;
    }

    // Cache for GET/HEAD requests
    if (_method === 'GET' || _method === 'HEAD') {
        if (options.cache === false) {
            options.url += (paramsPrefix + '_nocache=' + Date.now());
        }
    }

    // Create XHR
    var xhr = new XMLHttpRequest();

    // Save Request URL
    xhr.requestUrl = options.url;
    xhr.requestParameters = options;

    // Open XHR
    xhr.open(_method, options.url, options.async, options.user, options.password);

    // Create POST Data
    var postData = null;

    if ((_method === 'POST' || _method === 'PUT') && options.data) {
        if (options.processData) {
            var postDataInstances = [ArrayBuffer, Blob, Document, FormData];
            // Post Data
            if (postDataInstances.indexOf(options.data.constructor) >= 0) {
                postData = options.data;
            }
            else {
                // POST Headers
                var boundary = '---------------------------' + Date.now().toString(16);

                if (options.contentType === 'multipart\/form-data') {
                    xhr.setRequestHeader('Content-Type', 'multipart\/form-data; boundary=' + boundary);
                }
                else {
                    xhr.setRequestHeader('Content-Type', options.contentType);
                }
                postData = '';
                var _data = $.serializeObject(options.data);
                if (options.contentType === 'multipart\/form-data') {
                    boundary = '---------------------------' + Date.now().toString(16);
                    _data = _data.split('&');
                    var _newData = [];
                    for (var i = 0; i < _data.length; i++) {
                        _newData.push('Content-Disposition: form-data; name="' + _data[i].split('=')[0] + '"\r\n\r\n' + _data[i].split('=')[1] + '\r\n');
                    }
                    postData = '--' + boundary + '\r\n' + _newData.join('--' + boundary + '\r\n') + '--' + boundary + '--\r\n';
                }
                else {
                    postData = options.contentType === 'application/x-www-form-urlencoded' ? _data : _data.replace(/&/g, '\r\n');
                }
            }
        }
        else {
            postData = options.data;
        }

    }

    // Additional headers
    if (options.headers) {
        $.each(options.headers, function (headerName, headerCallback) {
            xhr.setRequestHeader(headerName, headerCallback);
        });
    }

    // Check for crossDomain
    if (typeof options.crossDomain === 'undefined') {
        options.crossDomain = /^([\w-]+:)?\/\/([^\/]+)/.test(options.url) && RegExp.$2 !== window.location.host;
    }

    if (!options.crossDomain) {
        xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
    }

    if (options.xhrFields) {
        $.each(options.xhrFields, function (fieldName, fieldValue) {
            xhr[fieldName] = fieldValue;
        });
    }

    var xhrTimeout;
    // Handle XHR
    xhr.onload = function (e) {
        if (xhrTimeout) clearTimeout(xhrTimeout);
        if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 0) {
            var responseData;
            if (options.dataType === 'json') {
                try {
                    responseData = JSON.parse(xhr.responseText);
                    fireAjaxCallback('ajaxSuccess', {xhr: xhr}, 'success', responseData, xhr.status, xhr);
                }
                catch (err) {
                    fireAjaxCallback('ajaxError', {xhr: xhr, parseerror: true}, 'error', xhr, 'parseerror');
                }
            }
            else {
                fireAjaxCallback('ajaxSuccess', {xhr: xhr}, 'success', xhr.responseText, xhr.status, xhr);
            }
        }
        else {
            fireAjaxCallback('ajaxError', {xhr: xhr}, 'error', xhr, xhr.status);
        }
        if (options.statusCode) {
            if (globalAjaxOptions.statusCode && globalAjaxOptions.statusCode[xhr.status]) globalAjaxOptions.statusCode[xhr.status](xhr);
            if (options.statusCode[xhr.status]) options.statusCode[xhr.status](xhr);
        }
        fireAjaxCallback('ajaxComplete', {xhr: xhr}, 'complete', xhr, xhr.status);
    };

    xhr.onerror = function (e) {
        if (xhrTimeout) clearTimeout(xhrTimeout);
        fireAjaxCallback('ajaxError', {xhr: xhr}, 'error', xhr, xhr.status);
    };

    // Ajax start callback
    fireAjaxCallback('ajaxStart', {xhr: xhr}, 'start', xhr);
    fireAjaxCallback(undefined, undefined, 'beforeSend', xhr);

    // Send XHR
    xhr.send(postData);

    // Timeout
    if (options.timeout > 0) {
        xhrTimeout = setTimeout(function () {
            xhr.abort();
            fireAjaxCallback('ajaxError', {xhr: xhr, timeout: true}, 'error', xhr, 'timeout');
            fireAjaxCallback('ajaxComplete', {xhr: xhr, timeout: true}, 'complete', xhr, 'timeout');
        }, options.timeout);
    }

    // Return XHR object
    return xhr;
};
// Shrotcuts
(function () {
    var methods = ('get post getJSON').split(' ');
    function createMethod(method) {
        $[method] = function (url, data, success) {
            return $.ajax({
                url: url,
                method: method === 'post' ? 'POST' : 'GET',
                data: typeof data === 'function' ? undefined : data,
                success: typeof data === 'function' ? data : success,
                dataType: method === 'getJSON' ? 'json' : undefined
            });
        };
    }
    for (var i = 0; i < methods.length; i++) {
        createMethod(methods[i]);
    }
})();
<commit_msg>Fix responseData different from `text`<commit_after>// Global Ajax Setup
var globalAjaxOptions = {};
$.ajaxSetup = function (options) {
    if (options.type) options.method = options.type;
    $.each(options, function (optionName, optionValue) {
        globalAjaxOptions[optionName]  = optionValue;
    });
};

// Ajax
var _jsonpRequests = 0;
$.ajax = function (options) {
    var defaults = {
        method: 'GET',
        data: false,
        async: true,
        cache: true,
        user: '',
        password: '',
        headers: {},
        xhrFields: {},
        statusCode: {},
        processData: true,
        dataType: 'text',
        contentType: 'application/x-www-form-urlencoded',
        timeout: 0
    };
    var callbacks = ['beforeSend', 'error', 'complete', 'success', 'statusCode'];

    //For jQuery guys
    if (options.type) options.method = options.type;

    // Merge global and defaults
    $.each(globalAjaxOptions, function (globalOptionName, globalOptionValue) {
        if (callbacks.indexOf(globalOptionName) < 0) defaults[globalOptionName] = globalOptionValue;
    });

    // Function to run XHR callbacks and events
    function fireAjaxCallback (eventName, eventData, callbackName) {
        var a = arguments;
        if (eventName) $(document).trigger(eventName, eventData);
        if (callbackName) {
            // Global callback
            if (callbackName in globalAjaxOptions) globalAjaxOptions[callbackName](a[3], a[4], a[5], a[6]);
            // Options callback
            if (options[callbackName]) options[callbackName](a[3], a[4], a[5], a[6]);
        }
    }

    // Merge options and defaults
    $.each(defaults, function (prop, defaultValue) {
        if (!(prop in options)) options[prop] = defaultValue;
    });

    // Default URL
    if (!options.url) {
        options.url = window.location.toString();
    }
    // Parameters Prefix
    var paramsPrefix = options.url.indexOf('?') >= 0 ? '&' : '?';

    // UC method
    var _method = options.method.toUpperCase();
    // Data to modify GET URL
    if ((_method === 'GET' || _method === 'HEAD') && options.data) {
        var stringData;
        if (typeof options.data === 'string') {
            // Should be key=value string
            if (options.data.indexOf('?') >= 0) stringData = options.data.split('?')[1];
            else stringData = options.data;
        }
        else {
            // Should be key=value object
            stringData = $.serializeObject(options.data);
        }
        if (stringData.length) {
            options.url += paramsPrefix + stringData;
            if (paramsPrefix === '?') paramsPrefix = '&';
        }
    }
    // JSONP
    if (options.dataType === 'json' && options.url.indexOf('callback=') >= 0) {

        var callbackName = 'f7jsonp_' + Date.now() + (_jsonpRequests++);
        var abortTimeout;
        var callbackSplit = options.url.split('callback=');
        var requestUrl = callbackSplit[0] + 'callback=' + callbackName;
        if (callbackSplit[1].indexOf('&') >= 0) {
            var addVars = callbackSplit[1].split('&').filter(function (el) { return el.indexOf('=') > 0; }).join('&');
            if (addVars.length > 0) requestUrl += '&' + addVars;
        }

        // Create script
        var script = document.createElement('script');
        script.type = 'text/javascript';
        script.onerror = function() {
            clearTimeout(abortTimeout);
            fireAjaxCallback(undefined, undefined, 'error', null, 'scripterror');
        };
        script.src = requestUrl;

        // Handler
        window[callbackName] = function (data) {
            clearTimeout(abortTimeout);
            fireAjaxCallback(undefined, undefined, 'success', data);
            script.parentNode.removeChild(script);
            script = null;
            delete window[callbackName];
        };
        document.querySelector('head').appendChild(script);

        if (options.timeout > 0) {
            abortTimeout = setTimeout(function () {
                script.parentNode.removeChild(script);
                script = null;
                fireAjaxCallback(undefined, undefined, 'error', null, 'timeout');
            }, options.timeout);
        }

        return;
    }

    // Cache for GET/HEAD requests
    if (_method === 'GET' || _method === 'HEAD') {
        if (options.cache === false) {
            options.url += (paramsPrefix + '_nocache=' + Date.now());
        }
    }

    // Create XHR
    var xhr = new XMLHttpRequest();

    // Save Request URL
    xhr.requestUrl = options.url;
    xhr.requestParameters = options;

    // Open XHR
    xhr.open(_method, options.url, options.async, options.user, options.password);

    // Create POST Data
    var postData = null;

    if ((_method === 'POST' || _method === 'PUT') && options.data) {
        if (options.processData) {
            var postDataInstances = [ArrayBuffer, Blob, Document, FormData];
            // Post Data
            if (postDataInstances.indexOf(options.data.constructor) >= 0) {
                postData = options.data;
            }
            else {
                // POST Headers
                var boundary = '---------------------------' + Date.now().toString(16);

                if (options.contentType === 'multipart\/form-data') {
                    xhr.setRequestHeader('Content-Type', 'multipart\/form-data; boundary=' + boundary);
                }
                else {
                    xhr.setRequestHeader('Content-Type', options.contentType);
                }
                postData = '';
                var _data = $.serializeObject(options.data);
                if (options.contentType === 'multipart\/form-data') {
                    boundary = '---------------------------' + Date.now().toString(16);
                    _data = _data.split('&');
                    var _newData = [];
                    for (var i = 0; i < _data.length; i++) {
                        _newData.push('Content-Disposition: form-data; name="' + _data[i].split('=')[0] + '"\r\n\r\n' + _data[i].split('=')[1] + '\r\n');
                    }
                    postData = '--' + boundary + '\r\n' + _newData.join('--' + boundary + '\r\n') + '--' + boundary + '--\r\n';
                }
                else {
                    postData = options.contentType === 'application/x-www-form-urlencoded' ? _data : _data.replace(/&/g, '\r\n');
                }
            }
        }
        else {
            postData = options.data;
        }

    }

    // Additional headers
    if (options.headers) {
        $.each(options.headers, function (headerName, headerCallback) {
            xhr.setRequestHeader(headerName, headerCallback);
        });
    }

    // Check for crossDomain
    if (typeof options.crossDomain === 'undefined') {
        options.crossDomain = /^([\w-]+:)?\/\/([^\/]+)/.test(options.url) && RegExp.$2 !== window.location.host;
    }

    if (!options.crossDomain) {
        xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
    }

    if (options.xhrFields) {
        $.each(options.xhrFields, function (fieldName, fieldValue) {
            xhr[fieldName] = fieldValue;
        });
    }

    var xhrTimeout;
    // Handle XHR
    xhr.onload = function (e) {
        if (xhrTimeout) clearTimeout(xhrTimeout);
        if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 0) {
            var responseData;
            if (options.dataType === 'json') {
                try {
                    responseData = JSON.parse(xhr.responseText);
                    fireAjaxCallback('ajaxSuccess', {xhr: xhr}, 'success', responseData, xhr.status, xhr);
                }
                catch (err) {
                    fireAjaxCallback('ajaxError', {xhr: xhr, parseerror: true}, 'error', xhr, 'parseerror');
                }
            }
            else {
                responseData = xhr.responseType === 'text' || xhr.responseType === '' ? xhr.responseText : xhr.response;
                fireAjaxCallback('ajaxSuccess', {xhr: xhr}, 'success', responseData, xhr.status, xhr);
            }
        }
        else {
            fireAjaxCallback('ajaxError', {xhr: xhr}, 'error', xhr, xhr.status);
        }
        if (options.statusCode) {
            if (globalAjaxOptions.statusCode && globalAjaxOptions.statusCode[xhr.status]) globalAjaxOptions.statusCode[xhr.status](xhr);
            if (options.statusCode[xhr.status]) options.statusCode[xhr.status](xhr);
        }
        fireAjaxCallback('ajaxComplete', {xhr: xhr}, 'complete', xhr, xhr.status);
    };

    xhr.onerror = function (e) {
        if (xhrTimeout) clearTimeout(xhrTimeout);
        fireAjaxCallback('ajaxError', {xhr: xhr}, 'error', xhr, xhr.status);
    };

    // Ajax start callback
    fireAjaxCallback('ajaxStart', {xhr: xhr}, 'start', xhr);
    fireAjaxCallback(undefined, undefined, 'beforeSend', xhr);

    // Send XHR
    xhr.send(postData);

    // Timeout
    if (options.timeout > 0) {
        xhrTimeout = setTimeout(function () {
            xhr.abort();
            fireAjaxCallback('ajaxError', {xhr: xhr, timeout: true}, 'error', xhr, 'timeout');
            fireAjaxCallback('ajaxComplete', {xhr: xhr, timeout: true}, 'complete', xhr, 'timeout');
        }, options.timeout);
    }

    // Return XHR object
    return xhr;
};
// Shrotcuts
(function () {
    var methods = ('get post getJSON').split(' ');
    function createMethod(method) {
        $[method] = function (url, data, success) {
            return $.ajax({
                url: url,
                method: method === 'post' ? 'POST' : 'GET',
                data: typeof data === 'function' ? undefined : data,
                success: typeof data === 'function' ? data : success,
                dataType: method === 'getJSON' ? 'json' : undefined
            });
        };
    }
    for (var i = 0; i < methods.length; i++) {
        createMethod(methods[i]);
    }
})();
<|endoftext|>


<commit_before>/*
 * Copyright 2015 Akamai Technologies, 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.
 */

/**
 * @requires jQuery and Galleria
 */
(function($, Akamai) {

    /**
     * Array that stores the ImViewer instances
     */
    Akamai.ImViewers = [];

    /**
     * Construct and render the ImViewer
     * @constructor
     */
    Akamai.ImViewer = function(element, options) {
        this.element = $(element);
        this.options = $.extend(true, {}, options);

        Akamai.ImViewers.push(this);
        this.options.index = Akamai.ImViewers.length - 1;

        this.options.viewerSelector = (this.element.attr("id")) ? ("#" + this.element.attr("id")) : ("." + this.element.attr("class")).replace(' ', '.');
        this.options.currentGalleryIndex = this.options.currentGalleryIndex || 0;
        this.options.dimensions = this.options.dimensions || {};
        this.options.imageWidth = this.options.imageWidth || 0;
        this.options.bigWidth = this.options.bigWidth || 0;
        this.options.lastResizeTime = this.options.lastResizeTime || 0;
        this.render(this.element);
    };

    /**
     * Re-initialize the specified ImViewer with new options.
     * @function restartGalleria
     * @memberof Akamai.ImViewer
     * @static
     */
    Akamai.ImViewer.restartGalleria = function(options) {
        Galleria.get(options.index).destroy();
        Akamai.ImViewers.splice(options.index, 1);

        // re-index the ImViewer and Galleria instances
        for (var i = 0; i < Akamai.ImViewers.length; i++) {
            Akamai.ImViewers[i].options.index = i;
            Galleria.get(i)._options.index = i;
        }

        $(options.galleryContainer).empty();
        $(options.zoomContainer).empty();
        $(options.viewerSelector).viewer(options);
    };

    /**
     * Load data for ImViewer and then start the render process.
     */
    Akamai.ImViewer.prototype.render = function() {
        try {
            var self = this;

            this.setDefault();
            var jsonUrl = "";

            if (this.options.dataSource) {
                this.startGalleria(this.options.dataSource, this.options.galleries);
                return;
            } else if (this.options.json) {
                jsonUrl = this.options.json;
            } else {
                this.options.baseUrl = this.options.baseUrl.replace(/\/$/, "");
                jsonUrl += this.options.baseUrl + "/.imviewer?aki_token=" + this.options.lunaToken + "&aki_collection=" + this.options.imageCollectionId;
            }

            $.ajax({
                type: "GET",
                dataType: "json",
                url: jsonUrl,
                contentType: "text/plain",
                success: function(json, textStatus, jqXHR) {
                    self.initializeViewer(json, self.options.viewerSelector);
                },
                error: function() {
                    var comingSoon = {};
                    if (self.options.dummyImage) {
                        comingSoon = $(document.createElement("img")).attr({
                            'src': self.options.dummyImage,
                            'class': 'img-responsive'
                        }).css('width', '100%');
                    } else {
                        comingSoon = $(document.createElement("p")).html('Image Comming Soon.').css('width', '100%');
                    }
                    $(self.options.viewerSelector).append(comingSoon);
                    console.error("Error retrieving the JSON file.");
                }
            });
        } catch (e) {
            console.error(e);
        }
    };

    /**
     * If there are un-specified required options, throw exception.
     * If there are un-specified optinal options, set them to the default value.
     */
    Akamai.ImViewer.prototype.setDefault = function() {
        // These are mandatory and must be set by the user
        if (!this.options.galleriaTheme) {
            throw "A galleriaTheme is required to initialize viewer. ";
        }
        if (!this.options.baseUrl) {
            throw "A base URL is required to initialize viewer. ";
        }
        if (!this.options.lunaToken && !this.options.json) {
            throw "A luna token is required to initialize viewer. ";
        }
        if (!this.options.imageCollectionId  && !this.options.json) {
            throw "An image collection ID is required to initialize viewer. ";
        }

        var defaultOptions = {
            rotationInverse: false,
            galleryContainer: null,
            windowWidthThreshold: '600px',
            viewerWidth: '100%',
            viewerHeight: '100%',
            smViewerWidth: '100%',
            smViewerHeight: '100%',
            thumbnailWidth: "50px",
            hoverFocus: false,
            showImageData: false,
            zoomContainer: null,
            zoomWidth: "200px",
            zoomHeight: "200px",
            zoomLevel: 2,
            enableZoom: true
        }

        this.options = $.extend(defaultOptions, this.options);
    };

    /**
     * Determine the dimensions of ImViewer and start Galleria with the dimensions
     */
    Akamai.ImViewer.prototype.initializeViewer = function(jsonData) {
        this.updateViewerDimension(this.options.viewerSelector);
        var galleries = [];
        var imageData = this.loadViewerData(jsonData, galleries);

        // attach a listener on the browser to detect when it has been resized
        $(window).on('resize', null, {
            jsonData: jsonData,
            index: this.options.index
        }, this.onViewportResize);

        this.resizeViewer(this.options.viewerSelector, this.options.viewerDimension);

        if (imageData.length > 0) {
            this.startGalleria(imageData, galleries);
        }
    }

    /**
     * Determine the dimensions of ImViewer and store the values in options
     */
    Akamai.ImViewer.prototype.updateViewerDimension = function () {
        var viewportWidth = parseInt($(window).width(), 10);
        var viewportHeight = parseInt($(window).height(), 10);
        if (viewportWidth < this.options.windowWidthThreshold.replace('px','')) {
            this.options.dimensions.width = Akamai.Util.convertToPx(this.options.smViewerWidth, viewportWidth);
            this.options.dimensions.height = Akamai.Util.convertToPx(this.options.smViewerHeight, viewportHeight);
        } else {
            this.options.dimensions.width = Akamai.Util.convertToPx(this.options.viewerWidth, viewportWidth);
            this.options.dimensions.height = Akamai.Util.convertToPx(this.options.viewerHeight, viewportHeight);
        }
    };

    /**
     * Resize the specified viewer to the dimensions stored in options
     */
    Akamai.ImViewer.prototype.resizeViewer = function () {
        var viewportWidth = $(window).width();
        var zoomContainer = this.options.zoomContainer;

        $(this.options.viewerSelector).css('width', this.options.dimensions.width);
        $(this.options.viewerSelector).css('height', this.options.dimensions.height);

        if (zoomContainer && parseInt(viewportWidth, 10) < this.options.windowWidthThreshold.replace('px','')) {
            $(zoomContainer).hide(0);
        } else {
            $(zoomContainer).show(0);
        }
    };

    /**
     * Updates the ImViewer dimension and the image data when the viewport (i.e. browser window) resizes.
     */
    Akamai.ImViewer.prototype.onViewportResize = function(event) {
        var index = event.data.index;
        var self = Akamai.ImViewers[index];
        if (Date.now() - self.options.lastResizeTime < 50) {
            return;
        }

        var galleria = Galleria.get(index);
        var galleries = [];
        var oldWidth = self.options.dimensions.width;
        self.updateViewerDimension();
        self.resizeViewer();
        self.options.lastResizeTime = Date.now();

        var newImages = self.loadViewerData(event.data.jsonData, galleries);
        galleria.setOptions({
            show: galleria.getIndex()
        });
        galleria.load(newImages);
    };

    /**
     * Start the specified galleria with given options and datas.
     */
    Akamai.ImViewer.prototype.startGalleria = function (imageData, galleries) {
        Galleria.loadTheme(this.options.galleriaTheme);

        $.extend(true, this.options, {
            dataSource: imageData,
            wait: true,
            transition: "fade",
            preload: 0,
            galleries: galleries,
            imageData: imageData,
            carouselSteps: 1,
            lightbox: false,
            maxScaleRatio: 1,
            metadata: ["dimensions", "size", "type"]
        });

        if (this.options.viewerSelector) {
            Galleria.run(this.options.viewerSelector, this.options);
        } else {
            console.error("Viewer needs a selector to initialize itself in");
        }
    };

    /**
     * Parse the jsonData into objects that Galleria can use.
     */
    Akamai.ImViewer.prototype.loadViewerData = function(jsonData, galleries) {
        var imageData = [];
        var galleryIndex = 0;

        this.updateAkiQueryParams(this.options.viewerSelector);
        var akiQueryParams = this.options.akiQueryParams;
        var argObject = {
            baseUrl: this.options.baseUrl,
            akiQueryParams: this.options.akiQueryParams,
            allowInnerGallery: true,
            allowThumbnail: true
        };

        jsonData.items.forEach(function(currentItem) {
            try{
                switch (currentItem.type) {
                    case "Gallery":
                        currentItem.galleryIndex = galleryIndex;
                        var thisGallery = Akamai.parseToImageData(currentItem, argObject);
                        galleries.push(thisGallery);
                        if (currentItem.galleryIndex == this.options.currentGalleryIndex) {
                            imageData = imageData.concat(thisGallery.items);
                        }
                        galleryIndex++;
                        break;
                    case "Rotatable":
                        if (this.options.rotationInverse) {
                            currentItem.items.reverse();
                        }
                    case "AkaImage":
                    case "Image":
                        imageData.push(Akamai.parseToImageData(currentItem, argObject));
                        break;
                    default:
                        throw "Invalid type: " + currentItem.type;
                }
            } catch (e) {
                console.error(e);
            }
        }, this);

        return imageData;
    };

    /**
     * Updates the Akami query parameters (e.g. aki_width) and store them in options
     */
    Akamai.ImViewer.prototype.updateAkiQueryParams = function() {
        this.updateViewerDimension(this.options.viewerSelector);

        var viewerWidth = this.options.dimensions.width;
        if (viewerWidth > this.options.bigWidth) {
            this.options.imageWidth = viewerWidth;
            this.options.bigWidth = viewerWidth * this.options.zoomLevel;
        } else if (viewerWidth > this.options.imageWidth) {
            this.options.imageWidth = this.options.bigWidth;
            this.options.bigWidth = viewerWidth * this.options.zoomLevel;
        } else if (viewerWidth * this.options.zoomLevel > this.options.bigWidth) {
            this.options.bigWidth = viewerWidth * this.options.zoomLevel;
        }

        var akiQueryParams = {};
        var akiPolicy = "";
        var akiPolicyThumb = "";
        var akiDensity = ""
        var akiThumbWidth = "aki_width=" + Akamai.Util.convertToPx(this.options.thumbnailWidth, $(".galleria-thumbnails-list").width());
        var akiWidth = "aki_width=" + this.options.imageWidth;
        var akiWidthLarge = "aki_width=" + this.options.bigWidth;

        if (OptimalImageSelector.getIsRetinaDisplay()) {
            akiDensity = "aki_density=2";
        } else {
            akiDensity = "aki_density=1";
        }

        if (this.options.policy) {
            akiPolicy = "aki_policy=" + this.options.policy;
            akiQueryParams.image = "&" + akiPolicy + "&" + akiWidth + "&" + akiDensity;
            akiQueryParams.big = "&" + akiPolicy + "&" + akiWidthLarge + "&" + akiDensity;
        } else {
            akiQueryParams.image = "&" + akiWidth + "&" + akiDensity;
            akiQueryParams.big = "&" + akiWidthLarge + "&" + akiDensity;
        }

        if (this.options.policyThumb) {
            akiPolicyThumb = "aki_policy=" + this.options.policyThumb;
            akiQueryParams.thumb = "&" + akiPolicyThumb + "&" + akiThumbWidth + "&" + akiDensity;
        } else {
            akiQueryParams.thumb = "&" + akiThumbWidth + "&" + akiDensity;
        }

        this.options.akiQueryParams = akiQueryParams;
    };

    /**
     * Calls the constructor for ImViewer for each of the selected HTML element.
     */
    $.fn.viewer = function(options) {
        var $this = $(this);
        var data = $this.data('imViewer');

        if (!data) {
            $.data($this, 'imViewer', new Akamai.ImViewer(this, options));
        }
    };

})(jQuery, window.Akamai = window.Akamai || {});<commit_msg>small typo<commit_after>/*
 * Copyright 2015 Akamai Technologies, 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.
 */

/**
 * @requires jQuery and Galleria
 */
(function($, Akamai) {

    /**
     * Array that stores the ImViewer instances
     */
    Akamai.ImViewers = [];

    /**
     * Construct and render the ImViewer
     * @constructor
     */
    Akamai.ImViewer = function(element, options) {
        this.element = $(element);
        this.options = $.extend(true, {}, options);

        Akamai.ImViewers.push(this);
        this.options.index = Akamai.ImViewers.length - 1;

        this.options.viewerSelector = (this.element.attr("id")) ? ("#" + this.element.attr("id")) : ("." + this.element.attr("class")).replace(' ', '.');
        this.options.currentGalleryIndex = this.options.currentGalleryIndex || 0;
        this.options.dimensions = this.options.dimensions || {};
        this.options.imageWidth = this.options.imageWidth || 0;
        this.options.bigWidth = this.options.bigWidth || 0;
        this.options.lastResizeTime = this.options.lastResizeTime || 0;
        this.render(this.element);
    };

    /**
     * Re-initialize the specified ImViewer with new options.
     * @function restartGalleria
     * @memberof Akamai.ImViewer
     * @static
     */
    Akamai.ImViewer.restartGalleria = function(options) {
        Galleria.get(options.index).destroy();
        Akamai.ImViewers.splice(options.index, 1);

        // re-index the ImViewer and Galleria instances
        for (var i = 0; i < Akamai.ImViewers.length; i++) {
            Akamai.ImViewers[i].options.index = i;
            Galleria.get(i)._options.index = i;
        }

        $(options.galleryContainer).empty();
        $(options.zoomContainer).empty();
        $(options.viewerSelector).viewer(options);
    };

    /**
     * Load data for ImViewer and then start the render process.
     */
    Akamai.ImViewer.prototype.render = function() {
        try {
            var self = this;

            this.setDefault();
            var jsonUrl = "";

            if (this.options.dataSource) {
                this.startGalleria(this.options.dataSource, this.options.galleries);
                return;
            } else if (this.options.json) {
                jsonUrl = this.options.json;
            } else {
                this.options.baseUrl = this.options.baseUrl.replace(/\/$/, "");
                jsonUrl += this.options.baseUrl + "/.imviewer?aki_token=" + this.options.lunaToken + "&aki_collection=" + this.options.imageCollectionId;
            }

            $.ajax({
                type: "GET",
                dataType: "json",
                url: jsonUrl,
                contentType: "text/plain",
                success: function(json, textStatus, jqXHR) {
                    self.initializeViewer(json, self.options.viewerSelector);
                },
                error: function() {
                    var comingSoon = {};
                    if (self.options.dummyImage) {
                        comingSoon = $(document.createElement("img")).attr({
                            'src': self.options.dummyImage,
                            'class': 'img-responsive'
                        }).css('width', '100%');
                    } else {
                        comingSoon = $(document.createElement("p")).html('Image Not Available').css('width', '100%');
                    }
                    $(self.options.viewerSelector).append(comingSoon);
                    console.error("Error retrieving the JSON file.");
                }
            });
        } catch (e) {
            console.error(e);
        }
    };

    /**
     * If there are un-specified required options, throw exception.
     * If there are un-specified optinal options, set them to the default value.
     */
    Akamai.ImViewer.prototype.setDefault = function() {
        // These are mandatory and must be set by the user
        if (!this.options.galleriaTheme) {
            throw "A galleriaTheme is required to initialize viewer. ";
        }
        if (!this.options.baseUrl) {
            throw "A base URL is required to initialize viewer. ";
        }
        if (!this.options.lunaToken && !this.options.json) {
            throw "A luna token is required to initialize viewer. ";
        }
        if (!this.options.imageCollectionId  && !this.options.json) {
            throw "An image collection ID is required to initialize viewer. ";
        }

        var defaultOptions = {
            rotationInverse: false,
            galleryContainer: null,
            windowWidthThreshold: '600px',
            viewerWidth: '100%',
            viewerHeight: '100%',
            smViewerWidth: '100%',
            smViewerHeight: '100%',
            thumbnailWidth: "50px",
            hoverFocus: false,
            showImageData: false,
            zoomContainer: null,
            zoomWidth: "200px",
            zoomHeight: "200px",
            zoomLevel: 2,
            enableZoom: true
        }

        this.options = $.extend(defaultOptions, this.options);
    };

    /**
     * Determine the dimensions of ImViewer and start Galleria with the dimensions
     */
    Akamai.ImViewer.prototype.initializeViewer = function(jsonData) {
        this.updateViewerDimension(this.options.viewerSelector);
        var galleries = [];
        var imageData = this.loadViewerData(jsonData, galleries);

        // attach a listener on the browser to detect when it has been resized
        $(window).on('resize', null, {
            jsonData: jsonData,
            index: this.options.index
        }, this.onViewportResize);

        this.resizeViewer(this.options.viewerSelector, this.options.viewerDimension);

        if (imageData.length > 0) {
            this.startGalleria(imageData, galleries);
        }
    }

    /**
     * Determine the dimensions of ImViewer and store the values in options
     */
    Akamai.ImViewer.prototype.updateViewerDimension = function () {
        var viewportWidth = parseInt($(window).width(), 10);
        var viewportHeight = parseInt($(window).height(), 10);
        if (viewportWidth < this.options.windowWidthThreshold.replace('px','')) {
            this.options.dimensions.width = Akamai.Util.convertToPx(this.options.smViewerWidth, viewportWidth);
            this.options.dimensions.height = Akamai.Util.convertToPx(this.options.smViewerHeight, viewportHeight);
        } else {
            this.options.dimensions.width = Akamai.Util.convertToPx(this.options.viewerWidth, viewportWidth);
            this.options.dimensions.height = Akamai.Util.convertToPx(this.options.viewerHeight, viewportHeight);
        }
    };

    /**
     * Resize the specified viewer to the dimensions stored in options
     */
    Akamai.ImViewer.prototype.resizeViewer = function () {
        var viewportWidth = $(window).width();
        var zoomContainer = this.options.zoomContainer;

        $(this.options.viewerSelector).css('width', this.options.dimensions.width);
        $(this.options.viewerSelector).css('height', this.options.dimensions.height);

        if (zoomContainer && parseInt(viewportWidth, 10) < this.options.windowWidthThreshold.replace('px','')) {
            $(zoomContainer).hide(0);
        } else {
            $(zoomContainer).show(0);
        }
    };

    /**
     * Updates the ImViewer dimension and the image data when the viewport (i.e. browser window) resizes.
     */
    Akamai.ImViewer.prototype.onViewportResize = function(event) {
        var index = event.data.index;
        var self = Akamai.ImViewers[index];
        if (Date.now() - self.options.lastResizeTime < 50) {
            return;
        }

        var galleria = Galleria.get(index);
        var galleries = [];
        var oldWidth = self.options.dimensions.width;
        self.updateViewerDimension();
        self.resizeViewer();
        self.options.lastResizeTime = Date.now();

        var newImages = self.loadViewerData(event.data.jsonData, galleries);
        galleria.setOptions({
            show: galleria.getIndex()
        });
        galleria.load(newImages);
    };

    /**
     * Start the specified galleria with given options and datas.
     */
    Akamai.ImViewer.prototype.startGalleria = function (imageData, galleries) {
        Galleria.loadTheme(this.options.galleriaTheme);

        $.extend(true, this.options, {
            dataSource: imageData,
            wait: true,
            transition: "fade",
            preload: 0,
            galleries: galleries,
            imageData: imageData,
            carouselSteps: 1,
            lightbox: false,
            maxScaleRatio: 1,
            metadata: ["dimensions", "size", "type"]
        });

        if (this.options.viewerSelector) {
            Galleria.run(this.options.viewerSelector, this.options);
        } else {
            console.error("Viewer needs a selector to initialize itself in");
        }
    };

    /**
     * Parse the jsonData into objects that Galleria can use.
     */
    Akamai.ImViewer.prototype.loadViewerData = function(jsonData, galleries) {
        var imageData = [];
        var galleryIndex = 0;

        this.updateAkiQueryParams(this.options.viewerSelector);
        var akiQueryParams = this.options.akiQueryParams;
        var argObject = {
            baseUrl: this.options.baseUrl,
            akiQueryParams: this.options.akiQueryParams,
            allowInnerGallery: true,
            allowThumbnail: true
        };

        jsonData.items.forEach(function(currentItem) {
            try{
                switch (currentItem.type) {
                    case "Gallery":
                        currentItem.galleryIndex = galleryIndex;
                        var thisGallery = Akamai.parseToImageData(currentItem, argObject);
                        galleries.push(thisGallery);
                        if (currentItem.galleryIndex == this.options.currentGalleryIndex) {
                            imageData = imageData.concat(thisGallery.items);
                        }
                        galleryIndex++;
                        break;
                    case "Rotatable":
                        if (this.options.rotationInverse) {
                            currentItem.items.reverse();
                        }
                    case "AkaImage":
                    case "Image":
                        imageData.push(Akamai.parseToImageData(currentItem, argObject));
                        break;
                    default:
                        throw "Invalid type: " + currentItem.type;
                }
            } catch (e) {
                console.error(e);
            }
        }, this);

        return imageData;
    };

    /**
     * Updates the Akami query parameters (e.g. aki_width) and store them in options
     */
    Akamai.ImViewer.prototype.updateAkiQueryParams = function() {
        this.updateViewerDimension(this.options.viewerSelector);

        var viewerWidth = this.options.dimensions.width;
        if (viewerWidth > this.options.bigWidth) {
            this.options.imageWidth = viewerWidth;
            this.options.bigWidth = viewerWidth * this.options.zoomLevel;
        } else if (viewerWidth > this.options.imageWidth) {
            this.options.imageWidth = this.options.bigWidth;
            this.options.bigWidth = viewerWidth * this.options.zoomLevel;
        } else if (viewerWidth * this.options.zoomLevel > this.options.bigWidth) {
            this.options.bigWidth = viewerWidth * this.options.zoomLevel;
        }

        var akiQueryParams = {};
        var akiPolicy = "";
        var akiPolicyThumb = "";
        var akiDensity = ""
        var akiThumbWidth = "aki_width=" + Akamai.Util.convertToPx(this.options.thumbnailWidth, $(".galleria-thumbnails-list").width());
        var akiWidth = "aki_width=" + this.options.imageWidth;
        var akiWidthLarge = "aki_width=" + this.options.bigWidth;

        if (OptimalImageSelector.getIsRetinaDisplay()) {
            akiDensity = "aki_density=2";
        } else {
            akiDensity = "aki_density=1";
        }

        if (this.options.policy) {
            akiPolicy = "aki_policy=" + this.options.policy;
            akiQueryParams.image = "&" + akiPolicy + "&" + akiWidth + "&" + akiDensity;
            akiQueryParams.big = "&" + akiPolicy + "&" + akiWidthLarge + "&" + akiDensity;
        } else {
            akiQueryParams.image = "&" + akiWidth + "&" + akiDensity;
            akiQueryParams.big = "&" + akiWidthLarge + "&" + akiDensity;
        }

        if (this.options.policyThumb) {
            akiPolicyThumb = "aki_policy=" + this.options.policyThumb;
            akiQueryParams.thumb = "&" + akiPolicyThumb + "&" + akiThumbWidth + "&" + akiDensity;
        } else {
            akiQueryParams.thumb = "&" + akiThumbWidth + "&" + akiDensity;
        }

        this.options.akiQueryParams = akiQueryParams;
    };

    /**
     * Calls the constructor for ImViewer for each of the selected HTML element.
     */
    $.fn.viewer = function(options) {
        var $this = $(this);
        var data = $this.data('imViewer');

        if (!data) {
            $.data($this, 'imViewer', new Akamai.ImViewer(this, options));
        }
    };

})(jQuery, window.Akamai = window.Akamai || {});
<|endoftext|>


<commit_before>// The logic behind the magic. It is very unoptimized as it is a work in progress and there is a lot of experimentation.

function colorBasedOnState(tile) {
    var normalizedValue = Math.floor(tile.density * 255);
    var intensity = (normalizedValue).toString(16);
    if (intensity.length < 2) {
        intensity = '0' + intensity;
    }
    if (tile.infected) {
        return '#00' + intensity + '00';
    } else {
        return '#' + intensity + '0000';
    }
}

var game = {};
game.infection = {
    // Used to determine how likely the infection is to spreading.
    contagion_multiplier: 0.4,
    // How much of the infected population survives per tick.
    survival_multiplier: 0.8,
    // The minimum population density required for a tile to continue active
    minimum_population_density: 0.4
};

function getRandomBetween(minimum, maximum) {
    var delta = maximum - minimum;
    return minimum + delta * Math.random();
}

function setUp() {
    var minimum_tile_population_density = 0.2;
    var maximum_tile_population_density = 0.8;
    game.running = false;
    game.map = {};
    game.map.tiles = [];
    var canvas = document.getElementById('canvas');
    var context = canvas.getContext('2d');
    var width = canvas.width;
    var height = canvas.height;
    var tilesPerRow = game.tilesPerRow = 20;
    context.fillRect(0, 0, width, height);
    if (width !== height || width < 0) {
        throw Error('Expected a square canvas.');
    }
    if (width % tilesPerRow !== 0) {
        throw Error('Expected the side of the canvas to be a multiple of 20.');
    }
    var canvasSide = width;
    var squareSide = width / tilesPerRow;
    for (var y = 0; y <= canvasSide - squareSide; y += squareSide) {
        var tileRow = [];
        for (var x = 0; x <= canvasSide - squareSide; x += squareSide) {
            var tile = {
                'density': getRandomBetween(minimum_tile_population_density, maximum_tile_population_density),
                'infected': false
            };

            tileRow.push(tile);
        }
        game.map.tiles.push(tileRow);
    }
    game.canvas = canvas;
    game.updateCanvas();

    canvas.addEventListener('click', function (event) {
        if (!game.running) {
            var mousePosition = getMousePosition(canvas, event);
            var tilePosition = translateToTilePosition(canvas, mousePosition, tilesPerRow);
            game.map.tiles[tilePosition.y][tilePosition.x].infected = true;
            game.running = true;
        }
    }, false);
}

function getMousePosition(canvas, event) {
    var rectangle = canvas.getBoundingClientRect();
    return {
        x: event.clientX - rectangle.left,
        y: event.clientY - rectangle.top
    };
}

function translateToTilePosition(canvas, position, tilesPerRow) {
    var tileWidth = canvas.width / tilesPerRow;
    var tileHeight = canvas.height / tilesPerRow;
    return {x: Math.floor(position.x / tileWidth), y: Math.floor(position.y / tileHeight)};
}

game.renderTick = function () {
    for (var y = 0; y < game.tilesPerRow; y++) {
        for (var x = 0; x < game.tilesPerRow; x++) {
            var tile = game.map.tiles[y][x];
            if (tile.infected && tile.density != 0) {
                var neighbors = [[x - 1, y], [x, y - 1], [x, y + 1], [x + 1, y]];
                for (var i = 0; i < neighbors.length; i++) {
                    var neighbor = neighbors[i];
                    if (0 <= neighbor[0] && neighbor[0] < game.tilesPerRow) {
                        if (0 <= neighbor[1] && neighbor[1] < game.tilesPerRow) {
                            var adjacentTile = game.map.tiles[neighbor[1]][neighbor[0]];
                            if (!adjacentTile.infected) {
                                if (Math.random() < game.infection.contagion_multiplier * tile.density) {
                                    adjacentTile.infected = true;
                                }
                            }
                        }
                    }
                }
                if (tile.density < game.infection.minimum_population_density) {
                    tile.density = 0;
                } else {
                    tile.density *= 0.8;
                }
            }
        }
    }
};

game.updateCanvas = function () {
    var squareSide = game.canvas.width / game.tilesPerRow;
    var context = game.canvas.getContext("2d");
    for (var y = 0; y < game.tilesPerRow; y++) {
        for (var x = 0; x < game.tilesPerRow; x++) {
            context.fillStyle = colorBasedOnState(game.map.tiles[y][x]);
            context.fillRect(x * squareSide, y * squareSide, squareSide, squareSide);
        }
    }
};

(function () {
    setUp();
    var tickLength = 200; // 200 milliseconds.
    game.lastTickTimeFrame = window.performance.now();
    function main(timeFrame) {
        window.requestAnimationFrame(main); // A DOMHighResTimeStamp will be provided to the callback
        if (game.running) {
            if (game.lastTickTimeFrame + tickLength < timeFrame) {
                game.renderTick();
                game.updateCanvas();
                game.lastTickTimeFrame = timeFrame;
            }
        }
    }

    main();
})();
<commit_msg>The infection should spread a little easier<commit_after>// The logic behind the magic. It is very unoptimized as it is a work in progress and there is a lot of experimentation.

function colorBasedOnState(tile) {
    var normalizedValue = Math.floor(tile.density * 255);
    var intensity = (normalizedValue).toString(16);
    if (intensity.length < 2) {
        intensity = '0' + intensity;
    }
    if (tile.infected) {
        return '#00' + intensity + '00';
    } else {
        return '#' + intensity + '0000';
    }
}

var game = {};
game.infection = {
    // Used to determine how likely the infection is to spreading.
    contagion_multiplier: 0.6,
    // How much of the infected population survives per tick.
    survival_multiplier: 0.8,
    // The minimum population density required for a tile to continue active
    minimum_population_density: 0.4
};

function getRandomBetween(minimum, maximum) {
    var delta = maximum - minimum;
    return minimum + delta * Math.random();
}

function setUp() {
    var minimum_tile_population_density = 0.2;
    var maximum_tile_population_density = 0.8;
    game.running = false;
    game.map = {};
    game.map.tiles = [];
    var canvas = document.getElementById('canvas');
    var context = canvas.getContext('2d');
    var width = canvas.width;
    var height = canvas.height;
    var tilesPerRow = game.tilesPerRow = 20;
    context.fillRect(0, 0, width, height);
    if (width !== height || width < 0) {
        throw Error('Expected a square canvas.');
    }
    if (width % tilesPerRow !== 0) {
        throw Error('Expected the side of the canvas to be a multiple of 20.');
    }
    var canvasSide = width;
    var squareSide = width / tilesPerRow;
    for (var y = 0; y <= canvasSide - squareSide; y += squareSide) {
        var tileRow = [];
        for (var x = 0; x <= canvasSide - squareSide; x += squareSide) {
            var tile = {
                'density': getRandomBetween(minimum_tile_population_density, maximum_tile_population_density),
                'infected': false
            };

            tileRow.push(tile);
        }
        game.map.tiles.push(tileRow);
    }
    game.canvas = canvas;
    game.updateCanvas();

    canvas.addEventListener('click', function (event) {
        if (!game.running) {
            var mousePosition = getMousePosition(canvas, event);
            var tilePosition = translateToTilePosition(canvas, mousePosition, tilesPerRow);
            game.map.tiles[tilePosition.y][tilePosition.x].infected = true;
            game.running = true;
        }
    }, false);
}

function getMousePosition(canvas, event) {
    var rectangle = canvas.getBoundingClientRect();
    return {
        x: event.clientX - rectangle.left,
        y: event.clientY - rectangle.top
    };
}

function translateToTilePosition(canvas, position, tilesPerRow) {
    var tileWidth = canvas.width / tilesPerRow;
    var tileHeight = canvas.height / tilesPerRow;
    return {x: Math.floor(position.x / tileWidth), y: Math.floor(position.y / tileHeight)};
}

game.renderTick = function () {
    for (var y = 0; y < game.tilesPerRow; y++) {
        for (var x = 0; x < game.tilesPerRow; x++) {
            var tile = game.map.tiles[y][x];
            if (tile.infected && tile.density != 0) {
                var neighbors = [[x - 1, y], [x, y - 1], [x, y + 1], [x + 1, y]];
                for (var i = 0; i < neighbors.length; i++) {
                    var neighbor = neighbors[i];
                    if (0 <= neighbor[0] && neighbor[0] < game.tilesPerRow) {
                        if (0 <= neighbor[1] && neighbor[1] < game.tilesPerRow) {
                            var adjacentTile = game.map.tiles[neighbor[1]][neighbor[0]];
                            if (!adjacentTile.infected) {
                                if (Math.random() < game.infection.contagion_multiplier * tile.density) {
                                    adjacentTile.infected = true;
                                }
                            }
                        }
                    }
                }
                if (tile.density < game.infection.minimum_population_density) {
                    tile.density = 0;
                } else {
                    tile.density *= 0.8;
                }
            }
        }
    }
};

game.updateCanvas = function () {
    var squareSide = game.canvas.width / game.tilesPerRow;
    var context = game.canvas.getContext("2d");
    for (var y = 0; y < game.tilesPerRow; y++) {
        for (var x = 0; x < game.tilesPerRow; x++) {
            context.fillStyle = colorBasedOnState(game.map.tiles[y][x]);
            context.fillRect(x * squareSide, y * squareSide, squareSide, squareSide);
        }
    }
};

(function () {
    setUp();
    var tickLength = 200; // 200 milliseconds.
    game.lastTickTimeFrame = window.performance.now();
    function main(timeFrame) {
        window.requestAnimationFrame(main); // A DOMHighResTimeStamp will be provided to the callback
        if (game.running) {
            if (game.lastTickTimeFrame + tickLength < timeFrame) {
                game.renderTick();
                game.updateCanvas();
                game.lastTickTimeFrame = timeFrame;
            }
        }
    }

    main();
})();
<|endoftext|>


<commit_before>/* global google */

import './common'

let location = require('./location/locationSelector')
const templating = require('./template-render')
const browser = require('./browser')
const supportedCities = require('./location/supportedCities')

const buildMap = () => {
  return new google.maps.Map(document.querySelector('.js-map'), {
    zoom: 6,
    center: { lat: 52.776100, lng: -1.777515 }
  })
}

window.initMap = () => { }

const redirectToHubPage = function(locationId) {
  browser.redirect(`/${locationId}`)
}

const displayMap = function (hubs) {
  setTimeout(() => {
    const map = buildMap()

    hubs
      .forEach((l) => {
        const marker = new google.maps.Marker({
          position: { lat: l.latitude, lng: l.longitude },
          map: map,
          id: l.id,
          title: l.name,
          animation: google.maps.Animation.DROP,
          icon: {
            url: '/assets/img/map-pin.png',
            size: new google.maps.Size(34, 34),
            anchor: new google.maps.Point(15, 24)
          }
        })

        google.maps.event.addListener(marker, 'click', function() {
          redirectToHubPage(this.id)
        })
      })
  }, 1000)
}

const init = () => {
  const theData = {
    locations: [{ id: '', name: '- Select a hub -' }, ...supportedCities.locations]
  }
  const callback = function () {
    location.handler((result) => {
      if (result.length) {
        redirectToHubPage(result)
      }
    }, '.js-homepage-promo-location-selector')

    displayMap(supportedCities.locations)
  }

  templating.renderTemplate('js-content-tpl', theData, 'js-template-output', callback)
}

init()
<commit_msg>on hub change, set location<commit_after>/* global google */

import './common'

let location = require('./location/locationSelector')
const templating = require('./template-render')
const browser = require('./browser')
const supportedCities = require('./location/supportedCities')

const buildMap = () => {
  return new google.maps.Map(document.querySelector('.js-map'), {
    zoom: 6,
    center: { lat: 52.776100, lng: -1.777515 }
  })
}

window.initMap = () => { }

const redirectToHubPage = function(locationId) {
  location.setCurrent(locationId)
  browser.redirect(`/${locationId}`)
}

const displayMap = function (hubs) {
  setTimeout(() => {
    const map = buildMap()

    hubs
      .forEach((l) => {
        const marker = new google.maps.Marker({
          position: { lat: l.latitude, lng: l.longitude },
          map: map,
          id: l.id,
          title: l.name,
          animation: google.maps.Animation.DROP,
          icon: {
            url: '/assets/img/map-pin.png',
            size: new google.maps.Size(34, 34),
            anchor: new google.maps.Point(15, 24)
          }
        })

        google.maps.event.addListener(marker, 'click', function() {
          redirectToHubPage(this.id)
        })
      })
  }, 1000)
}

const init = () => {
  const theData = {
    locations: [{ id: '', name: '- Select a hub -' }, ...supportedCities.locations]
  }
  const callback = function () {
    location.handler((result) => {
      if (result.length) {
        redirectToHubPage(result)
      }
    }, '.js-homepage-promo-location-selector')

    displayMap(supportedCities.locations)
  }

  templating.renderTemplate('js-content-tpl', theData, 'js-template-output', callback)
}

init()
<|endoftext|>