<commit_before>(function(root, factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define(['angular'], factory);
  } else if (typeof exports === 'object') {
    // Node. Does not work with strict CommonJS, but
    // only CommonJS-like environments that support module.exports,
    // like Node.
    module.exports = factory(require('angular'));
  } else {
    // Browser globals (root is window)
    root.returnExports = factory(root.angular);
  }
}(this, function(angular) {
  /**
   * @ngdoc service
   * @name ngMeta.ngMeta
   * @description
   * # A metatags service for single-page applications
   * that supports setting arbitrary meta tags
   */
  angular.module('ngMeta', [])
    .provider('ngMeta', function() {

      'use strict';

      //Object for storing default tag/values
      var defaults = {
        title: '',
        titleSuffix: ''
      };

      //One-time configuration
      var config = {
        useTitleSuffix: false
      };

      function Meta($rootScope) {

        /**
         * @ngdoc method
         * @name ngMeta#setTitle
         * @description
         * Sets the title of the page, optionally
         * appending a title suffix.
         *
         * If suffix usage is enabled and the title suffix
         * parameter is missing, the default title suffix
         * (if available) is used as a fallback.
         *
         * @example
         * //title and titleSuffix
         * ngMeta.setTitle('Page name', ' - Site name | Tagline of the site');
         *
         * //title only (default titleSuffix may be suffixed,
         * //depending on useTitleSuffix configuration)
         * ngMeta.setTitle('Page name');
         *
         * @returns {Object} self
         */
        var setTitle = function(title, titleSuffix) {
          if (!$rootScope.ngMeta) {
            throw new Error('Cannot call setTitle when ngMeta is undefined. Did you forget to call ngMeta.init() in the run block? \nRefer: https://github.com/vinaygopinath/ngMeta#getting-started');
          }
          $rootScope.ngMeta.title = angular.isDefined(title) ? title : defaults.title;
          if (config.useTitleSuffix) {
            $rootScope.ngMeta.title += angular.isDefined(titleSuffix) ? titleSuffix : defaults.titleSuffix;
          }
          return this;
        };

        /**
         * @ngdoc method
         * @name ngMeta#setTag
         * @description
         * Sets the value of a meta tag, using
         * the default value (if available) as
         * a fallback.
         *
         * @example
         * ngMeta.setTag('og:image', 'http://example.com/a.png');
         *
         * @returns {Object} self
         */
        var setTag = function(tag, value) {
          if (!$rootScope.ngMeta) {
            throw new Error('Cannot call setTag when ngMeta is undefined. Did you forget to call ngMeta.init() in the run block? \nRefer: https://github.com/vinaygopinath/ngMeta#getting-started');
          }
          if (tag === 'title' || tag === 'titleSuffix') {
            throw new Error('Attempt to set \'' + tag + '\' through \'setTag\': \'title\' and \'titleSuffix\' are reserved tag names. Please use \'ngMeta.setTitle\' instead');
          }
          $rootScope.ngMeta[tag] = angular.isDefined(value) ? value : defaults[tag];
          return this;
        };

        /**
         * @ngdoc method
         * @name ngMeta#setDefaultTag
         * @description
         * Sets the default tag for all routes that are missing a custom
         * `tag` property in their meta objects.
         *
         * @example
         * ngMeta.setDefaultTag('titleSuffix', ' | Tagline of the site');
         *
         * @returns {Object} self
         */
        var setDefaultTag = function(tag, value) {
          if (!$rootScope.ngMeta) {
            throw new Error('Cannot call setDefaultTag when ngMeta is undefined. Did you forget to call ngMeta.init() in the run block? \nRefer: https://github.com/vinaygopinath/ngMeta#getting-started');
          }

          if (tag === 'title') {
            if (angular.isDefined($rootScope.ngMeta.title)) {
              //if currently using default title, change the current title
              if ((defaults.title === '') &&
                    (($rootScope.ngMeta.title === defaults.title) ||
                      (config.useTitleSuffix && ($rootScope.ngMeta.title === defaults.titleSuffix)))) {
                $rootScope.ngMeta.title = value + $rootScope.ngMeta.title;
              } else if ($rootScope.ngMeta.title.startsWith(defaults.title)) {
                $rootScope.ngMeta.title.replace(defaults.title, value);
              }
            } else {
              $rootScope.ngMeta.title = value + (config.useTitleSuffix ? defaults.titleSuffix : '');
            }
          } else if (tag === 'titleSuffix') {
            if (config.useTitleSuffix) {
              if (angular.isDefined($rootScope.ngMeta.title)) {
                //if currently using default titleSuffix, change the current titleSuffix
                if ((defaults.titleSuffix === '') && ($rootScope.ngMeta.title === defaults.title)) {
                  $rootScope.ngMeta.title += value;
                } else if ($rootScope.ngMeta.title.endsWith(defaults.titleSuffix)) {
                  $rootScope.ngMeta.title.replace(defaults.titleSuffix, value);
                }
              } else {
                $rootScope.ngMeta.title = defaults.title + value;
              }
            }
          } else {
            //if currently using default tag (or was undefined), change/set the current tag
            if ((angular.isUndefined(defaults[tag]) && angular.isUndefined($rootScope.ngMeta[tag])) || ($rootScope.ngMeta[tag] === defaults[tag])) {
              $rootScope.ngMeta[tag] = value;
            }
          }

          defaults[tag] = value;
          return this;
        };

        /**
         * @ngdoc method
         * @name readRouteMeta
         * @description
         * Helper function to process meta tags on route/state
         * change.
         *
         * It:
         * 1. Sets the title (with titleSuffix, as appropriate)
         * 2. Iterates through all the state/route tags (other than title)
         *    and sets their values
         * 3. Iterates through all default tags and sets the ones
         *    that were not utilized while setting the state/route tags.
         *
         * @returns {Object} self
         */
        var readRouteMeta = function(meta) {
          meta = meta || {};

          if (meta.disableUpdate) {
            return false;
          }

          setTitle(meta.title, meta.titleSuffix);

          var def = angular.copy(defaults);

          delete meta.title;
          delete meta.titleSuffix;
          delete def.title;
          delete def.titleSuffix;

          var metaKeys = Object.keys(meta);
          for (var i = 0; i < metaKeys.length; i++) {
            if (def.hasOwnProperty(metaKeys[i])) {
              delete def[metaKeys[i]];
            }
            setTag(metaKeys[i], meta[metaKeys[i]]);
          }

          var defaultKeys = Object.keys(def);
          for (var j = 0; j < defaultKeys.length; j++) {
            setTag(defaultKeys[j], def[defaultKeys[j]]);
          }
        };

        var update = function(event, current) {
          readRouteMeta(angular.copy(current.meta));
        };

        /**
         * @ngdoc method
         * @name ngMeta#init
         * @description
         * Initializes the ngMeta object and sets up
         * listeners for route/state change broadcasts
         *
         * @example
         * angular.module('yourApp', ['ngRoute', 'ngMeta'])
         * .config(function($routeProvider, ngMetaProvider) {
         *   ....
         * })
         * .run(function(ngMeta) {
         *   ngMeta.init();
         * });
         */
        var init = function() {
          $rootScope.ngMeta = {};
          $rootScope.$on('$routeChangeSuccess', update);
          $rootScope.$on('$stateChangeSuccess', update);
        };

        return {
          'init': init,
          'setTitle': setTitle,
          'setTag': setTag,
          'setDefaultTag': setDefaultTag
        };
      }

      /* Set defaults */

      /**
       * @ngdoc method
       * @name ngMetaProvider#setDefaultTitle
       * @param {string} titleStr The default title of the page. If a
       * route/state does not define a `title` param in its meta object, this
       * value is used instead.
       *
       * @description
       * Sets the default title for all routes that are missing a custom `title`
       * property in their meta objects.
       *
       * @returns {Object} self
       */
      this.setDefaultTitle = function(titleStr) {
        defaults.title = titleStr;
        return this;
      };

      /**
       * @ngdoc method
       * @name ngMetaProvider#setDefaultTitleSuffix
       * @param {string} titleSuffix The default title suffix of the page. If a
       * route/state does not define a `titleSuffix` param in its meta object,
       * this value is used instead.
       *
       * @description
       * Sets the default title suffix for all routes that are missing a custom
       * `titleSuffix` property in their meta objects.
       *
       * @returns {Object} self
       */
      this.setDefaultTitleSuffix = function(titleSuffix) {
        defaults.titleSuffix = titleSuffix;
        return this;
      };

      /**
       * @ngdoc method
       * @name ngMetaProvider#setDefaultTag
       * @param {string} tag The default tag name. The default tag can be
       * overridden by defining a custom property of the same name in the meta
       * object of any route.
       *
       * @param {string} value The value of the tag.
       *
       * @description
       * Sets the default tag for all routes that are missing a custom
       * `tag` property in their meta objects.
       *
       * @returns {Object} self
       */
      this.setDefaultTag = function(tag, value) {
        defaults[tag] = value;
        return this;
      };

      /* One-time config */

      /**
       * @ngdoc method
       * @name ngMetaProvider#useTitleSuffix
       * @param {boolean} bool A boolean indicating the use of title suffix.
       * Defaults to false.
       *
       * @description
       * Toggles the use of the title suffix throughout the site.
       *
       * @returns {Object} self
       */
      this.useTitleSuffix = function(bool) {
        config.useTitleSuffix = !!bool;
        return this;
      };

      this.$get = function($rootScope) {
        return new Meta($rootScope);
      };
    });
}));<commit_msg>- Added useSuffixOnlyCustomTitle boolean to indicate whether suffix should be omitted when using default title<commit_after>(function(root, factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define(['angular'], factory);
  } else if (typeof exports === 'object') {
    // Node. Does not work with strict CommonJS, but
    // only CommonJS-like environments that support module.exports,
    // like Node.
    module.exports = factory(require('angular'));
  } else {
    // Browser globals (root is window)
    root.returnExports = factory(root.angular);
  }
}(this, function(angular) {
  /**
   * @ngdoc service
   * @name ngMeta.ngMeta
   * @description
   * # A metatags service for single-page applications
   * that supports setting arbitrary meta tags
   */
  angular.module('ngMeta', [])
    .provider('ngMeta', function() {

      'use strict';

      //Object for storing default tag/values
      var defaults = {
        title: '',
        titleSuffix: ''
      };

      //One-time configuration
      var config = {
        useTitleSuffix: false,
        useSuffixOnlyCustomTitle: false
      };

      function Meta($rootScope) {

        /**
         * @ngdoc method
         * @name ngMeta#setTitle
         * @description
         * Sets the title of the page, optionally
         * appending a title suffix.
         *
         * If suffix usage is enabled and the title suffix
         * parameter is missing, the default title suffix
         * (if available) is used as a fallback.
         *
         * @example
         * //title and titleSuffix
         * ngMeta.setTitle('Page name', ' - Site name | Tagline of the site');
         *
         * //title only (default titleSuffix may be suffixed,
         * //depending on useTitleSuffix configuration)
         * ngMeta.setTitle('Page name');
         *
         * @returns {Object} self
         */
        var setTitle = function(title, titleSuffix) {
          if (!$rootScope.ngMeta) {
            throw new Error('Cannot call setTitle when ngMeta is undefined. Did you forget to call ngMeta.init() in the run block? \nRefer: https://github.com/vinaygopinath/ngMeta#getting-started');
          }
          $rootScope.ngMeta.title = angular.isDefined(title) ? title : defaults.title;
          if (config.useTitleSuffix && (!config.useSuffixOnlyCustomTitle || angular.isDefined(title))) {
            $rootScope.ngMeta.title += angular.isDefined(titleSuffix) ? titleSuffix : defaults.titleSuffix;
          }
          return this;
        };

        /**
         * @ngdoc method
         * @name ngMeta#setTag
         * @description
         * Sets the value of a meta tag, using
         * the default value (if available) as
         * a fallback.
         *
         * @example
         * ngMeta.setTag('og:image', 'http://example.com/a.png');
         *
         * @returns {Object} self
         */
        var setTag = function(tag, value) {
          if (!$rootScope.ngMeta) {
            throw new Error('Cannot call setTag when ngMeta is undefined. Did you forget to call ngMeta.init() in the run block? \nRefer: https://github.com/vinaygopinath/ngMeta#getting-started');
          }
          if (tag === 'title' || tag === 'titleSuffix') {
            throw new Error('Attempt to set \'' + tag + '\' through \'setTag\': \'title\' and \'titleSuffix\' are reserved tag names. Please use \'ngMeta.setTitle\' instead');
          }
          $rootScope.ngMeta[tag] = angular.isDefined(value) ? value : defaults[tag];
          return this;
        };

        /**
         * @ngdoc method
         * @name ngMeta#setDefaultTag
         * @description
         * Sets the default tag for all routes that are missing a custom
         * `tag` property in their meta objects.
         *
         * @example
         * ngMeta.setDefaultTag('titleSuffix', ' | Tagline of the site');
         *
         * @returns {Object} self
         */
        var setDefaultTag = function(tag, value) {
          if (!$rootScope.ngMeta) {
            throw new Error('Cannot call setDefaultTag when ngMeta is undefined. Did you forget to call ngMeta.init() in the run block? \nRefer: https://github.com/vinaygopinath/ngMeta#getting-started');
          }

          if (tag === 'title') {
            if (angular.isDefined($rootScope.ngMeta.title)) {
              //if currently using default title, change the current title
              if ((defaults.title === '') &&
                    (($rootScope.ngMeta.title === defaults.title) ||
                      (config.useTitleSuffix && ($rootScope.ngMeta.title === defaults.titleSuffix)))) {
                $rootScope.ngMeta.title = value + $rootScope.ngMeta.title;
              } else if ($rootScope.ngMeta.title.startsWith(defaults.title)) {
                $rootScope.ngMeta.title.replace(defaults.title, value);
              }
            } else {
              $rootScope.ngMeta.title = value;
              if (config.useTitleSuffix) {
                $rootScope.ngMeta.title += (config.useSuffixOnlyCustomTitle ? '' : defaults.titleSuffix);
              }
            }
          } else if (tag === 'titleSuffix') {
            if (config.useTitleSuffix) {
              if (angular.isDefined($rootScope.ngMeta.title)) {
                //if currently using default titleSuffix, change the current titleSuffix
                if ((defaults.titleSuffix === '') && ($rootScope.ngMeta.title === defaults.title)) {
                  $rootScope.ngMeta.title += (config.useSuffixOnlyCustomTitle ? '' : value);
                } else if ($rootScope.ngMeta.title.endsWith(defaults.titleSuffix)) {
                  $rootScope.ngMeta.title.replace(defaults.titleSuffix, value);
                }
              } else {
                $rootScope.ngMeta.title = defaults.title;
                $rootScope.ngMeta.title += (config.useSuffixOnlyCustomTitle ? '' : value);
              }
            }
          } else {
            //if currently using default tag (or was undefined), change/set the current tag
            if ((angular.isUndefined(defaults[tag]) && angular.isUndefined($rootScope.ngMeta[tag])) || ($rootScope.ngMeta[tag] === defaults[tag])) {
              $rootScope.ngMeta[tag] = value;
            }
          }

          defaults[tag] = value;
          return this;
        };

        /**
         * @ngdoc method
         * @name readRouteMeta
         * @description
         * Helper function to process meta tags on route/state
         * change.
         *
         * It:
         * 1. Sets the title (with titleSuffix, as appropriate)
         * 2. Iterates through all the state/route tags (other than title)
         *    and sets their values
         * 3. Iterates through all default tags and sets the ones
         *    that were not utilized while setting the state/route tags.
         *
         * @returns {Object} self
         */
        var readRouteMeta = function(meta) {
          meta = meta || {};

          if (meta.disableUpdate) {
            return false;
          }

          setTitle(meta.title, meta.titleSuffix);

          var def = angular.copy(defaults);

          delete meta.title;
          delete meta.titleSuffix;
          delete def.title;
          delete def.titleSuffix;

          var metaKeys = Object.keys(meta);
          for (var i = 0; i < metaKeys.length; i++) {
            if (def.hasOwnProperty(metaKeys[i])) {
              delete def[metaKeys[i]];
            }
            setTag(metaKeys[i], meta[metaKeys[i]]);
          }

          var defaultKeys = Object.keys(def);
          for (var j = 0; j < defaultKeys.length; j++) {
            setTag(defaultKeys[j], def[defaultKeys[j]]);
          }
        };

        var update = function(event, current) {
          readRouteMeta(angular.copy(current.meta));
        };

        /**
         * @ngdoc method
         * @name ngMeta#init
         * @description
         * Initializes the ngMeta object and sets up
         * listeners for route/state change broadcasts
         *
         * @example
         * angular.module('yourApp', ['ngRoute', 'ngMeta'])
         * .config(function($routeProvider, ngMetaProvider) {
         *   ....
         * })
         * .run(function(ngMeta) {
         *   ngMeta.init();
         * });
         */
        var init = function() {
          $rootScope.ngMeta = {};
          $rootScope.$on('$routeChangeSuccess', update);
          $rootScope.$on('$stateChangeSuccess', update);
        };

        return {
          'init': init,
          'setTitle': setTitle,
          'setTag': setTag,
          'setDefaultTag': setDefaultTag
        };
      }

      /* Set defaults */

      /**
       * @ngdoc method
       * @name ngMetaProvider#setDefaultTitle
       * @param {string} titleStr The default title of the page. If a
       * route/state does not define a `title` param in its meta object, this
       * value is used instead.
       *
       * @description
       * Sets the default title for all routes that are missing a custom `title`
       * property in their meta objects.
       *
       * @returns {Object} self
       */
      this.setDefaultTitle = function(titleStr) {
        defaults.title = titleStr;
        return this;
      };

      /**
       * @ngdoc method
       * @name ngMetaProvider#setDefaultTitleSuffix
       * @param {string} titleSuffix The default title suffix of the page. If a
       * route/state does not define a `titleSuffix` param in its meta object,
       * this value is used instead.
       *
       * @description
       * Sets the default title suffix for all routes that are missing a custom
       * `titleSuffix` property in their meta objects.
       *
       * @returns {Object} self
       */
      this.setDefaultTitleSuffix = function(titleSuffix) {
        defaults.titleSuffix = titleSuffix;
        return this;
      };

      /**
       * @ngdoc method
       * @name ngMetaProvider#setDefaultTag
       * @param {string} tag The default tag name. The default tag can be
       * overridden by defining a custom property of the same name in the meta
       * object of any route.
       *
       * @param {string} value The value of the tag.
       *
       * @description
       * Sets the default tag for all routes that are missing a custom
       * `tag` property in their meta objects.
       *
       * @returns {Object} self
       */
      this.setDefaultTag = function(tag, value) {
        defaults[tag] = value;
        return this;
      };

      /* One-time config */

      /**
       * @ngdoc method
       * @name ngMetaProvider#useTitleSuffix
       * @param {boolean} bool A boolean indicating the use of title suffix.
       * Defaults to false.
       *
       * @description
       * Toggles the use of the title suffix throughout the site.
       *
       * @returns {Object} self
       */
      this.useTitleSuffix = function(bool) {
        config.useTitleSuffix = !!bool;
        return this;
      };

      /**
       * @ngdoc method
       * @name ngMetaProvider#useSuffixOnlyCustomTitle
       * @param {boolean} bool A boolean indicating if the title suffix
       * should only be used when the default title is not being used.
       * Defaults to false.
       *
       * @description
       * Toggles the use of the title suffix throughout the site when a
       * custom title is set by the state/route.
       *
       * @returns {Object} self
       */
      this.useSuffixOnlyCustomTitle = function(bool) {
        config.useSuffixOnlyCustomTitle = !!bool;
        return this;
      };

      this.$get = function($rootScope) {
        return new Meta($rootScope);
      };
    });
}));<|endoftext|>


<commit_before>Element.addMethods({
	// extracts id number from element(using it's id)
	// exmaple: $('test_12).extractId() -> 12
	extractId:  function(element){
		return (element.id && element.id.match(/\w+_(\d+)/)[1]) || 0;
	}
});
<commit_msg>fix in element.extractId() example code<commit_after>Element.addMethods({
	// extracts id number from element(using it's id)
	// exmaple: $('test_12').extractId() -> 12
	extractId:  function(element){
		return (element.id && element.id.match(/\w+_(\d+)/)[1]) || 0;
	}
});
<|endoftext|>


<commit_before>;

// Load dependencies
(function() {
    "use strict";
    var noop = function() {},

        originalConsoleLog = console.log,

        injectOrFail = function(path) {
            var result = phantom.injectJs(path);

            if (result !== true) {
                throw new Error("Could not inject " + path);
            }
        }

        // Hide console logging during libary loading
    console.log = noop;

    // Until a fully functioning require(...) is implemented
    injectOrFail("lib/underscore-min.js");
    injectOrFail("lib/q.min.js");

    // Restore console logging
    console.log = originalConsoleLog;
}());

(function(global, _) {
    "use strict";

    var defaults = {
        debugLevel: 4,
        scripts: ["lib/jquery-2.0.3.min.js", "lib/underscore-min.js", "lib/formfieldinfo.joelpurra.js"],
        timeout: 10000
    },
        // TODO: use a deep clone function
        options = {
            debugLevel: defaults.debugLevel,
            scripts: defaults.scripts.slice(0),
            timeout: defaults.timeout
        },
        priv = {},
        modes = {},
        qDef = {},
        _generalMixins = {},
        debug = {
            level: 4,
            out: function(fn, lvl, args) {
                if (lvl >= this.level) {
                    fn.apply(console, priv.toArray(args));
                }
            }
        };

    debug.init = function() {
        ["log", "debug", "info", "warn", "error"].forEach(function(fnName, index, array) {
            this[fnName] = function() {
                this.out(console[fnName], index, arguments);
            };
        }, debug);
    };

    modes.help = function(done) {
        // TODO: make debug level a command line argument
        console.log("# extract-field-info.js: extracts general form field info from HTML pages over HTTP.");
        console.log("# Usage: extract-field-info.js <mode> [arguments]");
        console.log("#   MODE \t\t ARGUMENTS");
        console.log("#   ---- \t\t ---------");

        Object.keys(modes).forEach(function(key) {
            var mode = modes[key];

            console.log("#   " + key + " \t\t " + priv.getModeFunctionArguments(mode).join(" "));
        });

        done();
    };

    modes.fields = function(done, address) {
        var tag = "mode.fields";

        function parseFieldSummaries(fieldSummaries) {
            debug.log(tag, "then", arguments, address, fieldSummaries, fieldSummaries.length);

            priv.printFieldSummaries(fieldSummaries);
        }

        Q.when(qDef.getFieldSummaries(address)).then(parseFieldSummaries, priv.logError(tag, "fail")).fin(done);
    };

    modes.shared = function(done, address1, address2, more) {
        var tag = "modes.shared",
            // Replacing the dummy addresses
            // Fix by improving the command line help/usage system
            addresses = priv.toArray(arguments).slice(1),
            i, allRequests = [];

        function afterFetched(fieldSummariesArray) {
            var tag = "modes.shared.afterFetched",
                _fieldSummariesArray = _(fieldSummariesArray);

            _fieldSummariesArray.each(function(fieldSummaries, index, list) {
                debug.log(tag, "fieldSummaries", index, "[i].length", fieldSummaries.length);
            });

            var shared = priv.getFieldSummariesIntersection(fieldSummariesArray);

            // HACK: unwrap underscore object so it won't get wrapped twice
            priv.printFieldSummaries(shared.toArray());
        }

        for (i = 0; i < addresses.length; i++) {
            allRequests.push(qDef.getFieldSummaries(addresses[i]));
        }

        Q.all(allRequests).then(afterFetched, priv.logError(tag, "fail")).fin(done);
    };

    priv.getFunctionArguments = function(fn) {
        var source = fn.toString(),
            start = source.indexOf("("),
            end = source.indexOf(")"),
            args = source.substring(start + 1, end).split(",");

        return args;
    };

    priv.getModeFunctionArguments = function(fn) {
        return priv.getFunctionArguments(fn).slice(1);
    }

    priv.getPageFieldGroups = function(page) {
        var fieldGroups = page.evaluate(function() {
            return JoelPurra.FormFieldInfo.getFields().removeEmptyNames().mergeArrays().groups().toArray();
        });

        return fieldGroups;
    };

    priv.getPageFieldSummaries = function(page) {
        var fieldSummaries = page.evaluate(function() {
            return JoelPurra.FormFieldInfo.getFields().removeEmptyNames().mergeArrays().groups().nameValues().toArray();
        });

        return fieldSummaries;
    };

    priv.printFieldSummaries = function(fieldSummaries) {

        _(fieldSummaries).each(function(fieldSummary, index, list) {
            console.log("\"" + fieldSummary.name + "\"", fieldSummary.values.map(function(value) {
                return "\"" + value + "\""
            }).toString());
        });
    };

    priv.getFieldSummariesIntersection = function(fieldSummariesArray) {
        var tag = "priv.getFieldSummariesIntersection",
            _fieldSummariesArray = _(fieldSummariesArray),
            intersection = _fieldSummariesArray.intersectionPropertyEq("name");

        return intersection;
    };

    priv.toArray = function(args) {
        return Array.prototype.slice.call(args, 0);
    };

    priv.injectJss = function(page, scripts) {
        debug.log("priv.injectJss", "start", scripts);

        var success = true;

        scripts.forEach(function(script, index, array) {
            success = success && priv.injectJs(page, script);
        });

        debug.log("priv.injectJss", success ? "done" : "fail", scripts);

        return success;
    };

    priv.injectJs = function(page, script) {
        debug.log("priv.injectJs", "start", script);

        var success = page.injectJs(script);

        debug.log("priv.injectJs", success ? "done" : "fail", script);

        return success;
    };

    priv.gotoUrl = function(address, callback) {
        var tag = "priv.gotoUrl",
            page = require("webpage").create();

        function release() {
            debug.log(tag, "release", address, page);

            page.release();
        }

        page.open(address, function(status) {
            debug.log("page.open(...)", status, address);

            try {
                if (status === "success") {
                    //if (debug.isLogEnabled())
                    {
                        // TODO: implement debug.isLogEnabled()
                        var title = page.evaluate(function() {
                            return document.title;
                        });

                        debug.log("Page title is " + title);
                    }

                    var scriptsSuccess = priv.injectJss(page, options.scripts);

                    var jQueryVersion = page.evaluate(function() {
                        return window.jQuery.fn.jquery;
                    });

                    debug.log("jQuery version", jQueryVersion);

                    var underscoreVersion = page.evaluate(function() {
                        return _.VERSION;
                    });

                    debug.log("underscore version", underscoreVersion);

                    callback.call(null, null, page);
                } else {
                    callback.call(null, status);
                }
            } catch (e) {
                debug.error(tag, "catch", e);

                throw e;
            } finally {
                release();
            }
        });
    };

    priv.done = function() {
        debug.log("done");

        var timer = setTimeout(function() {
            debug.log("really done");

            global.exit();
        }, 1000);
    };

    priv.init = function() {
        var system = require("system"),
            commandLineArguments = system.args,
            mode, args;

        // TODO: make debug level a command line argument
        debug.level = options.debugLevel;

        debug.log("commandLineArguments", commandLineArguments);

        try {
            if (commandLineArguments.length < 2) {
                mode = "help";
            } else {
                mode = commandLineArguments[1];
            }

            args = commandLineArguments.slice(2);
            args.unshift(priv.done);

            modes[mode].apply(null, args);
        } catch (e) {
            debug.error("priv.init", "General error", e);

            priv.done();
        } finally {
            debug.log("priv.init", "finally done")
        }
    };

    priv.logError = function() {
        var knownArgs = priv.toArray(arguments);

        return function() {
            debug.error.apply(debug, knownArgs.concat(priv.toArray(arguments)));
        }
    };

    qDef.gotoUrl = function(address, timeout) {
        var gotoDeferred = Q.ncall(priv.gotoUrl, priv, address);

        return Q.timeout(gotoDeferred, timeout);
    };

    qDef.getPageFieldGroups = function(address) {
        var tag = "qDef.getPageFieldGroups";

        function parsePage(page) {
            debug.log(tag, "then", arguments, page);

            var fieldGroups = priv.getPageFieldGroups(page);

            return fieldGroups;
        };

        return Q.when(qDef.gotoUrl(address, options.timeout)).then(parsePage, priv.logError(tag, "fail"));
    };

    qDef.getFieldSummaries = function(address) {
        var tag = "qDef.getFieldSummaries";

        function parsePage(page) {
            debug.log(tag, "then", arguments, page);

            var fieldSummaries = priv.getPageFieldSummaries(page);

            return fieldSummaries;
        };

        return Q.when(qDef.gotoUrl(address, options.timeout)).then(parsePage, priv.logError(tag, "fail"));
    };

    _generalMixins.filterPropertyEq = function(list, propertyName, value) {
        var filtered = _(list).filter(function(inner, index, list) {
            return inner[propertyName] === value;
        });

        return _(filtered);
    };

    _generalMixins.intersectionPropertyEq = function(lists, propertyName) {
        var tag = "_.intersectionPropertyEq",
            _lists = _(lists);

        var union = _.union.apply(_, _lists.toArray());
        union = _(union);

        debug.log(tag, "union.size()", union.size());

        var duplicates = union.filter(function(val, index, list) {
            var moreThanOne = union.filterPropertyEq(propertyName, val[propertyName]).size() > 1;

            return moreThanOne;
        });
        duplicates = _(duplicates);

        debug.log(tag, "duplicates.size()", duplicates.size());

        var discovered = {};

        var intersection = duplicates.filter(function(val, index, list) {
            if (discovered[val[propertyName]] === undefined) {
                discovered[val[propertyName]] = 1;

                return true;
            }

            discovered[val[propertyName]]++;

            return false;
        });
        intersection = _(intersection);

        debug.log(tag, "intersection.size()", intersection.size());

        return intersection;
    };

    // TODO: create a copy of underscore and add mixins locally only?
    _.mixin(_generalMixins);

    debug.init();
    priv.init();
}(phantom, _));<commit_msg>Move library path to function<commit_after>;

function fileInLibrary(name) {
    return "../lib/" + name;
}

// Load dependencies
(function() {
    "use strict";
    var noop = function() {},

        originalConsoleLog = console.log,

        injectOrFail = function(path) {
            var result = phantom.injectJs(path);

            if (result !== true) {
                throw new Error("Could not inject " + path);
            }
        }

        // Hide console logging during libary loading
    console.log = noop;

    // Until a fully functioning require(...) is implemented
    injectOrFail(fileInLibrary("underscore-min.js"));
    injectOrFail(fileInLibrary("q.min.js"));

    // Restore console logging
    console.log = originalConsoleLog;
}());

(function(global, _) {
    "use strict";

    var defaults = {
        debugLevel: 4,
        scripts: [fileInLibrary("jquery-2.0.3.min.js"), fileInLibrary("underscore-min.js"), fileInLibrary("formfieldinfo.joelpurra.js")],
        timeout: 10000
    },
        // TODO: use a deep clone function
        options = {
            debugLevel: defaults.debugLevel,
            scripts: defaults.scripts.slice(0),
            timeout: defaults.timeout
        },
        priv = {},
        modes = {},
        qDef = {},
        _generalMixins = {},
        debug = {
            level: 4,
            out: function(fn, lvl, args) {
                if (lvl >= this.level) {
                    fn.apply(console, priv.toArray(args));
                }
            }
        };

    debug.init = function() {
        ["log", "debug", "info", "warn", "error"].forEach(function(fnName, index, array) {
            this[fnName] = function() {
                this.out(console[fnName], index, arguments);
            };
        }, debug);
    };

    modes.help = function(done) {
        // TODO: make debug level a command line argument
        console.log("# extract-field-info.js: extracts general form field info from HTML pages over HTTP.");
        console.log("# Usage: extract-field-info.js <mode> [arguments]");
        console.log("#   MODE \t\t ARGUMENTS");
        console.log("#   ---- \t\t ---------");

        Object.keys(modes).forEach(function(key) {
            var mode = modes[key];

            console.log("#   " + key + " \t\t " + priv.getModeFunctionArguments(mode).join(" "));
        });

        done();
    };

    modes.fields = function(done, address) {
        var tag = "mode.fields";

        function parseFieldSummaries(fieldSummaries) {
            debug.log(tag, "then", arguments, address, fieldSummaries, fieldSummaries.length);

            priv.printFieldSummaries(fieldSummaries);
        }

        Q.when(qDef.getFieldSummaries(address)).then(parseFieldSummaries, priv.logError(tag, "fail")).fin(done);
    };

    modes.shared = function(done, address1, address2, more) {
        var tag = "modes.shared",
            // Replacing the dummy addresses
            // Fix by improving the command line help/usage system
            addresses = priv.toArray(arguments).slice(1),
            i, allRequests = [];

        function afterFetched(fieldSummariesArray) {
            var tag = "modes.shared.afterFetched",
                _fieldSummariesArray = _(fieldSummariesArray);

            _fieldSummariesArray.each(function(fieldSummaries, index, list) {
                debug.log(tag, "fieldSummaries", index, "[i].length", fieldSummaries.length);
            });

            var shared = priv.getFieldSummariesIntersection(fieldSummariesArray);

            // HACK: unwrap underscore object so it won't get wrapped twice
            priv.printFieldSummaries(shared.toArray());
        }

        for (i = 0; i < addresses.length; i++) {
            allRequests.push(qDef.getFieldSummaries(addresses[i]));
        }

        Q.all(allRequests).then(afterFetched, priv.logError(tag, "fail")).fin(done);
    };

    priv.getFunctionArguments = function(fn) {
        var source = fn.toString(),
            start = source.indexOf("("),
            end = source.indexOf(")"),
            args = source.substring(start + 1, end).split(",");

        return args;
    };

    priv.getModeFunctionArguments = function(fn) {
        return priv.getFunctionArguments(fn).slice(1);
    }

    priv.getPageFieldGroups = function(page) {
        var fieldGroups = page.evaluate(function() {
            return JoelPurra.FormFieldInfo.getFields().removeEmptyNames().mergeArrays().groups().toArray();
        });

        return fieldGroups;
    };

    priv.getPageFieldSummaries = function(page) {
        var fieldSummaries = page.evaluate(function() {
            return JoelPurra.FormFieldInfo.getFields().removeEmptyNames().mergeArrays().groups().nameValues().toArray();
        });

        return fieldSummaries;
    };

    priv.printFieldSummaries = function(fieldSummaries) {

        _(fieldSummaries).each(function(fieldSummary, index, list) {
            console.log("\"" + fieldSummary.name + "\"", fieldSummary.values.map(function(value) {
                return "\"" + value + "\""
            }).toString());
        });
    };

    priv.getFieldSummariesIntersection = function(fieldSummariesArray) {
        var tag = "priv.getFieldSummariesIntersection",
            _fieldSummariesArray = _(fieldSummariesArray),
            intersection = _fieldSummariesArray.intersectionPropertyEq("name");

        return intersection;
    };

    priv.toArray = function(args) {
        return Array.prototype.slice.call(args, 0);
    };

    priv.injectJss = function(page, scripts) {
        debug.log("priv.injectJss", "start", scripts);

        var success = true;

        scripts.forEach(function(script, index, array) {
            success = success && priv.injectJs(page, script);
        });

        debug.log("priv.injectJss", success ? "done" : "fail", scripts);

        return success;
    };

    priv.injectJs = function(page, script) {
        debug.log("priv.injectJs", "start", script);

        var success = page.injectJs(script);

        debug.log("priv.injectJs", success ? "done" : "fail", script);

        return success;
    };

    priv.gotoUrl = function(address, callback) {
        var tag = "priv.gotoUrl",
            page = require("webpage").create();

        function release() {
            debug.log(tag, "release", address, page);

            page.release();
        }

        page.open(address, function(status) {
            debug.log("page.open(...)", status, address);

            try {
                if (status === "success") {
                    //if (debug.isLogEnabled())
                    {
                        // TODO: implement debug.isLogEnabled()
                        var title = page.evaluate(function() {
                            return document.title;
                        });

                        debug.log("Page title is " + title);
                    }

                    var scriptsSuccess = priv.injectJss(page, options.scripts);

                    var jQueryVersion = page.evaluate(function() {
                        return window.jQuery.fn.jquery;
                    });

                    debug.log("jQuery version", jQueryVersion);

                    var underscoreVersion = page.evaluate(function() {
                        return _.VERSION;
                    });

                    debug.log("underscore version", underscoreVersion);

                    callback.call(null, null, page);
                } else {
                    callback.call(null, status);
                }
            } catch (e) {
                debug.error(tag, "catch", e);

                throw e;
            } finally {
                release();
            }
        });
    };

    priv.done = function() {
        debug.log("done");

        var timer = setTimeout(function() {
            debug.log("really done");

            global.exit();
        }, 1000);
    };

    priv.init = function() {
        var system = require("system"),
            commandLineArguments = system.args,
            mode, args;

        // TODO: make debug level a command line argument
        debug.level = options.debugLevel;

        debug.log("commandLineArguments", commandLineArguments);

        try {
            if (commandLineArguments.length < 2) {
                mode = "help";
            } else {
                mode = commandLineArguments[1];
            }

            args = commandLineArguments.slice(2);
            args.unshift(priv.done);

            modes[mode].apply(null, args);
        } catch (e) {
            debug.error("priv.init", "General error", e);

            priv.done();
        } finally {
            debug.log("priv.init", "finally done")
        }
    };

    priv.logError = function() {
        var knownArgs = priv.toArray(arguments);

        return function() {
            debug.error.apply(debug, knownArgs.concat(priv.toArray(arguments)));
        }
    };

    qDef.gotoUrl = function(address, timeout) {
        var gotoDeferred = Q.ncall(priv.gotoUrl, priv, address);

        return Q.timeout(gotoDeferred, timeout);
    };

    qDef.getPageFieldGroups = function(address) {
        var tag = "qDef.getPageFieldGroups";

        function parsePage(page) {
            debug.log(tag, "then", arguments, page);

            var fieldGroups = priv.getPageFieldGroups(page);

            return fieldGroups;
        };

        return Q.when(qDef.gotoUrl(address, options.timeout)).then(parsePage, priv.logError(tag, "fail"));
    };

    qDef.getFieldSummaries = function(address) {
        var tag = "qDef.getFieldSummaries";

        function parsePage(page) {
            debug.log(tag, "then", arguments, page);

            var fieldSummaries = priv.getPageFieldSummaries(page);

            return fieldSummaries;
        };

        return Q.when(qDef.gotoUrl(address, options.timeout)).then(parsePage, priv.logError(tag, "fail"));
    };

    _generalMixins.filterPropertyEq = function(list, propertyName, value) {
        var filtered = _(list).filter(function(inner, index, list) {
            return inner[propertyName] === value;
        });

        return _(filtered);
    };

    _generalMixins.intersectionPropertyEq = function(lists, propertyName) {
        var tag = "_.intersectionPropertyEq",
            _lists = _(lists);

        var union = _.union.apply(_, _lists.toArray());
        union = _(union);

        debug.log(tag, "union.size()", union.size());

        var duplicates = union.filter(function(val, index, list) {
            var moreThanOne = union.filterPropertyEq(propertyName, val[propertyName]).size() > 1;

            return moreThanOne;
        });
        duplicates = _(duplicates);

        debug.log(tag, "duplicates.size()", duplicates.size());

        var discovered = {};

        var intersection = duplicates.filter(function(val, index, list) {
            if (discovered[val[propertyName]] === undefined) {
                discovered[val[propertyName]] = 1;

                return true;
            }

            discovered[val[propertyName]]++;

            return false;
        });
        intersection = _(intersection);

        debug.log(tag, "intersection.size()", intersection.size());

        return intersection;
    };

    // TODO: create a copy of underscore and add mixins locally only?
    _.mixin(_generalMixins);

    debug.init();
    priv.init();
}(phantom, _));<|endoftext|>


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

    if (T.envtype !== "browser") {
        return;
    }

    var fn = T.fn;
    var modules = T.modules;

    fn.register("audio.jsonp", function(_args) {
        var BufferNode = fn.getClass("buffer");
        var instance = new BufferNode(_args);

        instance.playbackState = fn.FINISHED_STATE;
        instance._.isLoaded = false;

        Object.defineProperties(instance, {
            isLoaded: {
                get: function() {
                    return this._.isLoaded;
                }
            }
        });

        instance.load     = load;
        instance.loadthis = loadthis;

        return instance;
    });

    var re = /(_)?callback=([_\w\d]+)/;

    var load = function(url) {
        var self = this, _ = this._;
        var dfd = new modules.Deferred(this);

        var args = arguments, i = 1;

        dfd.done(function() {
            self._.emit("done");
        });

        if (typeof args[i] === "function") {
            dfd.done(args[i++]);
            if (typeof args[i] === "function") {
                dfd.fail(args[i++]);
            }
        }

        var m, callback, script;

        if (_.script) {
            dfd.reject();
        } else {
            m = re.exec(url);
            callback = "timbrejs_audiojsonp";
            if (m) {
                if (m[1]) {
                    url = url.replace(m[0], "");
                    url = url.replace(/\?$/, "");
                }
                callback += "_" + m[2] + "";
            }
            var onloadedmetadata = function(result, msg) {
                var _ = self._;
                if (result) {
                    self.playbackState = fn.PLAYING_STATE;
                    _.samplerate = result.samplerate;
                    _.channels   = result.channels;
                    _.bufferMix  = null;
                    _.buffer     = result.buffer;
                    _.phase      = 0;
                    _.phaseIncr  = result.samplerate / T.samplerate;
                    _.duration   = result.duration * 1000;
                    _.currentTime = 0;
                    if (_.isReversed) {
                        _.phaseIncr *= -1;
                        _.phase = result.buffer[0].length + _.phaseIncr;
                    }
                    self._.emit("loadedmetadata");
                } else {
                    dfd.reject(msg);
                }
            };

            var onloadeddata = function() {
                self._.isLoaded  = true;
                self._.plotFlush = true;
                self._.emit("loadeddata");
                dfd.resolveWith(self);
            };

            window[callback] = function(base64, ext) {
                var bin = atob(base64);
                var a = new Array(bin.length), i, imax;
                for (i = 0, imax = a.length; i < imax; ++i) {
                    a[i] = bin.charCodeAt(i);
                }
                var src = { type:ext, data:new Uint8Array(a) };
                new modules.Decoder().decode(src, onloadedmetadata, onloadeddata);

                delete window[callback];
                _.script = null;
            };
            script = document.createElement("script");
            script.src = url;
            document.body.appendChild(script);
            _.script = script;
        }

        return dfd.promise();
    };

    var loadthis = function() {
        load.apply(this, arguments);
        return this;
    };

})(timbre);
<commit_msg>added: base64decode<commit_after>(function(T) {
    "use strict";

    if (T.envtype !== "browser") {
        return;
    }

    var fn = T.fn;
    var modules = T.modules;

    fn.register("audio.jsonp", function(_args) {
        var BufferNode = fn.getClass("buffer");
        var instance = new BufferNode(_args);

        instance.playbackState = fn.FINISHED_STATE;
        instance._.isLoaded = false;

        Object.defineProperties(instance, {
            isLoaded: {
                get: function() {
                    return this._.isLoaded;
                }
            }
        });

        instance.load     = load;
        instance.loadthis = loadthis;

        return instance;
    });

    var re = /(_)?callback=([_\w\d]+)/;

    var load = function(url) {
        var self = this, _ = this._;
        var dfd = new modules.Deferred(this);

        var args = arguments, i = 1;

        dfd.done(function() {
            self._.emit("done");
        });

        if (typeof args[i] === "function") {
            dfd.done(args[i++]);
            if (typeof args[i] === "function") {
                dfd.fail(args[i++]);
            }
        }

        var m, callback, script;

        if (_.script) {
            dfd.reject();
        } else {
            m = re.exec(url);
            callback = "timbrejs_audiojsonp";
            if (m) {
                if (m[1]) {
                    url = url.replace(m[0], "");
                    url = url.replace(/\?$/, "");
                }
                callback += "_" + m[2] + "";
            }
            var onloadedmetadata = function(result, msg) {
                var _ = self._;
                if (result) {
                    self.playbackState = fn.PLAYING_STATE;
                    _.samplerate = result.samplerate;
                    _.channels   = result.channels;
                    _.bufferMix  = null;
                    _.buffer     = result.buffer;
                    _.phase      = 0;
                    _.phaseIncr  = result.samplerate / T.samplerate;
                    _.duration   = result.duration * 1000;
                    _.currentTime = 0;
                    if (_.isReversed) {
                        _.phaseIncr *= -1;
                        _.phase = result.buffer[0].length + _.phaseIncr;
                    }
                    self._.emit("loadedmetadata");
                } else {
                    dfd.reject(msg);
                }
            };

            var onloadeddata = function() {
                self._.isLoaded  = true;
                self._.plotFlush = true;
                self._.emit("loadeddata");
                dfd.resolveWith(self);
            };

            window[callback] = function(base64, ext) {
                var bin, a, i, imax, data;
                if (typeof atob === "function") {
                    bin = atob(base64);
                    a = new Array(bin.length);
                    for (i = 0, imax = a.length; i < imax; ++i) {
                        a[i] = bin.charCodeAt(i);
                    }
                    data = new Uint8Array(a);
                } else {
                    data = base64decode(base64);
                }

                new modules.Decoder().decode({type:ext, data:data}, onloadedmetadata, onloadeddata);

                delete window[callback];
                _.script = null;
            };
            script = document.createElement("script");
            script.src = url;
            document.body.appendChild(script);
            _.script = script;
        }

        return dfd.promise();
    };

    var loadthis = function() {
        load.apply(this, arguments);
        return this;
    };

    var base64DecMap = new Uint8Array([
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3F,
        0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,
        0x3C, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
        0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
        0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
        0x17, 0x18, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
        0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
        0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
        0x31, 0x32, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00
    ]);

    var base64decode = function(src) {
        var a = new Uint8Array(src.length);
        var len, sidx, didx;
        var i, imax = src.length;
        for (i = 0; i < imax; i++) {
            if (src.charAt(i) === "=") {
                break;
            }
            a[i] = base64DecMap[src.charCodeAt(i)];
        }
        len = i;
        if ((len % 4) === 1) {
            return null;
        }
        len -= ((len + 3) / 4)|0;
        if (!len) {
            return null;
        }

        sidx = 0;
        didx = 0;
        if (len > 1) {
            while (didx < len - 2) {
                a[didx    ] = (((a[sidx    ] << 2) & 255) | ((a[sidx + 1] >>> 4) &  3));
                a[didx + 1] = (((a[sidx + 1] << 4) & 255) | ((a[sidx + 2] >>> 2) & 15));
                a[didx + 2] = (((a[sidx + 2] << 6) & 255) | ((a[sidx + 3] &  63)     ));
                sidx += 4;
                didx += 3;
            }
        }
        if (didx < len) {
            a[didx] = (((a[sidx    ] << 2) & 255) | ((a[sidx + 1] >>> 4) &  3));
        }
        if (++didx < len) {
            a[didx] = (((a[sidx + 1] << 4) & 255) | ((a[sidx + 2] >>> 2) & 15));
        }
        return a.subarray(0, len);
    };

})(timbre);
<|endoftext|>


<commit_before>/**
 * Pie chart class factory
 */
(function() {
    'use strict';

    function PieChartFact(BaseChart, Utils) {

        function PieChart($scope) {
            BaseChart.apply(this, [$scope]);
            var _this = this;
            _this.labelsFormatter = labelsFormatter;

            $scope.item.toggleLegend = toggleLegend;
            $scope.item.toggleValues = toggleValues;
            $scope.item.isBtnValues = true;
            var opt = {series: {allowPointSelect: true, stickyTracking: false}};
            if (!$scope.chartConfig.options.plotOptions) $scope.chartConfig.options.plotOptions = {};
            Utils.merge($scope.chartConfig.options.plotOptions, opt);

            if (this.desc.type === "donutChart" || this.desc.type === "donutChart3D") {
                opt = {
                    plotOptions: {
                        pie: {
                            innerSize: "20%"
                        }
                    }
                };
                Utils.merge($scope.chartConfig.options, opt);
            }
            if (this.desc.type === "pieChart3D" || this.desc.type === "donutChart3D") {
                opt = {
                    chart: {
                        options3d: {
                            enabled: true,
                            alpha: 55,
                            beta: 0
                        }
                    },
                    plotOptions: {
                        pie: {
                            allowPointSelect: true,
                            cursor: 'pointer',
                            depth: 35
                        }
                    }
                };
                Utils.merge($scope.chartConfig.options, opt);

            }

            var po = {
                plotOptions: {
                    pie: {
                        allowPointSelect: true,
                        cursor: 'pointer',
                        dataLabels: {
                            enabled: $scope.item.showValues
                        }
                    }
                }
            };
            Utils.merge($scope.chartConfig.options, po);

            if (!$scope.chartConfig.options.plotOptions.series.dataLabels) {
                $scope.chartConfig.options.plotOptions.series.dataLabels = {};
            }
            $scope.chartConfig.options.plotOptions.series.dataLabels.enabled = $scope.item.isLegend;

            if (!$scope.item.showValues) {
                delete $scope.chartConfig.options.plotOptions.series.dataLabels.formatter;
                delete $scope.chartConfig.options.plotOptions.pie.dataLabels.formatter;
            }
            /*if ($scope.chartConfig.options.plotOptions.pie.dataLabels.enabled)
            {
                $scope.chartConfig.options.plotOptions.series.dataLabels.enabled = false;
            }
*/

            this.setType('pie');
            this.requestData();

            /**
             * Toggles legend of pie chart
             */
            function toggleLegend() {
                _this.toggleButton("isLegend");
                if (_this.chart) {
                    $scope.chartConfig.options.plotOptions.series.dataLabels = {
                        enabled: $scope.item.isLegend
                    };
                }
            }

            function labelsFormatter() {
                /* jshint ignore:start */
                var t = this;
                /* jshint ignore:end */
                var fmt = t.series.options.format;
                var val = t.y;

                if (fmt) val = _this.formatNumber(val, fmt);
                return t.key + ", " + val;
            }

            function toggleValues() {
                _this.toggleButton("showValues");
                $scope.chartConfig.options.plotOptions.pie.dataLabels = {
                    enabled: $scope.item.showValues,
                    formatter: _this.labelsFormatter
                };
                if (!$scope.item.showValues) {
                    delete $scope.chartConfig.options.plotOptions.series.dataLabels.formatter;
                    delete $scope.chartConfig.options.plotOptions.pie.dataLabels.formatter;
                }
            }

        }

        return PieChart;
    }

    angular.module('widgets')
        .factory('PieChart', ['BaseChart', 'Utils', PieChartFact]);

})();<commit_msg>Fix problem with using default labelFormatter on page loading.<commit_after>/**
 * Pie chart class factory
 */
(function() {
    'use strict';

    function PieChartFact(BaseChart, Utils) {

        function PieChart($scope) {
            BaseChart.apply(this, [$scope]);
            var _this = this;
            _this.labelsFormatter = labelsFormatter;

            $scope.item.toggleLegend = toggleLegend;
            $scope.item.toggleValues = toggleValues;
            $scope.item.isBtnValues = true;
            var opt = {series: {allowPointSelect: true, stickyTracking: false}};
            if (!$scope.chartConfig.options.plotOptions) $scope.chartConfig.options.plotOptions = {};
            Utils.merge($scope.chartConfig.options.plotOptions, opt);

            if (this.desc.type === "donutChart" || this.desc.type === "donutChart3D") {
                opt = {
                    plotOptions: {
                        pie: {
                            innerSize: "20%"
                        }
                    }
                };
                Utils.merge($scope.chartConfig.options, opt);
            }
            if (this.desc.type === "pieChart3D" || this.desc.type === "donutChart3D") {
                opt = {
                    chart: {
                        options3d: {
                            enabled: true,
                            alpha: 55,
                            beta: 0
                        }
                    },
                    plotOptions: {
                        pie: {
                            allowPointSelect: true,
                            cursor: 'pointer',
                            depth: 35
                        }
                    }
                };
                Utils.merge($scope.chartConfig.options, opt);

            }

            var po = {
                plotOptions: {
                    pie: {
                        allowPointSelect: true,
                        cursor: 'pointer',
                        dataLabels: {
                            enabled: $scope.item.showValues
                        }
                    },
                    series: {
                        dataLabels: {
                            formatter: _this.labelsFormatter
                        }
                    }
                }
            };
            Utils.merge($scope.chartConfig.options, po);

            if (!$scope.chartConfig.options.plotOptions.series.dataLabels) {
                $scope.chartConfig.options.plotOptions.series.dataLabels = {};
            }
            $scope.chartConfig.options.plotOptions.series.dataLabels.enabled = $scope.item.isLegend;

            if (!$scope.item.showValues) {
                delete $scope.chartConfig.options.plotOptions.series.dataLabels.formatter;
                delete $scope.chartConfig.options.plotOptions.pie.dataLabels.formatter;
            }
            /*if ($scope.chartConfig.options.plotOptions.pie.dataLabels.enabled)
            {
                $scope.chartConfig.options.plotOptions.series.dataLabels.enabled = false;
            }
*/

            this.setType('pie');
            this.requestData();

            /**
             * Toggles legend of pie chart
             */
            function toggleLegend() {
                _this.toggleButton("isLegend");
                if (_this.chart) {
                    $scope.chartConfig.options.plotOptions.series.dataLabels = {
                        enabled: $scope.item.isLegend
                    };
                }
            }

            function labelsFormatter() {
                /* jshint ignore:start */
                var t = this;
                /* jshint ignore:end */
                var fmt = t.series.options.format;
                var val = t.y;

                if (fmt) val = _this.formatNumber(val, fmt);
                return t.key + ", " + val;
            }

            function toggleValues() {
                _this.toggleButton("showValues");
                $scope.chartConfig.options.plotOptions.pie.dataLabels = {
                    enabled: $scope.item.showValues,
                    formatter: _this.labelsFormatter
                };
                if (!$scope.item.showValues) {
                    delete $scope.chartConfig.options.plotOptions.series.dataLabels.formatter;
                    delete $scope.chartConfig.options.plotOptions.pie.dataLabels.formatter;
                }
            }

        }

        return PieChart;
    }

    angular.module('widgets')
        .factory('PieChart', ['BaseChart', 'Utils', PieChartFact]);

})();<|endoftext|>


<commit_before>(function( jQuery ) {

var rtable = /^t(?:able|d|h)$/i,
	rroot = /^(?:body|html)$/i;

if ( "getBoundingClientRect" in document.documentElement ) {
	jQuery.fn.offset = function( options ) {
		var elem = this[0], box;

		if ( options ) {
			return this.each(function( i ) {
				jQuery.offset.setOffset( this, options, i );
			});
		}

		if ( !elem || !elem.ownerDocument ) {
			return null;
		}

		if ( elem === elem.ownerDocument.body ) {
			return jQuery.offset.bodyOffset( elem );
		}

		try {
			box = elem.getBoundingClientRect();

		} catch(e) {
			box = { top: 0, left: 0 };
		}

		var doc = elem.ownerDocument,
			body = doc.body,
			docElem = doc.documentElement,
			win = getWindow(doc),
			clientTop  = docElem.clientTop  || body.clientTop  || 0,
			clientLeft = docElem.clientLeft || body.clientLeft || 0,
			scrollTop  = (win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop  || body.scrollTop ),
			scrollLeft = (win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft),
			top  = box.top  + scrollTop  - clientTop,
			left = box.left + scrollLeft - clientLeft;

		return { top: top, left: left };
	};

} else {
	jQuery.fn.offset = function( options ) {
		var elem = this[0];

		if ( options ) {
			return this.each(function( i ) {
				jQuery.offset.setOffset( this, options, i );
			});
		}

		if ( !elem || !elem.ownerDocument ) {
			return null;
		}

		if ( elem === elem.ownerDocument.body ) {
			return jQuery.offset.bodyOffset( elem );
		}

		jQuery.offset.initialize();

		var offsetParent = elem.offsetParent, prevOffsetParent = elem,
			doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement,
			body = doc.body, defaultView = doc.defaultView,
			prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
			top = elem.offsetTop, left = elem.offsetLeft;

		while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
			if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
				break;
			}

			computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
			top  -= elem.scrollTop;
			left -= elem.scrollLeft;

			if ( elem === offsetParent ) {
				top  += elem.offsetTop;
				left += elem.offsetLeft;

				if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
					top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
					left += parseFloat( computedStyle.borderLeftWidth ) || 0;
				}

				prevOffsetParent = offsetParent;
				offsetParent = elem.offsetParent;
			}

			if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
				top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
				left += parseFloat( computedStyle.borderLeftWidth ) || 0;
			}

			prevComputedStyle = computedStyle;
		}

		if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
			top  += body.offsetTop;
			left += body.offsetLeft;
		}

		if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
			top  += Math.max( docElem.scrollTop, body.scrollTop );
			left += Math.max( docElem.scrollLeft, body.scrollLeft );
		}

		return { top: top, left: left };
	};
}

jQuery.offset = {
	initialize: function() {
		var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, "marginTop") ) || 0,
			html = "

";

		jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );

		container.innerHTML = html;
		body.insertBefore( container, body.firstChild );
		innerDiv = container.firstChild;
		checkDiv = innerDiv.firstChild;
		td = innerDiv.nextSibling.firstChild.firstChild;

		this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
		this.doesAddBorderForTableAndCells = (td.offsetTop === 5);

		checkDiv.style.position = "fixed";
		checkDiv.style.top = "20px";

		// safari subtracts parent border width here which is 5px
		this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
		checkDiv.style.position = checkDiv.style.top = "";

		innerDiv.style.overflow = "hidden";
		innerDiv.style.position = "relative";

		this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);

		this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);

		body.removeChild( container );
		body = container = innerDiv = checkDiv = table = td = null;
		jQuery.offset.initialize = jQuery.noop;
	},

	bodyOffset: function( body ) {
		var top = body.offsetTop, left = body.offsetLeft;

		jQuery.offset.initialize();

		if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
			top  += parseFloat( jQuery.css(body, "marginTop") ) || 0;
			left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
		}

		return { top: top, left: left };
	},

	setOffset: function( elem, options, i ) {
		var position = jQuery.css( elem, "position" );

		// set position first, in-case top/left are set even on static elem
		if ( position === "static" ) {
			elem.style.position = "relative";
		}

		var curElem = jQuery( elem ),
			curOffset = curElem.offset(),
			curCSSTop = jQuery.css( elem, "top" ),
			curCSSLeft = jQuery.css( elem, "left" ),
			calculatePosition = (position === "absolute" && jQuery.inArray('auto', [curCSSTop, curCSSLeft]) > -1),
			props = {}, curPosition = {}, curTop, curLeft;

		// need to be able to calculate position if either top or left is auto and position is absolute
		if ( calculatePosition ) {
			curPosition = curElem.position();
		}

		curTop  = calculatePosition ? curPosition.top  : parseInt( curCSSTop,  10 ) || 0;
		curLeft = calculatePosition ? curPosition.left : parseInt( curCSSLeft, 10 ) || 0;

		if ( jQuery.isFunction( options ) ) {
			options = options.call( elem, i, curOffset );
		}

		if (options.top != null) {
			props.top = (options.top - curOffset.top) + curTop;
		}
		if (options.left != null) {
			props.left = (options.left - curOffset.left) + curLeft;
		}

		if ( "using" in options ) {
			options.using.call( elem, props );
		} else {
			curElem.css( props );
		}
	}
};

jQuery.fn.extend({
	position: function() {
		if ( !this[0] ) {
			return null;
		}

		var elem = this[0],

		// Get *real* offsetParent
		offsetParent = this.offsetParent(),

		// Get correct offsets
		offset       = this.offset(),
		parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();

		// Subtract element margins
		// note: when an element has margin: auto the offsetLeft and marginLeft
		// are the same in Safari causing offset.left to incorrectly be 0
		offset.top  -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
		offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;

		// Add offsetParent borders
		parentOffset.top  += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
		parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;

		// Subtract the two offsets
		return {
			top:  offset.top  - parentOffset.top,
			left: offset.left - parentOffset.left
		};
	},

	offsetParent: function() {
		return this.map(function() {
			var offsetParent = this.offsetParent || document.body;
			while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
				offsetParent = offsetParent.offsetParent;
			}
			return offsetParent;
		});
	}
});

// Create scrollLeft and scrollTop methods
jQuery.each( ["Left", "Top"], function( i, name ) {
	var method = "scroll" + name;

	jQuery.fn[ method ] = function(val) {
		var elem = this[0], win;

		if ( !elem ) {
			return null;
		}

		if ( val !== undefined ) {
			// Set the scroll offset
			return this.each(function() {
				win = getWindow( this );

				if ( win ) {
					win.scrollTo(
						!i ? val : jQuery(win).scrollLeft(),
						 i ? val : jQuery(win).scrollTop()
					);

				} else {
					this[ method ] = val;
				}
			});
		} else {
			win = getWindow( elem );

			// Return the scroll offset
			return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
				jQuery.support.boxModel && win.document.documentElement[ method ] ||
					win.document.body[ method ] :
				elem[ method ];
		}
	};
});

function getWindow( elem ) {
	return jQuery.isWindow( elem ) ?
		elem :
		elem.nodeType === 9 ?
			elem.defaultView || elem.parentWindow :
			false;
}

})( jQuery );
<commit_msg>Return the zeroed-out bounding box instead of passing it on.<commit_after>(function( jQuery ) {

var rtable = /^t(?:able|d|h)$/i,
	rroot = /^(?:body|html)$/i;

if ( "getBoundingClientRect" in document.documentElement ) {
	jQuery.fn.offset = function( options ) {
		var elem = this[0], box;

		if ( options ) {
			return this.each(function( i ) {
				jQuery.offset.setOffset( this, options, i );
			});
		}

		if ( !elem || !elem.ownerDocument ) {
			return null;
		}

		if ( elem === elem.ownerDocument.body ) {
			return jQuery.offset.bodyOffset( elem );
		}

		try {
			box = elem.getBoundingClientRect();

		} catch(e) {
			return { top: 0, left: 0 };
		}

		var doc = elem.ownerDocument,
			body = doc.body,
			docElem = doc.documentElement,
			win = getWindow(doc),
			clientTop  = docElem.clientTop  || body.clientTop  || 0,
			clientLeft = docElem.clientLeft || body.clientLeft || 0,
			scrollTop  = (win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop  || body.scrollTop ),
			scrollLeft = (win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft),
			top  = box.top  + scrollTop  - clientTop,
			left = box.left + scrollLeft - clientLeft;

		return { top: top, left: left };
	};

} else {
	jQuery.fn.offset = function( options ) {
		var elem = this[0];

		if ( options ) {
			return this.each(function( i ) {
				jQuery.offset.setOffset( this, options, i );
			});
		}

		if ( !elem || !elem.ownerDocument ) {
			return null;
		}

		if ( elem === elem.ownerDocument.body ) {
			return jQuery.offset.bodyOffset( elem );
		}

		jQuery.offset.initialize();

		var offsetParent = elem.offsetParent, prevOffsetParent = elem,
			doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement,
			body = doc.body, defaultView = doc.defaultView,
			prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
			top = elem.offsetTop, left = elem.offsetLeft;

		while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
			if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
				break;
			}

			computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
			top  -= elem.scrollTop;
			left -= elem.scrollLeft;

			if ( elem === offsetParent ) {
				top  += elem.offsetTop;
				left += elem.offsetLeft;

				if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
					top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
					left += parseFloat( computedStyle.borderLeftWidth ) || 0;
				}

				prevOffsetParent = offsetParent;
				offsetParent = elem.offsetParent;
			}

			if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
				top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
				left += parseFloat( computedStyle.borderLeftWidth ) || 0;
			}

			prevComputedStyle = computedStyle;
		}

		if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
			top  += body.offsetTop;
			left += body.offsetLeft;
		}

		if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
			top  += Math.max( docElem.scrollTop, body.scrollTop );
			left += Math.max( docElem.scrollLeft, body.scrollLeft );
		}

		return { top: top, left: left };
	};
}

jQuery.offset = {
	initialize: function() {
		var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, "marginTop") ) || 0,
			html = "

";

		jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );

		container.innerHTML = html;
		body.insertBefore( container, body.firstChild );
		innerDiv = container.firstChild;
		checkDiv = innerDiv.firstChild;
		td = innerDiv.nextSibling.firstChild.firstChild;

		this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
		this.doesAddBorderForTableAndCells = (td.offsetTop === 5);

		checkDiv.style.position = "fixed";
		checkDiv.style.top = "20px";

		// safari subtracts parent border width here which is 5px
		this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
		checkDiv.style.position = checkDiv.style.top = "";

		innerDiv.style.overflow = "hidden";
		innerDiv.style.position = "relative";

		this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);

		this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);

		body.removeChild( container );
		body = container = innerDiv = checkDiv = table = td = null;
		jQuery.offset.initialize = jQuery.noop;
	},

	bodyOffset: function( body ) {
		var top = body.offsetTop, left = body.offsetLeft;

		jQuery.offset.initialize();

		if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
			top  += parseFloat( jQuery.css(body, "marginTop") ) || 0;
			left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
		}

		return { top: top, left: left };
	},

	setOffset: function( elem, options, i ) {
		var position = jQuery.css( elem, "position" );

		// set position first, in-case top/left are set even on static elem
		if ( position === "static" ) {
			elem.style.position = "relative";
		}

		var curElem = jQuery( elem ),
			curOffset = curElem.offset(),
			curCSSTop = jQuery.css( elem, "top" ),
			curCSSLeft = jQuery.css( elem, "left" ),
			calculatePosition = (position === "absolute" && jQuery.inArray('auto', [curCSSTop, curCSSLeft]) > -1),
			props = {}, curPosition = {}, curTop, curLeft;

		// need to be able to calculate position if either top or left is auto and position is absolute
		if ( calculatePosition ) {
			curPosition = curElem.position();
		}

		curTop  = calculatePosition ? curPosition.top  : parseInt( curCSSTop,  10 ) || 0;
		curLeft = calculatePosition ? curPosition.left : parseInt( curCSSLeft, 10 ) || 0;

		if ( jQuery.isFunction( options ) ) {
			options = options.call( elem, i, curOffset );
		}

		if (options.top != null) {
			props.top = (options.top - curOffset.top) + curTop;
		}
		if (options.left != null) {
			props.left = (options.left - curOffset.left) + curLeft;
		}

		if ( "using" in options ) {
			options.using.call( elem, props );
		} else {
			curElem.css( props );
		}
	}
};

jQuery.fn.extend({
	position: function() {
		if ( !this[0] ) {
			return null;
		}

		var elem = this[0],

		// Get *real* offsetParent
		offsetParent = this.offsetParent(),

		// Get correct offsets
		offset       = this.offset(),
		parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();

		// Subtract element margins
		// note: when an element has margin: auto the offsetLeft and marginLeft
		// are the same in Safari causing offset.left to incorrectly be 0
		offset.top  -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
		offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;

		// Add offsetParent borders
		parentOffset.top  += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
		parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;

		// Subtract the two offsets
		return {
			top:  offset.top  - parentOffset.top,
			left: offset.left - parentOffset.left
		};
	},

	offsetParent: function() {
		return this.map(function() {
			var offsetParent = this.offsetParent || document.body;
			while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
				offsetParent = offsetParent.offsetParent;
			}
			return offsetParent;
		});
	}
});

// Create scrollLeft and scrollTop methods
jQuery.each( ["Left", "Top"], function( i, name ) {
	var method = "scroll" + name;

	jQuery.fn[ method ] = function(val) {
		var elem = this[0], win;

		if ( !elem ) {
			return null;
		}

		if ( val !== undefined ) {
			// Set the scroll offset
			return this.each(function() {
				win = getWindow( this );

				if ( win ) {
					win.scrollTo(
						!i ? val : jQuery(win).scrollLeft(),
						 i ? val : jQuery(win).scrollTop()
					);

				} else {
					this[ method ] = val;
				}
			});
		} else {
			win = getWindow( elem );

			// Return the scroll offset
			return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
				jQuery.support.boxModel && win.document.documentElement[ method ] ||
					win.document.body[ method ] :
				elem[ method ];
		}
	};
});

function getWindow( elem ) {
	return jQuery.isWindow( elem ) ?
		elem :
		elem.nodeType === 9 ?
			elem.defaultView || elem.parentWindow :
			false;
}

})( jQuery );
<|endoftext|>


<commit_before>define( [
	"./core",
	"./core/access",
	"./var/document",
	"./var/documentElement",
	"./css/var/rnumnonpx",
	"./css/curCSS",
	"./css/addGetHookIf",
	"./css/support",
	"./var/isWindow",
	"./core/init",
	"./css",
	"./selector" // contains
], function( jQuery, access, document, documentElement, rnumnonpx,
             curCSS, addGetHookIf, support, isWindow ) {

"use strict";

jQuery.offset = {
	setOffset: function( elem, options, i ) {
		var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
			position = jQuery.css( elem, "position" ),
			curElem = jQuery( elem ),
			props = {};

		// Set position first, in-case top/left are set even on static elem
		if ( position === "static" ) {
			elem.style.position = "relative";
		}

		curOffset = curElem.offset();
		curCSSTop = jQuery.css( elem, "top" );
		curCSSLeft = jQuery.css( elem, "left" );
		calculatePosition = ( position === "absolute" || position === "fixed" ) &&
			( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;

		// Need to be able to calculate position if either
		// top or left is auto and position is either absolute or fixed
		if ( calculatePosition ) {
			curPosition = curElem.position();
			curTop = curPosition.top;
			curLeft = curPosition.left;

		} else {
			curTop = parseFloat( curCSSTop ) || 0;
			curLeft = parseFloat( curCSSLeft ) || 0;
		}

		if ( jQuery.isFunction( options ) ) {

			// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
			options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
		}

		if ( options.top != null ) {
			props.top = ( options.top - curOffset.top ) + curTop;
		}
		if ( options.left != null ) {
			props.left = ( options.left - curOffset.left ) + curLeft;
		}

		if ( "using" in options ) {
			options.using.call( elem, props );

		} else {
			curElem.css( props );
		}
	}
};

jQuery.fn.extend( {

	// offset() relates an element's border box to the document origin
	offset: function( options ) {

		// Preserve chaining for setter
		if ( arguments.length ) {
			return options === undefined ?
				this :
				this.each( function( i ) {
					jQuery.offset.setOffset( this, options, i );
				} );
		}

		var rect, win,
			elem = this[ 0 ];

		if ( !elem ) {
			return;
		}

		// Return zeros for disconnected and hidden (display: none) elements (gh-2310)
		// Support: IE <=11 only
		// Running getBoundingClientRect on a
		// disconnected node in IE throws an error
		if ( !elem.getClientRects().length ) {
			return { top: 0, left: 0 };
		}

		// Get document-relative position by adding viewport scroll to viewport-relative gBCR
		rect = elem.getBoundingClientRect();
		win = elem.ownerDocument.defaultView;
		return {
			top: rect.top + win.pageYOffset,
			left: rect.left + win.pageXOffset
		};
	},

	// position() relates an element's margin box to its offset parent's padding box
	// This corresponds to the behavior of CSS absolute positioning
	position: function() {
		if ( !this[ 0 ] ) {
			return;
		}

		var offsetParent, offset, doc,
			elem = this[ 0 ],
			parentOffset = { top: 0, left: 0 };

		// position:fixed elements are offset from the viewport, which itself always has zero offset
		if ( jQuery.css( elem, "position" ) === "fixed" ) {

			// Assume position:fixed implies availability of getBoundingClientRect
			offset = elem.getBoundingClientRect();

		} else {
			offset = this.offset();

			// Account for the *real* offset parent, which can be the document or its root element
			// when a statically positioned element is identified
			doc = elem.ownerDocument;
			offsetParent = elem.offsetParent || doc.documentElement;
			while ( offsetParent &&
				( offsetParent === doc.body || offsetParent === doc.documentElement ) &&
				jQuery.css( offsetParent, "position" ) === "static" ) {

				offsetParent = offsetParent.parentNode;
			}
			if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) {

				// Incorporate borders into its offset, since they are outside its content origin
				parentOffset = jQuery( offsetParent ).offset();
				parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
				parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
			}
		}

		// Subtract parent offsets and element margins
		return {
			top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
			left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
		};
	},

	// This method will return documentElement in the following cases:
	// 1) For the element inside the iframe without offsetParent, this method will return
	//    documentElement of the parent window
	// 2) For the hidden or detached element
	// 3) For body or html element, i.e. in case of the html node - it will return itself
	//
	// but those exceptions were never presented as a real life use-cases
	// and might be considered as more preferable results.
	//
	// This logic, however, is not guaranteed and can change at any point in the future
	offsetParent: function() {
		return this.map( function() {
			var offsetParent = this.offsetParent;

			while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
				offsetParent = offsetParent.offsetParent;
			}

			return offsetParent || documentElement;
		} );
	}
} );

// Create scrollLeft and scrollTop methods
jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
	var top = "pageYOffset" === prop;

	jQuery.fn[ method ] = function( val ) {
		return access( this, function( elem, method, val ) {

			// Coalesce documents and windows
			var win;
			if ( isWindow( elem ) ) {
				win = elem;
			} else if ( elem.nodeType === 9 ) {
				win = elem.defaultView;
			}

			if ( val === undefined ) {
				return win ? win[ prop ] : elem[ method ];
			}

			if ( win ) {
				win.scrollTo(
					!top ? val : win.pageXOffset,
					top ? val : win.pageYOffset
				);

			} else {
				elem[ method ] = val;
			}
		}, method, val, arguments.length );
	};
} );

// Support: Safari <=7 - 9.1, Chrome <=37 - 49
// Add the top/left cssHooks using jQuery.fn.position
// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
// getComputedStyle returns percent when specified for top/left/bottom/right;
// rather than make the css module depend on the offset module, just check for it here
jQuery.each( [ "top", "left" ], function( i, prop ) {
	jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
		function( elem, computed ) {
			if ( computed ) {
				computed = curCSS( elem, prop );

				// If curCSS returns percentage, fallback to offset
				return rnumnonpx.test( computed ) ?
					jQuery( elem ).position()[ prop ] + "px" :
					computed;
			}
		}
	);
} );

return jQuery;
} );
<commit_msg>Offset: fix error from bad merge in #3695<commit_after>define( [
	"./core",
	"./core/access",
	"./var/document",
	"./var/documentElement",
	"./css/var/rnumnonpx",
	"./css/curCSS",
	"./css/addGetHookIf",
	"./css/support",
	"./var/isWindow",
	"./core/init",
	"./css",
	"./selector" // contains
], function( jQuery, access, document, documentElement, rnumnonpx,
             curCSS, addGetHookIf, support, isWindow ) {

"use strict";

jQuery.offset = {
	setOffset: function( elem, options, i ) {
		var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
			position = jQuery.css( elem, "position" ),
			curElem = jQuery( elem ),
			props = {};

		// Set position first, in-case top/left are set even on static elem
		if ( position === "static" ) {
			elem.style.position = "relative";
		}

		curOffset = curElem.offset();
		curCSSTop = jQuery.css( elem, "top" );
		curCSSLeft = jQuery.css( elem, "left" );
		calculatePosition = ( position === "absolute" || position === "fixed" ) &&
			( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;

		// Need to be able to calculate position if either
		// top or left is auto and position is either absolute or fixed
		if ( calculatePosition ) {
			curPosition = curElem.position();
			curTop = curPosition.top;
			curLeft = curPosition.left;

		} else {
			curTop = parseFloat( curCSSTop ) || 0;
			curLeft = parseFloat( curCSSLeft ) || 0;
		}

		if ( jQuery.isFunction( options ) ) {

			// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
			options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
		}

		if ( options.top != null ) {
			props.top = ( options.top - curOffset.top ) + curTop;
		}
		if ( options.left != null ) {
			props.left = ( options.left - curOffset.left ) + curLeft;
		}

		if ( "using" in options ) {
			options.using.call( elem, props );

		} else {
			curElem.css( props );
		}
	}
};

jQuery.fn.extend( {

	// offset() relates an element's border box to the document origin
	offset: function( options ) {

		// Preserve chaining for setter
		if ( arguments.length ) {
			return options === undefined ?
				this :
				this.each( function( i ) {
					jQuery.offset.setOffset( this, options, i );
				} );
		}

		var rect, win,
			elem = this[ 0 ];

		if ( !elem ) {
			return;
		}

		// Return zeros for disconnected and hidden (display: none) elements (gh-2310)
		// Support: IE <=11 only
		// Running getBoundingClientRect on a
		// disconnected node in IE throws an error
		if ( !elem.getClientRects().length ) {
			return { top: 0, left: 0 };
		}

		// Get document-relative position by adding viewport scroll to viewport-relative gBCR
		rect = elem.getBoundingClientRect();
		win = elem.ownerDocument.defaultView;
		return {
			top: rect.top + win.pageYOffset,
			left: rect.left + win.pageXOffset
		};
	},

	// position() relates an element's margin box to its offset parent's padding box
	// This corresponds to the behavior of CSS absolute positioning
	position: function() {
		if ( !this[ 0 ] ) {
			return;
		}

		var offsetParent, offset, doc,
			elem = this[ 0 ],
			parentOffset = { top: 0, left: 0 };

		// position:fixed elements are offset from the viewport, which itself always has zero offset
		if ( jQuery.css( elem, "position" ) === "fixed" ) {

			// Assume position:fixed implies availability of getBoundingClientRect
			offset = elem.getBoundingClientRect();

		} else {
			offset = this.offset();

			// Account for the *real* offset parent, which can be the document or its root element
			// when a statically positioned element is identified
			doc = elem.ownerDocument;
			offsetParent = elem.offsetParent || doc.documentElement;
			while ( offsetParent &&
				( offsetParent === doc.body || offsetParent === doc.documentElement ) &&
				jQuery.css( offsetParent, "position" ) === "static" ) {

				offsetParent = offsetParent.parentNode;
			}
			if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) {

				// Incorporate borders into its offset, since they are outside its content origin
				parentOffset = jQuery( offsetParent ).offset();
				parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true );
				parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true );
			}
		}

		// Subtract parent offsets and element margins
		return {
			top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
			left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
		};
	},

	// This method will return documentElement in the following cases:
	// 1) For the element inside the iframe without offsetParent, this method will return
	//    documentElement of the parent window
	// 2) For the hidden or detached element
	// 3) For body or html element, i.e. in case of the html node - it will return itself
	//
	// but those exceptions were never presented as a real life use-cases
	// and might be considered as more preferable results.
	//
	// This logic, however, is not guaranteed and can change at any point in the future
	offsetParent: function() {
		return this.map( function() {
			var offsetParent = this.offsetParent;

			while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
				offsetParent = offsetParent.offsetParent;
			}

			return offsetParent || documentElement;
		} );
	}
} );

// Create scrollLeft and scrollTop methods
jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
	var top = "pageYOffset" === prop;

	jQuery.fn[ method ] = function( val ) {
		return access( this, function( elem, method, val ) {

			// Coalesce documents and windows
			var win;
			if ( isWindow( elem ) ) {
				win = elem;
			} else if ( elem.nodeType === 9 ) {
				win = elem.defaultView;
			}

			if ( val === undefined ) {
				return win ? win[ prop ] : elem[ method ];
			}

			if ( win ) {
				win.scrollTo(
					!top ? val : win.pageXOffset,
					top ? val : win.pageYOffset
				);

			} else {
				elem[ method ] = val;
			}
		}, method, val, arguments.length );
	};
} );

// Support: Safari <=7 - 9.1, Chrome <=37 - 49
// Add the top/left cssHooks using jQuery.fn.position
// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
// getComputedStyle returns percent when specified for top/left/bottom/right;
// rather than make the css module depend on the offset module, just check for it here
jQuery.each( [ "top", "left" ], function( i, prop ) {
	jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
		function( elem, computed ) {
			if ( computed ) {
				computed = curCSS( elem, prop );

				// If curCSS returns percentage, fallback to offset
				return rnumnonpx.test( computed ) ?
					jQuery( elem ).position()[ prop ] + "px" :
					computed;
			}
		}
	);
} );

return jQuery;
} );
<|endoftext|>


<commit_before>/**
 * This is the actual embed script that people put on their page. I use the
 * technique of passing in variables as function parameters, even if not
 * defined, to remove the need for a `var` statement.
 *
 * This script creates a window.branch object with a number of calls. When you
 * call them, it saves your call for later.
 */
'use strict';

(function(root, doc, scriptStr, branchStr, createCallback, branchSdk, funcs, i, scriptTag, firstScript) {
	if (!root[branchStr] || !root[branchStr]._q) {
		while (i < funcs.length) {
			createCallback(branchSdk, funcs[i++]);
		}

		scriptTag = doc.createElement(scriptStr);
		scriptTag.async = 1;
		scriptTag.src = 'SCRIPT_URL_HERE';
		firstScript = doc.getElementsByTagName(scriptStr)[0];
		firstScript.parentNode.insertBefore(scriptTag, firstScript);

		root[branchStr] = branchSdk;
	}
})(
	window, document, 'script', 'branch', function(branch, name) {
		branch[name] = function() {
			branch._q.push([ name, arguments ]);
		};
	},
	{
		_q: [], // _q: the "queue" of calls
		_v: 1 // _v: the "version" of the embed script
	},
	[
		'addListener',
		'applyCode',
		'autoAppIndex',
		'banner',
		'closeBanner',
		'creditHistory',
		'credits',
		'data',
		'deepview',
		'deepviewCta',
		'first',
		'getCode',
		'init',
		'link',
		'logout',
		'redeem',
		'referrals',
		'removeListener',
		'sendSMS',
		'setBranchViewData',
		'setIdentity',
		'track',
		'validateCode'
	],
	0
);
<commit_msg>adding in missing closeJourney reference<commit_after>/**
 * This is the actual embed script that people put on their page. I use the
 * technique of passing in variables as function parameters, even if not
 * defined, to remove the need for a `var` statement.
 *
 * This script creates a window.branch object with a number of calls. When you
 * call them, it saves your call for later.
 */
'use strict';

(function(root, doc, scriptStr, branchStr, createCallback, branchSdk, funcs, i, scriptTag, firstScript) {
	if (!root[branchStr] || !root[branchStr]._q) {
		while (i < funcs.length) {
			createCallback(branchSdk, funcs[i++]);
		}

		scriptTag = doc.createElement(scriptStr);
		scriptTag.async = 1;
		scriptTag.src = 'SCRIPT_URL_HERE';
		firstScript = doc.getElementsByTagName(scriptStr)[0];
		firstScript.parentNode.insertBefore(scriptTag, firstScript);

		root[branchStr] = branchSdk;
	}
})(
	window, document, 'script', 'branch', function(branch, name) {
		branch[name] = function() {
			branch._q.push([ name, arguments ]);
		};
	},
	{
		_q: [], // _q: the "queue" of calls
		_v: 1 // _v: the "version" of the embed script
	},
	[
		'addListener',
		'applyCode',
		'autoAppIndex',
		'banner',
		'closeBanner',
		'closeJourney',
		'creditHistory',
		'credits',
		'data',
		'deepview',
		'deepviewCta',
		'first',
		'getCode',
		'init',
		'link',
		'logout',
		'redeem',
		'referrals',
		'removeListener',
		'sendSMS',
		'setBranchViewData',
		'setIdentity',
		'track',
		'validateCode'
	],
	0
);
<|endoftext|>