<commit_before>'use strict';

/**
 * @ngdoc module
 * @name vxWamp
 * @description
 *
 * # vxWamp
 *
 * The `vxWamp` module provides seamless WAMPv2 integration, by wrapping AutobahnJS, for angular apps.
 *
 * ## Example
 * See {@link $wamp#example $wamp} for an example of configuring and using `vxWamp`.
 *
 *
 *

 */
/* global -vxWampModule */
var vxWampModule = angular.module('vxWamp', []).provider('$wamp', $WampProvider);

/**
 * @ngdoc provider
 * @name $wampProvider
 *
 * @description
 *
 * Used for accessing a WAMP resource.
 *
 * ## Example
 * See {@link $wamp#example $wamp} for an example of configuring and using `vxWamp`.
 *
 * ## Dependencies
 * Requires the {@link vxWamp `vxWamp`} module to be installed.
 */
function $WampProvider() {
    var options;

    /**
     * @ngdoc method
     * @name $wampProvider#init
     *
     * @param {Object} initOptions autobahnJS connection options
     *
     *    Object properties:
     *
     *      Required options:
     *
     *    - `url`: `{string=}` - the WebSocket URL of the WAMP router to connect to, e.g. ws://myserver.com:8080/ws
     *    - `realm`: `{string=}` - The WAMP realm to join, e.g. realm1
     *
     *    Optional options:
     *
     *      Options that control what kind of Deferreds to use:
     *
     *      - `use_es6_promises`: `{boolean=}` - use deferreds based on ES6 promises
     *      - `use_deferred`: `{callable=}` - if provided, use this deferred constructor, e.g. jQuery.Deferred or Q.defer
     *
     *      Options that control automatic reconnection:
     *
     *      - `max_retries`: `{integer=}` - Maximum number of reconnection attempts (default: 15)
     *      - `initial_retry_delay`: `{float=}` - Initial delay for reconnection attempt in seconds (default: 1.5).
     *      - `max_retry_delay`: `{float=}` - Maximum delay for reconnection attempts in seconds (default: 300).
     *      - `retry_delay_growth`: `{float=}` - The growth factor applied to the retry delay between reconnection attempts (default: 1.5).
     *      - `retry_delay_jitter`: `{float=}` - The standard deviation of a Gaussian to jitter the delay on each retry cycle as a fraction of the mean (default: 0.1).
     *
     * @description
     * Configures the AutobhanJS Service
     */
    this.init = function (initOptions) {
        options = initOptions || {};
    };

    this.$get = function ($rootScope, $q, $log) {

        /**
         * @ngdoc service
         * @name $wamp
         *
         * @description
         * `$wamp` give you access to the autobahnJS methods, call, register, subscribe, unsubscribe and publish.
         *
         * Requires the {@link vxWamp `vxWamp`} module to be installed.
         *
         * You can configure the WAMP connection through {@link vxWamp.$wampProvider $wampProvider}'s API.
         *
         * @example
         *
         * app.config(function ($wampProvider) {
         *      $wampProvider.init({
         *          url: 'ws://127.0.0.1:9000/',
         *          realm: 'realm1'
         *      });
         * })
         *
         *  app.controller("MyCtrl", function($scope, $wamp) {
         *
         *      // 1) subscribe to a topic
         *      function onevent(args) {
         *          $scope.hello = args[0];
         *      }
         *      $wamp.subscribe('com.myapp.hello', onevent);
         *
         *      // 2) publish an event
         *      $wamp.publish('com.myapp.hello', ['Hello, world!']);
         *
         *      // 3) register a procedure for remoting
         *      function add2(args) {
         *          return args[0] + args[1];
         *      }
         *      $wamp.register('com.myapp.add2', add2);
         *
         *      // 4) call a remote procedure
         *      $wamp.call('com.myapp.add2', [2, 3]).then(
         *          function (res) {
         *          $scope.add2 = res;
         *      });
         * });
         *
         *
         * @todo write more docs
         */

        var connection;

        var sessionDeferred = $q.defer();
        var sessionPromise = sessionDeferred.promise;

        var onChallengeDeferred = $q.defer();

        /**
         * @param session
         * @param method
         * @param extra
         * @returns {*}
         *
         * @description
         * Gets called when a Challenge Message is sent by the router
         */
        var onchallenge = function (session, method, extra) {

            $rootScope.$broadcast("$wamp.onchallenge", {
                promise: onChallengeDeferred,
                session: session,
                method: method,
                extra: extra
            });

            return onChallengeDeferred.promise;
        };

        /**
         * @param func
         * @returns {Function}
         *
         * @description
         * Wraps a callback with a function that calls scope.$apply(), so that the callback is added to the digest
         */
        function digestWrapper(func) {
            return function () {
                var cb = func.apply(this, arguments);
                $rootScope.$apply();
                return cb;
            };
        }

        options = angular.extend({onchallenge: digestWrapper(onchallenge), use_deferred: $q.defer}, options);

        connection = new autobahn.Connection(options);
        connection.onopen = digestWrapper(function (session) {
            $log.debug("Congrats!  You're connected to the WAMP server!");
            $rootScope.$broadcast("$wamp.open", session);

            sessionDeferred.resolve(session);
        });

        connection.onclose = digestWrapper(function (reason, details) {
            $log.debug("Connection Closed: ", reason);
            $rootScope.$broadcast("$wamp.close", {reason: reason, details: details});

        });

        /**
         * Subscription object which self manages reconnections
         * @param topic
         * @param handler
         * @param options
         * @param subscribedCallback
         * @returns {{}}
         * @constructor
         */
        var Subscription = function (topic, handler, options, subscribedCallback) {

            var subscription = {}, unregister, onOpen, deferred = $q.defer();

            handler = digestWrapper(handler);

            onOpen = function () {
                var p = connection.session.subscribe(topic, handler, options).then(
                    function (s) {
                        subscription = angular.extend(s, subscription);
                        deferred.resolve(subscription);
                        return s;
                    }
                );
                if (subscribedCallback) {
                    subscribedCallback(p);
                }

            };

            if (connection.isOpen) {
                onOpen();
            }

            unregister = $rootScope.$on("$wamp.open", onOpen);

            subscription.promise = deferred.promise;
            subscription.unsubscribe = function () {
                unregister(); //Remove the event listener, so this object can get cleaned up by gc
                return connection.session.unsubscribe(subscription);
            };

            return subscription;
        };

        return {
            connection: connection,
            open: function () {
                connection.open();
            },
            close: function () {
                connection.close();
            },
            subscribe: function (topic, handler, options, subscribedCallback) {
                return Subscription(topic, handler, options, subscribedCallback).promise;
            },
            unsubscribe: function (subscription) {
                return subscription.unsubscribe();
            },
            publish: function (topic, args, kwargs, options) {

                var deferred = $q.defer();

                sessionPromise.then(
                    function(session) {
                        $q.when(session.publish(topic, args, kwargs, options)).then(
                            function(publication) {
                                deferred.resolve(publication);
                            }
                        );
                     }
                );

                return deferred.promise;
            },
            register: function (procedure, endpoint, options) {

                endpoint = digestWrapper(endpoint);

                var deferred = $q.defer();

                sessionPromise.then(
                    function(session) {
                        $q.when(session.register(procedure, endpoint, option)).then(
                            function(registration) {
                                deferred.resolve(registration);
                            }
                        );
                    }
                );

                return deferred.promise;
            },
            call: function (procedure, args, kwargs, options) {

                var deferred = $q.defer();

                sessionPromise.then(
                    function(session) {
                        $q.when(session.call(procedure, args, kwargs, options)).then(
                            function(result) {
                                deferred.resolve(result);
                            }
                        );
                    }
                );

                return deferred.promise;
            }
        };
    };

    return this;

}
<commit_msg>removed unneeded q.when wrapping<commit_after>'use strict';

/**
 * @ngdoc module
 * @name vxWamp
 * @description
 *
 * # vxWamp
 *
 * The `vxWamp` module provides seamless WAMPv2 integration, by wrapping AutobahnJS, for angular apps.
 *
 * ## Example
 * See {@link $wamp#example $wamp} for an example of configuring and using `vxWamp`.
 *
 *
 *

 */
/* global -vxWampModule */
var vxWampModule = angular.module('vxWamp', []).provider('$wamp', $WampProvider);

/**
 * @ngdoc provider
 * @name $wampProvider
 *
 * @description
 *
 * Used for accessing a WAMP resource.
 *
 * ## Example
 * See {@link $wamp#example $wamp} for an example of configuring and using `vxWamp`.
 *
 * ## Dependencies
 * Requires the {@link vxWamp `vxWamp`} module to be installed.
 */
function $WampProvider() {
    var options;

    /**
     * @ngdoc method
     * @name $wampProvider#init
     *
     * @param {Object} initOptions autobahnJS connection options
     *
     *    Object properties:
     *
     *      Required options:
     *
     *    - `url`: `{string=}` - the WebSocket URL of the WAMP router to connect to, e.g. ws://myserver.com:8080/ws
     *    - `realm`: `{string=}` - The WAMP realm to join, e.g. realm1
     *
     *    Optional options:
     *
     *      Options that control what kind of Deferreds to use:
     *
     *      - `use_es6_promises`: `{boolean=}` - use deferreds based on ES6 promises
     *      - `use_deferred`: `{callable=}` - if provided, use this deferred constructor, e.g. jQuery.Deferred or Q.defer
     *
     *      Options that control automatic reconnection:
     *
     *      - `max_retries`: `{integer=}` - Maximum number of reconnection attempts (default: 15)
     *      - `initial_retry_delay`: `{float=}` - Initial delay for reconnection attempt in seconds (default: 1.5).
     *      - `max_retry_delay`: `{float=}` - Maximum delay for reconnection attempts in seconds (default: 300).
     *      - `retry_delay_growth`: `{float=}` - The growth factor applied to the retry delay between reconnection attempts (default: 1.5).
     *      - `retry_delay_jitter`: `{float=}` - The standard deviation of a Gaussian to jitter the delay on each retry cycle as a fraction of the mean (default: 0.1).
     *
     * @description
     * Configures the AutobhanJS Service
     */
    this.init = function (initOptions) {
        options = initOptions || {};
    };

    this.$get = function ($rootScope, $q, $log) {

        /**
         * @ngdoc service
         * @name $wamp
         *
         * @description
         * `$wamp` give you access to the autobahnJS methods, call, register, subscribe, unsubscribe and publish.
         *
         * Requires the {@link vxWamp `vxWamp`} module to be installed.
         *
         * You can configure the WAMP connection through {@link vxWamp.$wampProvider $wampProvider}'s API.
         *
         * @example
         *
         * app.config(function ($wampProvider) {
         *      $wampProvider.init({
         *          url: 'ws://127.0.0.1:9000/',
         *          realm: 'realm1'
         *      });
         * })
         *
         *  app.controller("MyCtrl", function($scope, $wamp) {
         *
         *      // 1) subscribe to a topic
         *      function onevent(args) {
         *          $scope.hello = args[0];
         *      }
         *      $wamp.subscribe('com.myapp.hello', onevent);
         *
         *      // 2) publish an event
         *      $wamp.publish('com.myapp.hello', ['Hello, world!']);
         *
         *      // 3) register a procedure for remoting
         *      function add2(args) {
         *          return args[0] + args[1];
         *      }
         *      $wamp.register('com.myapp.add2', add2);
         *
         *      // 4) call a remote procedure
         *      $wamp.call('com.myapp.add2', [2, 3]).then(
         *          function (res) {
         *          $scope.add2 = res;
         *      });
         * });
         *
         *
         * @todo write more docs
         */

        var connection;

        var sessionDeferred = $q.defer();
        var sessionPromise = sessionDeferred.promise;

        var onChallengeDeferred = $q.defer();

        /**
         * @param session
         * @param method
         * @param extra
         * @returns {*}
         *
         * @description
         * Gets called when a Challenge Message is sent by the router
         */
        var onchallenge = function (session, method, extra) {

            $rootScope.$broadcast("$wamp.onchallenge", {
                promise: onChallengeDeferred,
                session: session,
                method: method,
                extra: extra
            });

            return onChallengeDeferred.promise;
        };

        /**
         * @param func
         * @returns {Function}
         *
         * @description
         * Wraps a callback with a function that calls scope.$apply(), so that the callback is added to the digest
         */
        function digestWrapper(func) {
            return function () {
                var cb = func.apply(this, arguments);
                $rootScope.$apply();
                return cb;
            };
        }

        options = angular.extend({onchallenge: digestWrapper(onchallenge), use_deferred: $q.defer}, options);

        connection = new autobahn.Connection(options);
        connection.onopen = digestWrapper(function (session) {
            $log.debug("Congrats!  You're connected to the WAMP server!");
            $rootScope.$broadcast("$wamp.open", session);

            sessionDeferred.resolve(session);
        });

        connection.onclose = digestWrapper(function (reason, details) {
            $log.debug("Connection Closed: ", reason);
            $rootScope.$broadcast("$wamp.close", {reason: reason, details: details});

        });

        /**
         * Subscription object which self manages reconnections
         * @param topic
         * @param handler
         * @param options
         * @param subscribedCallback
         * @returns {{}}
         * @constructor
         */
        var Subscription = function (topic, handler, options, subscribedCallback) {

            var subscription = {}, unregister, onOpen, deferred = $q.defer();

            handler = digestWrapper(handler);

            onOpen = function () {
                var p = connection.session.subscribe(topic, handler, options).then(
                    function (s) {
                        subscription = angular.extend(s, subscription);
                        deferred.resolve(subscription);
                        return s;
                    }
                );
                if (subscribedCallback) {
                    subscribedCallback(p);
                }

            };

            if (connection.isOpen) {
                onOpen();
            }

            unregister = $rootScope.$on("$wamp.open", onOpen);

            subscription.promise = deferred.promise;
            subscription.unsubscribe = function () {
                unregister(); //Remove the event listener, so this object can get cleaned up by gc
                return connection.session.unsubscribe(subscription);
            };

            return subscription;
        };

        return {
            connection: connection,
            open: function () {
                connection.open();
            },
            close: function () {
                connection.close();
            },
            subscribe: function (topic, handler, options, subscribedCallback) {
                return Subscription(topic, handler, options, subscribedCallback).promise;
            },
            unsubscribe: function (subscription) {
                return subscription.unsubscribe();
            },
            publish: function (topic, args, kwargs, options) {

                var deferred = $q.defer();

                sessionPromise.then(
                    function(session) {
                        var publishPromise = session.publish(topic, args, kwargs, options);

                        if (publishPromise) {
                            publishPromise.then(
                                function(publication) {
                                    deferred.resolve(publication);
                                }
                            );
                        }
                        else
                            deferred.resolve(true);
                     }
                );

                return deferred.promise;
            },
            register: function (procedure, endpoint, options) {

                endpoint = digestWrapper(endpoint);

                var deferred = $q.defer();

                sessionPromise.then(
                    function(session) {
                        session.register(procedure, endpoint, options).then(
                            function(registration) {
                                deferred.resolve(registration);
                            }
                        );
                    }
                );

                return deferred.promise;
            },
            call: function (procedure, args, kwargs, options) {

                var deferred = $q.defer();

                sessionPromise.then(
                    function(session) {
                        session.call(procedure, args, kwargs, options).then(
                            function(result) {
                                deferred.resolve(result);
                            }
                        );
                    }
                );

                return deferred.promise;
            }
        };
    };

    return this;

}
<|endoftext|>


<commit_before>import init from './init';
import createParentElement from '../util/create-parent-element'

var DocumentFragmentPrototype = DocumentFragment.prototype;

function decorateFragmentMethods (frag) {
  frag.appendChild = function (el) {
    return DocumentFragmentPrototype.appendChild.call(this, init(el));
  };

  frag.insertBefore = function (el, beforeEl) {
    return DocumentFragmentPrototype.insertBefore.call(this, init(el), beforeEl);
  };

  frag.replaceChild = function (el, replacedEl) {
    return DocumentFragmentPrototype.replaceChild.call(this, init(el), replacedEl);
  };

  frag.cloneNode = function () {
    var clone = DocumentFragmentPrototype.cloneNode.apply(this, arguments);
    decorateFragmentMethods(clone);
    for (var i = 0; i < clone.childElementCount; i++) {
      init(clone.childNodes[i]);
    }
    return clone;
  };
}

function createInitingFragment() {
  var frag = document.createDocumentFragment();
  decorateFragmentMethods(frag);
  return frag;
}

export default function (html) {
  var frag = createInitingFragment();
  if (typeof html === 'string') {
    var par = createParentElement(html);
    par.innerHTML = html;
    while (par.firstElementChild) {
      frag.appendChild(par.firstElementChild);
    }
  }
  return frag;
}
<commit_msg>Inline decorating of document fragment's methods for skate.fragment().<commit_after>import init from './init';
import createParentElement from '../util/create-parent-element'

var DocumentFragmentPrototype = DocumentFragment.prototype;

function decorateFragmentMethods (frag) {
  frag.appendChild = function (el) {
    return DocumentFragmentPrototype.appendChild.call(this, init(el));
  };

  frag.insertBefore = function (el, beforeEl) {
    return DocumentFragmentPrototype.insertBefore.call(this, init(el), beforeEl);
  };

  frag.replaceChild = function (el, replacedEl) {
    return DocumentFragmentPrototype.replaceChild.call(this, init(el), replacedEl);
  };

  frag.cloneNode = function () {
    var clone = DocumentFragmentPrototype.cloneNode.apply(this, arguments);
    decorateFragmentMethods(clone);
    for (var i = 0; i < clone.childElementCount; i++) {
      init(clone.childNodes[i]);
    }
    return clone;
  };
}

export default function (html) {
  var frag = document.createDocumentFragment();
  decorateFragmentMethods(frag);
  if (typeof html === 'string') {
    var par = createParentElement(html);
    par.innerHTML = html;
    while (par.firstElementChild) {
      frag.appendChild(par.firstElementChild);
    }
  }
  return frag;
}
<|endoftext|>


<commit_before>var webworkify = require('webworkify');
var queryParams = require('./query-params');
var utils = require('./utils');
var Renderer = require('./renderer');

var Base64 = require('js-base64').Base64;

function Compiler (editor, handleGithubCall, outputField, hidingRHP, updateFiles) {
  var renderer = new Renderer(editor, this, updateFiles);

  var compileJSON;
  var compilerAcceptsMultipleFiles;

  var previousInput = '';
  var sourceAnnotations = [];

  var cachedRemoteFiles = {};
  var worker = null;

  var compileTimeout = null;

  function onChange () {
    var input = editor.getValue();
    if (input === '') {
      editor.setCacheFileContent('');
      return;
    }
    if (input === previousInput) {
      return;
    }
    previousInput = input;
    if (compileTimeout) {
      window.clearTimeout(compileTimeout);
    }
    compileTimeout = window.setTimeout(compile, 300);
  }

  editor.onChangeSetup(onChange);

  var compile = function (missingInputs) {
    editor.clearAnnotations();
    sourceAnnotations = [];
    outputField.empty();
    var input = editor.getValue();
    editor.setCacheFileContent(input)

    var files = {};
    files[editor.getCacheFile()] = input;
    gatherImports(files, missingInputs, function (input, error) {
      outputField.empty();
      if (input === null) {
        renderer.error(error);
      } else {
        var optimize = queryParams.get().optimize;
        compileJSON(input, optimize ? 1 : 0);
      }
    });
  };
  this.compile = compile;

  this.addAnnotation = function (annotation) {
    sourceAnnotations[sourceAnnotations.length] = annotation;
    editor.setAnnotations(sourceAnnotations);
  };

  function onCompilerLoaded (setVersionText) {
    if (worker === null) {
      var compile;
      var missingInputs = [];
      if ('_compileJSONCallback' in Module) {
        compilerAcceptsMultipleFiles = true;
        var missingInputsCallback = Module.Runtime.addFunction(function (path, contents, error) {
          missingInputs.push(Module.Pointer_stringify(path));
        });
        var compileInternal = Module.cwrap('compileJSONCallback', 'string', [ 'string', 'number', 'number' ]);
        compile = function (input, optimize) {
          missingInputs.length = 0;
          return compileInternal(input, optimize, missingInputsCallback);
        };
      } else if ('_compileJSONMulti' in Module) {
        compilerAcceptsMultipleFiles = true;
        compile = Module.cwrap('compileJSONMulti', 'string', [ 'string', 'number' ]);
      } else {
        compilerAcceptsMultipleFiles = false;
        compile = Module.cwrap('compileJSON', 'string', [ 'string', 'number' ]);
      }
      compileJSON = function (source, optimize, cb) {
        try {
          var result = compile(source, optimize);
        } catch (exception) {
          result = JSON.stringify({ error: 'Uncaught JavaScript exception:\n' + exception });
        }
        compilationFinished(result, missingInputs);
      };
      setVersionText(Module.cwrap('version', 'string', [])());
    }
    previousInput = '';
    onChange();
  };
  this.onCompilerLoaded = onCompilerLoaded;

  function compilationFinished (result, missingInputs) {
    var data;
    var noFatalErrors = true; // ie warnings are ok

    try {
      data = JSON.parse(result);
    } catch (exception) {
      renderer.error('Invalid JSON output from the compiler: ' + exception);
      return;
    }

    if (data['error'] !== undefined) {
      renderer.error(data['error']);
      if (utils.errortype(data['error']) !== 'warning') {
        noFatalErrors = false;
      }
    }
    if (data['errors'] !== undefined) {
      data['errors'].forEach(function (err) {
        renderer.error(err);
        if (utils.errortype(err) !== 'warning') {
          noFatalErrors = false;
        }
      });
    }

    if (missingInputs !== undefined && missingInputs.length > 0) {
      compile(missingInputs);
    } else if (noFatalErrors && !hidingRHP()) {
      renderer.contracts(data, editor.getValue());
    }
  }

  this.loadVersion = function (usingWorker, version, setVersionText) {
    if (usingWorker) {
      loadWorker(version, setVersionText);
    } else {
      loadInternal(version, setVersionText);
    }
  };

  function loadInternal (version, setVersionText) {
    Module = null;
    // Set a safe fallback until the new one is loaded
    compileJSON = function(source, optimize) { compilationFinished('{}'); };

    var newScript = document.createElement('script');
    newScript.type = 'text/javascript';
    newScript.src = url;
    document.getElementsByTagName('head')[0].appendChild(newScript);
    var check = window.setInterval(function () {
      if (!Module) {
        return;
      }
      window.clearInterval(check);
      onCompilerLoaded(setVersionText);
    }, 200);
  }

  function loadWorker (version, setVersionText) {
    if (worker !== null) {
      worker.terminate();
    }
    worker = webworkify(require('./compiler-worker.js'));
    worker.addEventListener('message', function (msg) {
      var data = msg.data;
      switch (data.cmd) {
      case 'versionLoaded':
        setVersionText(data.data);
        compilerAcceptsMultipleFiles = !!data.acceptsMultipleFiles;
        onCompilerLoaded(setVersionText);
        break;
      case 'compiled':
        compilationFinished(data.data, data.missingInputs);
        break;
      };
    });
    worker.onerror = function (msg) { console.log(msg.data); };
    worker.addEventListener('error', function (msg) { console.log(msg.data); });
    compileJSON = function (source, optimize) {
      worker.postMessage({cmd: 'compile', source: source, optimize: optimize});
    };
    worker.postMessage({cmd: 'loadVersion', data: 'https://ethereum.github.io/solc-bin/bin/' + version});
  };

  function gatherImports (files, importHints, cb) {
    importHints = importHints || [];
    if (!compilerAcceptsMultipleFiles) {
      cb(files[editor.getCacheFile()]);
      return;
    }
    var importRegex = /^\s*import\s*[\'\"]([^\'\"]+)[\'\"];/g;
    var reloop = false;
    var githubMatch;
    do {
      reloop = false;
      for (var fileName in files) {
        var match;
        while (match = importRegex.exec(files[fileName])) {
          importHints.push(match[1]);
        }
      }
      while (importHints.length > 0) {
        var m = importHints.pop();
        if (m in files) {
          continue;
        }
        if (editor.hasFile(m)) {
          files[m] = window.localStorage[utils.fileKey(m)];
          reloop = true;
        } else if (m.startsWith('./') && editor.hasFile(m.slice(2))) {
          files[m] = window.localStorage[utils.fileKey(m.slice(2))];
          reloop = true;
        } else if (m in cachedRemoteFiles) {
          files[m] = cachedRemoteFiles[m];
          reloop = true;
        } else if (githubMatch = /^(https?:\/\/)?(www.)?github.com\/([^\/]*\/[^\/]*)\/(.*)/.exec(m)) {
          handleGithubCall(githubMatch[3], githubMatch[4], function (result) {
            if ('content' in result) {
              var content = Base64.decode(result.content);
              cachedRemoteFiles[m] = content;
              files[m] = content;
              gatherImports(files, importHints, cb);
            } else {
              cb(null, 'Unable to import "' + m + '"');
            }
          }).fail(function () {
            cb(null, 'Unable to import "' + m + '"');
          });
          return;
        } else {
          cb(null, 'Unable to import "' + m + '"');
          return;
        }
      }
    } while (reloop);
    cb(JSON.stringify({ 'sources': files }));
  }
}

module.exports = Compiler
<commit_msg>Compiler: onCompilerLoaded is not public anymore<commit_after>var webworkify = require('webworkify');
var queryParams = require('./query-params');
var utils = require('./utils');
var Renderer = require('./renderer');

var Base64 = require('js-base64').Base64;

function Compiler (editor, handleGithubCall, outputField, hidingRHP, updateFiles) {
  var renderer = new Renderer(editor, this, updateFiles);

  var compileJSON;
  var compilerAcceptsMultipleFiles;

  var previousInput = '';
  var sourceAnnotations = [];

  var cachedRemoteFiles = {};
  var worker = null;

  var compileTimeout = null;

  function onChange () {
    var input = editor.getValue();
    if (input === '') {
      editor.setCacheFileContent('');
      return;
    }
    if (input === previousInput) {
      return;
    }
    previousInput = input;
    if (compileTimeout) {
      window.clearTimeout(compileTimeout);
    }
    compileTimeout = window.setTimeout(compile, 300);
  }

  editor.onChangeSetup(onChange);

  var compile = function (missingInputs) {
    editor.clearAnnotations();
    sourceAnnotations = [];
    outputField.empty();
    var input = editor.getValue();
    editor.setCacheFileContent(input)

    var files = {};
    files[editor.getCacheFile()] = input;
    gatherImports(files, missingInputs, function (input, error) {
      outputField.empty();
      if (input === null) {
        renderer.error(error);
      } else {
        var optimize = queryParams.get().optimize;
        compileJSON(input, optimize ? 1 : 0);
      }
    });
  };
  this.compile = compile;

  this.addAnnotation = function (annotation) {
    sourceAnnotations[sourceAnnotations.length] = annotation;
    editor.setAnnotations(sourceAnnotations);
  };

  function onCompilerLoaded (setVersionText) {
    if (worker === null) {
      var compile;
      var missingInputs = [];
      if ('_compileJSONCallback' in Module) {
        compilerAcceptsMultipleFiles = true;
        var missingInputsCallback = Module.Runtime.addFunction(function (path, contents, error) {
          missingInputs.push(Module.Pointer_stringify(path));
        });
        var compileInternal = Module.cwrap('compileJSONCallback', 'string', [ 'string', 'number', 'number' ]);
        compile = function (input, optimize) {
          missingInputs.length = 0;
          return compileInternal(input, optimize, missingInputsCallback);
        };
      } else if ('_compileJSONMulti' in Module) {
        compilerAcceptsMultipleFiles = true;
        compile = Module.cwrap('compileJSONMulti', 'string', [ 'string', 'number' ]);
      } else {
        compilerAcceptsMultipleFiles = false;
        compile = Module.cwrap('compileJSON', 'string', [ 'string', 'number' ]);
      }
      compileJSON = function (source, optimize, cb) {
        try {
          var result = compile(source, optimize);
        } catch (exception) {
          result = JSON.stringify({ error: 'Uncaught JavaScript exception:\n' + exception });
        }
        compilationFinished(result, missingInputs);
      };
      setVersionText(Module.cwrap('version', 'string', [])());
    }
    previousInput = '';
    onChange();
  };

  function compilationFinished (result, missingInputs) {
    var data;
    var noFatalErrors = true; // ie warnings are ok

    try {
      data = JSON.parse(result);
    } catch (exception) {
      renderer.error('Invalid JSON output from the compiler: ' + exception);
      return;
    }

    if (data['error'] !== undefined) {
      renderer.error(data['error']);
      if (utils.errortype(data['error']) !== 'warning') {
        noFatalErrors = false;
      }
    }
    if (data['errors'] !== undefined) {
      data['errors'].forEach(function (err) {
        renderer.error(err);
        if (utils.errortype(err) !== 'warning') {
          noFatalErrors = false;
        }
      });
    }

    if (missingInputs !== undefined && missingInputs.length > 0) {
      compile(missingInputs);
    } else if (noFatalErrors && !hidingRHP()) {
      renderer.contracts(data, editor.getValue());
    }
  }

  this.loadVersion = function (usingWorker, version, setVersionText) {
    if (usingWorker) {
      loadWorker(version, setVersionText);
    } else {
      loadInternal(version, setVersionText);
    }
  };

  function loadInternal (version, setVersionText) {
    Module = null;
    // Set a safe fallback until the new one is loaded
    compileJSON = function(source, optimize) { compilationFinished('{}'); };

    var newScript = document.createElement('script');
    newScript.type = 'text/javascript';
    newScript.src = url;
    document.getElementsByTagName('head')[0].appendChild(newScript);
    var check = window.setInterval(function () {
      if (!Module) {
        return;
      }
      window.clearInterval(check);
      onCompilerLoaded(setVersionText);
    }, 200);
  }

  function loadWorker (version, setVersionText) {
    if (worker !== null) {
      worker.terminate();
    }
    worker = webworkify(require('./compiler-worker.js'));
    worker.addEventListener('message', function (msg) {
      var data = msg.data;
      switch (data.cmd) {
      case 'versionLoaded':
        setVersionText(data.data);
        compilerAcceptsMultipleFiles = !!data.acceptsMultipleFiles;
        onCompilerLoaded(setVersionText);
        break;
      case 'compiled':
        compilationFinished(data.data, data.missingInputs);
        break;
      };
    });
    worker.onerror = function (msg) { console.log(msg.data); };
    worker.addEventListener('error', function (msg) { console.log(msg.data); });
    compileJSON = function (source, optimize) {
      worker.postMessage({cmd: 'compile', source: source, optimize: optimize});
    };
    worker.postMessage({cmd: 'loadVersion', data: 'https://ethereum.github.io/solc-bin/bin/' + version});
  };

  function gatherImports (files, importHints, cb) {
    importHints = importHints || [];
    if (!compilerAcceptsMultipleFiles) {
      cb(files[editor.getCacheFile()]);
      return;
    }
    var importRegex = /^\s*import\s*[\'\"]([^\'\"]+)[\'\"];/g;
    var reloop = false;
    var githubMatch;
    do {
      reloop = false;
      for (var fileName in files) {
        var match;
        while (match = importRegex.exec(files[fileName])) {
          importHints.push(match[1]);
        }
      }
      while (importHints.length > 0) {
        var m = importHints.pop();
        if (m in files) {
          continue;
        }
        if (editor.hasFile(m)) {
          files[m] = window.localStorage[utils.fileKey(m)];
          reloop = true;
        } else if (m.startsWith('./') && editor.hasFile(m.slice(2))) {
          files[m] = window.localStorage[utils.fileKey(m.slice(2))];
          reloop = true;
        } else if (m in cachedRemoteFiles) {
          files[m] = cachedRemoteFiles[m];
          reloop = true;
        } else if (githubMatch = /^(https?:\/\/)?(www.)?github.com\/([^\/]*\/[^\/]*)\/(.*)/.exec(m)) {
          handleGithubCall(githubMatch[3], githubMatch[4], function (result) {
            if ('content' in result) {
              var content = Base64.decode(result.content);
              cachedRemoteFiles[m] = content;
              files[m] = content;
              gatherImports(files, importHints, cb);
            } else {
              cb(null, 'Unable to import "' + m + '"');
            }
          }).fail(function () {
            cb(null, 'Unable to import "' + m + '"');
          });
          return;
        } else {
          cb(null, 'Unable to import "' + m + '"');
          return;
        }
      }
    } while (reloop);
    cb(JSON.stringify({ 'sources': files }));
  }
}

module.exports = Compiler
<|endoftext|>


<commit_before>/**
 * Grunt Mustacher
 * https://github.com/malas34/grunt-mustacher
 *
 * Copyright (c) 2014 Matthieu Lassalvy
 * Licensed under the MIT license.
 *
 * HANDLEBARS
 * @see http://handlebarsjs.com/
 *
 */
/*jslint indent: 4 */
/*global module, require */
(function () {
    'use strict';
    var IncludeHelper,
        Path = require('path'),
        Grunt = require('grunt'),
        lodash = require('lodash'),
        Utils = require('./../task-utils'),
        Handlebars = require('handlebars'),
        lf = Grunt.util.linefeed,
        debug = Grunt.option('debug');

    IncludeHelper = function () {};

    IncludeHelper.prototype.register = function () {
        Handlebars.registerHelper('$include', this.render.bind(this));
    };

    IncludeHelper.prototype.render = function (path, options) {

        var data, root, content, // .hbs content
            absolute, // absolute .hbs path form system root
            relative, // relative path from cwd to .hbs
            errorOutput = 'Unable to load file',
            args = Utils.hasOptions(arguments);

        if (!args || args.length < 2 || !lodash.isString(path)) {
            throw new Error('IncludeHelper missing arguments');
        }

        data = Handlebars.createFrame(options.data || {});
        root = data.root;

        // @TODO to test file path
        absolute = Path.join(root.cwd, root.partials.src, path);
        absolute = Path.normalize(absolute + root.partials.ext);
        relative = Path.relative(root.cwd, absolute);
        relative = Path.join('.', relative );

        if (!Grunt.file.exists(relative)) {
            errorOutput = errorOutput + ' ' + relative;
            Grunt.log.error(errorOutput);
        } else {
            content = Grunt.file.read(relative);
            errorOutput = Handlebars.compile(content)(relative, {
                data: data
            }).trim();
        }

        if (debug) {
            output = '<!-- ' + relative + ' -->' + lf + output + lf + '<!-- endof ' + relative + ' -->';
        }

        return new Handlebars.SafeString(output.trim());
    };

    module.exports = IncludeHelper;

}());
<commit_msg>fix(tests): path to include file - travis<commit_after>/**
 * Grunt Mustacher
 * https://github.com/malas34/grunt-mustacher
 *
 * Copyright (c) 2014 Matthieu Lassalvy
 * Licensed under the MIT license.
 *
 * HANDLEBARS
 * @see http://handlebarsjs.com/
 *
 */
/*jslint indent: 4 */
/*global module, require */
(function () {
    'use strict';
    var IncludeHelper,
        Path = require('path'),
        Grunt = require('grunt'),
        lodash = require('lodash'),
        Utils = require('./../task-utils'),
        Handlebars = require('handlebars'),
        lf = Grunt.util.linefeed,
        debug = Grunt.option('debug');

    IncludeHelper = function () {};

    IncludeHelper.prototype.register = function () {
        Handlebars.registerHelper('$include', this.render.bind(this));
    };

    IncludeHelper.prototype.render = function (path, options) {

        var data, root, output, content, // .hbs content
            absolute, // absolute .hbs path form system root
            relative, // relative path from cwd to .hbs
            output = 'Unable to load file',
            args = Utils.hasOptions(arguments);

        if (!args || args.length < 2 || !lodash.isString(path)) {
            throw new Error('IncludeHelper missing arguments');
        }

        data = Handlebars.createFrame(options.data || {});
        root = data.root;

        // @TODO to test file path
        absolute = Path.join(root.cwd, root.partials.src, path);
        absolute = Path.normalize(absolute + root.partials.ext);
        relative = Path.relative(root.cwd, absolute);

        if (!Grunt.file.exists(relative)) {
            output = output + ' ' + relative;
            Grunt.log.error(output);
        } else {
            content = Grunt.file.read(relative);
            output = Handlebars.compile(content)(relative, {
                data: data
            }).trim();
        }

        if (debug) {
            output = '<!-- ' + relative + ' -->' + lf + output + lf + '<!-- endof ' + relative + ' -->';
        }

        return new Handlebars.SafeString(output.trim());

    };

    module.exports = IncludeHelper;

}());
<|endoftext|>


<commit_before>const Log = require('prhone-log');

module.exports = new Log('vulcanval', {
  history: false,
  scale: 2,
  throwErrors: true
});
<commit_msg>update: log<commit_after>const Log = require('prhone-log');

module.exports = new Log('VulcanVal', {
  history: false,
  scale: 2,
  throwErrors: true
});
<|endoftext|>


<commit_before>export default (msg, isVerbose = false) => {
  if (isVerbose) {
    console.log(`[METEOR-NOW] - ${msg}`); // eslint-disable-line no-console
  }
};
<commit_msg>logger will only work if user passes -d flag<commit_after>import { isDebug } from './utils';

export default (message) => {
  if (isDebug()) {
    console.log(`[METEOR-NOW] - ${message}`); // eslint-disable-line no-console
  }
};
<|endoftext|>


<commit_before>function openPre(data)
{
	var newWindow = window.open();
	if (!newWindow)
		return false;

	var html = "";
	html += "
";
	html += data;
	html += "
";

	newWindow.document.write(html);
	return newWindow;
}

var address = document.URL;
var name = document.title;
var body = document.getElementsByTagName("body")[0];
var text = "";

for (var i = 0; i < document.forms.length; i++) {
	var form_elements =  "len = " + document.forms[i].elements.length;
	for (var j = 0; j < document.forms[i].elements.length; j++) {
		var el = document.forms[i].elements[j];

		if (el.name != "") {
			if (form_elements == "")
				form_elements = '\t\t\t"' + el.name + '": "' + el.value + '"';
			else
				form_elements += ',\n\t\t\t"' + el.name + '": "' + el.value + '"';
		} else {
				form_elements += '((((' + el.id + '))))';
		}
	}

	var form_text = '\t\t"action": "' + document.forms[i].action + '",\n\t\t"method": "' + document.forms[i].method + '",\n\t\t"fields":\n\t\t{\n' + form_elements + '\n\t\t}';
	text += '{\n\t"type":"site",\n\t"name": "' + name + '",\n\t"address": "' + address + '",\n\t"form":\n\t{\n' + form_text + '\n\t}\n}\n';
}

openPre(text);
<commit_msg>revert all changes to form bookmarklet<commit_after>function openPre(data)
{
	var newWindow = window.open();
	if (!newWindow)
		return false;

	var html = "";
	html += "
";
	html += data;
	html += "
";

	newWindow.document.write(html);
	return newWindow;
}

var address = document.URL;
var name = document.title;
var body = document.getElementsByTagName("body")[0];
var text = "";

for (var i = 0; i < document.forms.length; i++) {
	var form = document.forms[i];

	var form_elements =  "";
	for (var j = 0; j < form.elements.length; j++) {
		var el = form.elements[j];

		if (el.name == "")
			continue;

		if (form_elements == "")
			form_elements = '\t\t\t"' + el.name + '": "' + el.value + '"';
		else
			form_elements += ',\n\t\t\t"' + el.name + '": "' + el.value + '"';
	}

	var form_text = '\t\t"action": "' + form.action + '",\n\t\t"method": "' + form.method + '",\n\t\t"fields":\n\t\t{\n' + form_elements + '\n\t\t}';
	text += '{\n\t"type":"site",\n\t"name": "' + name + '",\n\t"address": "' + address + '",\n\t"form":\n\t{\n' + form_text + '\n\t}\n}\n';
}

openPre(text);
<|endoftext|>


<commit_before><commit_msg>Allow for keywords as xml attribute names<commit_after><|endoftext|>


<commit_before>/*
   Copyright 2011 Lazar Laszlo (lazarsoft@gmail.com, www.lazarsoft.info)

   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.
*/

qrcode = {};
qrcode.imagedata = null;
qrcode.width = 0;
qrcode.height = 0;
qrcode.qrCodeSymbol = null;
qrcode.debug = false;
qrcode.maxImgSize = 1024*1024;

qrcode.sizeOfDataLengthInfo =  [  [ 10, 9, 8, 8 ],  [ 12, 11, 16, 10 ],  [ 14, 13, 16, 12 ] ];

qrcode.callback = null;

qrcode.decode = function(src){

    if(arguments.length==0)
    {
        var canvas_qr = document.getElementById("qr-canvas");
        var context = canvas_qr.getContext('2d');
        qrcode.width = canvas_qr.width;
        qrcode.height = canvas_qr.height;
        qrcode.imagedata = context.getImageData(0, 0, qrcode.width, qrcode.height);
        qrcode.result = qrcode.process(context);
        if(qrcode.callback!=null)
            qrcode.callback(qrcode.result);
        return qrcode.result;
    }
    else
    {
        var image = new Image();
        image.onload=function(){
            //var canvas_qr = document.getElementById("qr-canvas");
            var canvas_qr = document.createElement('canvas');
            var context = canvas_qr.getContext('2d');
            var nheight = image.height;
            var nwidth = image.width;
            if(image.width*image.height>qrcode.maxImgSize)
            {
                var ir = image.width / image.height;
                nheight = Math.sqrt(qrcode.maxImgSize/ir);
                nwidth=ir*nheight;
            }

            canvas_qr.width = nwidth;
            canvas_qr.height = nheight;

            context.drawImage(image, 0, 0, canvas_qr.width, canvas_qr.height );
            qrcode.width = canvas_qr.width;
            qrcode.height = canvas_qr.height;
            try{
                qrcode.imagedata = context.getImageData(0, 0, canvas_qr.width, canvas_qr.height);
            }catch(e){
                qrcode.result = "Cross domain image reading not supported in your browser! Save it to your computer then drag and drop the file!";
                if(qrcode.callback!=null)
                    qrcode.callback(qrcode.result);
                return;
            }

            try
            {
                qrcode.result = qrcode.process(context);
            }
            catch(e)
            {
                console.log(e);
                qrcode.result = "error decoding QR Code";
            }
            if(qrcode.callback!=null)
                qrcode.callback(qrcode.result);
        }
        image.src = src;
    }
}

qrcode.isUrl = function(s)
{
    var regexp = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
    return regexp.test(s);
}

qrcode.decode_url = function (s)
{
  var escaped = "";
  try{
    escaped = escape( s );
  }
  catch(e)
  {
    console.log(e);
    escaped = s;
  }
  var ret = "";
  try{
    ret = decodeURIComponent( escaped );
  }
  catch(e)
  {
    console.log(e);
    ret = escaped;
  }
  return ret;
}

qrcode.decode_utf8 = function ( s )
{
    if(qrcode.isUrl(s))
        return qrcode.decode_url(s);
    else
        return s;
}

qrcode.process = function(ctx){

    var start = new Date().getTime();

    var image = qrcode.grayScaleToBitmap(qrcode.grayscale());
    //var image = qrcode.binarize(128);

    if(qrcode.debug)
    {
        for (var y = 0; y < qrcode.height; y++)
        {
            for (var x = 0; x < qrcode.width; x++)
            {
                var point = (x * 4) + (y * qrcode.width * 4);
                qrcode.imagedata.data[point] = image[x+y*qrcode.width]?0:0;
                qrcode.imagedata.data[point+1] = image[x+y*qrcode.width]?0:0;
                qrcode.imagedata.data[point+2] = image[x+y*qrcode.width]?255:0;
            }
        }
        ctx.putImageData(qrcode.imagedata, 0, 0);
    }

    //var finderPatternInfo = new FinderPatternFinder().findFinderPattern(image);

    var detector = new Detector(image);

    var qRCodeMatrix = detector.detect();

    /*for (var y = 0; y < qRCodeMatrix.bits.Height; y++)
    {
        for (var x = 0; x < qRCodeMatrix.bits.Width; x++)
        {
            var point = (x * 4*2) + (y*2 * qrcode.width * 4);
            qrcode.imagedata.data[point] = qRCodeMatrix.bits.get_Renamed(x,y)?0:0;
            qrcode.imagedata.data[point+1] = qRCodeMatrix.bits.get_Renamed(x,y)?0:0;
            qrcode.imagedata.data[point+2] = qRCodeMatrix.bits.get_Renamed(x,y)?255:0;
        }
    }*/
    if(qrcode.debug)
        ctx.putImageData(qrcode.imagedata, 0, 0);

    var reader = Decoder.decode(qRCodeMatrix.bits);
    var data = reader.DataByte;
    var str="";
    for(var i=0;i<data.length;i++)
    {
        for(var j=0;j<data[i].length;j++)
            str+=String.fromCharCode(data[i][j]);
    }

    var end = new Date().getTime();
    var time = end - start;
    console.log(time);

    return qrcode.decode_utf8(str);
    //alert("Time:" + time + " Code: "+str);
}

qrcode.getPixel = function(x,y){
    if (qrcode.width < x) {
        throw "point error";
    }
    if (qrcode.height < y) {
        throw "point error";
    }
    point = (x * 4) + (y * qrcode.width * 4);
    p = (qrcode.imagedata.data[point]*33 + qrcode.imagedata.data[point + 1]*34 + qrcode.imagedata.data[point + 2]*33)/100;
    return p;
}

qrcode.binarize = function(th){
    var ret = new Array(qrcode.width*qrcode.height);
    for (var y = 0; y < qrcode.height; y++)
    {
        for (var x = 0; x < qrcode.width; x++)
        {
            var gray = qrcode.getPixel(x, y);

            ret[x+y*qrcode.width] = gray<=th?true:false;
        }
    }
    return ret;
}

qrcode.getMiddleBrightnessPerArea=function(image)
{
    var numSqrtArea = 4;
    //obtain middle brightness((min + max) / 2) per area
    var areaWidth = Math.floor(qrcode.width / numSqrtArea);
    var areaHeight = Math.floor(qrcode.height / numSqrtArea);
    var minmax = new Array(numSqrtArea);
    for (var i = 0; i < numSqrtArea; i++)
    {
        minmax[i] = new Array(numSqrtArea);
        for (var i2 = 0; i2 < numSqrtArea; i2++)
        {
            minmax[i][i2] = new Array(0,0);
        }
    }
    for (var ay = 0; ay < numSqrtArea; ay++)
    {
        for (var ax = 0; ax < numSqrtArea; ax++)
        {
            minmax[ax][ay][0] = 0xFF;
            for (var dy = 0; dy < areaHeight; dy++)
            {
                for (var dx = 0; dx < areaWidth; dx++)
                {
                    var target = image[areaWidth * ax + dx+(areaHeight * ay + dy)*qrcode.width];
                    if (target < minmax[ax][ay][0])
                        minmax[ax][ay][0] = target;
                    if (target > minmax[ax][ay][1])
                        minmax[ax][ay][1] = target;
                }
            }
            //minmax[ax][ay][0] = (minmax[ax][ay][0] + minmax[ax][ay][1]) / 2;
        }
    }
    var middle = new Array(numSqrtArea);
    for (var i3 = 0; i3 < numSqrtArea; i3++)
    {
        middle[i3] = new Array(numSqrtArea);
    }
    for (var ay = 0; ay < numSqrtArea; ay++)
    {
        for (var ax = 0; ax < numSqrtArea; ax++)
        {
            middle[ax][ay] = Math.floor((minmax[ax][ay][0] + minmax[ax][ay][1]) / 2);
            //Console.out.print(middle[ax][ay] + ",");
        }
        //Console.out.println("");
    }
    //Console.out.println("");

    return middle;
}

qrcode.grayScaleToBitmap=function(grayScale)
{
    var middle = qrcode.getMiddleBrightnessPerArea(grayScale);
    var sqrtNumArea = middle.length;
    var areaWidth = Math.floor(qrcode.width / sqrtNumArea);
    var areaHeight = Math.floor(qrcode.height / sqrtNumArea);
    var bitmap = new Array(qrcode.height*qrcode.width);

    for (var ay = 0; ay < sqrtNumArea; ay++)
    {
        for (var ax = 0; ax < sqrtNumArea; ax++)
        {
            for (var dy = 0; dy < areaHeight; dy++)
            {
                for (var dx = 0; dx < areaWidth; dx++)
                {
                    bitmap[areaWidth * ax + dx+ (areaHeight * ay + dy)*qrcode.width] = (grayScale[areaWidth * ax + dx+ (areaHeight * ay + dy)*qrcode.width] < middle[ax][ay])?true:false;
                }
            }
        }
    }
    return bitmap;
}

qrcode.grayscale = function(){
    var ret = new Array(qrcode.width*qrcode.height);
    for (var y = 0; y < qrcode.height; y++)
    {
        for (var x = 0; x < qrcode.width; x++)
        {
            var gray = qrcode.getPixel(x, y);

            ret[x+y*qrcode.width] = gray;
        }
    }
    return ret;
}

function URShift( number,  bits)
{
    if (number >= 0)
        return number >> bits;
    else
        return (number >> bits) + (2 << ~bits);
}

Array.prototype.remove = function(from, to) {
  var rest = this.slice((to || from) + 1 || this.length);
  this.length = from < 0 ? this.length + from : from;
  return this.push.apply(this, rest);
};
<commit_msg>Allow cross-origin canvas image<commit_after>/*
   Copyright 2011 Lazar Laszlo (lazarsoft@gmail.com, www.lazarsoft.info)

   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.
*/

qrcode = {};
qrcode.imagedata = null;
qrcode.width = 0;
qrcode.height = 0;
qrcode.qrCodeSymbol = null;
qrcode.debug = false;
qrcode.maxImgSize = 1024*1024;

qrcode.sizeOfDataLengthInfo =  [  [ 10, 9, 8, 8 ],  [ 12, 11, 16, 10 ],  [ 14, 13, 16, 12 ] ];

qrcode.callback = null;

qrcode.decode = function(src){

    if(arguments.length==0)
    {
        var canvas_qr = document.getElementById("qr-canvas");
        var context = canvas_qr.getContext('2d');
        qrcode.width = canvas_qr.width;
        qrcode.height = canvas_qr.height;
        qrcode.imagedata = context.getImageData(0, 0, qrcode.width, qrcode.height);
        qrcode.result = qrcode.process(context);
        if(qrcode.callback!=null)
            qrcode.callback(qrcode.result);
        return qrcode.result;
    }
    else
    {
        var image = new Image();
        image.crossOrigin = "Anonymous";
        image.onload=function(){
            //var canvas_qr = document.getElementById("qr-canvas");
            var canvas_qr = document.createElement('canvas');
            var context = canvas_qr.getContext('2d');
            var nheight = image.height;
            var nwidth = image.width;
            if(image.width*image.height>qrcode.maxImgSize)
            {
                var ir = image.width / image.height;
                nheight = Math.sqrt(qrcode.maxImgSize/ir);
                nwidth=ir*nheight;
            }

            canvas_qr.width = nwidth;
            canvas_qr.height = nheight;

            context.drawImage(image, 0, 0, canvas_qr.width, canvas_qr.height );
            qrcode.width = canvas_qr.width;
            qrcode.height = canvas_qr.height;
            try{
                qrcode.imagedata = context.getImageData(0, 0, canvas_qr.width, canvas_qr.height);
            }catch(e){
                qrcode.result = "Cross domain image reading not supported in your browser! Save it to your computer then drag and drop the file!";
                if(qrcode.callback!=null)
                    qrcode.callback(qrcode.result);
                return;
            }

            try
            {
                qrcode.result = qrcode.process(context);
            }
            catch(e)
            {
                console.log(e);
                qrcode.result = "error decoding QR Code";
            }
            if(qrcode.callback!=null)
                qrcode.callback(qrcode.result);
        }
        image.src = src;
    }
}

qrcode.isUrl = function(s)
{
    var regexp = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
    return regexp.test(s);
}

qrcode.decode_url = function (s)
{
  var escaped = "";
  try{
    escaped = escape( s );
  }
  catch(e)
  {
    console.log(e);
    escaped = s;
  }
  var ret = "";
  try{
    ret = decodeURIComponent( escaped );
  }
  catch(e)
  {
    console.log(e);
    ret = escaped;
  }
  return ret;
}

qrcode.decode_utf8 = function ( s )
{
    if(qrcode.isUrl(s))
        return qrcode.decode_url(s);
    else
        return s;
}

qrcode.process = function(ctx){

    var start = new Date().getTime();

    var image = qrcode.grayScaleToBitmap(qrcode.grayscale());
    //var image = qrcode.binarize(128);

    if(qrcode.debug)
    {
        for (var y = 0; y < qrcode.height; y++)
        {
            for (var x = 0; x < qrcode.width; x++)
            {
                var point = (x * 4) + (y * qrcode.width * 4);
                qrcode.imagedata.data[point] = image[x+y*qrcode.width]?0:0;
                qrcode.imagedata.data[point+1] = image[x+y*qrcode.width]?0:0;
                qrcode.imagedata.data[point+2] = image[x+y*qrcode.width]?255:0;
            }
        }
        ctx.putImageData(qrcode.imagedata, 0, 0);
    }

    //var finderPatternInfo = new FinderPatternFinder().findFinderPattern(image);

    var detector = new Detector(image);

    var qRCodeMatrix = detector.detect();

    /*for (var y = 0; y < qRCodeMatrix.bits.Height; y++)
    {
        for (var x = 0; x < qRCodeMatrix.bits.Width; x++)
        {
            var point = (x * 4*2) + (y*2 * qrcode.width * 4);
            qrcode.imagedata.data[point] = qRCodeMatrix.bits.get_Renamed(x,y)?0:0;
            qrcode.imagedata.data[point+1] = qRCodeMatrix.bits.get_Renamed(x,y)?0:0;
            qrcode.imagedata.data[point+2] = qRCodeMatrix.bits.get_Renamed(x,y)?255:0;
        }
    }*/
    if(qrcode.debug)
        ctx.putImageData(qrcode.imagedata, 0, 0);

    var reader = Decoder.decode(qRCodeMatrix.bits);
    var data = reader.DataByte;
    var str="";
    for(var i=0;i<data.length;i++)
    {
        for(var j=0;j<data[i].length;j++)
            str+=String.fromCharCode(data[i][j]);
    }

    var end = new Date().getTime();
    var time = end - start;
    console.log(time);

    return qrcode.decode_utf8(str);
    //alert("Time:" + time + " Code: "+str);
}

qrcode.getPixel = function(x,y){
    if (qrcode.width < x) {
        throw "point error";
    }
    if (qrcode.height < y) {
        throw "point error";
    }
    point = (x * 4) + (y * qrcode.width * 4);
    p = (qrcode.imagedata.data[point]*33 + qrcode.imagedata.data[point + 1]*34 + qrcode.imagedata.data[point + 2]*33)/100;
    return p;
}

qrcode.binarize = function(th){
    var ret = new Array(qrcode.width*qrcode.height);
    for (var y = 0; y < qrcode.height; y++)
    {
        for (var x = 0; x < qrcode.width; x++)
        {
            var gray = qrcode.getPixel(x, y);

            ret[x+y*qrcode.width] = gray<=th?true:false;
        }
    }
    return ret;
}

qrcode.getMiddleBrightnessPerArea=function(image)
{
    var numSqrtArea = 4;
    //obtain middle brightness((min + max) / 2) per area
    var areaWidth = Math.floor(qrcode.width / numSqrtArea);
    var areaHeight = Math.floor(qrcode.height / numSqrtArea);
    var minmax = new Array(numSqrtArea);
    for (var i = 0; i < numSqrtArea; i++)
    {
        minmax[i] = new Array(numSqrtArea);
        for (var i2 = 0; i2 < numSqrtArea; i2++)
        {
            minmax[i][i2] = new Array(0,0);
        }
    }
    for (var ay = 0; ay < numSqrtArea; ay++)
    {
        for (var ax = 0; ax < numSqrtArea; ax++)
        {
            minmax[ax][ay][0] = 0xFF;
            for (var dy = 0; dy < areaHeight; dy++)
            {
                for (var dx = 0; dx < areaWidth; dx++)
                {
                    var target = image[areaWidth * ax + dx+(areaHeight * ay + dy)*qrcode.width];
                    if (target < minmax[ax][ay][0])
                        minmax[ax][ay][0] = target;
                    if (target > minmax[ax][ay][1])
                        minmax[ax][ay][1] = target;
                }
            }
            //minmax[ax][ay][0] = (minmax[ax][ay][0] + minmax[ax][ay][1]) / 2;
        }
    }
    var middle = new Array(numSqrtArea);
    for (var i3 = 0; i3 < numSqrtArea; i3++)
    {
        middle[i3] = new Array(numSqrtArea);
    }
    for (var ay = 0; ay < numSqrtArea; ay++)
    {
        for (var ax = 0; ax < numSqrtArea; ax++)
        {
            middle[ax][ay] = Math.floor((minmax[ax][ay][0] + minmax[ax][ay][1]) / 2);
            //Console.out.print(middle[ax][ay] + ",");
        }
        //Console.out.println("");
    }
    //Console.out.println("");

    return middle;
}

qrcode.grayScaleToBitmap=function(grayScale)
{
    var middle = qrcode.getMiddleBrightnessPerArea(grayScale);
    var sqrtNumArea = middle.length;
    var areaWidth = Math.floor(qrcode.width / sqrtNumArea);
    var areaHeight = Math.floor(qrcode.height / sqrtNumArea);
    var bitmap = new Array(qrcode.height*qrcode.width);

    for (var ay = 0; ay < sqrtNumArea; ay++)
    {
        for (var ax = 0; ax < sqrtNumArea; ax++)
        {
            for (var dy = 0; dy < areaHeight; dy++)
            {
                for (var dx = 0; dx < areaWidth; dx++)
                {
                    bitmap[areaWidth * ax + dx+ (areaHeight * ay + dy)*qrcode.width] = (grayScale[areaWidth * ax + dx+ (areaHeight * ay + dy)*qrcode.width] < middle[ax][ay])?true:false;
                }
            }
        }
    }
    return bitmap;
}

qrcode.grayscale = function(){
    var ret = new Array(qrcode.width*qrcode.height);
    for (var y = 0; y < qrcode.height; y++)
    {
        for (var x = 0; x < qrcode.width; x++)
        {
            var gray = qrcode.getPixel(x, y);

            ret[x+y*qrcode.width] = gray;
        }
    }
    return ret;
}

function URShift( number,  bits)
{
    if (number >= 0)
        return number >> bits;
    else
        return (number >> bits) + (2 << ~bits);
}

Array.prototype.remove = function(from, to) {
  var rest = this.slice((to || from) + 1 || this.length);
  this.length = from < 0 ? this.length + from : from;
  return this.push.apply(this, rest);
};
<|endoftext|>


<commit_before>import React from 'react';
import ReactDOM from 'react-dom';
import {Router} from 'react-router';
import createHistory from 'history/lib/createHashHistory';
import useScroll from 'scroll-behavior/lib/useSimpleScroll';

import configureRoutes from './configureRoutes';

export default (config, element) => {
  ReactDOM.render(
    <Router history={useScroll(createHistory)({queryKey: false})} routes={configureRoutes(config)} />,
    element
  );
};
<commit_msg>Allow `render` to be called more than once<commit_after>import React from 'react';
import ReactDOM from 'react-dom';
import {Router} from 'react-router';
import createHistory from 'history/lib/createHashHistory';
import useScroll from 'scroll-behavior/lib/useSimpleScroll';
import seqKey from './utils/seqKey';

import configureRoutes from './configureRoutes';

const history = useScroll(createHistory)({queryKey: false});

const getKey = seqKey('CatalogRouter');

export default (config, element) => {
  ReactDOM.render(
    <Router key={getKey()} history={history} routes={configureRoutes(config)} />,
    element
  );
};
<|endoftext|>


<commit_before>define(function(require) {

  var Backbone = require('backbone');

  var Router = Backbone.Router.extend({

    initialize: function (options) {
      this.app = options.app;
    },

    routes: {
      // use ! for urls to not conflict with remotestorage's #access_token parameter
      '!:url': 'open',
      '*404': 'openFirst'
    },

    openFirst: function() {
      this.app.open();
    },

    open: function(url) {
      var match = url.match(/^\((.+?)\)/);
      if (!match) return this.openFirst();
      var id = match[1];
      if (!id) return this.openFirst();
      var doc = this.app.docs.get(id);
      if (!doc) return this.openFirst();
      this.app.open(doc);
    }

  });

  return Router;
});
<commit_msg>router.js: /app/litewrite/g<commit_after>define(function(require) {

  var Backbone = require('backbone');

  var Router = Backbone.Router.extend({

    initialize: function (options) {
      this.litewrite = options.litewrite;
    },

    routes: {
      // use ! for urls to not conflict with remotestorage's #access_token parameter
      '!:url': 'open',
      '*404': 'openFirst'
    },

    openFirst: function() {
      this.litewrite.open();
    },

    open: function(url) {
      var match = url.match(/^\((.+?)\)/);
      if (!match) return this.openFirst();
      var id = match[1];
      if (!id) return this.openFirst();
      var doc = this.litewrite.docs.get(id);
      if (!doc) return this.openFirst();
      this.litewrite.open(doc);
    }

  });

  return Router;
});
<|endoftext|>


<commit_before>/**
* @license Apache-2.0
*
* Copyright (c) 2021 The Stdlib Authors.
*
* 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.
*/

// MODULES //

import config from './config.js';

// MAIN //

/**
* Application routes.
*
* @private
* @constant
* @type {Object}
*/
const routes = {
	'VERSION_DEFAULT': config.mount+':version',

	'SEARCH': config.mount+':version/search',
	'HELP': config.mount+':version/help',
	'NONPACKAGE_DEFAULT': config.mount+':version/*',

	'PACKAGE_DEFAULT': config.mount+':version/@stdlib/:pkg+',
	'PACKAGE_INDEX': config.mount+':version/@stdlib/:pkg+/index.html',
	'PACKAGE_BENCHMARKS': config.mount+':version/@stdlib/:pkg+/benchmarks',
	'PACKAGE_TESTS': config.mount+':version/@stdlib/:pkg+/tests',

	'ERROR_DECODER': config.mount+':version/error'
};

// EXPORTS //

export default routes;
<commit_msg>Fix route<commit_after>/**
* @license Apache-2.0
*
* Copyright (c) 2021 The Stdlib Authors.
*
* 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.
*/

// MODULES //

import config from './config.js';

// MAIN //

/**
* Application routes.
*
* @private
* @constant
* @type {Object}
*/
const routes = {
	'VERSION_DEFAULT': config.mount+':version',

	'SEARCH': config.mount+':version/search',
	'HELP': config.mount+':version/help',
	'NONPACKAGE_DEFAULT': config.mount+':version/*',

	'PACKAGE_DEFAULT': config.mount+':version/@stdlib/:pkg+',
	'PACKAGE_INDEX': config.mount+':version/@stdlib/:pkg+/index.html',
	'PACKAGE_BENCHMARKS': config.mount+':version/@stdlib/:pkg+/benchmarks',
	'PACKAGE_TESTS': config.mount+':version/@stdlib/:pkg+/tests',

	'ERROR_DECODER': config.mount+':version/error/decoder'
};

// EXPORTS //

export default routes;
<|endoftext|>


<commit_before>DrNicTest.Unit.Runner = function(testcases) {
  var argumentOptions = arguments[1] || {};
  var options = this.options = {};
  options.testLog = ('testLog' in argumentOptions) ? argumentOptions.testLog : 'testlog';
  options.resultsURL = this.queryParams.resultsURL;
  options.testLog = DrNicTest.$(options.testLog);

  this.tests = this.getTests(testcases);
  this.currentTest = 0;
  this.logger = new DrNicTest.Unit.Logger(options.testLog);

  var self = this;
  DrNicTest.Event.addEvent(window, "load", function() {
    setTimeout(function() {
      self.runTests();
    }, 0.1);
  });
};

DrNicTest.Unit.Runner.prototype.queryParams = function() {
  if (window.location.search.length > 0) {
    return window.location.search.parseQuery();
  }
  return "";
}();

DrNicTest.Unit.Runner.prototype.getTests = function(testcases) {
  var tests = [], options = this.options;
  if (this.queryParams.tests) tests = this.queryParams.tests.split(',');
  else if (options.tests) tests = options.tests;
  else if (options.test) tests = [option.test];
  else {
    for (testname in testcases) {
      if (testname.match(/^test/)) tests.push(testname);
    }
  }
  var results = [];
  for (var i=0; i < tests.length; i++) {
    var test = tests[i];
    if (testcases[test])
      results.push(
        new DrNicTest.Unit.Testcase(test, testcases[test], testcases.setup, testcases.teardown)
      );
  };
  return results;
};

DrNicTest.Unit.Runner.prototype.getResult = function() {
  var results = {
    tests: this.tests.length,
    assertions: 0,
    failures: 0,
    errors: 0
  };

  var results = [];
  for (var i=0; i < this.tests.length; i++) {
    var test = this.tests[i];
    results.assertions += test.assertions;
    results.failures   += test.failures;
    results.errors     += test.errors;
  };
  return results;
};

DrNicTest.Unit.Runner.prototype.postResults = function() {
  if (this.options.resultsURL) {
    // TODO replace prototype's Ajax.Request
    new Ajax.Request(this.options.resultsURL,
      { method: 'get', parameters: this.getResult(), asynchronous: false });
  }
};

DrNicTest.Unit.Runner.prototype.runTests = function() {
  var test = this.tests[this.currentTest], actions;

  if (!test) return this.finish();
  if (!test.isWaiting) this.logger.start(test.name);
  test.run();
  if(test.isWaiting) {
    this.logger.message("Waiting for " + test.timeToWait + "ms");
    // setTimeout(this.runTests.bind(this), test.timeToWait || 1000);
    setTimeout(function() {
      this.runTests();
    }, test.timeToWait || 1000);
    return;
  }

  this.logger.finish(test.status(), test.summary());
  if (actions = test.actions) this.logger.appendActionButtons(actions);
  this.currentTest++;
  // tail recursive, hopefully the browser will skip the stackframe
  this.runTests();
};

DrNicTest.Unit.Runner.prototype.finish = function() {
  this.postResults();
  this.logger.summary(this.summary());
};

DrNicTest.Unit.Runner.prototype.summary = function() {
  return new DrNicTest.Template('#{tests} tests, #{assertions} assertions, #{failures} failures, #{errors} errors').evaluate(this.getResult());
};
<commit_msg>fixed runner<commit_after>DrNicTest.Unit.Runner = function(testcases) {
  var argumentOptions = arguments[1] || {};
  var options = this.options = {};
  options.testLog = ('testLog' in argumentOptions) ? argumentOptions.testLog : 'testlog';
  options.resultsURL = this.queryParams.resultsURL;
  options.testLog = DrNicTest.$(options.testLog);

  this.tests = this.getTests(testcases);
  this.currentTest = 0;
  this.logger = new DrNicTest.Unit.Logger(options.testLog);

  var self = this;
  DrNicTest.Event.addEvent(window, "load", function() {
    setTimeout(function() {
      self.runTests();
    }, 0.1);
  });
};

DrNicTest.Unit.Runner.prototype.queryParams = function() {
  if (window.location.search.length > 0) {
    return window.location.search.parseQuery();
  }
  return "";
}();

DrNicTest.Unit.Runner.prototype.getTests = function(testcases) {
  var tests = [], options = this.options;
  if (this.queryParams.tests) tests = this.queryParams.tests.split(',');
  else if (options.tests) tests = options.tests;
  else if (options.test) tests = [option.test];
  else {
    for (testname in testcases) {
      if (testname.match(/^test/)) tests.push(testname);
    }
  }
  var results = [];
  for (var i=0; i < tests.length; i++) {
    var test = tests[i];
    if (testcases[test])
      results.push(
        new DrNicTest.Unit.Testcase(test, testcases[test], testcases.setup, testcases.teardown)
      );
  };
  return results;
};

DrNicTest.Unit.Runner.prototype.getResult = function() {
  var results = {
    tests: this.tests.length,
    assertions: 0,
    failures: 0,
    errors: 0
  };

  for (var i=0; i < this.tests.length; i++) {
    var test = this.tests[i];
    results.assertions += test.assertions;
    results.failures   += test.failures;
    results.errors     += test.errors;
  };
  return results;
};

DrNicTest.Unit.Runner.prototype.postResults = function() {
  if (this.options.resultsURL) {
    // TODO replace prototype's Ajax.Request
    new Ajax.Request(this.options.resultsURL,
      { method: 'get', parameters: this.getResult(), asynchronous: false });
  }
};

DrNicTest.Unit.Runner.prototype.runTests = function() {
  var test = this.tests[this.currentTest], actions;

  if (!test) return this.finish();
  if (!test.isWaiting) this.logger.start(test.name);
  test.run();
  if(test.isWaiting) {
    this.logger.message("Waiting for " + test.timeToWait + "ms");
    // setTimeout(this.runTests.bind(this), test.timeToWait || 1000);
    setTimeout(function() {
      this.runTests();
    }, test.timeToWait || 1000);
    return;
  }

  this.logger.finish(test.status(), test.summary());
  if (actions = test.actions) this.logger.appendActionButtons(actions);
  this.currentTest++;
  // tail recursive, hopefully the browser will skip the stackframe
  this.runTests();
};

DrNicTest.Unit.Runner.prototype.finish = function() {
  this.postResults();
  this.logger.summary(this.summary());
};

DrNicTest.Unit.Runner.prototype.summary = function() {
  return new DrNicTest.Template('#{tests} tests, #{assertions} assertions, #{failures} failures, #{errors} errors').evaluate(this.getResult());
};
<|endoftext|>


<commit_before>/**
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
(function (factory) {
    /*globals define, window, module */
    "use strict";

    if ( typeof define === 'function' && define.amd ) {
        define("runway", factory);
    }
    else if ( module !== undefined && module.exports ) {
        module.exports = factory();
    }
    else {
        window.runway = factory();
    }

}(function () {
    "use strict";

    /** The base class for all models */
    function BaseModel() {}

    /** The base class for defining a collection of models */
    function BaseCollection () {}

    /** Whether an object is a model or collection */
    function isModelOrCollection ( obj ) {
        return obj instanceof BaseModel || obj instanceof BaseCollection;
    }

    /** Iterates over the keys in an object */
    function eachObject(obj, callback, bind) {
        for ( var key in obj ) {
            if ( obj.hasOwnProperty(key) ) {
                callback.call(bind, obj[key], key);
            }
        }
    }

    /** Extends an object with values from another object */
    function extend(onto, source) {
        eachObject(source, function (value, key) {
            onto[key] = value;
        });
    }

    /**
     * A difficult-to-believe, but optimized internal dispatch function for
     * triggering events. Tries to keep the usual cases speedy. This function
     * was lifted almost directly from Backbone.
     */
    function triggerEvents(callbacks, bind, args) {
        var i = -1;
        var len = callbacks.length;

        var a1 = args[0], a2 = args[1], a3 = args[2];

        switch (args.length) {
            case 0:
                while (++i < len) { callbacks[i].call(bind); }
                return;
            case 1:
                while (++i < len) { callbacks[i].call(bind, a1); }
                return;
            case 2:
                while (++i < len) { callbacks[i].call(bind, a1, a2); }
                return;
            case 3:
                while (++i < len) { callbacks[i].call(bind, a1, a2, a3); }
                return;
            default:
                while (++i < len) { callbacks[i].apply(bind, args); }
                return;
        }
    }

    /** Returns the event map for an object, or adds one */
    function getEventMap (that) {
        if ( !that.hasOwnProperty('__events') ) {
            Object.defineProperty(that, '__events', {
                enumerable: false,
                writeable: false,
                value: {}
            });
        }
        return that.__events;
    }

    /** Splits an incoming event into multiple events before delegating */
    function prepEventHandler( inner ) {
        return function (events) {
            var args = [].slice.call(arguments, 1);
            args.unshift( getEventMap(this) );
            args.unshift( null );

            var eachEvent = events.split(' ');
            for ( var i = 0; i < eachEvent.length; i++ ) {
                args[0] = eachEvent[i];
                inner.apply(this, args);
            }
        };
    }

    /** Functions to for triggering and observing events */
    var eventInterface = {

        /** Triggers a change event for this model */
        trigger: prepEventHandler(function trigger ( event, map ) {
            var args = [].slice.call(arguments, 2);

            var parts = event.split(":");
            while ( parts.length ) {
                var eventName = parts.join(":");
                if ( map[eventName] ) {
                    triggerEvents(map[eventName], this, args);
                }
                parts.pop();
            }
        }),

        /** Subscribes to an event on this model */
        on: prepEventHandler(function on ( event, map, callback ) {
            if ( !map[event] ) {
                map[event] = [ callback ];
            }
            else {
                map[event].push(callback);
            }
        }),

        /** Unsubscribes to an event on this model */
        off: prepEventHandler(function off ( event, map, callback ) {
            if ( map[event] ) {
                for ( var i = 0; i < map[event].length; ) {
                    if ( map[event][i] === callback ) {
                        map[event].splice(i, 1);
                    }
                    else {
                        i++;
                    }
                }
            }
        })
    };

    /** Adds event support to a an object */
    function eventify( obj ) {
        extend(obj, eventInterface);
        return obj;
    }

    /** Binds a property to 'this' and sets up watches */
    function setProperty(that, value, key) {

        if ( that.hasOwnProperty(key) ) {
            return;
        }

        // Triggers an event when a nested value changes
        var triggerChange = that.trigger.bind(that, 'sub:change');

        if ( isModelOrCollection(value) ) {
            value.on('change sub:change', triggerChange);
        }

        Object.defineProperty(that, key, {
            enumerable: true,
            configurable: false,
            set: function ( newValue ) {
                var oldValue = value;
                value = newValue;

                if ( isModelOrCollection(oldValue) ) {
                    oldValue.off('change sub:change', triggerChange);
                }

                that.trigger(
                    'change:' + key, value, { old: oldValue, key: key }
                );

                if ( isModelOrCollection(newValue) ) {
                    newValue.on('change sub:change', triggerChange);
                }
            },
            get: function () {
                return value;
            }
        });
    }

    /** Given a hash of options, adds any functions to an object */
    function addFunctions(options, clazz) {
        eachObject(options, function (value, key) {
            if ( typeof value === 'function' && key !== 'initialize' ) {
                clazz.prototype[key] = value;
            }
        });
    }

    /* Start adding functions to the BaseModel */
    eventify( BaseModel.prototype );

    /** Configures a new model */
    function defineModel (options) {
        options = options || {};

        /** Constructor for the specific model */
        function Model (values) {

            if ( options.preprocess ) {
                values = options.preprocess.apply(this, arguments);
            }

            eachObject(values, setProperty.bind(null, this));
            eachObject(options.defaults, setProperty.bind(null, this));

            if ( options.initialize ) {
                options.initialize.call(this);
            }
        }

        Model.prototype = new BaseModel();

        addFunctions(options, Model);

        return Model;
    }

    /* Start adding functions to the BaseCollection */
    BaseCollection.prototype = [];

    eventify( BaseCollection.prototype );

    /** Returns a function that sorts and triggers an event */
    function createSorter( func ) {
        return function (compare) {
            Array.prototype[func].call(this, compare);
            this.trigger('sort change');
        };
    }

    /** Returns a function that sorts and triggers an event */
    function createRemover( func ) {
        return function () {
            var removed = Array.prototype[func].call(this);
            this.trigger('remove change', removed);

            if ( isModelOrCollection(removed) ) {
                removed.trigger('removed', this);
            }

            return removed;
        };
    }

    /** Creates a push or unshift method */
    function createAdder ( func ) {
        return function (value) {
            if ( this.__model && !(value instanceof this.__model) ) {
                value = new this.__model(value);
            }

            Array.prototype[func].call(this, value);
            this.trigger('add change', value);
        };
    }

    extend(BaseCollection.prototype, {

        /** Converts this object to an array */
        toArray: [].slice,

        /** Adds a value */
        add: createAdder('push'),

        /** Remove an element */
        remove: function (elem) {
            var removed = false;
            var index;
            while ( -1 !== (index = this.indexOf(elem)) ) {
                [].splice.call(this, index, 1);
                removed = true;
                this.trigger('remove change', elem);
            }

            if ( removed && isModelOrCollection(elem) ) {
                elem.trigger('removed', this);
            }
        },

        /** Override to handle events */
        push: createAdder('push'),

        /** Override to handle events */
        pop: createRemover('pop'),

        /** Override to handle events */
        unshift: createAdder('unshift'),

        /** Override to handle events */
        shift: createRemover('shift'),

        /** Override to handle events */
        sort: createSorter('sort'),

        /** Override to handle events */
        reverse: createSorter('reverse'),

        // Splice is... complicated. Clear it out right now to simplify how
        // events need to be handled.
        splice: null,

        /** Applies a callback to */
        eachAndAdded: function (callback) {
            this.forEach(callback, this);
            this.on('add', callback);
        }

    });

    /** Defines a collection of models */
    function defineCollection ( options ) {
        options = options || {};

        /** Constructor for the specific model */
        function Collection(values) {

            if ( options.preprocess ) {
                values = options.preprocess.apply(this, arguments);
            }

            // Store the defined model so it can be referenced by add and push
            if ( options.model ) {
                Object.defineProperty(this, '__model', {
                    enumerable: false,
                    value: options.model
                });
            }

            // Monitor for changes to nested elements and bubble up events
            var triggerSubChange = this.trigger.bind(this, 'sub:change');

            this.on('add', function (elem) {
                if ( isModelOrCollection(elem) ) {
                    elem.on('change sub:change', triggerSubChange);
                }
            });

            this.on('remove', function (elem) {
                if ( isModelOrCollection(elem) ) {
                    elem.off('change sub:change', triggerSubChange);
                }
            });

            if ( options.initialize ) {
                options.initialize.call(this);
            }

            (values || []).forEach(this.push, this);
        }

        Collection.prototype = new BaseCollection();

        addFunctions(options, Collection);

        return Collection;
    }

    return {
        model: defineModel,
        collection: defineCollection,
        eventify: eventify
    };

}));
<commit_msg>Simplify export<commit_after>/**
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
(function () {
    /*globals define, window, module */
    "use strict";

    /** The base class for all models */
    function BaseModel() {}

    /** The base class for defining a collection of models */
    function BaseCollection () {}

    /** Whether an object is a model or collection */
    function isModelOrCollection ( obj ) {
        return obj instanceof BaseModel || obj instanceof BaseCollection;
    }

    /** Iterates over the keys in an object */
    function eachObject(obj, callback, bind) {
        for ( var key in obj ) {
            if ( obj.hasOwnProperty(key) ) {
                callback.call(bind, obj[key], key);
            }
        }
    }

    /** Extends an object with values from another object */
    function extend(onto, source) {
        eachObject(source, function (value, key) {
            onto[key] = value;
        });
    }

    /**
     * A difficult-to-believe, but optimized internal dispatch function for
     * triggering events. Tries to keep the usual cases speedy. This function
     * was lifted almost directly from Backbone.
     */
    function triggerEvents(callbacks, bind, args) {
        var i = -1;
        var len = callbacks.length;

        var a1 = args[0], a2 = args[1], a3 = args[2];

        switch (args.length) {
            case 0:
                while (++i < len) { callbacks[i].call(bind); }
                return;
            case 1:
                while (++i < len) { callbacks[i].call(bind, a1); }
                return;
            case 2:
                while (++i < len) { callbacks[i].call(bind, a1, a2); }
                return;
            case 3:
                while (++i < len) { callbacks[i].call(bind, a1, a2, a3); }
                return;
            default:
                while (++i < len) { callbacks[i].apply(bind, args); }
                return;
        }
    }

    /** Returns the event map for an object, or adds one */
    function getEventMap (that) {
        if ( !that.hasOwnProperty('__events') ) {
            Object.defineProperty(that, '__events', {
                enumerable: false,
                writeable: false,
                value: {}
            });
        }
        return that.__events;
    }

    /** Splits an incoming event into multiple events before delegating */
    function prepEventHandler( inner ) {
        return function (events) {
            var args = [].slice.call(arguments, 1);
            args.unshift( getEventMap(this) );
            args.unshift( null );

            var eachEvent = events.split(' ');
            for ( var i = 0; i < eachEvent.length; i++ ) {
                args[0] = eachEvent[i];
                inner.apply(this, args);
            }
        };
    }

    /** Functions to for triggering and observing events */
    var eventInterface = {

        /** Triggers a change event for this model */
        trigger: prepEventHandler(function trigger ( event, map ) {
            var args = [].slice.call(arguments, 2);

            var parts = event.split(":");
            while ( parts.length ) {
                var eventName = parts.join(":");
                if ( map[eventName] ) {
                    triggerEvents(map[eventName], this, args);
                }
                parts.pop();
            }
        }),

        /** Subscribes to an event on this model */
        on: prepEventHandler(function on ( event, map, callback ) {
            if ( !map[event] ) {
                map[event] = [ callback ];
            }
            else {
                map[event].push(callback);
            }
        }),

        /** Unsubscribes to an event on this model */
        off: prepEventHandler(function off ( event, map, callback ) {
            if ( map[event] ) {
                for ( var i = 0; i < map[event].length; ) {
                    if ( map[event][i] === callback ) {
                        map[event].splice(i, 1);
                    }
                    else {
                        i++;
                    }
                }
            }
        })
    };

    /** Adds event support to a an object */
    function eventify( obj ) {
        extend(obj, eventInterface);
        return obj;
    }

    /** Binds a property to 'this' and sets up watches */
    function setProperty(that, value, key) {

        if ( that.hasOwnProperty(key) ) {
            return;
        }

        // Triggers an event when a nested value changes
        var triggerChange = that.trigger.bind(that, 'sub:change');

        if ( isModelOrCollection(value) ) {
            value.on('change sub:change', triggerChange);
        }

        Object.defineProperty(that, key, {
            enumerable: true,
            configurable: false,
            set: function ( newValue ) {
                var oldValue = value;
                value = newValue;

                if ( isModelOrCollection(oldValue) ) {
                    oldValue.off('change sub:change', triggerChange);
                }

                that.trigger(
                    'change:' + key, value, { old: oldValue, key: key }
                );

                if ( isModelOrCollection(newValue) ) {
                    newValue.on('change sub:change', triggerChange);
                }
            },
            get: function () {
                return value;
            }
        });
    }

    /** Given a hash of options, adds any functions to an object */
    function addFunctions(options, clazz) {
        eachObject(options, function (value, key) {
            if ( typeof value === 'function' && key !== 'initialize' ) {
                clazz.prototype[key] = value;
            }
        });
    }

    /* Start adding functions to the BaseModel */
    eventify( BaseModel.prototype );

    /** Configures a new model */
    function defineModel (options) {
        options = options || {};

        /** Constructor for the specific model */
        function Model (values) {

            if ( options.preprocess ) {
                values = options.preprocess.apply(this, arguments);
            }

            eachObject(values, setProperty.bind(null, this));
            eachObject(options.defaults, setProperty.bind(null, this));

            if ( options.initialize ) {
                options.initialize.call(this);
            }
        }

        Model.prototype = new BaseModel();

        addFunctions(options, Model);

        return Model;
    }

    /* Start adding functions to the BaseCollection */
    BaseCollection.prototype = [];

    eventify( BaseCollection.prototype );

    /** Returns a function that sorts and triggers an event */
    function createSorter( func ) {
        return function (compare) {
            Array.prototype[func].call(this, compare);
            this.trigger('sort change');
        };
    }

    /** Returns a function that sorts and triggers an event */
    function createRemover( func ) {
        return function () {
            var removed = Array.prototype[func].call(this);
            this.trigger('remove change', removed);

            if ( isModelOrCollection(removed) ) {
                removed.trigger('removed', this);
            }

            return removed;
        };
    }

    /** Creates a push or unshift method */
    function createAdder ( func ) {
        return function (value) {
            if ( this.__model && !(value instanceof this.__model) ) {
                value = new this.__model(value);
            }

            Array.prototype[func].call(this, value);
            this.trigger('add change', value);
        };
    }

    extend(BaseCollection.prototype, {

        /** Converts this object to an array */
        toArray: [].slice,

        /** Adds a value */
        add: createAdder('push'),

        /** Remove an element */
        remove: function (elem) {
            var removed = false;
            var index;
            while ( -1 !== (index = this.indexOf(elem)) ) {
                [].splice.call(this, index, 1);
                removed = true;
                this.trigger('remove change', elem);
            }

            if ( removed && isModelOrCollection(elem) ) {
                elem.trigger('removed', this);
            }
        },

        /** Override to handle events */
        push: createAdder('push'),

        /** Override to handle events */
        pop: createRemover('pop'),

        /** Override to handle events */
        unshift: createAdder('unshift'),

        /** Override to handle events */
        shift: createRemover('shift'),

        /** Override to handle events */
        sort: createSorter('sort'),

        /** Override to handle events */
        reverse: createSorter('reverse'),

        // Splice is... complicated. Clear it out right now to simplify how
        // events need to be handled.
        splice: null,

        /** Applies a callback to */
        eachAndAdded: function (callback) {
            this.forEach(callback, this);
            this.on('add', callback);
        }

    });

    /** Defines a collection of models */
    function defineCollection ( options ) {
        options = options || {};

        /** Constructor for the specific model */
        function Collection(values) {

            if ( options.preprocess ) {
                values = options.preprocess.apply(this, arguments);
            }

            // Store the defined model so it can be referenced by add and push
            if ( options.model ) {
                Object.defineProperty(this, '__model', {
                    enumerable: false,
                    value: options.model
                });
            }

            // Monitor for changes to nested elements and bubble up events
            var triggerSubChange = this.trigger.bind(this, 'sub:change');

            this.on('add', function (elem) {
                if ( isModelOrCollection(elem) ) {
                    elem.on('change sub:change', triggerSubChange);
                }
            });

            this.on('remove', function (elem) {
                if ( isModelOrCollection(elem) ) {
                    elem.off('change sub:change', triggerSubChange);
                }
            });

            if ( options.initialize ) {
                options.initialize.call(this);
            }

            (values || []).forEach(this.push, this);
        }

        Collection.prototype = new BaseCollection();

        addFunctions(options, Collection);

        return Collection;
    }

    var runway = {
        model: defineModel,
        collection: defineCollection,
        eventify: eventify
    };

    /** Export the public interface */
    if ( typeof define === 'function' && define.amd ) {
        define("runway", runway);
    }
    else if ( module !== undefined && module.exports ) {
        module.exports = runway;
    }
    else {
        window.runway = runway;
    }

}());
<|endoftext|>