Repository: kimmobrunfeldt/progressbar.js
Branch: master
Commit: 1f0ebf3afc00
Files: 35
Total size: 170.5 KB
Directory structure:
gitextract_1t5gj7f7/
├── .editorconfig
├── .eslintrc
├── .gitignore
├── .jscs.json
├── .travis.yml
├── Gruntfile.js
├── LICENSE
├── README.md
├── bower.json
├── dist/
│ └── progressbar.js
├── docs/
│ ├── api/
│ │ ├── general.md
│ │ ├── parameters.md
│ │ ├── path.md
│ │ └── shape.md
│ ├── contributing.md
│ ├── index.md
│ └── pip-requirements.txt
├── karma.conf.js
├── local-dev/
│ ├── index.html
│ ├── main.css
│ └── main.js
├── mkdocs.yml
├── package.json
├── saucelabs-browsers.js
├── src/
│ ├── circle.js
│ ├── line.js
│ ├── main.js
│ ├── path.js
│ ├── semicircle.js
│ ├── shape.js
│ ├── square.js
│ └── utils.js
└── tools/
├── lint.sh
├── release.js
└── test.sh
================================================
FILE CONTENTS
================================================
================================================
FILE: .editorconfig
================================================
# EditorConfig is awesome: http://EditorConfig.org
# top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true
# Tab indentation (no size specified)
[{*.js, *.css, *.scss}]
indent_style = space
indent_size = 4
# Matches the exact files package.json and .travis.yml
[{*.json,.travis.yml,Gruntfile.js}]
indent_style = space
indent_size = 2
[Makefile]
indent_style = tab
indent_size = 4
================================================
FILE: .eslintrc
================================================
{
"env": {
"browser": true,
"amd": true,
"node": true
},
"globals": {
"define": false,
"require": true,
"alert": true,
"console": true,
"module": true,
"describe": true,
"it": true,
"before": true,
"beforeEach": true,
"after": true,
"afterEach": true,
"expect": true,
"should": true,
"Promise": true, // allow possibly overwriting Promise
},
"rules": {
"dot-notation": 0, // allow obj['somePropertyName']
"new-cap": 0, // do not require 'new' keyword, allows i.e. "var promise = $.Deferred()"
"no-alert": 0, // disencourage alert() and confirm()
"no-console": 0,
"no-mixed-spaces-and-tabs": 1,
"semi-spacing": [2, {"before": false, "after": true}],
"no-spaced-func": 1,
"no-undef": 1,
"no-shadow": 1,
"no-trailing-spaces": 1,
"no-extra-parens": 1,
"no-underscore-dangle": 0, // allow _variableName
"no-new": 0,
"no-nested-ternary": 1,
"no-process-exit": 0,
// requires local variable names to be used, but allows unused arguments
"no-unused-vars": [2, { "vars": "all", "args": "none" }],
"no-use-before-define": 0,
// disable requirements for strict spacing rules in object properties or assignments
"key-spacing": 0,
"no-multi-spaces": 0,
"quotes": 0, // allow both single and double quotes
"space-after-keywords": 1,
"space-infix-ops": 1,
"space-return-throw-case": 1,
"strict": 0
}
}
================================================
FILE: .gitignore
================================================
# Logs
logs
# Node
*.log
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directory
# Commenting this out is preferred by some people, see
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git-
node_modules
# Users Environment Variables
.lock-wscript
# SASS
.sass-cache
*.css.map
# OS X
.DS_Store
# IDEA editor
.idea
# Secrets as environment variables
secrets.sh
# Local dev bundle
local-dev/bundle.js
.env
================================================
FILE: .jscs.json
================================================
{
"disallowImplicitTypeConversion": ["string"],
"disallowMixedSpacesAndTabs": true,
"disallowMultipleLineBreaks": true,
"disallowNewlineBeforeBlockStatements": true,
"disallowMultipleLineStrings": true,
"disallowMultipleVarDecl": null,
"disallowSpaceAfterPrefixUnaryOperators": true,
"disallowSpacesInAnonymousFunctionExpression": {
"beforeOpeningRoundBrace": true
},
"disallowSpacesInsideObjectBrackets": null,
"disallowSpacesInsideArrayBrackets": "all",
"disallowSpacesInsideParentheses": true,
"disallowTrailingWhitespace": true,
"maximumLineLength": {
"value": 100,
"allowComments": true,
"allowRegex": true
},
"fileExtensions": [".js", ".jsx"],
"requireCamelCaseOrUpperCaseIdentifiers": true,
"requireCommaBeforeLineBreak": true,
"requireCurlyBraces": [
"if",
"else",
"for",
"while",
"do",
"try",
"catch"
],
"requireSpaceAfterBinaryOperators": true,
"requireSpaceAfterKeywords": [
"do",
"for",
"if",
"else",
"switch",
"case",
"try",
"catch",
"void",
"while",
"with",
"return",
"typeof"
],
"requireSpaceBeforeBinaryOperators": [
"=", "+=", "-=", "*=", "/=", "%=", "<<=", ">>=", ">>>=",
"&=", "|=", "^=", "+=",
"+", "-", "*", "/", "%", "<<", ">>", ">>>", "&",
"|", "^", "&&", "||", "===", "==", ">=",
"<=", "<", ">", "!=", "!=="
],
"requireSpacesInConditionalExpression": true,
"requireSpaceBeforeBlockStatements": true,
"requireSpacesInForStatement": true,
"requireLineFeedAtFileEnd": true,
"requireSpacesInFunctionExpression": {
"beforeOpeningCurlyBrace": true
},
"validateLineBreaks": "LF",
"validateIndentation": 4,
"validateQuoteMarks": {
"mark": "'", "escape": true
}
}
================================================
FILE: .travis.yml
================================================
language: node_js
node_js:
- '12'
before_install:
- npm install -g npm
before_script:
- npm install
- npm install -g mocha grunt-cli testem
script:
- if [[ $TRAVIS_PULL_REQUEST != 'false' ]]; then testem ci -l phantomjs; fi
- if [[ $TRAVIS_PULL_REQUEST == 'false' ]]; then grunt sauce; fi
notifications:
email:
- kimmobrunfeldt+progressbar@gmail.com
env:
global:
- secure: I/NAJpZ+wySjPYYLAqsHfMrueU0HbvOZx1FAJgxHtm3Nkz6/mzL+8ZW/FSi9/XaxkqJLaWAmCqvbVZsrw4qAfb2KKq/Ymf6eEhdTHfCJs+hLf32qM2FENS3LGPu7uJ8y1/7WKhV0VotBttB6AhaH/SNuZ4d8yBDGbriZtvnBT5c=
- secure: SLhd3YYQXk5jD+ubnDatUAfeTGjSu6H3y30g7n0TryueNx5qBsBLAbeqAJ92JqZx3QEBAJ0vTJyhr66gJu9dG+G7US3O/KPjYXBHcDbVv0PEXibnWhxI8BLK8PIDQvGm2dwf4/6j0gDqNoWCnjBrhdgj481iR2z2cpR07A8Koew=
================================================
FILE: Gruntfile.js
================================================
var _ = require('lodash');
// Split array to smaller arrays containing n elements at max
function groupToElements(array, n) {
var lists = _.groupBy(array, function(element, index){
return Math.floor(index / n);
});
return _.toArray(lists);
}
// Setup karma configuration dynamically to run browsers sequentially
// https://github.com/karma-runner/karma-sauce-launcher/issues/8
var MAXIMUM_CONCURRENT_SAUCE = 3;
var sauceBrowsers = require('./saucelabs-browsers');
var browserGroups = groupToElements(Object.keys(sauceBrowsers), MAXIMUM_CONCURRENT_SAUCE);
var karmaConfig = {
options: {
configFile: 'karma.conf.js'
}
};
_.each(browserGroups, function(group, index) {
karmaConfig['sauce' + index] = {
browsers: group
}
});
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
shell: {
stageMinified: {
options: {
stdout: true,
// If minified files do not change on release,
// git command fails
failOnError: false
},
command: 'git add dist/progressbar.js dist/progressbar.min.js dist/progressbar.min.js.map'
},
browserifyDevelopment: {
options: {
stdout: true
},
command: 'browserify src/main.js -o dist/progressbar.js --standalone ProgressBar'
},
browserifyMinified: {
options: {
stdout: true
},
// The output file is minified by uglifyjs later.
command: 'browserify src/main.js -o dist/progressbar.min.js --standalone ProgressBar'
},
watchifyLocalDev: {
options: {
stdout: true
},
command: 'watchify local-dev/main.js -o local-dev/bundle.js --debug --verbose'
},
release: {
options: {
stdout: true
},
command: function(bump) {
bump = bump || 'patch';
return './tools/release.js ' + bump;
}
},
karma: {
options: {
stdout: true
},
// This will run tests in Sauce Lab
command: './node_modules/karma/bin/karma start'
},
},
// Uglify must be run after browserify
uglify: {
progressbar: {
options: {
sourceMap: true
},
files: {
'dist/progressbar.min.js': ['dist/progressbar.min.js']
}
}
},
// Calculated dynamically above
karma: karmaConfig
});
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-shell');
grunt.loadNpmTasks('grunt-karma');
grunt.registerTask('watch', function() {
grunt.task.run(['shell:watchifyLocalDev']);
});
grunt.registerTask('stageMinified', function() {
grunt.task.run(['shell:stageMinified']);
});
// Build distributables to dist folder
grunt.registerTask('build', [
'shell:browserifyDevelopment',
'shell:browserifyMinified',
'uglify:progressbar'
]);
// Run multiple tests serially, but continue if one of them fails.
// Adapted from http://stackoverflow.com/questions/16487681/gruntfile-getting-error-codes-from-programs-serially
grunt.registerTask('sauce', function() {
var done = this.async();
var tasks = {};
_.each(browserGroups, function(group, index) {
tasks['karma:sauce' + index] = 0;
});
var success = true;
grunt.util.async.forEachSeries(Object.keys(tasks), function(task, next) {
grunt.util.spawn({
// Use grunt to spawn
grunt: true,
args: [task],
// Print to the same stdout
opts: { stdio: 'inherit' }
}, function(err, result, code) {
tasks[task] = code;
if (code !== 0) {
success = false;
}
next();
});
}, function() {
done(success);
});
});
// Test, build, and release library to public
grunt.registerTask('release', function(bump) {
bump = bump || 'patch';
grunt.task.run([
'build',
'stageMinified',
'shell:release:' + bump
]);
});
};
================================================
FILE: LICENSE
================================================
The MIT License (MIT)
Copyright (c) 2015 Kimmo Brunfeldt
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
================================================
FILE: README.md
================================================
# ProgressBar.js
<br>

<br>
Responsive and slick progress bars with animated SVG paths.
Use built-in shapes or [create your own paths](http://progressbarjs.readthedocs.org/en/latest/api/path/).
[Customize](http://progressbarjs.readthedocs.org/en/latest/api/parameters/#custom-animations) the animations as you wish.
Documentation is [hosted at readthedocs.org](http://progressbarjs.readthedocs.org/en/latest/).
**Shortcuts**
- [Get started](http://progressbarjs.readthedocs.org/en/latest/)
- [Demo & Examples](https://kimmobrunfeldt.github.io/progressbar.js)
- [**Try** in JSFiddle](http://jsfiddle.net/kimmobrunfeldt/8xa87k31/392/)
- [API documentation](http://progressbarjs.readthedocs.org/en/latest/api/shape/)
- [Migration between versions](http://progressbarjs.readthedocs.org/en/latest/#migrations)
- [react-progressbar.js](https://github.com/kimmobrunfeldt/react-progressbar.js) progress bars in React.
## Contributing
See [documentation for contributors](http://progressbarjs.readthedocs.org/en/latest/contributing/).
## Thanks
This project is a grateful recipient of the [Futurice Open Source sponsorship program](http://futurice.com/blog/sponsoring-free-time-open-source-activities?utm_source=github&utm_medium=spice&utm_campaign=progressbar).
================================================
FILE: bower.json
================================================
{
"name": "progressbar.js",
"main": "dist/progressbar.js",
"homepage": "https://github.com/kimmobrunfeldt/progressbar.js",
"authors": [
"Kimmo Brunfeldt <kimmobrunfeldt@gmail.com>"
],
"description": "Responsive and slick progress bars with animated SVG paths",
"moduleType": [
"amd",
"globals"
],
"keywords": [
"progress",
"bar",
"js",
"svg",
"circular",
"circle",
"pace",
"radial",
"line",
"loading",
"loader"
],
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
]
}
================================================
FILE: dist/progressbar.js
================================================
// ProgressBar.js 1.1.1
// https://kimmobrunfeldt.github.io/progressbar.js
// License: MIT
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.ProgressBar = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
(function (global){(function (){
/**
* Lodash (Custom Build) <https://lodash.com/>
* Build: `lodash modularize exports="npm" -o ./`
* Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
* Released under MIT license <https://lodash.com/license>
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
*/
/** Used as the size to enable large array optimizations. */
var LARGE_ARRAY_SIZE = 200;
/** Used to stand-in for `undefined` hash values. */
var HASH_UNDEFINED = '__lodash_hash_undefined__';
/** Used to detect hot functions by number of calls within a span of milliseconds. */
var HOT_COUNT = 800,
HOT_SPAN = 16;
/** Used as references for various `Number` constants. */
var MAX_SAFE_INTEGER = 9007199254740991;
/** `Object#toString` result references. */
var argsTag = '[object Arguments]',
arrayTag = '[object Array]',
asyncTag = '[object AsyncFunction]',
boolTag = '[object Boolean]',
dateTag = '[object Date]',
errorTag = '[object Error]',
funcTag = '[object Function]',
genTag = '[object GeneratorFunction]',
mapTag = '[object Map]',
numberTag = '[object Number]',
nullTag = '[object Null]',
objectTag = '[object Object]',
proxyTag = '[object Proxy]',
regexpTag = '[object RegExp]',
setTag = '[object Set]',
stringTag = '[object String]',
undefinedTag = '[object Undefined]',
weakMapTag = '[object WeakMap]';
var arrayBufferTag = '[object ArrayBuffer]',
dataViewTag = '[object DataView]',
float32Tag = '[object Float32Array]',
float64Tag = '[object Float64Array]',
int8Tag = '[object Int8Array]',
int16Tag = '[object Int16Array]',
int32Tag = '[object Int32Array]',
uint8Tag = '[object Uint8Array]',
uint8ClampedTag = '[object Uint8ClampedArray]',
uint16Tag = '[object Uint16Array]',
uint32Tag = '[object Uint32Array]';
/**
* Used to match `RegExp`
* [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
*/
var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
/** Used to detect host constructors (Safari). */
var reIsHostCtor = /^\[object .+?Constructor\]$/;
/** Used to detect unsigned integer values. */
var reIsUint = /^(?:0|[1-9]\d*)$/;
/** Used to identify `toStringTag` values of typed arrays. */
var typedArrayTags = {};
typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
typedArrayTags[uint32Tag] = true;
typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
typedArrayTags[errorTag] = typedArrayTags[funcTag] =
typedArrayTags[mapTag] = typedArrayTags[numberTag] =
typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
typedArrayTags[setTag] = typedArrayTags[stringTag] =
typedArrayTags[weakMapTag] = false;
/** Detect free variable `global` from Node.js. */
var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
/** Detect free variable `self`. */
var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
/** Used as a reference to the global object. */
var root = freeGlobal || freeSelf || Function('return this')();
/** Detect free variable `exports`. */
var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
/** Detect free variable `module`. */
var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;
/** Detect the popular CommonJS extension `module.exports`. */
var moduleExports = freeModule && freeModule.exports === freeExports;
/** Detect free variable `process` from Node.js. */
var freeProcess = moduleExports && freeGlobal.process;
/** Used to access faster Node.js helpers. */
var nodeUtil = (function() {
try {
// Use `util.types` for Node.js 10+.
var types = freeModule && freeModule.require && freeModule.require('util').types;
if (types) {
return types;
}
// Legacy `process.binding('util')` for Node.js < 10.
return freeProcess && freeProcess.binding && freeProcess.binding('util');
} catch (e) {}
}());
/* Node.js helper references. */
var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
/**
* A faster alternative to `Function#apply`, this function invokes `func`
* with the `this` binding of `thisArg` and the arguments of `args`.
*
* @private
* @param {Function} func The function to invoke.
* @param {*} thisArg The `this` binding of `func`.
* @param {Array} args The arguments to invoke `func` with.
* @returns {*} Returns the result of `func`.
*/
function apply(func, thisArg, args) {
switch (args.length) {
case 0: return func.call(thisArg);
case 1: return func.call(thisArg, args[0]);
case 2: return func.call(thisArg, args[0], args[1]);
case 3: return func.call(thisArg, args[0], args[1], args[2]);
}
return func.apply(thisArg, args);
}
/**
* The base implementation of `_.times` without support for iteratee shorthands
* or max array length checks.
*
* @private
* @param {number} n The number of times to invoke `iteratee`.
* @param {Function} iteratee The function invoked per iteration.
* @returns {Array} Returns the array of results.
*/
function baseTimes(n, iteratee) {
var index = -1,
result = Array(n);
while (++index < n) {
result[index] = iteratee(index);
}
return result;
}
/**
* The base implementation of `_.unary` without support for storing metadata.
*
* @private
* @param {Function} func The function to cap arguments for.
* @returns {Function} Returns the new capped function.
*/
function baseUnary(func) {
return function(value) {
return func(value);
};
}
/**
* Gets the value at `key` of `object`.
*
* @private
* @param {Object} [object] The object to query.
* @param {string} key The key of the property to get.
* @returns {*} Returns the property value.
*/
function getValue(object, key) {
return object == null ? undefined : object[key];
}
/**
* Creates a unary function that invokes `func` with its argument transformed.
*
* @private
* @param {Function} func The function to wrap.
* @param {Function} transform The argument transform.
* @returns {Function} Returns the new function.
*/
function overArg(func, transform) {
return function(arg) {
return func(transform(arg));
};
}
/** Used for built-in method references. */
var arrayProto = Array.prototype,
funcProto = Function.prototype,
objectProto = Object.prototype;
/** Used to detect overreaching core-js shims. */
var coreJsData = root['__core-js_shared__'];
/** Used to resolve the decompiled source of functions. */
var funcToString = funcProto.toString;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;
/** Used to detect methods masquerading as native. */
var maskSrcKey = (function() {
var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
return uid ? ('Symbol(src)_1.' + uid) : '';
}());
/**
* Used to resolve the
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
* of values.
*/
var nativeObjectToString = objectProto.toString;
/** Used to infer the `Object` constructor. */
var objectCtorString = funcToString.call(Object);
/** Used to detect if a method is native. */
var reIsNative = RegExp('^' +
funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
.replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
);
/** Built-in value references. */
var Buffer = moduleExports ? root.Buffer : undefined,
Symbol = root.Symbol,
Uint8Array = root.Uint8Array,
allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined,
getPrototype = overArg(Object.getPrototypeOf, Object),
objectCreate = Object.create,
propertyIsEnumerable = objectProto.propertyIsEnumerable,
splice = arrayProto.splice,
symToStringTag = Symbol ? Symbol.toStringTag : undefined;
var defineProperty = (function() {
try {
var func = getNative(Object, 'defineProperty');
func({}, '', {});
return func;
} catch (e) {}
}());
/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,
nativeMax = Math.max,
nativeNow = Date.now;
/* Built-in method references that are verified to be native. */
var Map = getNative(root, 'Map'),
nativeCreate = getNative(Object, 'create');
/**
* The base implementation of `_.create` without support for assigning
* properties to the created object.
*
* @private
* @param {Object} proto The object to inherit from.
* @returns {Object} Returns the new object.
*/
var baseCreate = (function() {
function object() {}
return function(proto) {
if (!isObject(proto)) {
return {};
}
if (objectCreate) {
return objectCreate(proto);
}
object.prototype = proto;
var result = new object;
object.prototype = undefined;
return result;
};
}());
/**
* Creates a hash object.
*
* @private
* @constructor
* @param {Array} [entries] The key-value pairs to cache.
*/
function Hash(entries) {
var index = -1,
length = entries == null ? 0 : entries.length;
this.clear();
while (++index < length) {
var entry = entries[index];
this.set(entry[0], entry[1]);
}
}
/**
* Removes all key-value entries from the hash.
*
* @private
* @name clear
* @memberOf Hash
*/
function hashClear() {
this.__data__ = nativeCreate ? nativeCreate(null) : {};
this.size = 0;
}
/**
* Removes `key` and its value from the hash.
*
* @private
* @name delete
* @memberOf Hash
* @param {Object} hash The hash to modify.
* @param {string} key The key of the value to remove.
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
*/
function hashDelete(key) {
var result = this.has(key) && delete this.__data__[key];
this.size -= result ? 1 : 0;
return result;
}
/**
* Gets the hash value for `key`.
*
* @private
* @name get
* @memberOf Hash
* @param {string} key The key of the value to get.
* @returns {*} Returns the entry value.
*/
function hashGet(key) {
var data = this.__data__;
if (nativeCreate) {
var result = data[key];
return result === HASH_UNDEFINED ? undefined : result;
}
return hasOwnProperty.call(data, key) ? data[key] : undefined;
}
/**
* Checks if a hash value for `key` exists.
*
* @private
* @name has
* @memberOf Hash
* @param {string} key The key of the entry to check.
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
*/
function hashHas(key) {
var data = this.__data__;
return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);
}
/**
* Sets the hash `key` to `value`.
*
* @private
* @name set
* @memberOf Hash
* @param {string} key The key of the value to set.
* @param {*} value The value to set.
* @returns {Object} Returns the hash instance.
*/
function hashSet(key, value) {
var data = this.__data__;
this.size += this.has(key) ? 0 : 1;
data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
return this;
}
// Add methods to `Hash`.
Hash.prototype.clear = hashClear;
Hash.prototype['delete'] = hashDelete;
Hash.prototype.get = hashGet;
Hash.prototype.has = hashHas;
Hash.prototype.set = hashSet;
/**
* Creates an list cache object.
*
* @private
* @constructor
* @param {Array} [entries] The key-value pairs to cache.
*/
function ListCache(entries) {
var index = -1,
length = entries == null ? 0 : entries.length;
this.clear();
while (++index < length) {
var entry = entries[index];
this.set(entry[0], entry[1]);
}
}
/**
* Removes all key-value entries from the list cache.
*
* @private
* @name clear
* @memberOf ListCache
*/
function listCacheClear() {
this.__data__ = [];
this.size = 0;
}
/**
* Removes `key` and its value from the list cache.
*
* @private
* @name delete
* @memberOf ListCache
* @param {string} key The key of the value to remove.
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
*/
function listCacheDelete(key) {
var data = this.__data__,
index = assocIndexOf(data, key);
if (index < 0) {
return false;
}
var lastIndex = data.length - 1;
if (index == lastIndex) {
data.pop();
} else {
splice.call(data, index, 1);
}
--this.size;
return true;
}
/**
* Gets the list cache value for `key`.
*
* @private
* @name get
* @memberOf ListCache
* @param {string} key The key of the value to get.
* @returns {*} Returns the entry value.
*/
function listCacheGet(key) {
var data = this.__data__,
index = assocIndexOf(data, key);
return index < 0 ? undefined : data[index][1];
}
/**
* Checks if a list cache value for `key` exists.
*
* @private
* @name has
* @memberOf ListCache
* @param {string} key The key of the entry to check.
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
*/
function listCacheHas(key) {
return assocIndexOf(this.__data__, key) > -1;
}
/**
* Sets the list cache `key` to `value`.
*
* @private
* @name set
* @memberOf ListCache
* @param {string} key The key of the value to set.
* @param {*} value The value to set.
* @returns {Object} Returns the list cache instance.
*/
function listCacheSet(key, value) {
var data = this.__data__,
index = assocIndexOf(data, key);
if (index < 0) {
++this.size;
data.push([key, value]);
} else {
data[index][1] = value;
}
return this;
}
// Add methods to `ListCache`.
ListCache.prototype.clear = listCacheClear;
ListCache.prototype['delete'] = listCacheDelete;
ListCache.prototype.get = listCacheGet;
ListCache.prototype.has = listCacheHas;
ListCache.prototype.set = listCacheSet;
/**
* Creates a map cache object to store key-value pairs.
*
* @private
* @constructor
* @param {Array} [entries] The key-value pairs to cache.
*/
function MapCache(entries) {
var index = -1,
length = entries == null ? 0 : entries.length;
this.clear();
while (++index < length) {
var entry = entries[index];
this.set(entry[0], entry[1]);
}
}
/**
* Removes all key-value entries from the map.
*
* @private
* @name clear
* @memberOf MapCache
*/
function mapCacheClear() {
this.size = 0;
this.__data__ = {
'hash': new Hash,
'map': new (Map || ListCache),
'string': new Hash
};
}
/**
* Removes `key` and its value from the map.
*
* @private
* @name delete
* @memberOf MapCache
* @param {string} key The key of the value to remove.
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
*/
function mapCacheDelete(key) {
var result = getMapData(this, key)['delete'](key);
this.size -= result ? 1 : 0;
return result;
}
/**
* Gets the map value for `key`.
*
* @private
* @name get
* @memberOf MapCache
* @param {string} key The key of the value to get.
* @returns {*} Returns the entry value.
*/
function mapCacheGet(key) {
return getMapData(this, key).get(key);
}
/**
* Checks if a map value for `key` exists.
*
* @private
* @name has
* @memberOf MapCache
* @param {string} key The key of the entry to check.
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
*/
function mapCacheHas(key) {
return getMapData(this, key).has(key);
}
/**
* Sets the map `key` to `value`.
*
* @private
* @name set
* @memberOf MapCache
* @param {string} key The key of the value to set.
* @param {*} value The value to set.
* @returns {Object} Returns the map cache instance.
*/
function mapCacheSet(key, value) {
var data = getMapData(this, key),
size = data.size;
data.set(key, value);
this.size += data.size == size ? 0 : 1;
return this;
}
// Add methods to `MapCache`.
MapCache.prototype.clear = mapCacheClear;
MapCache.prototype['delete'] = mapCacheDelete;
MapCache.prototype.get = mapCacheGet;
MapCache.prototype.has = mapCacheHas;
MapCache.prototype.set = mapCacheSet;
/**
* Creates a stack cache object to store key-value pairs.
*
* @private
* @constructor
* @param {Array} [entries] The key-value pairs to cache.
*/
function Stack(entries) {
var data = this.__data__ = new ListCache(entries);
this.size = data.size;
}
/**
* Removes all key-value entries from the stack.
*
* @private
* @name clear
* @memberOf Stack
*/
function stackClear() {
this.__data__ = new ListCache;
this.size = 0;
}
/**
* Removes `key` and its value from the stack.
*
* @private
* @name delete
* @memberOf Stack
* @param {string} key The key of the value to remove.
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
*/
function stackDelete(key) {
var data = this.__data__,
result = data['delete'](key);
this.size = data.size;
return result;
}
/**
* Gets the stack value for `key`.
*
* @private
* @name get
* @memberOf Stack
* @param {string} key The key of the value to get.
* @returns {*} Returns the entry value.
*/
function stackGet(key) {
return this.__data__.get(key);
}
/**
* Checks if a stack value for `key` exists.
*
* @private
* @name has
* @memberOf Stack
* @param {string} key The key of the entry to check.
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
*/
function stackHas(key) {
return this.__data__.has(key);
}
/**
* Sets the stack `key` to `value`.
*
* @private
* @name set
* @memberOf Stack
* @param {string} key The key of the value to set.
* @param {*} value The value to set.
* @returns {Object} Returns the stack cache instance.
*/
function stackSet(key, value) {
var data = this.__data__;
if (data instanceof ListCache) {
var pairs = data.__data__;
if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
pairs.push([key, value]);
this.size = ++data.size;
return this;
}
data = this.__data__ = new MapCache(pairs);
}
data.set(key, value);
this.size = data.size;
return this;
}
// Add methods to `Stack`.
Stack.prototype.clear = stackClear;
Stack.prototype['delete'] = stackDelete;
Stack.prototype.get = stackGet;
Stack.prototype.has = stackHas;
Stack.prototype.set = stackSet;
/**
* Creates an array of the enumerable property names of the array-like `value`.
*
* @private
* @param {*} value The value to query.
* @param {boolean} inherited Specify returning inherited property names.
* @returns {Array} Returns the array of property names.
*/
function arrayLikeKeys(value, inherited) {
var isArr = isArray(value),
isArg = !isArr && isArguments(value),
isBuff = !isArr && !isArg && isBuffer(value),
isType = !isArr && !isArg && !isBuff && isTypedArray(value),
skipIndexes = isArr || isArg || isBuff || isType,
result = skipIndexes ? baseTimes(value.length, String) : [],
length = result.length;
for (var key in value) {
if ((inherited || hasOwnProperty.call(value, key)) &&
!(skipIndexes && (
// Safari 9 has enumerable `arguments.length` in strict mode.
key == 'length' ||
// Node.js 0.10 has enumerable non-index properties on buffers.
(isBuff && (key == 'offset' || key == 'parent')) ||
// PhantomJS 2 has enumerable non-index properties on typed arrays.
(isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
// Skip index properties.
isIndex(key, length)
))) {
result.push(key);
}
}
return result;
}
/**
* This function is like `assignValue` except that it doesn't assign
* `undefined` values.
*
* @private
* @param {Object} object The object to modify.
* @param {string} key The key of the property to assign.
* @param {*} value The value to assign.
*/
function assignMergeValue(object, key, value) {
if ((value !== undefined && !eq(object[key], value)) ||
(value === undefined && !(key in object))) {
baseAssignValue(object, key, value);
}
}
/**
* Assigns `value` to `key` of `object` if the existing value is not equivalent
* using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
* for equality comparisons.
*
* @private
* @param {Object} object The object to modify.
* @param {string} key The key of the property to assign.
* @param {*} value The value to assign.
*/
function assignValue(object, key, value) {
var objValue = object[key];
if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
(value === undefined && !(key in object))) {
baseAssignValue(object, key, value);
}
}
/**
* Gets the index at which the `key` is found in `array` of key-value pairs.
*
* @private
* @param {Array} array The array to inspect.
* @param {*} key The key to search for.
* @returns {number} Returns the index of the matched value, else `-1`.
*/
function assocIndexOf(array, key) {
var length = array.length;
while (length--) {
if (eq(array[length][0], key)) {
return length;
}
}
return -1;
}
/**
* The base implementation of `assignValue` and `assignMergeValue` without
* value checks.
*
* @private
* @param {Object} object The object to modify.
* @param {string} key The key of the property to assign.
* @param {*} value The value to assign.
*/
function baseAssignValue(object, key, value) {
if (key == '__proto__' && defineProperty) {
defineProperty(object, key, {
'configurable': true,
'enumerable': true,
'value': value,
'writable': true
});
} else {
object[key] = value;
}
}
/**
* The base implementation of `baseForOwn` which iterates over `object`
* properties returned by `keysFunc` and invokes `iteratee` for each property.
* Iteratee functions may exit iteration early by explicitly returning `false`.
*
* @private
* @param {Object} object The object to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @param {Function} keysFunc The function to get the keys of `object`.
* @returns {Object} Returns `object`.
*/
var baseFor = createBaseFor();
/**
* The base implementation of `getTag` without fallbacks for buggy environments.
*
* @private
* @param {*} value The value to query.
* @returns {string} Returns the `toStringTag`.
*/
function baseGetTag(value) {
if (value == null) {
return value === undefined ? undefinedTag : nullTag;
}
return (symToStringTag && symToStringTag in Object(value))
? getRawTag(value)
: objectToString(value);
}
/**
* The base implementation of `_.isArguments`.
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an `arguments` object,
*/
function baseIsArguments(value) {
return isObjectLike(value) && baseGetTag(value) == argsTag;
}
/**
* The base implementation of `_.isNative` without bad shim checks.
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a native function,
* else `false`.
*/
function baseIsNative(value) {
if (!isObject(value) || isMasked(value)) {
return false;
}
var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
return pattern.test(toSource(value));
}
/**
* The base implementation of `_.isTypedArray` without Node.js optimizations.
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
*/
function baseIsTypedArray(value) {
return isObjectLike(value) &&
isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
}
/**
* The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
*
* @private
* @param {Object} object The object to query.
* @returns {Array} Returns the array of property names.
*/
function baseKeysIn(object) {
if (!isObject(object)) {
return nativeKeysIn(object);
}
var isProto = isPrototype(object),
result = [];
for (var key in object) {
if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
result.push(key);
}
}
return result;
}
/**
* The base implementation of `_.merge` without support for multiple sources.
*
* @private
* @param {Object} object The destination object.
* @param {Object} source The source object.
* @param {number} srcIndex The index of `source`.
* @param {Function} [customizer] The function to customize merged values.
* @param {Object} [stack] Tracks traversed source values and their merged
* counterparts.
*/
function baseMerge(object, source, srcIndex, customizer, stack) {
if (object === source) {
return;
}
baseFor(source, function(srcValue, key) {
stack || (stack = new Stack);
if (isObject(srcValue)) {
baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
}
else {
var newValue = customizer
? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack)
: undefined;
if (newValue === undefined) {
newValue = srcValue;
}
assignMergeValue(object, key, newValue);
}
}, keysIn);
}
/**
* A specialized version of `baseMerge` for arrays and objects which performs
* deep merges and tracks traversed objects enabling objects with circular
* references to be merged.
*
* @private
* @param {Object} object The destination object.
* @param {Object} source The source object.
* @param {string} key The key of the value to merge.
* @param {number} srcIndex The index of `source`.
* @param {Function} mergeFunc The function to merge values.
* @param {Function} [customizer] The function to customize assigned values.
* @param {Object} [stack] Tracks traversed source values and their merged
* counterparts.
*/
function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
var objValue = safeGet(object, key),
srcValue = safeGet(source, key),
stacked = stack.get(srcValue);
if (stacked) {
assignMergeValue(object, key, stacked);
return;
}
var newValue = customizer
? customizer(objValue, srcValue, (key + ''), object, source, stack)
: undefined;
var isCommon = newValue === undefined;
if (isCommon) {
var isArr = isArray(srcValue),
isBuff = !isArr && isBuffer(srcValue),
isTyped = !isArr && !isBuff && isTypedArray(srcValue);
newValue = srcValue;
if (isArr || isBuff || isTyped) {
if (isArray(objValue)) {
newValue = objValue;
}
else if (isArrayLikeObject(objValue)) {
newValue = copyArray(objValue);
}
else if (isBuff) {
isCommon = false;
newValue = cloneBuffer(srcValue, true);
}
else if (isTyped) {
isCommon = false;
newValue = cloneTypedArray(srcValue, true);
}
else {
newValue = [];
}
}
else if (isPlainObject(srcValue) || isArguments(srcValue)) {
newValue = objValue;
if (isArguments(objValue)) {
newValue = toPlainObject(objValue);
}
else if (!isObject(objValue) || isFunction(objValue)) {
newValue = initCloneObject(srcValue);
}
}
else {
isCommon = false;
}
}
if (isCommon) {
// Recursively merge objects and arrays (susceptible to call stack limits).
stack.set(srcValue, newValue);
mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
stack['delete'](srcValue);
}
assignMergeValue(object, key, newValue);
}
/**
* The base implementation of `_.rest` which doesn't validate or coerce arguments.
*
* @private
* @param {Function} func The function to apply a rest parameter to.
* @param {number} [start=func.length-1] The start position of the rest parameter.
* @returns {Function} Returns the new function.
*/
function baseRest(func, start) {
return setToString(overRest(func, start, identity), func + '');
}
/**
* The base implementation of `setToString` without support for hot loop shorting.
*
* @private
* @param {Function} func The function to modify.
* @param {Function} string The `toString` result.
* @returns {Function} Returns `func`.
*/
var baseSetToString = !defineProperty ? identity : function(func, string) {
return defineProperty(func, 'toString', {
'configurable': true,
'enumerable': false,
'value': constant(string),
'writable': true
});
};
/**
* Creates a clone of `buffer`.
*
* @private
* @param {Buffer} buffer The buffer to clone.
* @param {boolean} [isDeep] Specify a deep clone.
* @returns {Buffer} Returns the cloned buffer.
*/
function cloneBuffer(buffer, isDeep) {
if (isDeep) {
return buffer.slice();
}
var length = buffer.length,
result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
buffer.copy(result);
return result;
}
/**
* Creates a clone of `arrayBuffer`.
*
* @private
* @param {ArrayBuffer} arrayBuffer The array buffer to clone.
* @returns {ArrayBuffer} Returns the cloned array buffer.
*/
function cloneArrayBuffer(arrayBuffer) {
var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
new Uint8Array(result).set(new Uint8Array(arrayBuffer));
return result;
}
/**
* Creates a clone of `typedArray`.
*
* @private
* @param {Object} typedArray The typed array to clone.
* @param {boolean} [isDeep] Specify a deep clone.
* @returns {Object} Returns the cloned typed array.
*/
function cloneTypedArray(typedArray, isDeep) {
var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
}
/**
* Copies the values of `source` to `array`.
*
* @private
* @param {Array} source The array to copy values from.
* @param {Array} [array=[]] The array to copy values to.
* @returns {Array} Returns `array`.
*/
function copyArray(source, array) {
var index = -1,
length = source.length;
array || (array = Array(length));
while (++index < length) {
array[index] = source[index];
}
return array;
}
/**
* Copies properties of `source` to `object`.
*
* @private
* @param {Object} source The object to copy properties from.
* @param {Array} props The property identifiers to copy.
* @param {Object} [object={}] The object to copy properties to.
* @param {Function} [customizer] The function to customize copied values.
* @returns {Object} Returns `object`.
*/
function copyObject(source, props, object, customizer) {
var isNew = !object;
object || (object = {});
var index = -1,
length = props.length;
while (++index < length) {
var key = props[index];
var newValue = customizer
? customizer(object[key], source[key], key, object, source)
: undefined;
if (newValue === undefined) {
newValue = source[key];
}
if (isNew) {
baseAssignValue(object, key, newValue);
} else {
assignValue(object, key, newValue);
}
}
return object;
}
/**
* Creates a function like `_.assign`.
*
* @private
* @param {Function} assigner The function to assign values.
* @returns {Function} Returns the new assigner function.
*/
function createAssigner(assigner) {
return baseRest(function(object, sources) {
var index = -1,
length = sources.length,
customizer = length > 1 ? sources[length - 1] : undefined,
guard = length > 2 ? sources[2] : undefined;
customizer = (assigner.length > 3 && typeof customizer == 'function')
? (length--, customizer)
: undefined;
if (guard && isIterateeCall(sources[0], sources[1], guard)) {
customizer = length < 3 ? undefined : customizer;
length = 1;
}
object = Object(object);
while (++index < length) {
var source = sources[index];
if (source) {
assigner(object, source, index, customizer);
}
}
return object;
});
}
/**
* Creates a base function for methods like `_.forIn` and `_.forOwn`.
*
* @private
* @param {boolean} [fromRight] Specify iterating from right to left.
* @returns {Function} Returns the new base function.
*/
function createBaseFor(fromRight) {
return function(object, iteratee, keysFunc) {
var index = -1,
iterable = Object(object),
props = keysFunc(object),
length = props.length;
while (length--) {
var key = props[fromRight ? length : ++index];
if (iteratee(iterable[key], key, iterable) === false) {
break;
}
}
return object;
};
}
/**
* Gets the data for `map`.
*
* @private
* @param {Object} map The map to query.
* @param {string} key The reference key.
* @returns {*} Returns the map data.
*/
function getMapData(map, key) {
var data = map.__data__;
return isKeyable(key)
? data[typeof key == 'string' ? 'string' : 'hash']
: data.map;
}
/**
* Gets the native function at `key` of `object`.
*
* @private
* @param {Object} object The object to query.
* @param {string} key The key of the method to get.
* @returns {*} Returns the function if it's native, else `undefined`.
*/
function getNative(object, key) {
var value = getValue(object, key);
return baseIsNative(value) ? value : undefined;
}
/**
* A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
*
* @private
* @param {*} value The value to query.
* @returns {string} Returns the raw `toStringTag`.
*/
function getRawTag(value) {
var isOwn = hasOwnProperty.call(value, symToStringTag),
tag = value[symToStringTag];
try {
value[symToStringTag] = undefined;
var unmasked = true;
} catch (e) {}
var result = nativeObjectToString.call(value);
if (unmasked) {
if (isOwn) {
value[symToStringTag] = tag;
} else {
delete value[symToStringTag];
}
}
return result;
}
/**
* Initializes an object clone.
*
* @private
* @param {Object} object The object to clone.
* @returns {Object} Returns the initialized clone.
*/
function initCloneObject(object) {
return (typeof object.constructor == 'function' && !isPrototype(object))
? baseCreate(getPrototype(object))
: {};
}
/**
* Checks if `value` is a valid array-like index.
*
* @private
* @param {*} value The value to check.
* @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
* @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
*/
function isIndex(value, length) {
var type = typeof value;
length = length == null ? MAX_SAFE_INTEGER : length;
return !!length &&
(type == 'number' ||
(type != 'symbol' && reIsUint.test(value))) &&
(value > -1 && value % 1 == 0 && value < length);
}
/**
* Checks if the given arguments are from an iteratee call.
*
* @private
* @param {*} value The potential iteratee value argument.
* @param {*} index The potential iteratee index or key argument.
* @param {*} object The potential iteratee object argument.
* @returns {boolean} Returns `true` if the arguments are from an iteratee call,
* else `false`.
*/
function isIterateeCall(value, index, object) {
if (!isObject(object)) {
return false;
}
var type = typeof index;
if (type == 'number'
? (isArrayLike(object) && isIndex(index, object.length))
: (type == 'string' && index in object)
) {
return eq(object[index], value);
}
return false;
}
/**
* Checks if `value` is suitable for use as unique object key.
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is suitable, else `false`.
*/
function isKeyable(value) {
var type = typeof value;
return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
? (value !== '__proto__')
: (value === null);
}
/**
* Checks if `func` has its source masked.
*
* @private
* @param {Function} func The function to check.
* @returns {boolean} Returns `true` if `func` is masked, else `false`.
*/
function isMasked(func) {
return !!maskSrcKey && (maskSrcKey in func);
}
/**
* Checks if `value` is likely a prototype object.
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
*/
function isPrototype(value) {
var Ctor = value && value.constructor,
proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
return value === proto;
}
/**
* This function is like
* [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
* except that it includes inherited enumerable properties.
*
* @private
* @param {Object} object The object to query.
* @returns {Array} Returns the array of property names.
*/
function nativeKeysIn(object) {
var result = [];
if (object != null) {
for (var key in Object(object)) {
result.push(key);
}
}
return result;
}
/**
* Converts `value` to a string using `Object.prototype.toString`.
*
* @private
* @param {*} value The value to convert.
* @returns {string} Returns the converted string.
*/
function objectToString(value) {
return nativeObjectToString.call(value);
}
/**
* A specialized version of `baseRest` which transforms the rest array.
*
* @private
* @param {Function} func The function to apply a rest parameter to.
* @param {number} [start=func.length-1] The start position of the rest parameter.
* @param {Function} transform The rest array transform.
* @returns {Function} Returns the new function.
*/
function overRest(func, start, transform) {
start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
return function() {
var args = arguments,
index = -1,
length = nativeMax(args.length - start, 0),
array = Array(length);
while (++index < length) {
array[index] = args[start + index];
}
index = -1;
var otherArgs = Array(start + 1);
while (++index < start) {
otherArgs[index] = args[index];
}
otherArgs[start] = transform(array);
return apply(func, this, otherArgs);
};
}
/**
* Gets the value at `key`, unless `key` is "__proto__" or "constructor".
*
* @private
* @param {Object} object The object to query.
* @param {string} key The key of the property to get.
* @returns {*} Returns the property value.
*/
function safeGet(object, key) {
if (key === 'constructor' && typeof object[key] === 'function') {
return;
}
if (key == '__proto__') {
return;
}
return object[key];
}
/**
* Sets the `toString` method of `func` to return `string`.
*
* @private
* @param {Function} func The function to modify.
* @param {Function} string The `toString` result.
* @returns {Function} Returns `func`.
*/
var setToString = shortOut(baseSetToString);
/**
* Creates a function that'll short out and invoke `identity` instead
* of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
* milliseconds.
*
* @private
* @param {Function} func The function to restrict.
* @returns {Function} Returns the new shortable function.
*/
function shortOut(func) {
var count = 0,
lastCalled = 0;
return function() {
var stamp = nativeNow(),
remaining = HOT_SPAN - (stamp - lastCalled);
lastCalled = stamp;
if (remaining > 0) {
if (++count >= HOT_COUNT) {
return arguments[0];
}
} else {
count = 0;
}
return func.apply(undefined, arguments);
};
}
/**
* Converts `func` to its source code.
*
* @private
* @param {Function} func The function to convert.
* @returns {string} Returns the source code.
*/
function toSource(func) {
if (func != null) {
try {
return funcToString.call(func);
} catch (e) {}
try {
return (func + '');
} catch (e) {}
}
return '';
}
/**
* Performs a
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
* comparison between two values to determine if they are equivalent.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to compare.
* @param {*} other The other value to compare.
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
* @example
*
* var object = { 'a': 1 };
* var other = { 'a': 1 };
*
* _.eq(object, object);
* // => true
*
* _.eq(object, other);
* // => false
*
* _.eq('a', 'a');
* // => true
*
* _.eq('a', Object('a'));
* // => false
*
* _.eq(NaN, NaN);
* // => true
*/
function eq(value, other) {
return value === other || (value !== value && other !== other);
}
/**
* Checks if `value` is likely an `arguments` object.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an `arguments` object,
* else `false`.
* @example
*
* _.isArguments(function() { return arguments; }());
* // => true
*
* _.isArguments([1, 2, 3]);
* // => false
*/
var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&
!propertyIsEnumerable.call(value, 'callee');
};
/**
* Checks if `value` is classified as an `Array` object.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an array, else `false`.
* @example
*
* _.isArray([1, 2, 3]);
* // => true
*
* _.isArray(document.body.children);
* // => false
*
* _.isArray('abc');
* // => false
*
* _.isArray(_.noop);
* // => false
*/
var isArray = Array.isArray;
/**
* Checks if `value` is array-like. A value is considered array-like if it's
* not a function and has a `value.length` that's an integer greater than or
* equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is array-like, else `false`.
* @example
*
* _.isArrayLike([1, 2, 3]);
* // => true
*
* _.isArrayLike(document.body.children);
* // => true
*
* _.isArrayLike('abc');
* // => true
*
* _.isArrayLike(_.noop);
* // => false
*/
function isArrayLike(value) {
return value != null && isLength(value.length) && !isFunction(value);
}
/**
* This method is like `_.isArrayLike` except that it also checks if `value`
* is an object.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an array-like object,
* else `false`.
* @example
*
* _.isArrayLikeObject([1, 2, 3]);
* // => true
*
* _.isArrayLikeObject(document.body.children);
* // => true
*
* _.isArrayLikeObject('abc');
* // => false
*
* _.isArrayLikeObject(_.noop);
* // => false
*/
function isArrayLikeObject(value) {
return isObjectLike(value) && isArrayLike(value);
}
/**
* Checks if `value` is a buffer.
*
* @static
* @memberOf _
* @since 4.3.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
* @example
*
* _.isBuffer(new Buffer(2));
* // => true
*
* _.isBuffer(new Uint8Array(2));
* // => false
*/
var isBuffer = nativeIsBuffer || stubFalse;
/**
* Checks if `value` is classified as a `Function` object.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a function, else `false`.
* @example
*
* _.isFunction(_);
* // => true
*
* _.isFunction(/abc/);
* // => false
*/
function isFunction(value) {
if (!isObject(value)) {
return false;
}
// The use of `Object#toString` avoids issues with the `typeof` operator
// in Safari 9 which returns 'object' for typed arrays and other constructors.
var tag = baseGetTag(value);
return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
}
/**
* Checks if `value` is a valid array-like length.
*
* **Note:** This method is loosely based on
* [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
* @example
*
* _.isLength(3);
* // => true
*
* _.isLength(Number.MIN_VALUE);
* // => false
*
* _.isLength(Infinity);
* // => false
*
* _.isLength('3');
* // => false
*/
function isLength(value) {
return typeof value == 'number' &&
value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
}
/**
* Checks if `value` is the
* [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
* of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
* @example
*
* _.isObject({});
* // => true
*
* _.isObject([1, 2, 3]);
* // => true
*
* _.isObject(_.noop);
* // => true
*
* _.isObject(null);
* // => false
*/
function isObject(value) {
var type = typeof value;
return value != null && (type == 'object' || type == 'function');
}
/**
* Checks if `value` is object-like. A value is object-like if it's not `null`
* and has a `typeof` result of "object".
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
* @example
*
* _.isObjectLike({});
* // => true
*
* _.isObjectLike([1, 2, 3]);
* // => true
*
* _.isObjectLike(_.noop);
* // => false
*
* _.isObjectLike(null);
* // => false
*/
function isObjectLike(value) {
return value != null && typeof value == 'object';
}
/**
* Checks if `value` is a plain object, that is, an object created by the
* `Object` constructor or one with a `[[Prototype]]` of `null`.
*
* @static
* @memberOf _
* @since 0.8.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
* @example
*
* function Foo() {
* this.a = 1;
* }
*
* _.isPlainObject(new Foo);
* // => false
*
* _.isPlainObject([1, 2, 3]);
* // => false
*
* _.isPlainObject({ 'x': 0, 'y': 0 });
* // => true
*
* _.isPlainObject(Object.create(null));
* // => true
*/
function isPlainObject(value) {
if (!isObjectLike(value) || baseGetTag(value) != objectTag) {
return false;
}
var proto = getPrototype(value);
if (proto === null) {
return true;
}
var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
return typeof Ctor == 'function' && Ctor instanceof Ctor &&
funcToString.call(Ctor) == objectCtorString;
}
/**
* Checks if `value` is classified as a typed array.
*
* @static
* @memberOf _
* @since 3.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
* @example
*
* _.isTypedArray(new Uint8Array);
* // => true
*
* _.isTypedArray([]);
* // => false
*/
var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
/**
* Converts `value` to a plain object flattening inherited enumerable string
* keyed properties of `value` to own properties of the plain object.
*
* @static
* @memberOf _
* @since 3.0.0
* @category Lang
* @param {*} value The value to convert.
* @returns {Object} Returns the converted plain object.
* @example
*
* function Foo() {
* this.b = 2;
* }
*
* Foo.prototype.c = 3;
*
* _.assign({ 'a': 1 }, new Foo);
* // => { 'a': 1, 'b': 2 }
*
* _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
* // => { 'a': 1, 'b': 2, 'c': 3 }
*/
function toPlainObject(value) {
return copyObject(value, keysIn(value));
}
/**
* Creates an array of the own and inherited enumerable property names of `object`.
*
* **Note:** Non-object values are coerced to objects.
*
* @static
* @memberOf _
* @since 3.0.0
* @category Object
* @param {Object} object The object to query.
* @returns {Array} Returns the array of property names.
* @example
*
* function Foo() {
* this.a = 1;
* this.b = 2;
* }
*
* Foo.prototype.c = 3;
*
* _.keysIn(new Foo);
* // => ['a', 'b', 'c'] (iteration order is not guaranteed)
*/
function keysIn(object) {
return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);
}
/**
* This method is like `_.assign` except that it recursively merges own and
* inherited enumerable string keyed properties of source objects into the
* destination object. Source properties that resolve to `undefined` are
* skipped if a destination value exists. Array and plain object properties
* are merged recursively. Other objects and value types are overridden by
* assignment. Source objects are applied from left to right. Subsequent
* sources overwrite property assignments of previous sources.
*
* **Note:** This method mutates `object`.
*
* @static
* @memberOf _
* @since 0.5.0
* @category Object
* @param {Object} object The destination object.
* @param {...Object} [sources] The source objects.
* @returns {Object} Returns `object`.
* @example
*
* var object = {
* 'a': [{ 'b': 2 }, { 'd': 4 }]
* };
*
* var other = {
* 'a': [{ 'c': 3 }, { 'e': 5 }]
* };
*
* _.merge(object, other);
* // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
*/
var merge = createAssigner(function(object, source, srcIndex) {
baseMerge(object, source, srcIndex);
});
/**
* Creates a function that returns `value`.
*
* @static
* @memberOf _
* @since 2.4.0
* @category Util
* @param {*} value The value to return from the new function.
* @returns {Function} Returns the new constant function.
* @example
*
* var objects = _.times(2, _.constant({ 'a': 1 }));
*
* console.log(objects);
* // => [{ 'a': 1 }, { 'a': 1 }]
*
* console.log(objects[0] === objects[1]);
* // => true
*/
function constant(value) {
return function() {
return value;
};
}
/**
* This method returns the first argument it receives.
*
* @static
* @since 0.1.0
* @memberOf _
* @category Util
* @param {*} value Any value.
* @returns {*} Returns `value`.
* @example
*
* var object = { 'a': 1 };
*
* console.log(_.identity(object) === object);
* // => true
*/
function identity(value) {
return value;
}
/**
* This method returns `false`.
*
* @static
* @memberOf _
* @since 4.13.0
* @category Util
* @returns {boolean} Returns `false`.
* @example
*
* _.times(2, _.stubFalse);
* // => [false, false]
*/
function stubFalse() {
return false;
}
module.exports = merge;
}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],2:[function(require,module,exports){
/*! For license information please see shifty.js.LICENSE.txt */
!function(t,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define("shifty",[],n):"object"==typeof exports?exports.shifty=n():t.shifty=n()}(self,(function(){return function(){"use strict";var t={720:function(t,n,e){e.r(n),e.d(n,{Scene:function(){return sn},Tweenable:function(){return kt},interpolate:function(){return nn},processTweens:function(){return dt},setBezierFunction:function(){return $},shouldScheduleUpdate:function(){return bt},tween:function(){return Pt},unsetBezierFunction:function(){return L}});var r={};e.r(r),e.d(r,{bounce:function(){return D},bouncePast:function(){return q},easeFrom:function(){return B},easeFromTo:function(){return Q},easeInBack:function(){return E},easeInCirc:function(){return j},easeInCubic:function(){return c},easeInExpo:function(){return w},easeInOutBack:function(){return T},easeInOutCirc:function(){return P},easeInOutCubic:function(){return l},easeInOutExpo:function(){return S},easeInOutQuad:function(){return s},easeInOutQuart:function(){return v},easeInOutQuint:function(){return d},easeInOutSine:function(){return b},easeInQuad:function(){return u},easeInQuart:function(){return h},easeInQuint:function(){return y},easeInSine:function(){return g},easeOutBack:function(){return A},easeOutBounce:function(){return M},easeOutCirc:function(){return k},easeOutCubic:function(){return f},easeOutExpo:function(){return O},easeOutQuad:function(){return a},easeOutQuart:function(){return p},easeOutQuint:function(){return _},easeOutSine:function(){return m},easeTo:function(){return N},elastic:function(){return I},linear:function(){return o},swingFrom:function(){return x},swingFromTo:function(){return F},swingTo:function(){return C}});var i={};e.r(i),e.d(i,{afterTween:function(){return Jt},beforeTween:function(){return Ht},doesApply:function(){return Wt},tweenCreated:function(){return Gt}});var o=function(t){return t},u=function(t){return Math.pow(t,2)},a=function(t){return-(Math.pow(t-1,2)-1)},s=function(t){return(t/=.5)<1?.5*Math.pow(t,2):-.5*((t-=2)*t-2)},c=function(t){return Math.pow(t,3)},f=function(t){return Math.pow(t-1,3)+1},l=function(t){return(t/=.5)<1?.5*Math.pow(t,3):.5*(Math.pow(t-2,3)+2)},h=function(t){return Math.pow(t,4)},p=function(t){return-(Math.pow(t-1,4)-1)},v=function(t){return(t/=.5)<1?.5*Math.pow(t,4):-.5*((t-=2)*Math.pow(t,3)-2)},y=function(t){return Math.pow(t,5)},_=function(t){return Math.pow(t-1,5)+1},d=function(t){return(t/=.5)<1?.5*Math.pow(t,5):.5*(Math.pow(t-2,5)+2)},g=function(t){return 1-Math.cos(t*(Math.PI/2))},m=function(t){return Math.sin(t*(Math.PI/2))},b=function(t){return-.5*(Math.cos(Math.PI*t)-1)},w=function(t){return 0===t?0:Math.pow(2,10*(t-1))},O=function(t){return 1===t?1:1-Math.pow(2,-10*t)},S=function(t){return 0===t?0:1===t?1:(t/=.5)<1?.5*Math.pow(2,10*(t-1)):.5*(2-Math.pow(2,-10*--t))},j=function(t){return-(Math.sqrt(1-t*t)-1)},k=function(t){return Math.sqrt(1-Math.pow(t-1,2))},P=function(t){return(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},M=function(t){return t<1/2.75?7.5625*t*t:t<2/2.75?7.5625*(t-=1.5/2.75)*t+.75:t<2.5/2.75?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375},E=function(t){var n=1.70158;return t*t*((n+1)*t-n)},A=function(t){var n=1.70158;return(t-=1)*t*((n+1)*t+n)+1},T=function(t){var n=1.70158;return(t/=.5)<1?t*t*((1+(n*=1.525))*t-n)*.5:.5*((t-=2)*t*((1+(n*=1.525))*t+n)+2)},I=function(t){return-1*Math.pow(4,-8*t)*Math.sin((6*t-1)*(2*Math.PI)/2)+1},F=function(t){var n=1.70158;return(t/=.5)<1?t*t*((1+(n*=1.525))*t-n)*.5:.5*((t-=2)*t*((1+(n*=1.525))*t+n)+2)},x=function(t){var n=1.70158;return t*t*((n+1)*t-n)},C=function(t){var n=1.70158;return(t-=1)*t*((n+1)*t+n)+1},D=function(t){return t<1/2.75?7.5625*t*t:t<2/2.75?7.5625*(t-=1.5/2.75)*t+.75:t<2.5/2.75?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375},q=function(t){return t<1/2.75?7.5625*t*t:t<2/2.75?2-(7.5625*(t-=1.5/2.75)*t+.75):t<2.5/2.75?2-(7.5625*(t-=2.25/2.75)*t+.9375):2-(7.5625*(t-=2.625/2.75)*t+.984375)},Q=function(t){return(t/=.5)<1?.5*Math.pow(t,4):-.5*((t-=2)*Math.pow(t,3)-2)},B=function(t){return Math.pow(t,4)},N=function(t){return Math.pow(t,.25)};function R(t,n,e,r,i,o){var u,a,s,c,f,l=0,h=0,p=0,v=function(t){return((l*t+h)*t+p)*t},y=function(t){return(3*l*t+2*h)*t+p},_=function(t){return t>=0?t:0-t};return l=1-(p=3*n)-(h=3*(r-n)-p),s=1-(f=3*e)-(c=3*(i-e)-f),u=t,a=function(t){return 1/(200*t)}(o),function(t){return((s*t+c)*t+f)*t}(function(t,n){var e,r,i,o,u,a;for(i=t,a=0;a<8;a++){if(o=v(i)-t,_(o)<n)return i;if(u=y(i),_(u)<1e-6)break;i-=o/u}if((i=t)<(e=0))return e;if(i>(r=1))return r;for(;e<r;){if(o=v(i),_(o-t)<n)return i;t>o?e=i:r=i,i=.5*(r-e)+e}return i}(u,a))}var z,U=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:.25,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:.25,e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:.75,r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:.75;return function(i){return R(i,t,n,e,r,1)}},$=function(t,n,e,r,i){var o=U(n,e,r,i);return o.displayName=t,o.x1=n,o.y1=e,o.x2=r,o.y2=i,kt.formulas[t]=o},L=function(t){return delete kt.formulas[t]};function V(t,n){if(!(t instanceof n))throw new TypeError("Cannot call a class as a function")}function W(t,n){for(var e=0;e<n.length;e++){var r=n[e];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}function G(t){return G="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},G(t)}function H(t){return function(t){if(Array.isArray(t))return J(t)}(t)||function(t){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(t))return Array.from(t)}(t)||function(t,n){if(t){if("string"==typeof t)return J(t,n);var e=Object.prototype.toString.call(t).slice(8,-1);return"Object"===e&&t.constructor&&(e=t.constructor.name),"Map"===e||"Set"===e?Array.from(t):"Arguments"===e||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(e)?J(t,n):void 0}}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function J(t,n){(null==n||n>t.length)&&(n=t.length);for(var e=0,r=new Array(n);e<n;e++)r[e]=t[e];return r}function K(t,n){var e=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(t,n).enumerable}))),e.push.apply(e,r)}return e}function X(t){for(var n=1;n<arguments.length;n++){var e=null!=arguments[n]?arguments[n]:{};n%2?K(Object(e),!0).forEach((function(n){Y(t,n,e[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(e)):K(Object(e)).forEach((function(n){Object.defineProperty(t,n,Object.getOwnPropertyDescriptor(e,n))}))}return t}function Y(t,n,e){return n in t?Object.defineProperty(t,n,{value:e,enumerable:!0,configurable:!0,writable:!0}):t[n]=e,t}var Z,tt,nt,et="linear",rt="undefined"!=typeof window?window:e.g,it="afterTween",ot="afterTweenEnd",ut="beforeTween",at="tweenCreated",st="function",ct="string",ft=rt.requestAnimationFrame||rt.webkitRequestAnimationFrame||rt.oRequestAnimationFrame||rt.msRequestAnimationFrame||rt.mozCancelRequestAnimationFrame&&rt.mozRequestAnimationFrame||setTimeout,lt=function(){},ht=null,pt=null,vt=X({},r),yt=function(t,n,e,r,i,o,u){var a,s,c,f=t<o?0:(t-o)/i,l=!1;for(var h in u&&u.call&&(l=!0,a=u(f)),n)l||(a=((s=u[h]).call?s:vt[s])(f)),c=e[h],n[h]=c+(r[h]-c)*a;return n},_t=function(t,n){var e=t._timestamp,r=t._currentState,i=t._delay;if(!(n<e+i)){var o=t._duration,u=t._targetState,a=e+i+o,s=n>a?a:n;t._hasEnded=s>=a;var c=o-(a-s),f=t._filters.length>0;if(t._hasEnded)return t._render(u,t._data,c),t.stop(!0);f&&t._applyFilter(ut),s<e+i?e=o=s=1:e+=i,yt(s,r,t._originalState,u,o,e,t._easing),f&&t._applyFilter(it),t._render(r,t._data,c)}},dt=function(){for(var t,n=kt.now(),e=ht;e;)t=e._next,_t(e,n),e=t},gt=Date.now||function(){return+new Date},mt=!1,bt=function(t){t&&mt||(mt=t,t&&wt())},wt=function t(){Z=gt(),mt&&ft.call(rt,t,16.666666666666668),dt()},Ot=function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:et,e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if(Array.isArray(n)){var r=U.apply(void 0,H(n));return r}var i=G(n);if(vt[n])return vt[n];if(i===ct||i===st)for(var o in t)e[o]=n;else for(var u in t)e[u]=n[u]||et;return e},St=function(t){t===ht?(ht=t._next)?ht._previous=null:pt=null:t===pt?(pt=t._previous)?pt._next=null:ht=null:(tt=t._previous,nt=t._next,tt._next=nt,nt._previous=tt),t._previous=t._next=null},jt="function"==typeof Promise?Promise:null;z=Symbol.toStringTag;var kt=function(){function t(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:void 0;V(this,t),Y(this,z,"Promise"),this._config={},this._data={},this._delay=0,this._filters=[],this._next=null,this._previous=null,this._timestamp=null,this._hasEnded=!1,this._resolve=null,this._reject=null,this._currentState=n||{},this._originalState={},this._targetState={},this._start=lt,this._render=lt,this._promiseCtor=jt,e&&this.setConfig(e)}var n,e;return n=t,e=[{key:"_applyFilter",value:function(t){for(var n=this._filters.length;n>0;n--){var e=this._filters[n-n][t];e&&e(this)}}},{key:"tween",value:function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:void 0;return this._isPlaying&&this.stop(),!n&&this._config||this.setConfig(n),this._pausedAtTime=null,this._timestamp=t.now(),this._start(this.get(),this._data),this._delay&&this._render(this._currentState,this._data,0),this._resume(this._timestamp)}},{key:"setConfig",value:function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=this._config;for(var r in n)e[r]=n[r];var i=e.promise,o=void 0===i?this._promiseCtor:i,u=e.start,a=void 0===u?lt:u,s=e.finish,c=e.render,f=void 0===c?this._config.step||lt:c,l=e.step,h=void 0===l?lt:l;this._data=e.data||e.attachment||this._data,this._isPlaying=!1,this._pausedAtTime=null,this._scheduleId=null,this._delay=n.delay||0,this._start=a,this._render=f||h,this._duration=e.duration||500,this._promiseCtor=o,s&&(this._resolve=s);var p=n.from,v=n.to,y=void 0===v?{}:v,_=this._currentState,d=this._originalState,g=this._targetState;for(var m in p)_[m]=p[m];var b=!1;for(var w in _){var O=_[w];b||G(O)!==ct||(b=!0),d[w]=O,g[w]=y.hasOwnProperty(w)?y[w]:O}if(this._easing=Ot(this._currentState,e.easing,this._easing),this._filters.length=0,b){for(var S in t.filters)t.filters[S].doesApply(this)&&this._filters.push(t.filters[S]);this._applyFilter(at)}return this}},{key:"then",value:function(t,n){var e=this;return this._promise=new this._promiseCtor((function(t,n){e._resolve=t,e._reject=n})),this._promise.then(t,n)}},{key:"catch",value:function(t){return this.then().catch(t)}},{key:"finally",value:function(t){return this.then().finally(t)}},{key:"get",value:function(){return X({},this._currentState)}},{key:"set",value:function(t){this._currentState=t}},{key:"pause",value:function(){if(this._isPlaying)return this._pausedAtTime=t.now(),this._isPlaying=!1,St(this),this}},{key:"resume",value:function(){return this._resume()}},{key:"_resume",value:function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:t.now();return null===this._timestamp?this.tween():this._isPlaying?this._promise:(this._pausedAtTime&&(this._timestamp+=n-this._pausedAtTime,this._pausedAtTime=null),this._isPlaying=!0,null===ht?(ht=this,pt=this):(this._previous=pt,pt._next=this,pt=this),this)}},{key:"seek",value:function(n){n=Math.max(n,0);var e=t.now();return this._timestamp+n===0||(this._timestamp=e-n,_t(this,e)),this}},{key:"stop",value:function(){var t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];if(!this._isPlaying)return this;this._isPlaying=!1,St(this);var n=this._filters.length>0;return t&&(n&&this._applyFilter(ut),yt(1,this._currentState,this._originalState,this._targetState,1,0,this._easing),n&&(this._applyFilter(it),this._applyFilter(ot))),this._resolve&&this._resolve({data:this._data,state:this._currentState,tweenable:this}),this._resolve=null,this._reject=null,this}},{key:"cancel",value:function(){var t=arguments.length>0&&void 0!==arguments[0]&&arguments[0],n=this._currentState,e=this._data,r=this._isPlaying;return r?(this._reject&&this._reject({data:e,state:n,tweenable:this}),this._resolve=null,this._reject=null,this.stop(t)):this}},{key:"isPlaying",value:function(){return this._isPlaying}},{key:"hasEnded",value:function(){return this._hasEnded}},{key:"setScheduleFunction",value:function(n){t.setScheduleFunction(n)}},{key:"data",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;return t&&(this._data=X({},t)),this._data}},{key:"dispose",value:function(){for(var t in this)delete this[t]}}],e&&W(n.prototype,e),t}();function Pt(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=new kt;return n.tween(t),n.tweenable=n,n}Y(kt,"now",(function(){return Z})),Y(kt,"setScheduleFunction",(function(t){return ft=t})),Y(kt,"filters",{}),Y(kt,"formulas",vt),bt(!0);var Mt,Et,At=/(\d|-|\.)/,Tt=/([^\-0-9.]+)/g,It=/[0-9.-]+/g,Ft=(Mt=It.source,Et=/,\s*/.source,new RegExp("rgba?\\(".concat(Mt).concat(Et).concat(Mt).concat(Et).concat(Mt,"(").concat(Et).concat(Mt,")?\\)"),"g")),xt=/^.*\(/,Ct=/#([0-9]|[a-f]){3,6}/gi,Dt="VAL",qt=function(t,n){return t.map((function(t,e){return"_".concat(n,"_").concat(e)}))};function Qt(t){return parseInt(t,16)}var Bt=function(t){return"rgb(".concat((n=t,3===(n=n.replace(/#/,"")).length&&(n=(n=n.split(""))[0]+n[0]+n[1]+n[1]+n[2]+n[2]),[Qt(n.substr(0,2)),Qt(n.substr(2,2)),Qt(n.substr(4,2))]).join(","),")");var n},Nt=function(t,n,e){var r=n.match(t),i=n.replace(t,Dt);return r&&r.forEach((function(t){return i=i.replace(Dt,e(t))})),i},Rt=function(t){for(var n in t){var e=t[n];"string"==typeof e&&e.match(Ct)&&(t[n]=Nt(Ct,e,Bt))}},zt=function(t){var n=t.match(It),e=n.slice(0,3).map(Math.floor),r=t.match(xt)[0];if(3===n.length)return"".concat(r).concat(e.join(","),")");if(4===n.length)return"".concat(r).concat(e.join(","),",").concat(n[3],")");throw new Error("Invalid rgbChunk: ".concat(t))},Ut=function(t){return t.match(It)},$t=function(t,n){var e={};return n.forEach((function(n){e[n]=t[n],delete t[n]})),e},Lt=function(t,n){return n.map((function(n){return t[n]}))},Vt=function(t,n){return n.forEach((function(n){return t=t.replace(Dt,+n.toFixed(4))})),t},Wt=function(t){for(var n in t._currentState)if("string"==typeof t._currentState[n])return!0;return!1};function Gt(t){var n=t._currentState;[n,t._originalState,t._targetState].forEach(Rt),t._tokenData=function(t){var n,e,r={};for(var i in t){var o=t[i];"string"==typeof o&&(r[i]={formatString:(n=o,e=void 0,e=n.match(Tt),e?(1===e.length||n.charAt(0).match(At))&&e.unshift(""):e=["",""],e.join(Dt)),chunkNames:qt(Ut(o),i)})}return r}(n)}function Ht(t){var n=t._currentState,e=t._originalState,r=t._targetState,i=t._easing,o=t._tokenData;!function(t,n){var e=function(e){var r=n[e].chunkNames,i=t[e];if("string"==typeof i){var o=i.split(" "),u=o[o.length-1];r.forEach((function(n,e){return t[n]=o[e]||u}))}else r.forEach((function(n){return t[n]=i}));delete t[e]};for(var r in n)e(r)}(i,o),[n,e,r].forEach((function(t){return function(t,n){var e=function(e){Ut(t[e]).forEach((function(r,i){return t[n[e].chunkNames[i]]=+r})),delete t[e]};for(var r in n)e(r)}(t,o)}))}function Jt(t){var n=t._currentState,e=t._originalState,r=t._targetState,i=t._easing,o=t._tokenData;[n,e,r].forEach((function(t){return function(t,n){for(var e in n){var r=n[e],i=r.chunkNames,o=r.formatString,u=Vt(o,Lt($t(t,i),i));t[e]=Nt(Ft,u,zt)}}(t,o)})),function(t,n){for(var e in n){var r=n[e].chunkNames,i=t[r[0]];t[e]="string"==typeof i?r.map((function(n){var e=t[n];return delete t[n],e})).join(" "):i}}(i,o)}function Kt(t,n){var e=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(t,n).enumerable}))),e.push.apply(e,r)}return e}function Xt(t){for(var n=1;n<arguments.length;n++){var e=null!=arguments[n]?arguments[n]:{};n%2?Kt(Object(e),!0).forEach((function(n){Yt(t,n,e[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(e)):Kt(Object(e)).forEach((function(n){Object.defineProperty(t,n,Object.getOwnPropertyDescriptor(e,n))}))}return t}function Yt(t,n,e){return n in t?Object.defineProperty(t,n,{value:e,enumerable:!0,configurable:!0,writable:!0}):t[n]=e,t}var Zt=new kt,tn=kt.filters,nn=function(t,n,e,r){var i=arguments.length>4&&void 0!==arguments[4]?arguments[4]:0,o=Xt({},t),u=Ot(t,r);for(var a in Zt._filters.length=0,Zt.set({}),Zt._currentState=o,Zt._originalState=t,Zt._targetState=n,Zt._easing=u,tn)tn[a].doesApply(Zt)&&Zt._filters.push(tn[a]);Zt._applyFilter("tweenCreated"),Zt._applyFilter("beforeTween");var s=yt(e,o,t,n,1,i,u);return Zt._applyFilter("afterTween"),s};function en(t,n){(null==n||n>t.length)&&(n=t.length);for(var e=0,r=new Array(n);e<n;e++)r[e]=t[e];return r}function rn(t,n){if(!(t instanceof n))throw new TypeError("Cannot call a class as a function")}function on(t,n){for(var e=0;e<n.length;e++){var r=n[e];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}function un(t,n){var e=n.get(t);if(!e)throw new TypeError("attempted to get private field on non-instance");return e.get?e.get.call(t):e.value}var an=new WeakMap,sn=function(){function t(){rn(this,t),an.set(this,{writable:!0,value:[]});for(var n=arguments.length,e=new Array(n),r=0;r<n;r++)e[r]=arguments[r];e.forEach(this.add.bind(this))}var n,e;return n=t,(e=[{key:"add",value:function(t){return un(this,an).push(t),t}},{key:"remove",value:function(t){var n=un(this,an).indexOf(t);return~n&&un(this,an).splice(n,1),t}},{key:"empty",value:function(){return this.tweenables.map(this.remove.bind(this))}},{key:"isPlaying",value:function(){return un(this,an).some((function(t){return t.isPlaying()}))}},{key:"play",value:function(){return un(this,an).forEach((function(t){return t.tween()})),this}},{key:"pause",value:function(){return un(this,an).forEach((function(t){return t.pause()})),this}},{key:"resume",value:function(){return this.playingTweenables.forEach((function(t){return t.resume()})),this}},{key:"stop",value:function(t){return un(this,an).forEach((function(n){return n.stop(t)})),this}},{key:"tweenables",get:function(){return function(t){if(Array.isArray(t))return en(t)}(t=un(this,an))||function(t){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(t))return Array.from(t)}(t)||function(t,n){if(t){if("string"==typeof t)return en(t,n);var e=Object.prototype.toString.call(t).slice(8,-1);return"Object"===e&&t.constructor&&(e=t.constructor.name),"Map"===e||"Set"===e?Array.from(t):"Arguments"===e||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(e)?en(t,n):void 0}}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}();var t}},{key:"playingTweenables",get:function(){return un(this,an).filter((function(t){return!t.hasEnded()}))}},{key:"promises",get:function(){return un(this,an).map((function(t){return t.then()}))}}])&&on(n.prototype,e),t}();kt.filters.token=i}},n={};function e(r){if(n[r])return n[r].exports;var i=n[r]={exports:{}};return t[r](i,i.exports,e),i.exports}return e.d=function(t,n){for(var r in n)e.o(n,r)&&!e.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:n[r]})},e.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(t){if("object"==typeof window)return window}}(),e.o=function(t,n){return Object.prototype.hasOwnProperty.call(t,n)},e.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},e(720)}()}));
},{}],3:[function(require,module,exports){
// Circle shaped progress bar
var Shape = require('./shape');
var utils = require('./utils');
var Circle = function Circle(container, options) {
// Use two arcs to form a circle
// See this answer http://stackoverflow.com/a/10477334/1446092
this._pathTemplate =
'M 50,50 m 0,-{radius}' +
' a {radius},{radius} 0 1 1 0,{2radius}' +
' a {radius},{radius} 0 1 1 0,-{2radius}';
this.containerAspectRatio = 1;
Shape.apply(this, arguments);
};
Circle.prototype = new Shape();
Circle.prototype.constructor = Circle;
Circle.prototype._pathString = function _pathString(opts) {
var widthOfWider = opts.strokeWidth;
if (opts.trailWidth && opts.trailWidth > opts.strokeWidth) {
widthOfWider = opts.trailWidth;
}
var r = 50 - widthOfWider / 2;
return utils.render(this._pathTemplate, {
radius: r,
'2radius': r * 2
});
};
Circle.prototype._trailString = function _trailString(opts) {
return this._pathString(opts);
};
module.exports = Circle;
},{"./shape":8,"./utils":10}],4:[function(require,module,exports){
// Line shaped progress bar
var Shape = require('./shape');
var utils = require('./utils');
var Line = function Line(container, options) {
this._pathTemplate = options.vertical
? 'M {center},100 L {center},0'
: 'M 0,{center} L 100,{center}';
Shape.apply(this, arguments);
};
Line.prototype = new Shape();
Line.prototype.constructor = Line;
Line.prototype._initializeSvg = function _initializeSvg(svg, opts) {
var viewBoxStr = opts.vertical
? '0 0 ' + opts.strokeWidth + ' 100'
: '0 0 100 ' + opts.strokeWidth;
svg.setAttribute('viewBox', viewBoxStr);
svg.setAttribute('preserveAspectRatio', 'none');
};
Line.prototype._pathString = function _pathString(opts) {
return utils.render(this._pathTemplate, {
center: opts.strokeWidth / 2
});
};
Line.prototype._trailString = function _trailString(opts) {
return this._pathString(opts);
};
module.exports = Line;
},{"./shape":8,"./utils":10}],5:[function(require,module,exports){
module.exports = {
// Higher level API, different shaped progress bars
Line: require('./line'),
Circle: require('./circle'),
SemiCircle: require('./semicircle'),
Square: require('./square'),
// Lower level API to use any SVG path
Path: require('./path'),
// Base-class for creating new custom shapes
// to be in line with the API of built-in shapes
// Undocumented.
Shape: require('./shape'),
// Internal utils, undocumented.
utils: require('./utils')
};
},{"./circle":3,"./line":4,"./path":6,"./semicircle":7,"./shape":8,"./square":9,"./utils":10}],6:[function(require,module,exports){
// Lower level API to animate any kind of svg path
var shifty = require('shifty');
var utils = require('./utils');
var Tweenable = shifty.Tweenable;
var EASING_ALIASES = {
easeIn: 'easeInCubic',
easeOut: 'easeOutCubic',
easeInOut: 'easeInOutCubic'
};
var Path = function Path(path, opts) {
// Throw a better error if not initialized with `new` keyword
if (!(this instanceof Path)) {
throw new Error('Constructor was called without new keyword');
}
// Default parameters for animation
opts = utils.extend({
delay: 0,
duration: 800,
easing: 'linear',
from: {},
to: {},
step: function() {}
}, opts);
var element;
if (utils.isString(path)) {
element = document.querySelector(path);
} else {
element = path;
}
// Reveal .path as public attribute
this.path = element;
this._opts = opts;
this._tweenable = null;
// Set up the starting positions
var length = this.path.getTotalLength();
this.path.style.strokeDasharray = length + ' ' + length;
this.set(0);
};
Path.prototype.value = function value() {
var offset = this._getComputedDashOffset();
var length = this.path.getTotalLength();
var progress = 1 - offset / length;
// Round number to prevent returning very small number like 1e-30, which
// is practically 0
return parseFloat(progress.toFixed(6), 10);
};
Path.prototype.set = function set(progress) {
this.stop();
this.path.style.strokeDashoffset = this._progressToOffset(progress);
var step = this._opts.step;
if (utils.isFunction(step)) {
var easing = this._easing(this._opts.easing);
var values = this._calculateTo(progress, easing);
var reference = this._opts.shape || this;
step(values, reference, this._opts.attachment);
}
};
Path.prototype.stop = function stop() {
this._stopTween();
this.path.style.strokeDashoffset = this._getComputedDashOffset();
};
// Method introduced here:
// http://jakearchibald.com/2013/animated-line-drawing-svg/
Path.prototype.animate = function animate(progress, opts, cb) {
opts = opts || {};
if (utils.isFunction(opts)) {
cb = opts;
opts = {};
}
var passedOpts = utils.extend({}, opts);
// Copy default opts to new object so defaults are not modified
var defaultOpts = utils.extend({}, this._opts);
opts = utils.extend(defaultOpts, opts);
var shiftyEasing = this._easing(opts.easing);
var values = this._resolveFromAndTo(progress, shiftyEasing, passedOpts);
this.stop();
// Trigger a layout so styles are calculated & the browser
// picks up the starting position before animating
this.path.getBoundingClientRect();
var offset = this._getComputedDashOffset();
var newOffset = this._progressToOffset(progress);
var self = this;
this._tweenable = new Tweenable();
this._tweenable.tween({
from: utils.extend({ offset: offset }, values.from),
to: utils.extend({ offset: newOffset }, values.to),
duration: opts.duration,
delay: opts.delay,
easing: shiftyEasing,
step: function(state) {
self.path.style.strokeDashoffset = state.offset;
var reference = opts.shape || self;
opts.step(state, reference, opts.attachment);
}
}).then(function(state) {
if (utils.isFunction(cb)) {
cb();
}
}).catch(function(err) {
console.error('Error in tweening:', err);
throw err;
});
};
Path.prototype._getComputedDashOffset = function _getComputedDashOffset() {
var computedStyle = window.getComputedStyle(this.path, null);
return parseFloat(computedStyle.getPropertyValue('stroke-dashoffset'), 10);
};
Path.prototype._progressToOffset = function _progressToOffset(progress) {
var length = this.path.getTotalLength();
return length - progress * length;
};
// Resolves from and to values for animation.
Path.prototype._resolveFromAndTo = function _resolveFromAndTo(progress, easing, opts) {
if (opts.from && opts.to) {
return {
from: opts.from,
to: opts.to
};
}
return {
from: this._calculateFrom(easing),
to: this._calculateTo(progress, easing)
};
};
// Calculate `from` values from options passed at initialization
Path.prototype._calculateFrom = function _calculateFrom(easing) {
return shifty.interpolate(this._opts.from, this._opts.to, this.value(), easing);
};
// Calculate `to` values from options passed at initialization
Path.prototype._calculateTo = function _calculateTo(progress, easing) {
return shifty.interpolate(this._opts.from, this._opts.to, progress, easing);
};
Path.prototype._stopTween = function _stopTween() {
if (this._tweenable !== null) {
this._tweenable.stop(true);
this._tweenable = null;
}
};
Path.prototype._easing = function _easing(easing) {
if (EASING_ALIASES.hasOwnProperty(easing)) {
return EASING_ALIASES[easing];
}
return easing;
};
module.exports = Path;
},{"./utils":10,"shifty":2}],7:[function(require,module,exports){
// Semi-SemiCircle shaped progress bar
var Shape = require('./shape');
var Circle = require('./circle');
var utils = require('./utils');
var SemiCircle = function SemiCircle(container, options) {
// Use one arc to form a SemiCircle
// See this answer http://stackoverflow.com/a/10477334/1446092
this._pathTemplate =
'M 50,50 m -{radius},0' +
' a {radius},{radius} 0 1 1 {2radius},0';
this.containerAspectRatio = 2;
Shape.apply(this, arguments);
};
SemiCircle.prototype = new Shape();
SemiCircle.prototype.constructor = SemiCircle;
SemiCircle.prototype._initializeSvg = function _initializeSvg(svg, opts) {
svg.setAttribute('viewBox', '0 0 100 50');
};
SemiCircle.prototype._initializeTextContainer = function _initializeTextContainer(
opts,
container,
textContainer
) {
if (opts.text.style) {
// Reset top style
textContainer.style.top = 'auto';
textContainer.style.bottom = '0';
if (opts.text.alignToBottom) {
utils.setStyle(textContainer, 'transform', 'translate(-50%, 0)');
} else {
utils.setStyle(textContainer, 'transform', 'translate(-50%, 50%)');
}
}
};
// Share functionality with Circle, just have different path
SemiCircle.prototype._pathString = Circle.prototype._pathString;
SemiCircle.prototype._trailString = Circle.prototype._trailString;
module.exports = SemiCircle;
},{"./circle":3,"./shape":8,"./utils":10}],8:[function(require,module,exports){
// Base object for different progress bar shapes
var Path = require('./path');
var utils = require('./utils');
var DESTROYED_ERROR = 'Object is destroyed';
var Shape = function Shape(container, opts) {
// Throw a better error if progress bars are not initialized with `new`
// keyword
if (!(this instanceof Shape)) {
throw new Error('Constructor was called without new keyword');
}
// Prevent calling constructor without parameters so inheritance
// works correctly. To understand, this is how Shape is inherited:
//
// Line.prototype = new Shape();
//
// We just want to set the prototype for Line.
if (arguments.length === 0) {
return;
}
// Default parameters for progress bar creation
this._opts = utils.extend({
color: '#555',
strokeWidth: 1.0,
trailColor: null,
trailWidth: null,
fill: null,
text: {
style: {
color: null,
position: 'absolute',
left: '50%',
top: '50%',
padding: 0,
margin: 0,
transform: {
prefix: true,
value: 'translate(-50%, -50%)'
}
},
autoStyleContainer: true,
alignToBottom: true,
value: null,
className: 'progressbar-text'
},
svgStyle: {
display: 'block',
width: '100%'
},
warnings: false
}, opts, true); // Use recursive extend
// If user specifies e.g. svgStyle or text style, the whole object
// should replace the defaults to make working with styles easier
if (utils.isObject(opts) && opts.svgStyle !== undefined) {
this._opts.svgStyle = opts.svgStyle;
}
if (utils.isObject(opts) && utils.isObject(opts.text) && opts.text.style !== undefined) {
this._opts.text.style = opts.text.style;
}
var svgView = this._createSvgView(this._opts);
var element;
if (utils.isString(container)) {
element = document.querySelector(container);
} else {
element = container;
}
if (!element) {
throw new Error('Container does not exist: ' + container);
}
this._container = element;
this._container.appendChild(svgView.svg);
if (this._opts.warnings) {
this._warnContainerAspectRatio(this._container);
}
if (this._opts.svgStyle) {
utils.setStyles(svgView.svg, this._opts.svgStyle);
}
// Expose public attributes before Path initialization
this.svg = svgView.svg;
this.path = svgView.path;
this.trail = svgView.trail;
this.text = null;
var newOpts = utils.extend({
attachment: undefined,
shape: this
}, this._opts);
this._progressPath = new Path(svgView.path, newOpts);
if (utils.isObject(this._opts.text) && this._opts.text.value !== null) {
this.setText(this._opts.text.value);
}
};
Shape.prototype.animate = function animate(progress, opts, cb) {
if (this._progressPath === null) {
throw new Error(DESTROYED_ERROR);
}
this._progressPath.animate(progress, opts, cb);
};
Shape.prototype.stop = function stop() {
if (this._progressPath === null) {
throw new Error(DESTROYED_ERROR);
}
// Don't crash if stop is called inside step function
if (this._progressPath === undefined) {
return;
}
this._progressPath.stop();
};
Shape.prototype.pause = function pause() {
if (this._progressPath === null) {
throw new Error(DESTROYED_ERROR);
}
if (this._progressPath === undefined) {
return;
}
if (!this._progressPath._tweenable) {
// It seems that we can't pause this
return;
}
this._progressPath._tweenable.pause();
};
Shape.prototype.resume = function resume() {
if (this._progressPath === null) {
throw new Error(DESTROYED_ERROR);
}
if (this._progressPath === undefined) {
return;
}
if (!this._progressPath._tweenable) {
// It seems that we can't resume this
return;
}
this._progressPath._tweenable.resume();
};
Shape.prototype.destroy = function destroy() {
if (this._progressPath === null) {
throw new Error(DESTROYED_ERROR);
}
this.stop();
this.svg.parentNode.removeChild(this.svg);
this.svg = null;
this.path = null;
this.trail = null;
this._progressPath = null;
if (this.text !== null) {
this.text.parentNode.removeChild(this.text);
this.text = null;
}
};
Shape.prototype.set = function set(progress) {
if (this._progressPath === null) {
throw new Error(DESTROYED_ERROR);
}
this._progressPath.set(progress);
};
Shape.prototype.value = function value() {
if (this._progressPath === null) {
throw new Error(DESTROYED_ERROR);
}
if (this._progressPath === undefined) {
return 0;
}
return this._progressPath.value();
};
Shape.prototype.setText = function setText(newText) {
if (this._progressPath === null) {
throw new Error(DESTROYED_ERROR);
}
if (this.text === null) {
// Create new text node
this.text = this._createTextContainer(this._opts, this._container);
this._container.appendChild(this.text);
}
// Remove previous text and add new
if (utils.isObject(newText)) {
utils.removeChildren(this.text);
this.text.appendChild(newText);
} else {
this.text.innerHTML = newText;
}
};
Shape.prototype._createSvgView = function _createSvgView(opts) {
var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
this._initializeSvg(svg, opts);
var trailPath = null;
// Each option listed in the if condition are 'triggers' for creating
// the trail path
if (opts.trailColor || opts.trailWidth) {
trailPath = this._createTrail(opts);
svg.appendChild(trailPath);
}
var path = this._createPath(opts);
svg.appendChild(path);
return {
svg: svg,
path: path,
trail: trailPath
};
};
Shape.prototype._initializeSvg = function _initializeSvg(svg, opts) {
svg.setAttribute('viewBox', '0 0 100 100');
};
Shape.prototype._createPath = function _createPath(opts) {
var pathString = this._pathString(opts);
return this._createPathElement(pathString, opts);
};
Shape.prototype._createTrail = function _createTrail(opts) {
// Create path string with original passed options
var pathString = this._trailString(opts);
// Prevent modifying original
var newOpts = utils.extend({}, opts);
// Defaults for parameters which modify trail path
if (!newOpts.trailColor) {
newOpts.trailColor = '#eee';
}
if (!newOpts.trailWidth) {
newOpts.trailWidth = newOpts.strokeWidth;
}
newOpts.color = newOpts.trailColor;
newOpts.strokeWidth = newOpts.trailWidth;
// When trail path is set, fill must be set for it instead of the
// actual path to prevent trail stroke from clipping
newOpts.fill = null;
return this._createPathElement(pathString, newOpts);
};
Shape.prototype._createPathElement = function _createPathElement(pathString, opts) {
var path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
path.setAttribute('d', pathString);
path.setAttribute('stroke', opts.color);
path.setAttribute('stroke-width', opts.strokeWidth);
if (opts.fill) {
path.setAttribute('fill', opts.fill);
} else {
path.setAttribute('fill-opacity', '0');
}
return path;
};
Shape.prototype._createTextContainer = function _createTextContainer(opts, container) {
var textContainer = document.createElement('div');
textContainer.className = opts.text.className;
var textStyle = opts.text.style;
if (textStyle) {
if (opts.text.autoStyleContainer) {
container.style.position = 'relative';
}
utils.setStyles(textContainer, textStyle);
// Default text color to progress bar's color
if (!textStyle.color) {
textContainer.style.color = opts.color;
}
}
this._initializeTextContainer(opts, container, textContainer);
return textContainer;
};
// Give custom shapes possibility to modify text element
Shape.prototype._initializeTextContainer = function(opts, container, element) {
// By default, no-op
// Custom shapes should respect API options, such as text.style
};
Shape.prototype._pathString = function _pathString(opts) {
throw new Error('Override this function for each progress bar');
};
Shape.prototype._trailString = function _trailString(opts) {
throw new Error('Override this function for each progress bar');
};
Shape.prototype._warnContainerAspectRatio = function _warnContainerAspectRatio(container) {
if (!this.containerAspectRatio) {
return;
}
var computedStyle = window.getComputedStyle(container, null);
var width = parseFloat(computedStyle.getPropertyValue('width'), 10);
var height = parseFloat(computedStyle.getPropertyValue('height'), 10);
if (!utils.floatEquals(this.containerAspectRatio, width / height)) {
console.warn(
'Incorrect aspect ratio of container',
'#' + container.id,
'detected:',
computedStyle.getPropertyValue('width') + '(width)',
'/',
computedStyle.getPropertyValue('height') + '(height)',
'=',
width / height
);
console.warn(
'Aspect ratio of should be',
this.containerAspectRatio
);
}
};
module.exports = Shape;
},{"./path":6,"./utils":10}],9:[function(require,module,exports){
// Square shaped progress bar
// Note: Square is not core part of API anymore. It's left here
// for reference. square is not included to the progressbar
// build anymore
var Shape = require('./shape');
var utils = require('./utils');
var Square = function Square(container, options) {
this._pathTemplate =
'M 0,{halfOfStrokeWidth}' +
' L {width},{halfOfStrokeWidth}' +
' L {width},{width}' +
' L {halfOfStrokeWidth},{width}' +
' L {halfOfStrokeWidth},{strokeWidth}';
this._trailTemplate =
'M {startMargin},{halfOfStrokeWidth}' +
' L {width},{halfOfStrokeWidth}' +
' L {width},{width}' +
' L {halfOfStrokeWidth},{width}' +
' L {halfOfStrokeWidth},{halfOfStrokeWidth}';
Shape.apply(this, arguments);
};
Square.prototype = new Shape();
Square.prototype.constructor = Square;
Square.prototype._pathString = function _pathString(opts) {
var w = 100 - opts.strokeWidth / 2;
return utils.render(this._pathTemplate, {
width: w,
strokeWidth: opts.strokeWidth,
halfOfStrokeWidth: opts.strokeWidth / 2
});
};
Square.prototype._trailString = function _trailString(opts) {
var w = 100 - opts.strokeWidth / 2;
return utils.render(this._trailTemplate, {
width: w,
strokeWidth: opts.strokeWidth,
halfOfStrokeWidth: opts.strokeWidth / 2,
startMargin: opts.strokeWidth / 2 - opts.trailWidth / 2
});
};
module.exports = Square;
},{"./shape":8,"./utils":10}],10:[function(require,module,exports){
// Utility functions
var merge = require('lodash.merge');
var PREFIXES = 'Webkit Moz O ms'.split(' ');
var FLOAT_COMPARISON_EPSILON = 0.001;
// Renders templates with given variables. Variables must be surrounded with
// braces without any spaces, e.g. {variable}
// All instances of variable placeholders will be replaced with given content
// Example:
// render('Hello, {message}!', {message: 'world'})
function render(template, vars) {
var rendered = template;
for (var key in vars) {
if (vars.hasOwnProperty(key)) {
var val = vars[key];
var regExpString = '\\{' + key + '\\}';
var regExp = new RegExp(regExpString, 'g');
rendered = rendered.replace(regExp, val);
}
}
return rendered;
}
function setStyle(element, style, value) {
var elStyle = element.style; // cache for performance
for (var i = 0; i < PREFIXES.length; ++i) {
var prefix = PREFIXES[i];
elStyle[prefix + capitalize(style)] = value;
}
elStyle[style] = value;
}
function setStyles(element, styles) {
forEachObject(styles, function(styleValue, styleName) {
// Allow disabling some individual styles by setting them
// to null or undefined
if (styleValue === null || styleValue === undefined) {
return;
}
// If style's value is {prefix: true, value: '50%'},
// Set also browser prefixed styles
if (isObject(styleValue) && styleValue.prefix === true) {
setStyle(element, styleName, styleValue.value);
} else {
element.style[styleName] = styleValue;
}
});
}
function capitalize(text) {
return text.charAt(0).toUpperCase() + text.slice(1);
}
function isString(obj) {
return typeof obj === 'string' || obj instanceof String;
}
function isFunction(obj) {
return typeof obj === 'function';
}
function isArray(obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
}
// Returns true if `obj` is object as in {a: 1, b: 2}, not if it's function or
// array
function isObject(obj) {
if (isArray(obj)) {
return false;
}
var type = typeof obj;
return type === 'object' && !!obj;
}
function forEachObject(object, callback) {
for (var key in object) {
if (object.hasOwnProperty(key)) {
var val = object[key];
callback(val, key);
}
}
}
function floatEquals(a, b) {
return Math.abs(a - b) < FLOAT_COMPARISON_EPSILON;
}
// https://coderwall.com/p/nygghw/don-t-use-innerhtml-to-empty-dom-elements
function removeChildren(el) {
while (el.firstChild) {
el.removeChild(el.firstChild);
}
}
module.exports = {
extend: merge,
render: render,
setStyle: setStyle,
setStyles: setStyles,
capitalize: capitalize,
isString: isString,
isFunction: isFunction,
isObject: isObject,
forEachObject: forEachObject,
floatEquals: floatEquals,
removeChildren: removeChildren
};
},{"lodash.merge":1}]},{},[5])(5)
});
================================================
FILE: docs/api/general.md
================================================
Functions use node-style callback convention. Callback function is always the last given parameter.
Shapes have different SVG canvas sizes:
Shape | Canvas size
-----------|------------------------
Circle | `100x100`
SemiCircle | `100x50`
Line | `100x{opts.strokeWidth}`
All shapes are fitted exactly to their canvases.
**Important:** make sure that your container has same aspect ratio
as the SVG canvas. For example: if you are using SemiCircle,
set e.g.
```css
#container {
width: 300px;
height: 150px;
}
```
## HTML structure
As an example, we'll use these options:
```js
var circle = new ProgressBar.Circle('#example-percent-container', {
color: '#FCB03C',
strokeWidth: 3,
trailWidth: 1,
text: {
value: '0'
}
});
```
They would produce the following HTML.
```html
<!-- If text is set, position: relative will be applied for the container -->
<div id="container" style="position: relative;">
<!-- The actual progress bar SVG -->
<svg viewBox="0 0 100 100">
<!-- Trail path -->
<path d="M 50,50 m 0,-48.5 a 48.5,48.5 0 1 1 0,97 a 48.5,48.5 0 1 1 0,-97" stroke="#eee" stroke-width="1" fill-opacity="0"></path>
<!-- Actual progress bar path -->
<path d="M 50,50 m 0,-48.5 a 48.5,48.5 0 1 1 0,97 a 48.5,48.5 0 1 1 0,-97" stroke="#FCB03C" stroke-width="3" fill-opacity="0" style="stroke-dasharray: 304.844360351563px, 304.844360351563px; stroke-dashoffset: 304.844360351563px;"></path>
</svg>
<!-- Text element created when text option is set -->
<p class="progressbar-text" style="position: absolute; top: 50%; left: 50%; padding: 0px; margin: 0px; -webkit-transform: translate(-50%, -50%); transform: translate(-50%, -50%); color: rgb(252, 176, 60);">0</p>
</div>
```
================================================
FILE: docs/api/parameters.md
================================================
# Easing
Easing functions [provided with *shifty* are supported](https://github.com/jeremyckahn/shifty/blob/master/src/shifty.formulas.js).
A few basic easing options:
* `'linear'`
* `'easeIn'`
* `'easeOut'`
* `'easeInOut'`
You can also provide an custom easing function.
# {custom-animations} Custom animations
See [example in demo page](https://kimmobrunfeldt.github.io/progressbar.js#example-custom-animation).
Customizing animations is possible with the help of `from`, `to` and `step` parameters.
Tweening engine changes defined values over time and calls step function for each animation's frame.
!!! note
There's a big difference between passing the `from` and `to` parameters in initialization
of progress bar compared to passing in `.animate()` call. Here's example code and illustrations to explain the difference:
**Pass in initialization**
```javascript
var bar = new ProgressBar.Line('#container', {
from: { color: '#000 '},
to: { color: '#888 '},
step: function(state, bar, attachment) {
bar.path.setAttribute('stroke', state.color);
}
});
```

**Pass in `.animate()` call**
```javascript
var bar = new ProgressBar.Line('#container', {
step: function(state, bar, attachment) {
bar.path.setAttribute('stroke', state.color);
}
});
var opts = {
from: { color: '#000 '},
to: { color: '#888'}
};
bar.animate(0.5, opts);
```

## `from` parameter
Object containing values which should be tweened.
These values represent the starting values of the animation. Default: `{}`.
For example
```javascript
{
// Start from thin gray line
width: 0.1,
color: '#eee'
}
```
Thanks to shifty, you can tween values in formats like `translateX(45px)`, `rgb(0,255,0)` and `#fff`.
See all supported string formats from [shifty's documentation](http://jeremyckahn.github.io/shifty/dist/doc/modules/Tweenable.token.html)
Easing defined as option for animation applies to all of the specified values.
## `to` parameter
Object containing values which should be tweened. These represent the final values after animation is done. Default: `{}`.
For example
```javascript
{
// Finish to thick black line
width: 1,
color: '#000'
}
```
*Signature must match `from`*
## `step` parameter
Function called for each animation step. Tweened values, a reference to the path or shape, and an attachment are passed as parameters. Attachment can be reference to any object you need to modify within step function. Default: `function() {}`.
!!! warning
This function is called multiple times per second.
To make sure animations run smoothly, keep it minimal.
For example
```javascript
function(state, shape, attachment) {
shape.path.setAttribute('stroke-width', state.width);
shape.path.setAttribute('stroke', state.color);
attachment.text.innerHTML = shape.value() * 100;
}
```
================================================
FILE: docs/api/path.md
================================================
# new Path(path, [*options*])
Custom shaped progress bar. You can create arbitrary shaped progress bars by
passing a SVG path created with e.g. Adobe Illustrator. It's on caller's responsibility to append SVG to DOM.
!!! note
Remember to add e.g. `stroke="1"` and `fill-opacity="0"` attributes for the SVG path.
They will reveal the true shape of the path.
**Example**
Assuming there was SVG object with heart shaped path in HTML
```html
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" x="0px" y="0px" viewBox="0 0 100 100">
<path fill-opacity="0" stroke-width="0.5" stroke="#f4f4f4" d="M81.495,13.923c-11.368-5.261-26.234-0.311-31.489,11.032C44.74,13.612,29.879,8.657,18.511,13.923 C6.402,19.539,0.613,33.883,10.175,50.804c6.792,12.04,18.826,21.111,39.831,37.379c20.993-16.268,33.033-25.344,39.819-37.379 C99.387,33.883,93.598,19.539,81.495,13.923z"/>
<path id="heart-path" fill-opacity="0" stroke-width="0.6" stroke="#555" d="M81.495,13.923c-11.368-5.261-26.234-0.311-31.489,11.032C44.74,13.612,29.879,8.657,18.511,13.923 C6.402,19.539,0.613,33.883,10.175,50.804c6.792,12.04,18.826,21.111,39.831,37.379c20.993-16.268,33.033-25.344,39.819-37.379 C99.387,33.883,93.598,19.539,81.495,13.923z"/>
</svg>
```
Initialization would be this easy
```javascript
var svgPath = document.getElementById('heart-path');
var path = new ProgressBar.Path(svgPath, {
duration: 300
});
```
**Working with embedded SVG**
If the SVG was not inline in the HTML but instead in, say,
an `<object>` tag, we'd have to take extra steps to wait until it has loaded
and then access it differently since it's in a separate DOM tree.
Given e.g.:
```html
<object id="heart" type="image/svg+xml" data="heart.svg">No SVG support :(</object>
```
we could do
```javascript
var heart = document.getElementById('heart');
heart.addEventListener('load', function() {
var path = new ProgressBar.Path(heartObject.contentDocument.querySelector('#heart-path'), {
duration: 300
});
```
**Parameters**
* `path` [SVG Path](https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths) object or plain selector string. For example `$('svg > path:first-child')[0]`.
* `options` Animation options.
```javascript
{
// Duration for animation in milliseconds
// Default: 800
duration: 1200,
// Delay for animation in milliseconds
// Default: 0
delay: 100,
// Easing for animation. See #easing section.
// Default: 'linear'
easing: 'easeIn',
// Attachment which can be any object
// you need to modify within the step function.
// Passed as a parameter to step function.
// Default: undefined
attachment: document.querySelector('#container > svg'),
// See #custom-animations section
from: { color: '#eee' },
to: { color: '#000' },
step: function(state, path, attachment) {
// Do any modifications to attachment and/or path attributes
}
}
```
## .path
Reference to [SVG path](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/path) which presents the actual progress bar.
## .animate(progress, [*options*], [*cb*])
Animates drawing of path.
**Example**
```javascript
path.animate(0.3, {
duration: 800
}, function() {
console.log('Animation has finished');
});
```
**Parameters**
* `progress` progress from 0 to 1.
* `options` Animation options. These options override the defaults given in initialization.
```javascript
{
// Duration for animation in milliseconds
// Default: 800
duration: 1200,
// Delay for animation in milliseconds
// Default: 0
delay: 100,
// Easing for animation. See #easing section.
// Default: 'linear'
easing: 'easeOut',
// Attachment which can be any object
// you need to modify within the step function.
// Passed as a parameter to step function.
// Default: undefined
attachment: document.querySelector('#container > svg'),
// See #custom-animations section
from: { color: '#eee' },
to: { color: '#000' },
step: function(state, path, attachment) {
// Do any modifications to attachment and/or path attributes
}
}
```
* `cb` Callback function which is called after transition ends.
## .pause()
Suspends animation at its current position.
## .resume()
Resumes animation from a previously paused position.
## .set(progress)
Set progress instantly without animation. Clears all transitions
for path.
## .stop()
Stops animation to its current position.
## .value()
Returns current shown progress from 0 to 1. This value changes when animation is running.
================================================
FILE: docs/api/shape.md
================================================
!!! note
Line, Circle and SemiCircle all point to the same
documentation which is named Shape. You should
replace it(Shape) with Line, Circle or SemiCircle.
**Example:** if documentation states `Shape.animate()`, replace it with
`Circle.animate()`, simple. Shape is the base object for all
progress bars.
# new Shape(container, [*options*])
Line, Circle or SemiCircle shaped progress bar. Appends SVG to container.
**Example**
```javascript
var progressBar = new ProgressBar.Circle('#container', {
strokeWidth: 2
});
```
With Line shape, you can control the width of the line by specifying e.g. `height: 5px`
with CSS.
**Parameters**
* `container` Element where SVG is added. Query string or element.
For example `'#container'` or `document.getElementById('#container')`
* `options` Options for path drawing.
```js
{
// Stroke color.
// Default: '#555'
color: '#3a3a3a',
// Width of the stroke.
// Unit is percentage of SVG canvas' size.
// Default: 1.0
// NOTE: In Line shape, you should control
// the stroke width by setting container's height.
// WARNING: IE doesn't support values over 6, see this bug:
// https://github.com/kimmobrunfeldt/progressbar.js/issues/79
strokeWidth: 2.1,
// If trail options are not defined, trail won't be drawn
// Color for lighter trail stroke
// underneath the actual progress path.
// Default: '#eee'
trailColor: '#f4f4f4',
// Width of the trail stroke. Trail is always centered relative to
// actual progress path.
// Default: same as strokeWidth
trailWidth: 0.8,
// Inline CSS styles for the created SVG element
// Set null to disable all default styles.
// You can disable individual defaults by setting them to `null`
// If you specify anything in this object, none of the default styles
// apply
svgStyle: {
display: 'block',
// Important: make sure that your container has same
// aspect ratio as the SVG canvas. See SVG canvas sizes above.
width: '100%'
},
// Text options. Text element is a <p> element appended to container
// You can add CSS rules for the text element with the className
// NOTE: When text is set, 'position: relative' will be set to the
// container for centering. You can also prevent all default inline
// styles with 'text.style: null'
// Default: null
text: {
// Initial value for text.
// Default: null
value: 'Text',
// Class name for text element.
// Default: 'progressbar-text'
className: 'progressbar__label',
// Inline CSS styles for the text element.
// If you want to modify all CSS your self, set null to disable
// all default styles.
// If the style option contains values, container is automatically
// set to position: relative. You can disable behavior this with
// autoStyleContainer: false
// If you specify anything in this object, none of the default styles
// apply
// Default: object speficied below
style: {
// Text color.
// Default: same as stroke color (options.color)
color: '#f00',
position: 'absolute',
left: '50%',
top: '50%',
padding: 0,
margin: 0,
// You can specify styles which will be browser prefixed
transform: {
prefix: true,
value: 'translate(-50%, -50%)'
}
},
// Only effective if the text.style is not null
// By default position: relative is applied to container if text
// is set. Setting this to false disables that feature.
autoStyleContainer: true,
// Only effective if the shape is SemiCircle.
// If true, baseline for text is aligned with bottom of
// the SVG canvas. If false, bottom line of SVG canvas
// is in the center of text.
// Default: true
alignToBottom: true
},
// Fill color for the shape. If null, no fill.
// Default: null
fill: 'rgba(0, 0, 0, 0.5)',
// Duration for animation in milliseconds
// Default: 800
duration: 1200,
// Delay for animation in milliseconds
// Default: 0
delay: 100,
// Easing for animation. See #easing section.
// Default: 'linear'
easing: 'easeOut',
// See #custom-animations section
// Built-in shape passes reference to itself and a custom attachment
// object to step function
from: { color: '#eee' },
to: { color: '#000' },
step: function(state, circle, attachment) {
circle.path.setAttribute('stroke', state.color);
},
// If true, some useful console.warn calls will be done if it seems
// that progressbar is used incorrectly
// Default: false
warnings: false
}
```
## .svg
Reference to [SVG](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/svg) element where progress bar is drawn.
## .path
Reference to [SVG path](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/path) which presents the actual progress bar.
## .trail
Reference to [SVG path](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/path) which presents the trail of the progress bar.
Returns `null` if trail is not defined.
## {text} .text
Reference to [p element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/p) which presents the text label for progress bar.
Returns `null` if text is not defined.
## .animate(progress, [*options*], [*cb*])
Animates drawing of a shape.
**Example**
```javascript
progressBar.animate(0.3, {
duration: 800
}, function() {
console.log('Animation has finished');
});
```
**Parameters**
* `progress` progress from 0 to 1.
* `options` Animation options. These options override the defaults given in initialization.
```javascript
{
// Duration for animation in milliseconds
// Default: 800
duration: 1200,
// Delay for animation in milliseconds
// Default: 0
delay: 100,
// Easing for animation. See #easing section.
// Default: 'linear'
easing: 'easeInOut',
// See #custom-animations section
// Built-in shape passes reference to itself and a custom attachment
// object to step function
from: { color: '#eee' },
to: { color: '#000' },
step: function(state, circle, attachment) {
circle.path.setAttribute('stroke', state.color);
}
}
```
* `cb` Callback function which is called after animation ends.
## .set(progress)
Sets progress instantly without animation. Clears all animations
for path.
## .stop()
Stops animation to its current position.
## .value()
Returns current shown progress from 0 to 1. This value changes when animation is running.
## .setText(text)
Sets text to given a string. If you need to dynamically modify the text element,
see [.text](#text) attribute.
## .destroy()
Removes SVG element from container and removes all references to DOM elements. Destroying is irreversible.
================================================
FILE: docs/contributing.md
================================================
# Contribution documentation
Pull requests and contributions are warmly welcome.
Please follow existing code style and commit message conventions. Also remember to keep documentation
updated.
**Pull requests:** You don't need to bump version numbers or modify anything related to releasing. That stuff is fully automated, just write the functionality.
## Get started with documentation
Documentation is written in markdown and [mkdocs](https://github.com/mkdocs/mkdocs) is used
to build documentation site. [ReadTheDocs](https://readthedocs.org/projects/progressbarjs/)
provides hosting for the documentation site and builds the documentation on each
commit.
To locally develop documentation, you need to install mkdocs and requirements specified
in pip-requirements.txt. After that you can run `mkdocs serve`.
## Get started with development
* [Install local environment](#install-environment).
* `cd local-dev` and serve folder to browser
* Open another terminal to project root and run `grunt watch`.
Then you can edit `src/progressbar.js` and changes can be tested in browser.
Edit `local-dev/main.js` to your testing needs.
Shorter way to do local development is running: ```npm run dev```.
## General project stuff
This package uses npm/node tools just in the developer environment. Grunt is used as a task runner
but there's no reason it couldn't be replaced with e.g. Makefile
*ProgressBar.js* depends on tweening library called [shifty](https://github.com/jeremyckahn/shifty).
*Shifty* is bundled inside the scripts in [dist/](https://github.com/kimmobrunfeldt/progressbar.js/blob/master/dist) directory.
Dependency is bundled in to ease using the library.
#### Versioning
Versioning follows [Semantic Versioning 2.0.0](http://semver.org/). The release script makes sure
that for each release, there exists only one commit in history where version number in *bower.json*
matches the release's version. That commit is tagged as the release, for example `0.4.1`. Commits after that have -dev suffix(*0.4.1-dev*) in the version number to avoid any possible confusion.
In other words, if you look into *bower.json*, you can tell if the code base is a released version or not.
## {install-environment} Install environment
Install tools needed for development:
npm install
npm install -g watchify
npm install -g browserify
For testing:
npm install -g mocha
npm install -g testem
## Test
Tests are written with [Mocha](http://mochajs.org/) + [expect.js](https://github.com/LearnBoost/expect.js/).
Sometimes the tests fail even though they actually work on the browser. That might be cause of setTimeouts used
in tests.
Quickly run tests:
grunt test
This will use testem to run tests with Chrome. Other options specified below.
#### Testem
[Testem](https://github.com/airportyh/testem) is used for running tests locally. It is fast and easy to use.
List of example commands:
* `testem` Serves testing page so that you can connect any browser to it.
* `testem ci` Runs tests an all available/detected local browsers.
* `testem ci -R dot -l chrome` Runs tests with Chrome using dot reported.
#### Karma
[Karma](http://karma-runner.github.io/) is used for running tests to be executed in Sauce Labs.
Karma was used because integrating it to Sauce Labs is easier than with Testem.
You must setup `SAUCE_USERNAME` and `SAUCE_ACCESS_KEY` environment variables.
See [karma-sauce-launcher project documentation](https://github.com/karma-runner/karma-sauce-launcher#username). Browsers used to test are specified in [karma.conf.js](karma.conf.js).
You can run tests with all browsers:
grunt karma
Tests are run sequentially in batches of browsers to prevent timeouts in Sauce Labs.
You can also run single set of browsers to see test results faster:
grunt karma:sauce0
## Release
**Before releasing, make sure there are no uncommitted files,
tests pass and jshint gives no errors.**
Creating a new release of the package is simple:
1. Commit and push all changes
2. Run local tests and linters with `npm test`
3. Make sure Sauce Labs tests pass
4. Run `grunt release`, which will create new tag and publish code to GitHub
Bower detects your new version of git tag.
5. Edit GitHub release notes
By default, patch release is done. You can specify the version bump as a parameter:
grunt release:major
Valid version bump values: `major`, `minor`, `patch`.
## Decision log
* Animate SVG paths with CSS3 transitions to make animations smooth.
* API must provide built-in shapes and a way to use totally custom SVG.
* Document manually. More overhead and risk of out dated information but easier to get started and contribute with pull requests.
* Animate paths with JS because IE does not support CSS transitions for SVG properties. This also allows
animation customizations and possible even using different easings per animation(in future).
* Expose ProgressBar so it can be used with basic module loaders or as a global.
* Bundle shifty inside the final distributable instead of requiring users to install both libs. If someone has already included shifty, then a custom build should be made.
* Ship distributables to Bower. Fully automate releasing.
* Ship distributables also to NPM to ease life of Browserify users.
* Delegate shifty dependency handling to NPM instead of keeping it in repository but still bundle it inside the final distributable.
* Automate tests so that testing is locally fast and CI runs tests with more browsers in Sauce Labs
* Because of introducing text attribute, the library must modify CSS also. Provide user an option to make CSS them selves.
* Keep **master** branch as a release branch so that new users can see the documentation for latest release instead of development version.
* Add some tasks to package.json aside with grunt tasks. I would want to move from Grunt to npm scripts totally but Sauce Labs tests are run with grunt.
================================================
FILE: docs/index.md
================================================
# Get started
*ProgressBar.js* is lightweight, MIT licensed and supports all major browsers including **IE11+** when using a polyfill.
See complete examples in [full examples](#full-examples) section.
### IE 11 compatibility
You can include ES6 polyfills by adding to your index.html:
```
<script crossorigin="anonymous" src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
```
See https://github.com/jeremyckahn/shifty#ie-compatibility and https://polyfill.io/v3/url-builder/.
#### {install} Installing
* Using bower `bower install progressbar.js`
* Using npm `npm install progressbar.js`
* Including [*dist/progressbar.js*](https://github.com/kimmobrunfeldt/progressbar.js/blob/master/dist/progressbar.js) or [dist/progressbar.min.js](https://github.com/kimmobrunfeldt/progressbar.js/blob/master/dist/progressbar.min.js) from latest tag to your project.
#### Loading module
CommonJS
```javascript
const ProgressBar = require('progressbar.js')
const line = new ProgressBar.Line('#container');
```
AMD
```javascript
require.config({
paths: {'progressbar': '../bower_components/progressbar.js/dist/progressbar'}
});
define(['progressbar'], function(ProgressBar) {
var line = new ProgressBar.Line('#container');
});
```
Global variable
```javascript
// If you aren't using any module loader, progressbar.js exposes
// global variable: window.ProgressBar
var line = new ProgressBar.Line('#container');
```
Files in `dist/` folder are UMD modules built with Browserify's `--standalone` switch. Read more about [standalone Browserify builds](http://www.forbeslindesay.co.uk/post/46324645400/standalone-browserify-builds).
# How it works
Progress bars are just regular SVG paths.
Read [Jake Archibald's blog post](http://jakearchibald.com/2013/animated-line-drawing-svg/) to see how the path drawing works under the hood.
*ProgressBar.js* uses [shifty](https://jeremyckahn.github.io/shifty/) tweening library to animate path drawing.
So in other words, animation is done with JavaScript using [requestAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/window.requestAnimationFrame).
Animating with JS gives more control over the animation and is supported across major browsers. For example IE [does not support](https://connect.microsoft.com/IE/feedbackdetail/view/920928/ie-11-css-transition-property-not-working-for-svg-elements)
animating SVG properties with CSS transitions.
## {migrations} Migration guide
To upgrade from version x to y:
* Go to [releases page](https://github.com/kimmobrunfeldt/progressbar.js/releases)
* Find the version x you are using
* Browse through release notes from x to y. API breaking releases are marked with `#breaking`.
* Fix your current code to use new API
*If you find this very tedious, please open a new issue.*
## {full-examples} Full examples
* [**Minimal**](http://kimmobrunfeldt.github.io/progressbar.js/examples/minimal/) [*see code*](https://github.com/kimmobrunfeldt/progressbar.js/tree/gh-pages/examples/minimal)
* [**File upload**](http://kimmobrunfeldt.github.io/progressbar.js/examples/upload/) [*see code*](https://github.com/kimmobrunfeldt/progressbar.js/tree/gh-pages/examples/upload)
* [**Telegram**](http://kimmobrunfeldt.github.io/progressbar.js/examples/telegram/) [*see code*](https://github.com/kimmobrunfeldt/progressbar.js/tree/gh-pages/examples/telegram)
* [**Password strength**](http://kimmobrunfeldt.github.io/progressbar.js/examples/password-strength/) [*see code*](https://github.com/kimmobrunfeldt/progressbar.js/tree/gh-pages/examples/password-strength)
# Contributing
See [documentation for contributors](contributing/).
================================================
FILE: docs/pip-requirements.txt
================================================
backports-abc==0.4
backports.ssl-match-hostname==3.5.0.1
certifi==2015.11.20.1
click==6.2
Jinja2==2.8
livereload==2.4.1
Markdown==2.6.5
MarkupSafe==0.23
mdx-sections==0.1
mkdocs==0.15.3
mkdocs-bootstrap==0.1.1
mkdocs-bootswatch==0.2.0
pymdown-extensions==1.0.1
PyYAML==3.11
singledispatch==3.4.0.3
six==1.10.0
tornado==4.3
wheel==0.24.0
================================================
FILE: karma.conf.js
================================================
var customLaunchers = require('./saucelabs-browsers');
module.exports = function(config) {
config.set({
frameworks: ['polyfill', 'mocha', 'browserify'],
polyfill: ['es6'],
files: [
'test/*.js'
],
preprocessors: {
'test/*.js': ['browserify']
},
browserify: {
debug: true
},
port: 9876,
colors: false,
// Possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
autoWatch: false,
singleRun: true,
sauceLabs: {
startConnect: true,
testName: 'ProgressBar.js',
build: process.env.TRAVIS_BUILD_NUMBER || 'manual',
tunnelIdentifier: process.env.TRAVIS_BUILD_NUMBER,
recordVideo: true
},
customLaunchers: customLaunchers,
browsers: Object.keys(customLaunchers),
reporters: ['dots', 'saucelabs'],
// Timeouts
browserDisconnectTimeout: 30 * 1000,
browserDisconnectTolerance: 3,
browserNoActivityTimeout: 30 * 1000,
captureTimeout: 120 * 1000
});
};
================================================
FILE: local-dev/index.html
================================================
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>ProgressBar.js - Local dev</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="main.css">
</head>
<body>
<div id="progress"></div>
<script src="bundle.js"></script>
</body>
</html>
================================================
FILE: local-dev/main.css
================================================
html, body {
height: 100%;
width: 100%;
}
svg {
display: block;
height: 100%;
}
#progress {
width: 300px;
height: 300px;
}
================================================
FILE: local-dev/main.js
================================================
var ProgressBar = require('../src/main.js');
function onLoad() {
var bar = new ProgressBar.Circle('#progress', {
duration: 4000,
from: {
color: '#f00'
},
to: {
color: '#0f0'
},
step: function(state, bar) {
bar.path.setAttribute('stroke', state.color);
},
});
bar.animate(1);
// Expose the bar to global so it is easy to test from console
window.bar = bar;
}
window.onload = onLoad;
================================================
FILE: mkdocs.yml
================================================
site_name: ProgressBar.js
repo_url: https://github.com/kimmobrunfeldt/progressbar.js
pages:
- Home: index.md
- API References:
- General information: api/general.md
- ProgressBar.Line, Circle, SemiCircle: api/shape.md
- ProgressBar.Path: api/path.md
- Parameters in detail: api/parameters.md
- Developers:
- Contributing: contributing.md
theme: readthedocs
strict: true
markdown_extensions:
- admonition
- toc:
permalink: True
- mdx_sections
- pymdownx.superfences
================================================
FILE: package.json
================================================
{
"name": "progressbar.js",
"version": "1.1.1",
"description": "Responsive and slick progress bars with animated SVG paths",
"main": "dist/progressbar.js",
"dependencies": {
"lodash.merge": "^4.6.2",
"shifty": "^2.8.3"
},
"devDependencies": {
"bluebird": "^2.3.6",
"browserify": "^13.0.0",
"commander": "^2.4.0",
"concurrently": "^2.0.0",
"eslint": "^1.0.0",
"grunt": "^0.4.5",
"grunt-cli": "^0.1.13",
"grunt-contrib-jshint": "^0.10.0",
"grunt-contrib-uglify": "^0.6.0",
"grunt-karma": "^2.0.0",
"grunt-shell": "^1.1.1",
"jscs": "^2.0.0",
"karma": "^2.0.2",
"karma-browserify": "^5.2.0",
"karma-mocha": "^1.3.0",
"karma-polyfill": "^1.1.0",
"karma-sauce-launcher": "^1.2.0",
"lodash": "^2.4.1",
"mocha": "^2.0.1",
"mustache": "^2.3.0",
"node-static": "^0.7.7",
"np": "^5.1.2",
"semver": "^4.1.0",
"shelljs": "^0.3.0",
"sinon": "~1.14.1",
"string": "^2.2.0",
"testem": "^1.6.0",
"watchify": "^3.9.0"
},
"scripts": {
"test": "./tools/test.sh",
"start": "npm run dev",
"dev": "concurrently 'npm run serve' 'grunt watch' 'open http://localhost:8080'",
"serve": "static ./local-dev -c 0",
"lint": "./tools/lint.sh",
"jscs": "jscs ./src ./test",
"eslint": "eslint --ext .js ./src ./test"
},
"repository": {
"type": "git",
"url": "git://github.com/kimmobrunfeldt/progressbar.js.git"
},
"author": "Kimmo Brunfeldt <kimmobrunfeldt@gmail.com> (http://kimmobrunfeldt.github.io/)",
"license": "MIT",
"bugs": {
"url": "https://github.com/kimmobrunfeldt/progressbar.js/issues"
},
"homepage": "https://kimmobrunfeldt.github.io/progressbar.js/",
"keywords": [
"progress",
"bar",
"js",
"svg",
"circular",
"circle",
"pace",
"radial",
"line",
"loading",
"loader",
"semi-circle",
"indicator"
]
}
================================================
FILE: saucelabs-browsers.js
================================================
// Browsers on Sauce Labs
// Check out https://saucelabs.com/platforms for all browser/platform combos
// and https://wiki.saucelabs.com/display/DOCS/Platform+Configurator#/
module.exports = {
// Chrome
sauce_chrome: {
base: 'SauceLabs',
browserName: 'chrome',
platform: 'macOS 10.15',
version: 'latest'
},
// Safari
sauce_safari: {
base: 'SauceLabs',
browserName: 'safari',
platform: 'macOS 10.15',
version: 'latest'
},
// Firefox
sauce_firefox: {
base: 'SauceLabs',
browserName: 'firefox',
platform: 'Windows 10',
version: 'latest'
},
// Internet explorer
sauce_windows_ie_11: {
base: 'SauceLabs',
browserName: 'internet explorer',
platform: 'Windows 10',
version: '11'
},
sauce_windows_ie_10: {
base: 'SauceLabs',
browserName: 'internet explorer',
platform: 'Windows 8',
version: '10'
},
// MS Edge
sauce_windows_edge: {
base: 'SauceLabs',
browserName: 'MicrosoftEdge',
platform: 'Windows 10',
version: 'latest'
},
};
================================================
FILE: src/circle.js
================================================
// Circle shaped progress bar
var Shape = require('./shape');
var utils = require('./utils');
var Circle = function Circle(container, options) {
// Use two arcs to form a circle
// See this answer http://stackoverflow.com/a/10477334/1446092
this._pathTemplate =
'M 50,50 m 0,-{radius}' +
' a {radius},{radius} 0 1 1 0,{2radius}' +
' a {radius},{radius} 0 1 1 0,-{2radius}';
this.containerAspectRatio = 1;
Shape.apply(this, arguments);
};
Circle.prototype = new Shape();
Circle.prototype.constructor = Circle;
Circle.prototype._pathString = function _pathString(opts) {
var widthOfWider = opts.strokeWidth;
if (opts.trailWidth && opts.trailWidth > opts.strokeWidth) {
widthOfWider = opts.trailWidth;
}
var r = 50 - widthOfWider / 2;
return utils.render(this._pathTemplate, {
radius: r,
'2radius': r * 2
});
};
Circle.prototype._trailString = function _trailString(opts) {
return this._pathString(opts);
};
module.exports = Circle;
================================================
FILE: src/line.js
================================================
// Line shaped progress bar
var Shape = require('./shape');
var utils = require('./utils');
var Line = function Line(container, options) {
this._pathTemplate = options.vertical
? 'M {center},100 L {center},0'
: 'M 0,{center} L 100,{center}';
Shape.apply(this, arguments);
};
Line.prototype = new Shape();
Line.prototype.constructor = Line;
Line.prototype._initializeSvg = function _initializeSvg(svg, opts) {
var viewBoxStr = opts.vertical
? '0 0 ' + opts.strokeWidth + ' 100'
: '0 0 100 ' + opts.strokeWidth;
svg.setAttribute('viewBox', viewBoxStr);
svg.setAttribute('preserveAspectRatio', 'none');
};
Line.prototype._pathString = function _pathString(opts) {
return utils.render(this._pathTemplate, {
center: opts.strokeWidth / 2
});
};
Line.prototype._trailString = function _trailString(opts) {
return this._pathString(opts);
};
module.exports = Line;
================================================
FILE: src/main.js
================================================
module.exports = {
// Higher level API, different shaped progress bars
Line: require('./line'),
Circle: require('./circle'),
SemiCircle: require('./semicircle'),
Square: require('./square'),
// Lower level API to use any SVG path
Path: require('./path'),
// Base-class for creating new custom shapes
// to be in line with the API of built-in shapes
// Undocumented.
Shape: require('./shape'),
// Internal utils, undocumented.
utils: require('./utils')
};
================================================
FILE: src/path.js
================================================
// Lower level API to animate any kind of svg path
var shifty = require('shifty');
var utils = require('./utils');
var Tweenable = shifty.Tweenable;
var EASING_ALIASES = {
easeIn: 'easeInCubic',
easeOut: 'easeOutCubic',
easeInOut: 'easeInOutCubic'
};
var Path = function Path(path, opts) {
// Throw a better error if not initialized with `new` keyword
if (!(this instanceof Path)) {
throw new Error('Constructor was called without new keyword');
}
// Default parameters for animation
opts = utils.extend({
delay: 0,
duration: 800,
easing: 'linear',
from: {},
to: {},
step: function() {}
}, opts);
var element;
if (utils.isString(path)) {
element = document.querySelector(path);
} else {
element = path;
}
// Reveal .path as public attribute
this.path = element;
this._opts = opts;
this._tweenable = null;
// Set up the starting positions
var length = this.path.getTotalLength();
this.path.style.strokeDasharray = length + ' ' + length;
this.set(0);
};
Path.prototype.value = function value() {
var offset = this._getComputedDashOffset();
var length = this.path.getTotalLength();
var progress = 1 - offset / length;
// Round number to prevent returning very small number like 1e-30, which
// is practically 0
return parseFloat(progress.toFixed(6), 10);
};
Path.prototype.set = function set(progress) {
this.stop();
this.path.style.strokeDashoffset = this._progressToOffset(progress);
var step = this._opts.step;
if (utils.isFunction(step)) {
var easing = this._easing(this._opts.easing);
var values = this._calculateTo(progress, easing);
var reference = this._opts.shape || this;
step(values, reference, this._opts.attachment);
}
};
Path.prototype.stop = function stop() {
this._stopTween();
this.path.style.strokeDashoffset = this._getComputedDashOffset();
};
// Method introduced here:
// http://jakearchibald.com/2013/animated-line-drawing-svg/
Path.prototype.animate = function animate(progress, opts, cb) {
opts = opts || {};
if (utils.isFunction(opts)) {
cb = opts;
opts = {};
}
var passedOpts = utils.extend({}, opts);
// Copy default opts to new object so defaults are not modified
var defaultOpts = utils.extend({}, this._opts);
opts = utils.extend(defaultOpts, opts);
var shiftyEasing = this._easing(opts.easing);
var values = this._resolveFromAndTo(progress, shiftyEasing, passedOpts);
this.stop();
// Trigger a layout so styles are calculated & the browser
// picks up the starting position before animating
this.path.getBoundingClientRect();
var offset = this._getComputedDashOffset();
var newOffset = this._progressToOffset(progress);
var self = this;
this._tweenable = new Tweenable();
this._tweenable.tween({
from: utils.extend({ offset: offset }, values.from),
to: utils.extend({ offset: newOffset }, values.to),
duration: opts.duration,
delay: opts.delay,
easing: shiftyEasing,
step: function(state) {
self.path.style.strokeDashoffset = state.offset;
var reference = opts.shape || self;
opts.step(state, reference, opts.attachment);
}
}).then(function(state) {
if (utils.isFunction(cb)) {
cb();
}
}).catch(function(err) {
console.error('Error in tweening:', err);
throw err;
});
};
Path.prototype._getComputedDashOffset = function _getComputedDashOffset() {
var computedStyle = window.getComputedStyle(this.path, null);
return parseFloat(computedStyle.getPropertyValue('stroke-dashoffset'), 10);
};
Path.prototype._progressToOffset = function _progressToOffset(progress) {
var length = this.path.getTotalLength();
return length - progress * length;
};
// Resolves from and to values for animation.
Path.prototype._resolveFromAndTo = function _resolveFromAndTo(progress, easing, opts) {
if (opts.from && opts.to) {
return {
from: opts.from,
to: opts.to
};
}
return {
from: this._calculateFrom(easing),
to: this._calculateTo(progress, easing)
};
};
// Calculate `from` values from options passed at initialization
Path.prototype._calculateFrom = function _calculateFrom(easing) {
return shifty.interpolate(this._opts.from, this._opts.to, this.value(), easing);
};
// Calculate `to` values from options passed at initialization
Path.prototype._calculateTo = function _calculateTo(progress, easing) {
return shifty.interpolate(this._opts.from, this._opts.to, progress, easing);
};
Path.prototype._stopTween = function _stopTween() {
if (this._tweenable !== null) {
this._tweenable.stop(true);
this._tweenable = null;
}
};
Path.prototype._easing = function _easing(easing) {
if (EASING_ALIASES.hasOwnProperty(easing)) {
return EASING_ALIASES[easing];
}
return easing;
};
module.exports = Path;
================================================
FILE: src/semicircle.js
================================================
// Semi-SemiCircle shaped progress bar
var Shape = require('./shape');
var Circle = require('./circle');
var utils = require('./utils');
var SemiCircle = function SemiCircle(container, options) {
// Use one arc to form a SemiCircle
// See this answer http://stackoverflow.com/a/10477334/1446092
this._pathTemplate =
'M 50,50 m -{radius},0' +
' a {radius},{radius} 0 1 1 {2radius},0';
this.containerAspectRatio = 2;
Shape.apply(this, arguments);
};
SemiCircle.prototype = new Shape();
SemiCircle.prototype.constructor = SemiCircle;
SemiCircle.prototype._initializeSvg = function _initializeSvg(svg, opts) {
svg.setAttribute('viewBox', '0 0 100 50');
};
SemiCircle.prototype._initializeTextContainer = function _initializeTextContainer(
opts,
container,
textContainer
) {
if (opts.text.style) {
// Reset top style
textContainer.style.top = 'auto';
textContainer.style.bottom = '0';
if (opts.text.alignToBottom) {
utils.setStyle(textContainer, 'transform', 'translate(-50%, 0)');
} else {
utils.setStyle(textContainer, 'transform', 'translate(-50%, 50%)');
}
}
};
// Share functionality with Circle, just have different path
SemiCircle.prototype._pathString = Circle.prototype._pathString;
SemiCircle.prototype._trailString = Circle.prototype._trailString;
module.exports = SemiCircle;
================================================
FILE: src/shape.js
================================================
// Base object for different progress bar shapes
var Path = require('./path');
var utils = require('./utils');
var DESTROYED_ERROR = 'Object is destroyed';
var Shape = function Shape(container, opts) {
// Throw a better error if progress bars are not initialized with `new`
// keyword
if (!(this instanceof Shape)) {
throw new Error('Constructor was called without new keyword');
}
// Prevent calling constructor without parameters so inheritance
// works correctly. To understand, this is how Shape is inherited:
//
// Line.prototype = new Shape();
//
// We just want to set the prototype for Line.
if (arguments.length === 0) {
return;
}
// Default parameters for progress bar creation
this._opts = utils.extend({
color: '#555',
strokeWidth: 1.0,
trailColor: null,
trailWidth: null,
fill: null,
text: {
style: {
color: null,
position: 'absolute',
left: '50%',
top: '50%',
padding: 0,
margin: 0,
transform: {
prefix: true,
value: 'translate(-50%, -50%)'
}
},
autoStyleContainer: true,
alignToBottom: true,
value: null,
className: 'progressbar-text'
},
svgStyle: {
display: 'block',
width: '100%'
},
warnings: false
}, opts, true); // Use recursive extend
// If user specifies e.g. svgStyle or text style, the whole object
// should replace the defaults to make working with styles easier
if (utils.isObject(opts) && opts.svgStyle !== undefined) {
this._opts.svgStyle = opts.svgStyle;
}
if (utils.isObject(opts) && utils.isObject(opts.text) && opts.text.style !== undefined) {
this._opts.text.style = opts.text.style;
}
var svgView = this._createSvgView(this._opts);
var element;
if (utils.isString(container)) {
element = document.querySelector(container);
} else {
element = container;
}
if (!element) {
throw new Error('Container does not exist: ' + container);
}
this._container = element;
this._container.appendChild(svgView.svg);
if (this._opts.warnings) {
this._warnContainerAspectRatio(this._container);
}
if (this._opts.svgStyle) {
utils.setStyles(svgView.svg, this._opts.svgStyle);
}
// Expose public attributes before Path initialization
this.svg = svgView.svg;
this.path = svgView.path;
this.trail = svgView.trail;
this.text = null;
var newOpts = utils.extend({
attachment: undefined,
shape: this
}, this._opts);
this._progressPath = new Path(svgView.path, newOpts);
if (utils.isObject(this._opts.text) && this._opts.text.value !== null) {
this.setText(this._opts.text.value);
}
};
Shape.prototype.animate = function animate(progress, opts, cb) {
if (this._progressPath === null) {
throw new Error(DESTROYED_ERROR);
}
this._progressPath.animate(progress, opts, cb);
};
Shape.prototype.stop = function stop() {
if (this._progressPath === null) {
throw new Error(DESTROYED_ERROR);
}
// Don't crash if stop is called inside step function
if (this._progressPath === undefined) {
return;
}
this._progressPath.stop();
};
Shape.prototype.pause = function pause() {
if (this._progressPath === null) {
throw new Error(DESTROYED_ERROR);
}
if (this._progressPath === undefined) {
return;
}
if (!this._progressPath._tweenable) {
// It seems that we can't pause this
return;
}
this._progressPath._tweenable.pause();
};
Shape.prototype.resume = function resume() {
if (this._progressPath === null) {
throw new Error(DESTROYED_ERROR);
}
if (this._progressPath === undefined) {
return;
}
if (!this._progressPath._tweenable) {
// It seems that we can't resume this
return;
}
this._progressPath._tweenable.resume();
};
Shape.prototype.destroy = function destroy() {
if (this._progressPath === null) {
throw new Error(DESTROYED_ERROR);
}
this.stop();
this.svg.parentNode.removeChild(this.svg);
this.svg = null;
this.path = null;
this.trail = null;
this._progressPath = null;
if (this.text !== null) {
this.text.parentNode.removeChild(this.text);
this.text = null;
}
};
Shape.prototype.set = function set(progress) {
if (this._progressPath === null) {
throw new Error(DESTROYED_ERROR);
}
this._progressPath.set(progress);
};
Shape.prototype.value = function value() {
if (this._progressPath === null) {
throw new Error(DESTROYED_ERROR);
}
if (this._progressPath === undefined) {
return 0;
}
return this._progressPath.value();
};
Shape.prototype.setText = function setText(newText) {
if (this._progressPath === null) {
throw new Error(DESTROYED_ERROR);
}
if (this.text === null) {
// Create new text node
this.text = this._createTextContainer(this._opts, this._container);
this._container.appendChild(this.text);
}
// Remove previous text and add new
if (utils.isObject(newText)) {
utils.removeChildren(this.text);
this.text.appendChild(newText);
} else {
this.text.innerHTML = newText;
}
};
Shape.prototype._createSvgView = function _createSvgView(opts) {
var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
this._initializeSvg(svg, opts);
var trailPath = null;
// Each option listed in the if condition are 'triggers' for creating
// the trail path
if (opts.trailColor || opts.trailWidth) {
trailPath = this._createTrail(opts);
svg.appendChild(trailPath);
}
var path = this._createPath(opts);
svg.appendChild(path);
return {
svg: svg,
path: path,
trail: trailPath
};
};
Shape.prototype._initializeSvg = function _initializeSvg(svg, opts) {
svg.setAttribute('viewBox', '0 0 100 100');
};
Shape.prototype._createPath = function _createPath(opts) {
var pathString = this._pathString(opts);
return this._createPathElement(pathString, opts);
};
Shape.prototype._createTrail = function _createTrail(opts) {
// Create path string with original passed options
var pathString = this._trailString(opts);
// Prevent modifying original
var newOpts = utils.extend({}, opts);
// Defaults for parameters which modify trail path
if (!newOpts.trailColor) {
newOpts.trailColor = '#eee';
}
if (!newOpts.trailWidth) {
newOpts.trailWidth = newOpts.strokeWidth;
}
newOpts.color = newOpts.trailColor;
newOpts.strokeWidth = newOpts.trailWidth;
// When trail path is set, fill must be set for it instead of the
// actual path to prevent trail stroke from clipping
newOpts.fill = null;
return this._createPathElement(pathString, newOpts);
};
Shape.prototype._createPathElement = function _createPathElement(pathString, opts) {
var path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
path.setAttribute('d', pathString);
path.setAttribute('stroke', opts.color);
path.setAttribute('stroke-width', opts.strokeWidth);
if (opts.fill) {
path.setAttribute('fill', opts.fill);
} else {
path.setAttribute('fill-opacity', '0');
}
return path;
};
Shape.prototype._createTextContainer = function _createTextContainer(opts, container) {
var textContainer = document.createElement('div');
textContainer.className = opts.text.className;
var textStyle = opts.text.style;
if (textStyle) {
if (opts.text.autoStyleContainer) {
container.style.position = 'relative';
}
utils.setStyles(textContainer, textStyle);
// Default text color to progress bar's color
if (!textStyle.color) {
textContainer.style.color = opts.color;
}
}
this._initializeTextContainer(opts, container, textContainer);
return textContainer;
};
// Give custom shapes possibility to modify text element
Shape.prototype._initializeTextContainer = function(opts, container, element) {
// By default, no-op
// Custom shapes should respect API options, such as text.style
};
Shape.prototype._pathString = function _pathString(opts) {
throw new Error('Override this function for each progress bar');
};
Shape.prototype._trailString = function _trailString(opts) {
throw new Error('Override this function for each progress bar');
};
Shape.prototype._warnContainerAspectRatio = function _warnContainerAspectRatio(container) {
if (!this.containerAspectRatio) {
return;
}
var computedStyle = window.getComputedStyle(container, null);
var width = parseFloat(computedStyle.getPropertyValue('width'), 10);
var height = parseFloat(computedStyle.getPropertyValue('height'), 10);
if (!utils.floatEquals(this.containerAspectRatio, width / height)) {
console.warn(
'Incorrect aspect ratio of container',
'#' + container.id,
'detected:',
computedStyle.getPropertyValue('width') + '(width)',
'/',
computedStyle.getPropertyValue('height') + '(height)',
'=',
width / height
);
console.warn(
'Aspect ratio of should be',
this.containerAspectRatio
);
}
};
module.exports = Shape;
================================================
FILE: src/square.js
================================================
// Square shaped progress bar
// Note: Square is not core part of API anymore. It's left here
// for reference. square is not included to the progressbar
// build anymore
var Shape = require('./shape');
var utils = require('./utils');
var Square = function Square(container, options) {
this._pathTemplate =
'M 0,{halfOfStrokeWidth}' +
' L {width},{halfOfStrokeWidth}' +
' L {width},{width}' +
' L {halfOfStrokeWidth},{width}' +
' L {halfOfStrokeWidth},{strokeWidth}';
this._trailTemplate =
'M {startMargin},{halfOfStrokeWidth}' +
' L {width},{halfOfStrokeWidth}' +
' L {width},{width}' +
' L {halfOfStrokeWidth},{width}' +
' L {halfOfStrokeWidth},{halfOfStrokeWidth}';
Shape.apply(this, arguments);
};
Square.prototype = new Shape();
Square.prototype.constructor = Square;
Square.prototype._pathString = function _pathString(opts) {
var w = 100 - opts.strokeWidth / 2;
return utils.render(this._pathTemplate, {
width: w,
strokeWidth: opts.strokeWidth,
halfOfStrokeWidth: opts.strokeWidth / 2
});
};
Square.prototype._trailString = function _trailString(opts) {
var w = 100 - opts.strokeWidth / 2;
return utils.render(this._trailTemplate, {
width: w,
strokeWidth: opts.strokeWidth,
halfOfStrokeWidth: opts.strokeWidth / 2,
startMargin: opts.strokeWidth / 2 - opts.trailWidth / 2
});
};
module.exports = Square;
================================================
FILE: src/utils.js
================================================
// Utility functions
var merge = require('lodash.merge');
var PREFIXES = 'Webkit Moz O ms'.split(' ');
var FLOAT_COMPARISON_EPSILON = 0.001;
// Renders templates with given variables. Variables must be surrounded with
// braces without any spaces, e.g. {variable}
// All instances of variable placeholders will be replaced with given content
// Example:
// render('Hello, {message}!', {message: 'world'})
function render(template, vars) {
var rendered = template;
for (var key in vars) {
if (vars.hasOwnProperty(key)) {
var val = vars[key];
var regExpString = '\\{' + key + '\\}';
var regExp = new RegExp(regExpString, 'g');
rendered = rendered.replace(regExp, val);
}
}
return rendered;
}
function setStyle(element, style, value) {
var elStyle = element.style; // cache for performance
for (var i = 0; i < PREFIXES.length; ++i) {
var prefix = PREFIXES[i];
elStyle[prefix + capitalize(style)] = value;
}
elStyle[style] = value;
}
function setStyles(element, styles) {
forEachObject(styles, function(styleValue, styleName) {
// Allow disabling some individual styles by setting them
// to null or undefined
if (styleValue === null || styleValue === undefined) {
return;
}
// If style's value is {prefix: true, value: '50%'},
// Set also browser prefixed styles
if (isObject(styleValue) && styleValue.prefix === true) {
setStyle(element, styleName, styleValue.value);
} else {
element.style[styleName] = styleValue;
}
});
}
function capitalize(text) {
return text.charAt(0).toUpperCase() + text.slice(1);
}
function isString(obj) {
return typeof obj === 'string' || obj instanceof String;
}
function isFunction(obj) {
return typeof obj === 'function';
}
function isArray(obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
}
// Returns true if `obj` is object as in {a: 1, b: 2}, not if it's function or
// array
function isObject(obj) {
if (isArray(obj)) {
return false;
}
var type = typeof obj;
return type === 'object' && !!obj;
}
function forEachObject(object, callback) {
for (var key in object) {
if (object.hasOwnProperty(key)) {
var val = object[key];
callback(val, key);
}
}
}
function floatEquals(a, b) {
return Math.abs(a - b) < FLOAT_COMPARISON_EPSILON;
}
// https://coderwall.com/p/nygghw/don-t-use-innerhtml-to-empty-dom-elements
function removeChildren(el) {
while (el.firstChild) {
el.removeChild(el.firstChild);
}
}
module.exports = {
extend: merge,
render: render,
setStyle: setStyle,
setStyles: setStyles,
capitalize: capitalize,
isString: isString,
isFunction: isFunction,
isObject: isObject,
forEachObject: forEachObject,
floatEquals: floatEquals,
removeChildren: removeChildren
};
================================================
FILE: tools/lint.sh
================================================
#!/bin/bash
# NOTE: Run this only from project root!
# Run all lint commands and if one fails, exit non-zero return code
EXIT_STATUS=0
npm run jscs || EXIT_STATUS=$?
npm run eslint || EXIT_STATUS=$?
exit $EXIT_STATUS
================================================
FILE: tools/release.js
================================================
#!/usr/bin/env node
// Release automation script inspired by
// https://github.com/geddski/grunt-release
var fs = require('fs');
var path = require('path');
var _ = require('lodash');
var S = require('string');
var shell = require('shelljs');
var Mustache = require('mustache');
var semver = require('semver');
var program = require('commander');
var Promise = require('bluebird');
// Message templates use https://github.com/janl/mustache.js
var config = {
indentation: 2,
releaseMessage: 'Release {{ version }}',
backToDevMessage: 'Bump to dev version',
bumpType: 'patch',
files: ['package.json'],
readmeFile: 'README.md',
// Banner to insert in beginning of distributables
bannerFiles: ['dist/progressbar.js', 'dist/progressbar.min.js'],
banner: '// ProgressBar.js {{ version }}\n// https://kimmobrunfeldt.github.io/progressbar.js\n// License: MIT\n\n',
// If true, don't execute anything, just tell what would have been done
dryRun: false,
// If true, don't push commits/tags or release to npm
noPush: false,
consolePrefix: '->',
devSuffix: '-dev'
}
var projectRoot = path.join(__dirname, '..');
process.chdir(projectRoot);
function main() {
parseArgs();
config = mergeArgsToDefaults(config);
if (config.dryRun) status('Dry run\n');
var newVersion = bumpVersion(config.files, config.bumpType);
var banner = Mustache.render(config.banner, {
version: newVersion
});
insertBanner(config.bannerFiles, banner);
_gitBranchName()
.then(function(stdout) {
if (stdout.trim().toLowerCase() !== 'master') {
throw new Error('You should be in master branch before running the script!');
}
return gitAdd(config.bannerFiles);
})
.then(function() {
return gitAdd([config.readmeFile]);
})
.then(function() {
return gitAdd(config.files);
})
.then(function() {
var message = Mustache.render(config.releaseMessage, {
version: newVersion
});
return gitCommit(message);
})
.then(function() {
return gitTag(newVersion);
})
.then(function() {
return gitPushTag(newVersion);
})
.then(npmPublish)
.then(function() {
bumpVersion(config.files, 'dev');
return gitAdd(config.files.concat(config.readmeFile));
})
.then(function() {
return gitCommit(config.backToDevMessage);
})
.then(function() {
gitPush();
})
.then(function() {
console.log('');
status('Release successfully done!');
})
.catch(function(err) {
console.error('\n!! Releasing failed')
console.trace(err);
process.exit(2);
});
}
function parseArgs() {
program
.usage('bump')
program.on('--help', function() {
console.log(' Example usage:');
console.log('');
console.log(' $ ./release.js minor');
});
program.parse(process.argv);
}
function mergeArgsToDefaults(config) {
if (program.args[0]) {
config.bumpType = program.args[0];
if (!_.contains(['major', 'minor', 'patch'], config.bumpType)) {
console.error('Error:', config.bumpType, 'is not a valid bump type');
process.exit(1);
}
}
return config;
}
function status( /* arguments */ ) {
var args = Array.prototype.slice.call(arguments);
console.log(config.consolePrefix, args.join(' '));
}
function run(cmd, msg) {
// All calls are actually synchronous but eventually some task
// will need async stuff, so keep them promises
return new Promise(function(resolve, reject) {
if (msg) {
status(msg);
}
if (config.dryRun) {
return resolve();
}
var exec = shell.exec(cmd);
var success = exec.code === 0;
if (success) {
resolve(exec.output);
} else {
var errMsg = 'Error executing: `' + cmd + '`\nOutput:\n' + exec.output;
var err = new Error(errMsg);
reject(err);
}
});
}
// Task functions
// All functions should return promise
// Bumps version in specified files.
// Files are assumed to contain JSON data which has "version" key following
// semantic versioning
function bumpVersion(files, bumpType) {
status('Bump', bumpType, 'version to files:', files.join(' '));
if (config.dryRun) return '[not available in dry run]';
var newVersion;
var originalVersion;
files.forEach(function(fileName) {
var filePath = path.join(projectRoot, fileName);
var data = JSON.parse(fs.readFileSync(filePath));
originalVersion = data.version;
var currentVersion = data.version;
if (!semver.valid(currentVersion)) {
var msg = 'Invalid version ' + currentVersion +
' in file ' + fileName;;
var err = new Error(msg);
throw err;
}
if (S(currentVersion).endsWith(config.devSuffix)) {
currentVersion = S(currentVersion).chompRight(config.devSuffix).s;
}
if (bumpType === 'dev') {
newVersion = currentVersion + config.devSuffix;
} else {
newVersion = semver.inc(currentVersion, bumpType);
}
data.version = newVersion;
var content = JSON.stringify(data, null, config.indentation);
fs.writeFileSync(filePath, content);
status('Bump', originalVersion, '->', newVersion, 'in',
fileName);
});
bumpReadmeVersion(originalVersion, newVersion, bumpType);
return newVersion;
}
function insertBanner(files, banner) {
status('Insert banner to', files.length, 'files');
if (config.dryRun) return;
_.each(files, function(fileName) {
var filePath = path.join(projectRoot, fileName);
var content = fs.readFileSync(filePath);
var newContent = banner + content;
fs.writeFileSync(filePath, newContent);
});
}
function bumpReadmeVersion(oldVersion, newVersion, bumpType) {
if (bumpType === 'dev') {
// Don't bump readme version in to dev version
return;
}
var oldReleaseVersion = oldVersion;
if (S(oldReleaseVersion).endsWith(config.devSuffix)) {
oldReleaseVersion = S(oldReleaseVersion).chompRight(config.devSuffix).s;
}
status('Replace readme version', oldReleaseVersion, '->', newVersion);
if (config.dryRun) return;
var filePath = path.join(projectRoot, config.readmeFile);
var content = fs.readFileSync(filePath, {encoding: 'utf-8'});
// Update visible version
var re = new RegExp('Version: ' + oldReleaseVersion, 'g');
var newContent = content.replace(re, 'Version: ' + newVersion);
// Replace link to previous stable
re = new RegExp('tree/[0-9]\\.[0-9]\\.[0-9]');
newContent = newContent.replace(re, 'tree/' + oldReleaseVersion);
fs.writeFileSync(filePath, newContent);
}
function gitAdd(files) {
var cmd = 'git add ' + files.join(' ');
var msg = 'Staged ' + files.length + ' files';
return run(cmd, msg);
}
function gitCommit(message) {
var cmd = 'git commit -m "' + message + '"';
var msg = 'Commit files'
return run(cmd, msg);
}
function gitTag(name) {
var cmd = 'git tag ' + name;
var msg = 'Created a new git tag: ' + name;
return run(cmd, msg);
}
function gitPush() {
if (config.noPush) return;
var cmd = 'git push';
var msg = 'Push to remote';
return run(cmd, msg);
}
function gitPushTag(tagName) {
if (config.noPush) return;
var cmd = 'git push origin ' + tagName;
var msg = 'Push created git tag to remote'
return run(cmd, msg);
}
function gitCheckout(branch) {
var cmd = 'git checkout ' + branch;
var msg = 'Checkout branch ' + branch;
return run(cmd, msg);
}
function npmPublish() {
if (config.noPush) return;
var cmd = 'npm publish';
var msg = 'Publish to npm';
return run(cmd, msg);
}
function _gitBranchName() {
var cmd = 'git rev-parse --abbrev-ref HEAD'
return run(cmd, false);
}
main();
================================================
FILE: tools/test.sh
================================================
#!/bin/bash
# NOTE: Run this only from project root!
# Run all commands and if one fails, exit non-zero return code
EXIT_STATUS=0
echo -e "\n---- Linting code..\n"
npm run lint || EXIT_STATUS=$?
exit $EXIT_STATUS
gitextract_1t5gj7f7/
├── .editorconfig
├── .eslintrc
├── .gitignore
├── .jscs.json
├── .travis.yml
├── Gruntfile.js
├── LICENSE
├── README.md
├── bower.json
├── dist/
│ └── progressbar.js
├── docs/
│ ├── api/
│ │ ├── general.md
│ │ ├── parameters.md
│ │ ├── path.md
│ │ └── shape.md
│ ├── contributing.md
│ ├── index.md
│ └── pip-requirements.txt
├── karma.conf.js
├── local-dev/
│ ├── index.html
│ ├── main.css
│ └── main.js
├── mkdocs.yml
├── package.json
├── saucelabs-browsers.js
├── src/
│ ├── circle.js
│ ├── line.js
│ ├── main.js
│ ├── path.js
│ ├── semicircle.js
│ ├── shape.js
│ ├── square.js
│ └── utils.js
└── tools/
├── lint.sh
├── release.js
└── test.sh
SYMBOL INDEX (143 symbols across 5 files)
FILE: Gruntfile.js
function groupToElements (line 4) | function groupToElements(array, n) {
FILE: dist/progressbar.js
function r (line 5) | function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==...
function apply (line 138) | function apply(func, thisArg, args) {
function baseTimes (line 157) | function baseTimes(n, iteratee) {
function baseUnary (line 174) | function baseUnary(func) {
function getValue (line 188) | function getValue(object, key) {
function overArg (line 200) | function overArg(func, transform) {
function object (line 279) | function object() {}
function Hash (line 301) | function Hash(entries) {
function hashClear (line 319) | function hashClear() {
function hashDelete (line 334) | function hashDelete(key) {
function hashGet (line 349) | function hashGet(key) {
function hashHas (line 367) | function hashHas(key) {
function hashSet (line 382) | function hashSet(key, value) {
function ListCache (line 403) | function ListCache(entries) {
function listCacheClear (line 421) | function listCacheClear() {
function listCacheDelete (line 435) | function listCacheDelete(key) {
function listCacheGet (line 461) | function listCacheGet(key) {
function listCacheHas (line 477) | function listCacheHas(key) {
function listCacheSet (line 491) | function listCacheSet(key, value) {
function MapCache (line 518) | function MapCache(entries) {
function mapCacheClear (line 536) | function mapCacheClear() {
function mapCacheDelete (line 554) | function mapCacheDelete(key) {
function mapCacheGet (line 569) | function mapCacheGet(key) {
function mapCacheHas (line 582) | function mapCacheHas(key) {
function mapCacheSet (line 596) | function mapCacheSet(key, value) {
function Stack (line 619) | function Stack(entries) {
function stackClear (line 631) | function stackClear() {
function stackDelete (line 645) | function stackDelete(key) {
function stackGet (line 662) | function stackGet(key) {
function stackHas (line 675) | function stackHas(key) {
function stackSet (line 689) | function stackSet(key, value) {
function arrayLikeKeys (line 720) | function arrayLikeKeys(value, inherited) {
function assignMergeValue (line 756) | function assignMergeValue(object, key, value) {
function assignValue (line 773) | function assignValue(object, key, value) {
function assocIndexOf (line 789) | function assocIndexOf(array, key) {
function baseAssignValue (line 808) | function baseAssignValue(object, key, value) {
function baseGetTag (line 841) | function baseGetTag(value) {
function baseIsArguments (line 857) | function baseIsArguments(value) {
function baseIsNative (line 869) | function baseIsNative(value) {
function baseIsTypedArray (line 884) | function baseIsTypedArray(value) {
function baseKeysIn (line 896) | function baseKeysIn(object) {
function baseMerge (line 922) | function baseMerge(object, source, srcIndex, customizer, stack) {
function baseMergeDeep (line 959) | function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customi...
function baseRest (line 1029) | function baseRest(func, start) {
function cloneBuffer (line 1058) | function cloneBuffer(buffer, isDeep) {
function cloneArrayBuffer (line 1076) | function cloneArrayBuffer(arrayBuffer) {
function cloneTypedArray (line 1090) | function cloneTypedArray(typedArray, isDeep) {
function copyArray (line 1103) | function copyArray(source, array) {
function copyObject (line 1124) | function copyObject(source, props, object, customizer) {
function createAssigner (line 1157) | function createAssigner(assigner) {
function createBaseFor (line 1190) | function createBaseFor(fromRight) {
function getMapData (line 1215) | function getMapData(map, key) {
function getNative (line 1230) | function getNative(object, key) {
function getRawTag (line 1242) | function getRawTag(value) {
function initCloneObject (line 1269) | function initCloneObject(object) {
function isIndex (line 1283) | function isIndex(value, length) {
function isIterateeCall (line 1303) | function isIterateeCall(value, index, object) {
function isKeyable (line 1324) | function isKeyable(value) {
function isMasked (line 1338) | function isMasked(func) {
function isPrototype (line 1349) | function isPrototype(value) {
function nativeKeysIn (line 1365) | function nativeKeysIn(object) {
function objectToString (line 1382) | function objectToString(value) {
function overRest (line 1395) | function overRest(func, start, transform) {
function safeGet (line 1424) | function safeGet(object, key) {
function shortOut (line 1455) | function shortOut(func) {
function toSource (line 1482) | function toSource(func) {
function eq (line 1526) | function eq(value, other) {
function isArrayLike (line 1603) | function isArrayLike(value) {
function isArrayLikeObject (line 1632) | function isArrayLikeObject(value) {
function isFunction (line 1672) | function isFunction(value) {
function isLength (line 1708) | function isLength(value) {
function isObject (line 1738) | function isObject(value) {
function isObjectLike (line 1767) | function isObjectLike(value) {
function isPlainObject (line 1799) | function isPlainObject(value) {
function toPlainObject (line 1855) | function toPlainObject(value) {
function keysIn (line 1882) | function keysIn(object) {
function constant (line 1940) | function constant(value) {
function identity (line 1962) | function identity(value) {
function stubFalse (line 1979) | function stubFalse() {
function R (line 1988) | function R(t,n,e,r,i,o){var u,a,s,c,f,l=0,h=0,p=0,v=function(t){return((...
function V (line 1988) | function V(t,n){if(!(t instanceof n))throw new TypeError("Cannot call a ...
function W (line 1988) | function W(t,n){for(var e=0;e<n.length;e++){var r=n[e];r.enumerable=r.en...
function G (line 1988) | function G(t){return G="function"==typeof Symbol&&"symbol"==typeof Symbo...
function H (line 1988) | function H(t){return function(t){if(Array.isArray(t))return J(t)}(t)||fu...
function J (line 1988) | function J(t,n){(null==n||n>t.length)&&(n=t.length);for(var e=0,r=new Ar...
function K (line 1988) | function K(t,n){var e=Object.keys(t);if(Object.getOwnPropertySymbols){va...
function X (line 1988) | function X(t){for(var n=1;n<arguments.length;n++){var e=null!=arguments[...
function Y (line 1988) | function Y(t,n,e){return n in t?Object.defineProperty(t,n,{value:e,enume...
function t (line 1988) | function t(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0...
function Pt (line 1988) | function Pt(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[...
function Qt (line 1988) | function Qt(t){return parseInt(t,16)}
function Gt (line 1988) | function Gt(t){var n=t._currentState;[n,t._originalState,t._targetState]...
function Ht (line 1988) | function Ht(t){var n=t._currentState,e=t._originalState,r=t._targetState...
function Jt (line 1988) | function Jt(t){var n=t._currentState,e=t._originalState,r=t._targetState...
function Kt (line 1988) | function Kt(t,n){var e=Object.keys(t);if(Object.getOwnPropertySymbols){v...
function Xt (line 1988) | function Xt(t){for(var n=1;n<arguments.length;n++){var e=null!=arguments...
function Yt (line 1988) | function Yt(t,n,e){return n in t?Object.defineProperty(t,n,{value:e,enum...
function en (line 1988) | function en(t,n){(null==n||n>t.length)&&(n=t.length);for(var e=0,r=new A...
function rn (line 1988) | function rn(t,n){if(!(t instanceof n))throw new TypeError("Cannot call a...
function on (line 1988) | function on(t,n){for(var e=0;e<n.length;e++){var r=n[e];r.enumerable=r.e...
function un (line 1988) | function un(t,n){var e=n.get(t);if(!e)throw new TypeError("attempted to ...
function t (line 1988) | function t(){rn(this,t),an.set(this,{writable:!0,value:[]});for(var n=ar...
function e (line 1988) | function e(r){if(n[r])return n[r].exports;var i=n[r]={exports:{}};return...
function render (line 2738) | function render(template, vars) {
function setStyle (line 2754) | function setStyle(element, style, value) {
function setStyles (line 2765) | function setStyles(element, styles) {
function capitalize (line 2783) | function capitalize(text) {
function isString (line 2787) | function isString(obj) {
function isFunction (line 2791) | function isFunction(obj) {
function isArray (line 2795) | function isArray(obj) {
function isObject (line 2801) | function isObject(obj) {
function forEachObject (line 2810) | function forEachObject(object, callback) {
function floatEquals (line 2819) | function floatEquals(a, b) {
function removeChildren (line 2824) | function removeChildren(el) {
FILE: local-dev/main.js
function onLoad (line 4) | function onLoad() {
FILE: src/utils.js
function render (line 13) | function render(template, vars) {
function setStyle (line 29) | function setStyle(element, style, value) {
function setStyles (line 40) | function setStyles(element, styles) {
function capitalize (line 58) | function capitalize(text) {
function isString (line 62) | function isString(obj) {
function isFunction (line 66) | function isFunction(obj) {
function isArray (line 70) | function isArray(obj) {
function isObject (line 76) | function isObject(obj) {
function forEachObject (line 85) | function forEachObject(object, callback) {
function floatEquals (line 94) | function floatEquals(a, b) {
function removeChildren (line 99) | function removeChildren(el) {
FILE: tools/release.js
function main (line 43) | function main() {
function parseArgs (line 105) | function parseArgs() {
function mergeArgsToDefaults (line 118) | function mergeArgsToDefaults(config) {
function status (line 131) | function status( /* arguments */ ) {
function run (line 136) | function run(cmd, msg) {
function bumpVersion (line 167) | function bumpVersion(files, bumpType) {
function insertBanner (line 209) | function insertBanner(files, banner) {
function bumpReadmeVersion (line 222) | function bumpReadmeVersion(oldVersion, newVersion, bumpType) {
function gitAdd (line 250) | function gitAdd(files) {
function gitCommit (line 256) | function gitCommit(message) {
function gitTag (line 262) | function gitTag(name) {
function gitPush (line 268) | function gitPush() {
function gitPushTag (line 276) | function gitPushTag(tagName) {
function gitCheckout (line 284) | function gitCheckout(branch) {
function npmPublish (line 290) | function npmPublish() {
function _gitBranchName (line 298) | function _gitBranchName() {
Condensed preview — 35 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (183K chars).
[
{
"path": ".editorconfig",
"chars": 474,
"preview": "# EditorConfig is awesome: http://EditorConfig.org\n\n# top-most EditorConfig file\nroot = true\n\n# Unix-style newlines with"
},
{
"path": ".eslintrc",
"chars": 1883,
"preview": "{\n \"env\": {\n \"browser\": true,\n \"amd\": true,\n \"node\": true\n },\n\n \"globals\":"
},
{
"path": ".gitignore",
"chars": 757,
"preview": "# Logs\nlogs\n# Node\n\n*.log\n\n# Runtime data\npids\n*.pid\n*.seed\n\n# Directory for instrumented libs generated by jscoverage/J"
},
{
"path": ".jscs.json",
"chars": 1972,
"preview": "{\n \"disallowImplicitTypeConversion\": [\"string\"],\n \"disallowMixedSpacesAndTabs\": true,\n \"disallowMultipleLineBre"
},
{
"path": ".travis.yml",
"chars": 739,
"preview": "language: node_js\nnode_js:\n- '12'\nbefore_install:\n- npm install -g npm\nbefore_script:\n- npm install\n- npm install -g moc"
},
{
"path": "Gruntfile.js",
"chars": 4201,
"preview": "var _ = require('lodash');\n\n// Split array to smaller arrays containing n elements at max\nfunction groupToElements(array"
},
{
"path": "LICENSE",
"chars": 1082,
"preview": "The MIT License (MIT)\n\nCopyright (c) 2015 Kimmo Brunfeldt\n\nPermission is hereby granted, free of charge, to any person o"
},
{
"path": "README.md",
"chars": 1306,
"preview": "# ProgressBar.js\n\n<br>\n\n\n\n<br>\n\nResponsive and slick progress bars with animate"
},
{
"path": "bower.json",
"chars": 611,
"preview": "{\n \"name\": \"progressbar.js\",\n \"main\": \"dist/progressbar.js\",\n \"homepage\": \"https://github.com/kimmobrunfeldt/progress"
},
{
"path": "dist/progressbar.js",
"chars": 96533,
"preview": "// ProgressBar.js 1.1.1\n// https://kimmobrunfeldt.github.io/progressbar.js\n// License: MIT\n\n(function(f){if(typeof expor"
},
{
"path": "docs/api/general.md",
"chars": 1784,
"preview": "Functions use node-style callback convention. Callback function is always the last given parameter.\n\nShapes have differe"
},
{
"path": "docs/api/parameters.md",
"chars": 2942,
"preview": "\n# Easing\n\nEasing functions [provided with *shifty* are supported](https://github.com/jeremyckahn/shifty/blob/master/src"
},
{
"path": "docs/api/path.md",
"chars": 4781,
"preview": "# new Path(path, [*options*])\n\nCustom shaped progress bar. You can create arbitrary shaped progress bars by\npassing a SV"
},
{
"path": "docs/api/shape.md",
"chars": 7631,
"preview": "!!! note\n\n Line, Circle and SemiCircle all point to the same\n documentation which is named Shape. You should\n r"
},
{
"path": "docs/contributing.md",
"chars": 5947,
"preview": "# Contribution documentation\n\nPull requests and contributions are warmly welcome.\nPlease follow existing code style and "
},
{
"path": "docs/index.md",
"chars": 3654,
"preview": "# Get started\n\n*ProgressBar.js* is lightweight, MIT licensed and supports all major browsers including **IE11+** when us"
},
{
"path": "docs/pip-requirements.txt",
"chars": 337,
"preview": "backports-abc==0.4\nbackports.ssl-match-hostname==3.5.0.1\ncertifi==2015.11.20.1\nclick==6.2\nJinja2==2.8\nlivereload==2.4.1\n"
},
{
"path": "karma.conf.js",
"chars": 1230,
"preview": "var customLaunchers = require('./saucelabs-browsers');\n\nmodule.exports = function(config) {\n config.set({\n fra"
},
{
"path": "local-dev/index.html",
"chars": 433,
"preview": "<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <meta http-equiv=\"X-UA-Compatible\" co"
},
{
"path": "local-dev/main.css",
"chars": 149,
"preview": "html, body {\n height: 100%;\n width: 100%;\n}\n\nsvg {\n display: block;\n height: 100%;\n}\n\n#progress {\n width:"
},
{
"path": "local-dev/main.js",
"chars": 499,
"preview": "var ProgressBar = require('../src/main.js');\n\n\nfunction onLoad() {\n var bar = new ProgressBar.Circle('#progress', {\n "
},
{
"path": "mkdocs.yml",
"chars": 509,
"preview": "site_name: ProgressBar.js\nrepo_url: https://github.com/kimmobrunfeldt/progressbar.js\n\npages:\n - Home: index.md\n - API "
},
{
"path": "package.json",
"chars": 1925,
"preview": "{\n \"name\": \"progressbar.js\",\n \"version\": \"1.1.1\",\n \"description\": \"Responsive and slick progress bars with animated S"
},
{
"path": "saucelabs-browsers.js",
"chars": 1186,
"preview": "// Browsers on Sauce Labs\n// Check out https://saucelabs.com/platforms for all browser/platform combos\n// and https://wi"
},
{
"path": "src/circle.js",
"chars": 1036,
"preview": "// Circle shaped progress bar\n\nvar Shape = require('./shape');\nvar utils = require('./utils');\n\nvar Circle = function Ci"
},
{
"path": "src/line.js",
"chars": 935,
"preview": "// Line shaped progress bar\n\nvar Shape = require('./shape');\nvar utils = require('./utils');\n\nvar Line = function Line(c"
},
{
"path": "src/main.js",
"chars": 510,
"preview": "module.exports = {\n // Higher level API, different shaped progress bars\n Line: require('./line'),\n Circle: requ"
},
{
"path": "src/path.js",
"chars": 5155,
"preview": "// Lower level API to animate any kind of svg path\n\nvar shifty = require('shifty');\nvar utils = require('./utils');\n\nvar"
},
{
"path": "src/semicircle.js",
"chars": 1425,
"preview": "// Semi-SemiCircle shaped progress bar\n\nvar Shape = require('./shape');\nvar Circle = require('./circle');\nvar utils = re"
},
{
"path": "src/shape.js",
"chars": 9806,
"preview": "// Base object for different progress bar shapes\n\nvar Path = require('./path');\nvar utils = require('./utils');\n\nvar DES"
},
{
"path": "src/square.js",
"chars": 1504,
"preview": "// Square shaped progress bar\n// Note: Square is not core part of API anymore. It's left here\n// for reference. sq"
},
{
"path": "src/utils.js",
"chars": 3023,
"preview": "// Utility functions\n\nvar merge = require('lodash.merge');\n\nvar PREFIXES = 'Webkit Moz O ms'.split(' ');\nvar FLOAT_COMPA"
},
{
"path": "tools/lint.sh",
"chars": 220,
"preview": "#!/bin/bash\n# NOTE: Run this only from project root!\n\n# Run all lint commands and if one fails, exit non-zero return cod"
},
{
"path": "tools/release.js",
"chars": 8150,
"preview": "#!/usr/bin/env node\n\n// Release automation script inspired by\n// https://github.com/geddski/grunt-release\n\nvar fs = requ"
},
{
"path": "tools/test.sh",
"chars": 217,
"preview": "#!/bin/bash\n# NOTE: Run this only from project root!\n\n# Run all commands and if one fails, exit non-zero return code\n\nEX"
}
]
About this extraction
This page contains the full source code of the kimmobrunfeldt/progressbar.js GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 35 files (170.5 KB), approximately 46.6k tokens, and a symbol index with 143 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.