diff --git a/.gitignore b/.gitignore index a67f2d66..4782b1c2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /nbproject /node_modules +/build diff --git a/Gruntfile.js b/Gruntfile.js index cdf65eab..74d1497b 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,46 +1,5 @@ module.exports = function(grunt) { + "use strict"; - grunt.initConfig({ - pkg: grunt.file.readJSON('package.json'), - jshint: { - files: ['velocity.js', 'velocity.ui.js'], - options: { - browser: true, - curly: true, - eqeqeq: true, - eqnull: true, - esversion: 3, // Velocity 1.* - forin: false, // Should really be true - freeze: true, - funcscope: true, - futurehostile: true, - laxbreak: true, // Makes it very hard to write readable code in some places without this option - loopfunc: true, // Velocity 1.* - nocomma: true, - nonbsp: true, - notypeof: true, - strict: true, - globals: { - jQuery: true - } - } - }, - uglify: { - my_target: { - options: { - preserveComments: /^!/, - screwIE8: false // Velocity 1.* - }, - files: { - 'velocity.min.js': ['velocity.js'], - 'velocity.ui.min.js': ['velocity.ui.js'] - } - } - } - }); - - grunt.loadNpmTasks('grunt-contrib-jshint'); - grunt.loadNpmTasks('grunt-contrib-uglify'); - - grunt.registerTask('default', ['jshint', 'uglify']); + require("load-grunt-tasks")(grunt); }; diff --git a/README.md b/README.md index 29e298ed..cf38be48 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ -# Velocity 1.5.1 +# Velocity 2.0.0 beta + +# This is a public beta - files are *not* available on CDN ## Docs -[http://VelocityJS.org](http://velocityjs.org) +[https://github.com/julianshapiro/velocity/wiki](https://github.com/julianshapiro/velocity/wiki) ## News WhatsApp, Tumblr, Windows, Samsung, Uber, and thousands of other companies rely on Velocity. Visit [Libscore.com](http://libscore.com/#$.Velocity) to see which sites use Velocity on their homepage. @@ -14,17 +16,17 @@ NPM: https://www.npmjs.com/package/velocity-react ## Quickstart ### Velocity (CDN, choose one of them): ```html - - + + ``` ### Velocity UI pack (CDN, choose one of them): ```html - - + + ``` -> Please note that JSDelivr will automatically supply the latest release, while CloudFlare needs to ask for a specific version. +> Please note that JSDelivr can automatically supply the latest release, while CloudFlare needs to ask for a specific version. ### Package managers: _npm:_ `npm install velocity-animate`
@@ -34,6 +36,7 @@ _bower:_ `bower install velocity` Ask on [StackOverflow](http://stackoverflow.com/tags/velocity.js) (make sure you add the `[velocity.js]` and `[javascript]` tags). ## Updates +- **[2.0](https://github.com/julianshapiro/velocity/compare/1.5.0...2.0.0)**: Typescript update and complete refactoring. - **[1.5](https://github.com/julianshapiro/velocity/compare/1.4.0...1.5.0)**: Bugfixes, IE9 compatibility fixes. - **[1.4](https://github.com/julianshapiro/velocity/compare/1.3.0...1.4.0)**: Pause / Resume (per element or global).
Forcefed string animation (just have matching number spaces) including unit conversions and colour names (ie `background:["rgba(red,0.1)", "blue"]`). @@ -57,6 +60,6 @@ Various fixes including ticker (loading Velocity in a background window) and col ==== -[MIT License](LICENSE.md). © Julian Shapiro (http://twitter.com/shapiro).
-[Stripe](https://stripe.com/blog/stripe-open-source-retreat) sponsors Velocity's development.
-[BrowserStack](http://www.browserstack.com/) provides testing services. +[MIT License](LICENSE.md). © Julian Shapiro (http://twitter.com/shapiro). + +[![Kiss My Button](https://presskit.kissmybutton.gr/logos/kissmybutton-logo-small.png)](https://kissmybutton.gr) sponsors Velocity's development. diff --git a/V2_CHANGES.md b/V2_CHANGES.md new file mode 100644 index 00000000..82b8dd32 --- /dev/null +++ b/V2_CHANGES.md @@ -0,0 +1,22 @@ +# Major Changes in Velocity V2 + +* Transforms - Use these directly within CSS, don't try the old shortcuts as they don't exist. +* Colors - All web colors are supported internally. +* SVG - All SVG attributes are supported internally, though they must be placed on the correct type of element. +* Loop - This no longer copies the animation call, it calls it multiple times. +* Repeat - This is almost identical to loop, but only runs one way. +* Chaining - Chaining is awesome, use it. Chained commands are designed to operate on the chained animation, not on the elements within it. +* Styles - Use `element.velocity("style", "propertyName"[, value])`, the old .Hook has gone. +* Per-element - Animations are now copied per-element, and not one a one-animation-per-array basis as in other libraries (and old Velocity v1). +* Sync - You can now de-sync animations so they start immediately per-element, rather than waiting for all to be ready. +* Speed - You can control the speed of the animation playback. +* Delay - You can pass a negative number to start inside the animation rather than just having a delay before it. +* There are APIs for extending Velocity - see the various register* commands. +* Display - This is a property, no longer an option. +* Visibility - This is a property, no longer an option. + +# Currently disabled / not updated: + +* UI-Pack +* Reverse +* Scroll (working, but not happy with interface - it's a property if people want to play, alias of scrollTop, there's also scrollLeft) diff --git a/grunt/aliases/default.js b/grunt/aliases/default.js new file mode 100644 index 00000000..1ae6217d --- /dev/null +++ b/grunt/aliases/default.js @@ -0,0 +1,6 @@ +module.exports = function(grunt) { + grunt.registerTask("default", [ + "ts", + "uglify" + ]); +}; diff --git a/grunt/aliases/major.js b/grunt/aliases/major.js new file mode 100644 index 00000000..eb4b2a0d --- /dev/null +++ b/grunt/aliases/major.js @@ -0,0 +1,7 @@ +module.exports = function(grunt) { + grunt.registerTask("patch", [ + "bump-only:patch", + "default", + "bump-commit" + ]); +}; diff --git a/grunt/aliases/minor.js b/grunt/aliases/minor.js new file mode 100644 index 00000000..eb4b2a0d --- /dev/null +++ b/grunt/aliases/minor.js @@ -0,0 +1,7 @@ +module.exports = function(grunt) { + grunt.registerTask("patch", [ + "bump-only:patch", + "default", + "bump-commit" + ]); +}; diff --git a/grunt/aliases/patch.js b/grunt/aliases/patch.js new file mode 100644 index 00000000..eb4b2a0d --- /dev/null +++ b/grunt/aliases/patch.js @@ -0,0 +1,7 @@ +module.exports = function(grunt) { + grunt.registerTask("patch", [ + "bump-only:patch", + "default", + "bump-commit" + ]); +}; diff --git a/grunt/options/bump.js b/grunt/options/bump.js new file mode 100644 index 00000000..2087185d --- /dev/null +++ b/grunt/options/bump.js @@ -0,0 +1,9 @@ +module.exports = { + main: { + options: { + updateConfigs: ["pkg"], + commitFiles: ["package.json"], + pushTo: "origin" + } + } +}; diff --git a/grunt/options/pkg.js b/grunt/options/pkg.js new file mode 100644 index 00000000..55e4c2de --- /dev/null +++ b/grunt/options/pkg.js @@ -0,0 +1,3 @@ +module.exports = function(grunt) { + return grunt.file.readJSON("package.json"); +}; diff --git a/grunt/options/ts.js b/grunt/options/ts.js new file mode 100644 index 00000000..168da4f6 --- /dev/null +++ b/grunt/options/ts.js @@ -0,0 +1,17 @@ +module.exports = { + options: { + "fast": "never" + }, + main: { + "tsconfig": true, + "files": { + "build/velocity.js": ["src/app.ts"] + } + }, + test: { + "tsconfig": "test/tsconfig.json", + "files": { + "test/test.js": ["test/src/app.ts"] + } + } +}; diff --git a/grunt/options/uglify.js b/grunt/options/uglify.js new file mode 100644 index 00000000..0e23b768 --- /dev/null +++ b/grunt/options/uglify.js @@ -0,0 +1,53 @@ +module.exports = { + main: { + options: { + sourceMap: { + root: "src/", + includeSources: true + }, + sourceMapIn: "build/velocity.js.map", + compress: false, + mangle: false, + beautify: true, + output: { + comments: "all" + }, + banner: `/*! VelocityJS.org (<%= pkg.version %>) (C) 2014 Julian Shapiro. MIT @license: en.wikipedia.org/wiki/MIT_License */ +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + define('Velocity', [], function() { + return (root['Velocity'] = factory()); + }); + } else if (typeof module === 'object' && module.exports) { + module.exports = factory(); + } else { + root['Velocity'] = factory(); + } +}(this, function() { +`, + footer: ` + return VelocityFn; +})); +` + }, + files: { + "velocity.js": ["build/velocity.js"] + } + }, + min: { + options: { + sourceMap: false, + banner: `/*! <%= pkg.name %> v<%= pkg.version %> (<%= grunt.template.today('dddd dS mmmm yyyy, h:MM:ss TT') %>) */`, + compress: { + drop_console: true, + drop_debugger: true, + pure_getters: true, + unsafe: true + } + }, + files: { + "velocity.min.js": ["velocity.js"], + "velocity.ui.min.js": ["velocity.ui.js"] + } + } +}; diff --git a/grunt/options/watch.js b/grunt/options/watch.js new file mode 100644 index 00000000..3c9f8711 --- /dev/null +++ b/grunt/options/watch.js @@ -0,0 +1,10 @@ +module.exports = { + main: { + files: ["index.d.ts", "src/**/*.ts"], + tasks: ["default"] + }, + test: { + files: ["test/src/**/*.ts"], + tasks: ["ts:test"] + } +}; diff --git a/index.d.ts b/index.d.ts new file mode 100644 index 00000000..58d69658 --- /dev/null +++ b/index.d.ts @@ -0,0 +1,872 @@ +/** + * Interfaces for VelocityJS + */ + +/** + * Velocity can run on both HTML and SVG elements. + */ +type HTMLorSVGElement = HTMLElement | SVGElement; + +/** + * All easings must return the current value given the start and end values, and + * a percentage complete. The property name is also passed in case that makes a + * difference to how values are used. + */ +type VelocityEasingFn = (percentComplete: number, startValue: number, endValue: number, property?: string) => number; + +/** + * Used for action callbacks. + */ +type VelocityActionFn = (args?: any[], elements?: VelocityResult, promiseHandler?: VelocityPromise, action?: string) => any; + +/** + * Used for normalization callbacks. + * + * @param element The element to be called on. + * + * @param propertyValue The value to set. If undefined then this is + * a get action and must return a string value for that element. + * + * @returns If a set action then returning any truthy value will prevent it + * trying to set the element.style[propertyName] value afterward + * returning. + */ +type VelocityNormalizationsFn = ((element: HTMLorSVGElement, propertyValue: string) => boolean) & ((element: HTMLorSVGElement) => string); + +/** + * List of all easing types for easy code completion in TypeScript + */ +type VelocityEasingType = VelocityEasingFn + | "linear" | "swing" | "spring" + | "ease" | "easeIn" | "easeOut" | "easeInOut" | "easeInSine" | "easeOutSine" + | "easeInOutSine" | "easeInQuad" | "easeOutQuad" | "easeInOutQuad" + | "easeInCubic" | "easeOutCubic" | "easeInOutCubic" | "easeInQuart" + | "easeOutQuart" | "easeInOutQuart" | "easeInQuint" | "easeOutQuint" + | "easeInOutQuint" | "easeInExpo" | "easeOutExpo" | "easeInOutExpo" + | "easeInCirc" | "easeOutCirc" | "easeInOutCirc" + | "ease-in" | "ease-out" | "ease-in-out" + | "at-start" | "at-end" | "during" + | string + | number[]; + +/** + * The return type of any velocity call. If this is called via a "utility" + * function (such a jQuery $(elements).velocity(...)) then it will + * be based on the array-like list of elements supplied, otherwise it will + * create a plain array. The extra values for Promises and Velocity are inserted + * into the array in such a way as to not interfere with other methods unless + * they are specifically overwriting them. + */ +type VelocityResult = Promise & HTMLorSVGElement[] & VelocityExtended; + +// TODO: I don't like having two of these - need to merge into a type or similar +type VelocityObjectArgs = { + elements?: HTMLorSVGElement[]; + properties?: VelocityProperties; + options?: VelocityOptions; + e?: HTMLorSVGElement[]; + p?: VelocityProperties; + o?: VelocityOptions; +}; + +/** + * The various formats of Element argument for Velocity. Some libraries such as + * jQuery and Zepto provide an array-like + */ +type VelocityElements = HTMLorSVGElement | HTMLorSVGElement[] | VelocityResult; + +/** + * A property value can be a string or a number. If it is a number then it will + * get the correct unit added to it depending on the property name if required. + */ +type VelocityPropertyValue = number | string | [number | string] | [number | string, VelocityEasingType | number | string] | [number | string, VelocityEasingType, number | string]; + +/** + * A callback to allow us to generate a property value for a property name. + */ +type VelocityPropertyFn = (this: HTMLorSVGElement, index?: number, total?: number, elements?: VelocityElements) => VelocityPropertyValue; + +/** + * A callback to allow us to generate a property start / end value. + */ +type VelocityPropertyValueFn = (this: HTMLorSVGElement, index?: number, total?: number) => number | string; + +/** + * A property value can be a string or a number. If it is a number then it will + * get the correct unit added to it depending on the property name if required. + */ +type VelocityProperty = VelocityPropertyValue | VelocityPropertyFn; + +// TODO: | ((element: HTMLorSVGElement, index: number, elements: HTMLorSVGElement[]) => number | string); + +/** + * The properties that are permitted to be animated. + * TODO: Add SVG and "Tween" properties. Should (can?) this get html / svg specifics later + */ +type VelocityProperties = { + [property in keyof CSSStyleDeclaration]?: VelocityProperty; +}; + +/** + * A callback used at the beginning or end of an animation. + */ +type VelocityCallback = (this: VelocityExtended & HTMLorSVGElement[], elements?: VelocityExtended & HTMLorSVGElement[], activeCall?: AnimationCall) => void; + +/** + * A callback used for progress tracking. + */ +type VelocityProgress = (this: VelocityExtended & HTMLorSVGElement[], elements?: VelocityExtended & HTMLorSVGElement[], percentComplete?: number, remaining?: number, tweenValue?: number, activeCall?: AnimationCall) => void; + +// TODO: Clean this up, add comments, remove deprecated options +interface VelocityOptions { + backwards?: boolean; + /** + * Begin handler. Only the first element to check this callback gets to use + * it. + * + * @default: undefined + */ + begin?: VelocityCallback; + /** + * Complete handler (only the last element in a set gets this). + * + * @default: undefined + */ + complete?: VelocityCallback; + /** + * How long the animation should delay after becoming active and before it + * actually starts to animate. This is a millisecond timer, but + * can handle some string values. + * "fast" = 200ms + * "normal" = 400ms + * "slow" = 600ms + * NOTE: If passing a negative number then this will allow you to start with + * the animation partially complete from the start. + * + * @default 0 + */ + delay?: "fast" | "normal" | "slow" | number; + drag?: boolean; + /** + * How long the animation should run for. This is a millisecond timer, but + * can handle some string values. + * "fast" = 200ms + * "normal" = 400ms (default) + * "slow" = 600ms + * + * @default 400 + */ + duration?: "fast" | "normal" | "slow" | number; + /** + * Easing is the rate of change over time for an animation. A linear easing + * would simply be 1% of the time to 1% of the animation. This allows you + * to specify how that rate of change should be. There are various named + * easings, but you can also supply your own. + * + * TODO: Copy more of the original description + * + * @default "swing" + */ + easing?: VelocityEasingType; + /** + * Maximum number of frames to render on each second for all animations + * + * @default 60 + */ + fpsLimit?: number; + /** + * How many times should this option loop. A loop is defined as a "return to + * start values", so it will run, then reverse. This counts as a single + * loop. Setting loop:4 will cause the animation to take the + * same time as 4n+1 iterations. + * + * @default 0 + */ + loop?: boolean | number; + /** + * The minimum frame time to achieve, the value is calculated based on fpsLimit + * + * @default 16.33333333 (1000ms / 60fps) + */ + minFrameTime?: number; + mobileHA?: boolean; + /** + * Progress handler (only the last element in a set gets this) + * + * @default: undefined + */ + progress?: VelocityProgress; + /** + * If this should return a Promise with everything else. If promises are not + * required at all, then simply setting it globally will turn them off. + * + * @default true + */ + promise?: boolean; + /** + * If promises are turned on, then the promise can reject if there are no + * elements supplied (an empty array is still valid). + * + * @default false + */ + promiseRejectEmpty?: boolean; + /** + * The name of the queue to use. If this is set to false then + * it will be added immediately ignoring any other queues running. Queues + * start playing automatically (unlike jQuery, this doesn't need a queue to + * be manually started). + * + * @default "" + */ + queue?: false | string; + /** + * How many times should this animation repeat. A repeat will restart at + * initial values and animate once. This is most useful for rotating + * animations where 0deg === 360deg. If you are after a more + * "bounce" effect then look at loop. + * + * @default 0 + */ + repeat?: boolean | number; + /** + * The speed to play the animation back at. This number can change while + * running, in order to vary the playback rate. + * + * @default 0 + */ + speed?: number; + stagger?: string | number; + /** + * When adding animations to elements each element has its own queue of + * pending animations. This ensures that when adding a single animation to + * multiple elements, they all begin at the same time. + * + * @default true + */ + sync?: boolean; + /** + * @deprecated + */ + container?: string | HTMLorSVGElement; + /** + * @deprecated + */ + display?: string | boolean; + /** + * @deprecated + */ + visibility?: boolean | string; + /** + * @deprecated + */ + offset?: number; + + /** + * Should the cache be used for the tweens. Turning this off can improve + * memory usage slightly, but will also make things slower when creating + * animations. + * + * @private + * @default true + */ + cache?: boolean; +} + +/** + * Used internally for storing the Promise if used. + */ +interface VelocityPromise { + /** + * A saved copy of the Promise. + * + * @private + */ + _promise?: Promise; + /** + * This method is called at most once to signify that the animation has + * completed. Currently a loop:true animation will never complete. This + * allows .then(fn) to run (see Promise support). + * + * @private + */ + _resolver?: (value?: (HTMLorSVGElement[] & VelocityExtended) | PromiseLike) => void; + /** + * This method is called at most once to signify that the animation has + * completed. Currently a loop:true animation will never complete. This + * allows .then(fn) to run (see Promise support). + * + * @private + */ + _rejecter?: (reason?: any) => void; +} + +/** + * After correcting the options so they are usable internally, they will be of + * this type. The base VelocityOptions includes human readable and shortcuts, + * which this doesn't. + */ +interface StrictVelocityOptions extends VelocityOptions, VelocityPromise { + /** + * Begin handler. Only the first element to check this callback gets to use + * it. Cleared after calling + * + * @private + */ + begin?: VelocityCallback; + /** + * Complete handler (only the last element in a set gets this) + * + * @private + */ + complete?: VelocityCallback; + /** + * The amount of delay before this animation can start doing anything. + */ + delay?: number; + /** + * The length of time this animation will run for. + */ + duration?: number; + /** + * Easing for this animation while running. + */ + easing?: VelocityEasingFn; + /** + * Loop, calls 2n-1 times reversing it each iteration + */ + loop?: true | number; + /** + * TODO: Remove this so it's a normal property + */ + mobileHA?: boolean; + /** + * Progress handler (only the last element in a set gets this) + * + * @private + */ + progress?: VelocityProgress; + /** + * Queue + */ + queue?: false | string; + /** + * Repeat this number of times. If looped then each iteration of the loop + * is actually repeated this number of times. + */ + repeat?: true | number; + /** + * This is a cache of the repeat value. When looping and repeating work + * together, the repeat is looped, so it needs to remember how many repeats + * to perform for each loop. + */ + repeatAgain?: true | number; + //} + // + //interface ExtendedVelocityOptions extends StrictVelocityOptions { + /** + * The first AnimationCall to get this - used for the progress callback. + * + * @private + */ + _first?: AnimationCall; + /** + * The total number of AnimationCalls that are pointing at this. + * + * @private + */ + _total?: number; + /** + * The number of AnimationCalls that are ready to start. + * + * @private + */ + _ready?: number; + /** + * The number of AnimationCalls that have started. + * + * @private + */ + _started?: number; + /** + * The number of AnimationCalls that have finished. + * + * @private + */ + _completed?: number; +} + +/** + * Global per-Element data. This is persistent between animations, and freed + * when the garbage collector removes the Element because it is no longer being + * used. + */ +interface ElementData { + /** + * A generated enum of types of this element, used for Normalizations. + */ + types: number; + /** + * A local cache of the current style values we're using, this is 80x faster + * than element.style access. + * + * Empty strings are set to null to get the value from getComputedStyle + * instead. If getComputedStyle returns an empty string then that is saved. + */ + cache: CSSStyleDeclaration; + /** + * A cached copy of getComputedStyle, this is 50% the speed of + * element.style access. + */ + computedStyle?: CSSStyleDeclaration; + /** + * Changed as animations start and finish on an element. This allows us to + * keep track of exactly how many are running at a given time. + */ + count: number; + /** + * Animations to be run for each queue. The animations are linked lists, + * but treated as a FIFO queue (new ones are added to the end). When the + * queue is empty (but still running) the key will still exist with a value + * of "null". When the queue is empty and the next entry is pulled from it + * then it will be set to "undefined". + * + * The default queue is an empty string - "" + */ + queueList: {[name: string]: AnimationCall}; + /** + * Last properties tweened per each queue. Used for both "reverse" and + * "repeat" methods. + */ + lastAnimationList: {[name: string]: AnimationCall}; + /** + * The time the last animation on an element finished. This is used for + * starting a new animation and making sure it follows directly if possible, + * otherwise it will start as if one frame in already. + */ + lastFinishList: {[name: string]: number}; +} + +type VelocityTween = [(string | number)[], VelocityEasingFn, (string | number)[], (string | number)[], boolean[]]; + +/** + * AnimationFlags are used internally. These are subject to change as they are + * only valid for the internal state of the current version of Velocity. + * + * To get these values use the "option" action with a key of "isReady" etc. All + * of these are gettable with the same pattern of keyname. + * + * @private + */ +declare const enum AnimationFlags { + /** + * When the tweens are expanded this is set to save future processing. + */ + EXPANDED = 1 << 0, + /** + * Set once the animation is ready to start - after any delay (and possible + * pause). + */ + READY = 1 << 1, + /** + * Set once the animation has started. + */ + STARTED = 1 << 2, + /** + * Set when an animation is manually stopped. + */ + STOPPED = 1 << 3, + /** + * The pause state of this animation. If true it is paused, if false it was + * paused and needs to be resumed, and if undefined / null then not either. + */ + PAUSED = 1 << 4, + /** + * Set when the animation is a sync animation. + */ + SYNC = 1 << 5, + /** + * When the animation is running in reverse, such as for a loop. + */ + REVERSE = 1 << 6, +} + +interface AnimationCall extends StrictVelocityOptions { + /** + * Used to store the next AnimationCell in this list. + * + * @private + */ + _next?: AnimationCall; + /** + * Used to store the previous AnimationCell in this list. Used to make + * removing items from the list significantly easier. + * + * @private + */ + _prev?: AnimationCall; + /** + * Used to store the next call with a Progress callback. + * + * @private + */ + _nextProgress?: AnimationCall; + /** + * Used to store the next call with a Complete callback. + * + * @private + */ + _nextComplete?: AnimationCall; + /** + * A number of flags for use in tracking an animation. + */ + _flags: number; + /** + * Properties to be tweened + */ + tweens?: {[property: string]: VelocityTween}; + /** + * The current value for the "tween" property, defaults to a percentage if + * not used. + */ + tween?: string; + /** + * The element this specific animation is for. If there is more than one in + * the elements list then this will be duplicated when it is pulled off a + * queue. + */ + element?: HTMLorSVGElement; + /** + * The list of elements associated with this specific animation. + * TODO: This should be removed so we're not trying to lock an element. + * Without this entry, any removed elements will simply not exist in Data + * (a WeakMap) and then can be removed from the list of animations. + * @deprecated + */ + elements?: HTMLorSVGElement[]; + /** + * Shared options for the entire set of elements. + */ + options?: StrictVelocityOptions; + /** + * The time this animation started according to whichever clock we are + * using. + */ + timeStart?: number; + /** + * The time (in ms) that this animation has already run. Used with the + * duration and easing to provide the exact tween needed. + */ + ellapsedTime?: number; + /** + * The percentage complete as a number 0 <= n <= 1 + */ + percentComplete?: number; +} + +/** + * VelocityChain is used to extend the chained Velocity calls with specific + * actions and their arguments. + */ +interface VelocityChain { + (action: string, ...args: any[]): any | VelocityResult; + (propertyMap: string | VelocityProperties, complete?: () => void): VelocityResult; + (propertyMap: string | VelocityProperties, duration?: number | "fast" | "normal" | "slow", complete?: () => void): VelocityResult; + (propertyMap: string | VelocityProperties, duration?: number | "fast" | "normal" | "slow", easing?: VelocityEasingType, complete?: () => void): VelocityResult; + (propertyMap: string | VelocityProperties, easing?: VelocityEasingType, complete?: () => void): VelocityResult; + (propertyMap: string | VelocityProperties, option?: VelocityOptions): VelocityResult; +} + +/** + * Direct Velocity access. + */ +interface Velocity { + // TODO: Add all variations of the velocity argument formats allowed. Make them TYPE based as they're used in multiple places. + (options: VelocityObjectArgs): VelocityResult; + (action: string, ...args: any[]): VelocityResult; + (elements: VelocityElements, action: string, ...args: any[]): VelocityResult; + (elements: VelocityElements, propertyMap: VelocityProperties, complete?: () => void): VelocityResult; + (elements: VelocityElements, propertyMap: VelocityProperties, duration?: number | "fast" | "normal" | "slow", complete?: () => void): VelocityResult; + (elements: VelocityElements, propertyMap: VelocityProperties, duration?: number | "fast" | "normal" | "slow", easing?: string | number[], complete?: () => void): VelocityResult; + (elements: VelocityElements, propertyMap: VelocityProperties, easing?: string | number[], complete?: () => void): VelocityResult; + (elements: VelocityElements, propertyMap: VelocityProperties, options?: VelocityOptions): VelocityResult; + + defaults: VelocityOptions & { + /** + * Provided in order to reset Velocity defaults back to their initial + * state. + */ + reset: () => void + }; + + queue(element: HTMLorSVGElement, animation: AnimationCall, queue?: string | boolean): void; + dequeue(element: HTMLorSVGElement, queue?: string | boolean, skip?: boolean): AnimationCall; + freeAnimationCall(animation: AnimationCall): void; + pauseAll(queueName?: string | false): void; + resumeAll(queueName?: string | false): void; + RunSequence(originalSequence): void; + RegisterEffect(effectName: string, properties): Velocity; + + /** + * Available to be able to check what version you're running against. + */ + readonly version: { + readonly major: number; + readonly minor: number; + readonly patch: number; + } + + CSS: { + getPropertyValue(element: HTMLorSVGElement, property: string, rootPropertyValue?: string, forceStyleLookup?: boolean): string; + getUnit(str: string, start?: number): string; + fixColors(str: string): string; + Normalizations: {[name: string]: VelocityNormalizationsFn}; + Names: { + camelCase(property: string): string; + SVGAttribute(property: string): boolean; + prefixCheck(property: string): [string, boolean]; + }; + Values: { + hexToRgb(hex: string): [number, number, number]; + isCSSNullValue(value: any): boolean; + getUnitType(property: string): string; + getDisplayType(element: HTMLorSVGElement): string; + addClass(element: HTMLorSVGElement, className: string): void; + removeClass(element: HTMLorSVGElement, className: string): void; + }; + }; + /** + * Current internal state of Velocity. + */ + readonly State: { + /** + * Detect if this is a NodeJS or web browser + */ + readonly isClient: boolean; + /** + * Detect mobile devices to determine if mobileHA should be turned + * on. + */ + readonly isMobile: boolean; + /** + * The mobileHA option's behavior changes on older Android devices + * (Gingerbread, versions 2.3.3-2.3.7). + */ + readonly isAndroid: boolean; + /** + * The mobileHA option's behavior changes on older Android devices + * (Gingerbread, versions 2.3.3-2.3.7). + */ + readonly isGingerbread: boolean; + /** + * Chrome browser + */ + readonly isChrome: boolean; + /** + * Firefox browser + */ + readonly isFirefox: boolean; + /** + * Create a cached element for re-use when checking for CSS property + * prefixes. + */ + readonly prefixElement: boolean; + /** + * Cache every prefix match to avoid repeating lookups. + */ + readonly prefixMatches: {[property: string]: string}; + /** + * Retrieve the appropriate scroll anchor and property name for the + * browser: https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY + * + * @deprecated + */ + windowScrollAnchor: boolean; + /** + * Cache the anchor used for animating window scrolling. + * + * @deprecated + */ + scrollAnchor: Element; + /** + * Cache the browser-specific property names associated with the + * + * @deprecated + * scroll anchor. + */ + scrollPropertyLeft: string; + /** + * Cache the browser-specific property names associated with the + * + * @deprecated + * scroll anchor. + */ + scrollPropertyTop: string; + /** + * Keep track of whether our RAF tick is running. + */ + readonly isTicking: boolean; + /** + * Container for every in-progress call to Velocity. + */ + readonly first: AnimationCall; + /** + * Container for every in-progress call to Velocity. + */ + readonly last: AnimationCall; + /** + * First new animation - to shortcut starting them all up and push + * any css reads to the start of the tick + */ + readonly firstNew: AnimationCall; + }; +} + +/** + * Chaining Velocity calls from various sources. + */ +interface VelocityExtended { + velocity: Velocity & VelocityChain & { + /** + * TODO: Decide if this should be public + * @private + */ + animations: AnimationCall[] + } +} + +//////////////////// +// Action: Finish // +//////////////////// +interface Velocity { + (action: "finish", stopAll?: true): VelocityResult; + (action: "finish", queue?: string | false, stopAll?: true): VelocityResult; + (elements: VelocityElements, action: "finish", stopAll?: true): VelocityResult; + (elements: VelocityElements, action: "finish", queue?: string | false, stopAll?: true): VelocityResult; +} + +interface VelocityChain { + (action: "finish", stopAll?: true): VelocityResult; + (action: "finish", queue?: string | false, stopAll?: true): VelocityResult; +} + +//////////////////// +// Action: Option // +//////////////////// +interface Velocity { + (action: "option", option: string): any; + (action: "option", option: string, value: any): VelocityResult; + (elements: VelocityElements, action: "option", option: string): any; + (elements: VelocityElements, action: "option", option: string, value: any): VelocityResult; +} + +interface VelocityChain { + (action: "option", option: string): any; + (action: "option", option: string, value: any): VelocityResult; +} + +/////////////////// +// Action: Pause // +/////////////////// +interface Velocity { + (action: "pause", queue?: string): VelocityResult; + (elements: VelocityElements, action: "pause", queue?: string): VelocityResult; +} + +interface VelocityChain { + (action: "pause", queue?: string): VelocityResult; +} + +//////////////////// +// Action: Resume // +//////////////////// +interface Velocity { + (action: "resume", queue?: string): VelocityResult; + (elements: VelocityElements, action: "resume", queue?: string): VelocityResult; +} + +interface VelocityChain { + (action: "resume", queue?: string): VelocityResult; +} + +//////////////////// +// Action: Resume // +//////////////////// +interface Velocity { + (action: "resume", queue?: string): VelocityResult; + (elements: VelocityElements, action: "resume", queue?: string): VelocityResult; +} + +interface VelocityChain { + (action: "resume", queue?: string): VelocityResult; +} + +////////////////// +// Action: Stop // +////////////////// +interface Velocity { + (action: "stop", stopAll?: true): VelocityResult; + (action: "stop", queue?: string | false, stopAll?: true): VelocityResult; + (elements: VelocityElements, action: "stop", stopAll?: true): VelocityResult; + (elements: VelocityElements, action: "stop", queue?: string | false, stopAll?: true): VelocityResult; +} + +interface VelocityChain { + (action: "stop", stopAll?: true): VelocityResult; + (action: "stop", queue?: string | false, stopAll?: true): VelocityResult; +} + +/////////////////// +// Action: Style // +/////////////////// +interface Velocity { + (action: "style", property: {[property: string]: string}): VelocityResult; + (action: "style", property: string): string | string[]; + (action: "style", property: string, value: string): VelocityResult; + (element: HTMLorSVGElement, action: "style", property: string): string; + (elements: VelocityElements, action: "style", property: {[property: string]: string}): VelocityResult; + (elements: VelocityElements, action: "style", property: string): string | string[]; + (elements: VelocityElements, action: "style", property: string, value: string): VelocityResult; + + style(elements: VelocityResult, property: {[property: string]: string}): VelocityResult; + style(elements: VelocityResult, property: string): string | string[]; + style(elements: VelocityResult, property: string, value: string): VelocityResult; +} + +interface VelocityChain { + (action: "style", property: {[property: string]: string}): VelocityResult; + (action: "style", property: string): string | string[]; + (action: "style", property: string, value: string): VelocityResult; +} + +/////////////////// +// Action: Tween // +/////////////////// +interface Velocity { + (action: "tween", percentComplete: number, property: string, value: VelocityPropertyValue, easing?: VelocityEasingType): string; + (action: "tween", percentComplete: number, propertyMap: VelocityProperties, easing?: VelocityEasingType): {[property in keyof CSSStyleDeclaration]?: string}; + (elements: VelocityElements, action: "tween", percentComplete: number, property: string, value: VelocityPropertyValue, easing?: VelocityEasingType): string; + (elements: VelocityElements, action: "tween", percentComplete: number, propertyMap: VelocityProperties, easing?: VelocityEasingType): {[property in keyof CSSStyleDeclaration]?: string}; +} + +interface VelocityChain { + (action: "tween", percentComplete: number, property: string, value: VelocityPropertyValue, easing?: VelocityEasingType): string; + (action: "tween", percentComplete: number, propertyMap: VelocityProperties, easing?: VelocityEasingType): {[property in keyof CSSStyleDeclaration]?: string}; +} + +/** + * Extend the return value from document.querySelectorAll(). + */ +interface NodeListOf extends VelocityExtended {} + +/** + * Extend Element directly. + */ +interface Element extends VelocityExtended {} + +/** + * Extend Element directly. + */ +interface HTMLCollection extends VelocityExtended {} + +declare const Velocity: Velocity; + diff --git a/legacy/README.md b/legacy/README.md new file mode 100644 index 00000000..c1ff65ae --- /dev/null +++ b/legacy/README.md @@ -0,0 +1,3 @@ +This folder contains code that is planned to go into a legacy browser support Javascript file for people targeting older versions of IE. + +This is a very low priority process, so there is no ETA (though people stating what parts are needed will help). diff --git a/legacy/blur.ts b/legacy/blur.ts new file mode 100644 index 00000000..f3ec76fa --- /dev/null +++ b/legacy/blur.ts @@ -0,0 +1,35 @@ +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + */ + +//namespace VelocityStatic.CSS { +// export function blur(element, propertyValue) { +// if (propertyValue === undefined) { +// let extracted = parseFloat(propertyValue); +// +// /* If extracted is NaN, meaning the value isn't already extracted. */ +// if (!(extracted || extracted === 0)) { +// let blurComponent = propertyValue.toString().match(/blur\(([0-9]+[A-z]+)\)/i); +// +// /* If the filter string had a blur component, return just the blur value and unit type. */ +// if (blurComponent) { +// extracted = blurComponent[1]; +// /* If the component doesn't exist, default blur to 0. */ +// } else { +// extracted = 0; +// } +// } +// +// return extracted + "px"; +// } +// /* For the blur effect to be fully de-applied, it needs to be set to "none" instead of 0. */ +// if (!parseFloat(propertyValue)) { +// return "none"; +// } +// return "blur(" + propertyValue + ")"; +// } +// +// registerNormalization(["blur", blur]); +//} diff --git a/legacy/borderColor.ts b/legacy/borderColor.ts new file mode 100644 index 00000000..ba2ee638 --- /dev/null +++ b/legacy/borderColor.ts @@ -0,0 +1,74 @@ +/// +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + */ + +namespace VelocityStatic.CSS { + /** + * Handle a browser not supplying a compound borderColor property. + */ + function borderColor(element: HTMLorSVGElement): string; + function borderColor(element: HTMLorSVGElement, propertyValue: string): boolean; + function borderColor(element: HTMLorSVGElement, propertyValue?: string): string | boolean { + if (propertyValue === undefined) { + var top = getPropertyValue(element, "borderTopColor", true), + right = getPropertyValue(element, "borderRightColor", true), + bottom = getPropertyValue(element, "borderBottomColor", true), + left = getPropertyValue(element, "borderLeftColor", true); + + if (left === right) { + if (top === bottom) { + if (top === left) { + return top; + } + return top + " " + right; + } + return top + " " + right + " " + bottom; + } + return top + " " + right + " " + bottom + " " + left; + } + let sides = propertyValue.match(/((rgba?|hsla?)\([^\)]+\)|#[0-9a-f])/gi); + + if (sides.length) { + switch (sides.length) { + default: + break; + + case 2: + top = right = bottom = left = sides[1]; + break; + + case 3: + top = bottom = sides[1]; + left = right = sides[2]; + break; + + case 4: + top = sides[1]; + left = right = sides[2]; + bottom = sides[3]; + break; + + case 5: + top = sides[1]; + right = sides[2]; + bottom = sides[3]; + left = sides[4]; + break; + } + } + setPropertyValue(element, "borderColorTop", top); + setPropertyValue(element, "borderColorRight", right); + setPropertyValue(element, "borderColorBottom", bottom); + setPropertyValue(element, "borderColorLeft", left); + return true; + } + + let style = State.prefixElement.style; + + if (!style.borderColor && style.borderTopColor) { + registerNormalization(["borderColor", borderColor]); + } +} diff --git a/legacy/clip.ts b/legacy/clip.ts new file mode 100644 index 00000000..3966251d --- /dev/null +++ b/legacy/clip.ts @@ -0,0 +1,30 @@ +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + */ + +//namespace VelocityStatic.CSS { +// export function clip(element, propertyValue) { +// if (propertyValue === undefined) { +// let extracted; +// +// /* If Velocity also extracted this value, skip extraction. */ +// if (CSS.RegEx.wrappedValueAlreadyExtracted.test(propertyValue)) { +// extracted = propertyValue; +// } else { +// /* Remove the "rect()" wrapper. */ +// extracted = propertyValue.toString().match(CSS.RegEx.valueUnwrap); +// +// /* Strip off commas. */ +// extracted = extracted ? extracted[1].replace(/,(\s+)?/g, " ") : propertyValue; +// } +// +// return extracted; +// } else { +// return "rect(" + propertyValue + ")"; +// } +// } +// +// registerNormalization(["clip", clip]); +//} \ No newline at end of file diff --git a/legacy/normalisations.ts b/legacy/normalisations.ts new file mode 100644 index 00000000..f0b2a019 --- /dev/null +++ b/legacy/normalisations.ts @@ -0,0 +1,23 @@ +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + */ + +// TODO: Need to override all properties for IE<=8 + +if (IE <= 8) { + try { + /* A try/catch is used for IE<=8, which throws an error when "invalid" CSS values are set, e.g. a negative width. + Try/catch is avoided for other browsers since it incurs a performance overhead. */ + if (Normalizations[propertyName]) { + Normalizations[propertyName](element, propertyValue); + } else { + element.style[propertyName] = propertyValue; + } + } catch (error) { + if (debug) { + console.log("Browser does not support [" + propertyValue + "] for [" + propertyName + "]"); + } + } +} diff --git a/legacy/opacity.ts b/legacy/opacity.ts new file mode 100644 index 00000000..b0190f55 --- /dev/null +++ b/legacy/opacity.ts @@ -0,0 +1,43 @@ +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + */ + +namespace VelocityStatic.CSS { + if (IE <= 8) { + /** + * IE8 and below returns a "filter" value of "alpha(opacity=\d{1,3})". + * Extract the value and convert it to a decimal value to match the + * standard CSS opacity property's formatting. + */ + function opacity(element: HTMLorSVGElement): string; + function opacity(element: HTMLorSVGElement, propertyValue: string): boolean; + function opacity(element: HTMLorSVGElement, propertyValue?: string): string | boolean { + if (propertyValue === undefined) { + let filterValue: number | string = getPropertyValue(element, "filter"), + extracted = filterValue.toString().match(/alpha\(opacity=(.*)\)/i); + + return String(extracted ? parseInt(extracted[1]) / 100 : 1); + } + let value = parseFloat(propertyValue); + + // Opacified elements are required to have their zoom + // property set to a non-zero value. + setPropertyValue(element, "zoom", 1); + // Setting the filter property on elements with certain font + // property combinations can result in a highly unappealing + // ultra-bolding effect. There's no way to remedy this through + // a tween, but dropping the value altogether (when opacity + // hits 1) at leasts ensures that the glitch is gone + // post-tweening. + + // As per the filter property's spec, convert the decimal value + // to a whole number and wrap the value. + setPropertyValue(element, "filter", value >= 1 ? "" : "alpha(opacity=" + Math.floor(value * 100) + ")"); + return true; + } + + registerNormalization(["opacity", opacity]); + } +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..cbc4e3df --- /dev/null +++ b/package-lock.json @@ -0,0 +1,2984 @@ +{ + "name": "velocity-animate", + "version": "2.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@types/qunit": { + "version": "2.0.31", + "resolved": "https://registry.npmjs.org/@types/qunit/-/qunit-2.0.31.tgz", + "integrity": "sha1-pT4s9jUmLIv0anGhN9jHlw3elWI=", + "dev": true + }, + "abbrev": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", + "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", + "dev": true + }, + "ansi-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz", + "integrity": "sha1-xQYbbg74qBd15Q9dZhUb9r83EQc=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "anymatch": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "dev": true, + "requires": { + "micromatch": "2.3.11", + "normalize-path": "2.1.1" + } + }, + "argparse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.7.tgz", + "integrity": "sha1-wolQZIBVeBDxSovGLXoG9j7X+VE=", + "dev": true, + "requires": { + "sprintf-js": "1.0.3" + } + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "1.1.0" + } + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "array-differ": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", + "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=", + "dev": true + }, + "array-find-index": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.1.tgz", + "integrity": "sha1-C8Jd2slB7IpJauJY/UrBiAA+868=", + "dev": true + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "1.0.3" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "async-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", + "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", + "dev": true + }, + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", + "dev": true + }, + "binary-extensions": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", + "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", + "dev": true + }, + "body-parser": { + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.14.2.tgz", + "integrity": "sha1-EBXLH+LEQ4WCWVgdtTMy+NDPUPk=", + "dev": true, + "requires": { + "bytes": "2.2.0", + "content-type": "1.0.2", + "debug": "2.2.0", + "depd": "1.1.0", + "http-errors": "1.3.1", + "iconv-lite": "0.4.13", + "on-finished": "2.3.0", + "qs": "5.2.0", + "raw-body": "2.1.7", + "type-is": "1.6.15" + }, + "dependencies": { + "qs": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-5.2.0.tgz", + "integrity": "sha1-qfMRQq9GjLcrJbMBNrokVoNJFr4=", + "dev": true + } + } + }, + "brace-expansion": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz", + "integrity": "sha1-cZfX6qm4fmSDkOph/GbIRCdCDfk=", + "dev": true, + "requires": { + "balanced-match": "0.4.2", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "requires": { + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" + } + }, + "browserify-zlib": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz", + "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=", + "dev": true, + "requires": { + "pako": "0.2.9" + } + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, + "bytes": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.2.0.tgz", + "integrity": "sha1-/TVGSkA/b5EXwt42Cez/nK4ABYg=", + "dev": true + }, + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "dev": true + }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "dev": true, + "requires": { + "camelcase": "2.1.1", + "map-obj": "1.0.1" + } + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "chokidar": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", + "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "dev": true, + "requires": { + "anymatch": "1.3.2", + "async-each": "1.0.1", + "fsevents": "1.1.3", + "glob-parent": "2.0.0", + "inherits": "2.0.1", + "is-binary-path": "1.0.1", + "is-glob": "2.0.1", + "path-is-absolute": "1.0.0", + "readdirp": "2.1.0" + } + }, + "cli": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz", + "integrity": "sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ=", + "dev": true, + "requires": { + "exit": "0.1.2", + "glob": "7.1.1" + }, + "dependencies": { + "glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", + "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.5", + "inherits": "2.0.1", + "minimatch": "3.0.3", + "once": "1.3.3", + "path-is-absolute": "1.0.0" + } + } + } + }, + "coffee-script": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.10.0.tgz", + "integrity": "sha1-EpOLz5vhlI+gBvkuDEyegXBRCMA=", + "dev": true + }, + "colors": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", + "dev": true + }, + "commander": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz", + "integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.3", + "typedarray": "0.0.6" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha1-No8lEtefnUb9/HE0mueHi7weuVw=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha1-D8Z9fBQYJd6UKC3VNr7GubzoYKs=", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, + "console-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", + "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", + "dev": true, + "requires": { + "date-now": "0.1.4" + } + }, + "content-type": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.2.tgz", + "integrity": "sha1-t9ETrueo3Se9IRM8TcJSnfFyHu0=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "csproj2ts": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/csproj2ts/-/csproj2ts-1.0.0.tgz", + "integrity": "sha1-INXQqnzrzE9YzHFd01UY/gUi5iU=", + "dev": true, + "requires": { + "es6-promise": "4.1.1", + "lodash": "4.17.4", + "semver": "5.4.1", + "xml2js": "0.4.19" + }, + "dependencies": { + "es6-promise": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.1.1.tgz", + "integrity": "sha1-iBHpCRXZoNujYnTwskLb2nj5ySo=", + "dev": true + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true + }, + "semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", + "dev": true + } + } + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "requires": { + "array-find-index": "1.0.1" + } + }, + "date-now": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", + "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", + "dev": true + }, + "dateformat": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz", + "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=", + "dev": true, + "requires": { + "get-stdin": "4.0.1", + "meow": "3.7.0" + } + }, + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "dev": true, + "requires": { + "ms": "0.7.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "depd": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.0.tgz", + "integrity": "sha1-4b2Cxqq2ztlluXuIsX7T5SjKGMM=", + "dev": true + }, + "detect-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", + "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", + "dev": true, + "requires": { + "repeating": "2.0.1" + } + }, + "detect-newline": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", + "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=", + "dev": true + }, + "dom-serializer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", + "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", + "dev": true, + "requires": { + "domelementtype": "1.1.3", + "entities": "1.1.1" + }, + "dependencies": { + "domelementtype": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", + "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=", + "dev": true + }, + "entities": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", + "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=", + "dev": true + } + } + }, + "domelementtype": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", + "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=", + "dev": true + }, + "domhandler": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", + "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=", + "dev": true, + "requires": { + "domelementtype": "1.3.0" + } + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "dev": true, + "requires": { + "dom-serializer": "0.1.0", + "domelementtype": "1.3.0" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "entities": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", + "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=", + "dev": true + }, + "error-ex": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.0.tgz", + "integrity": "sha1-5ntD8+gsluo6WE/+4Ln8MyXYAtk=", + "dev": true, + "requires": { + "is-arrayish": "0.2.1" + } + }, + "es6-promise": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-0.1.2.tgz", + "integrity": "sha1-8RLCn+paCZhTn8tqL9IUQ9KPBfc=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "esprima": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.2.tgz", + "integrity": "sha1-9DvlQ2CZhOrkTJM6xjNSpq818zk=", + "dev": true + }, + "eventemitter2": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", + "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=", + "dev": true + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "requires": { + "is-posix-bracket": "0.1.1" + } + }, + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "dev": true, + "requires": { + "fill-range": "2.2.3" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + }, + "faye-websocket": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", + "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", + "dev": true, + "requires": { + "websocket-driver": "0.6.5" + } + }, + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true, + "requires": { + "escape-string-regexp": "1.0.5", + "object-assign": "4.1.0" + } + }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", + "dev": true + }, + "fill-range": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", + "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "dev": true, + "requires": { + "is-number": "2.1.0", + "isobject": "2.1.0", + "randomatic": "1.1.7", + "repeat-element": "1.1.2", + "repeat-string": "1.6.1" + } + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" + } + }, + "findup-sync": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz", + "integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=", + "dev": true, + "requires": { + "glob": "5.0.15" + }, + "dependencies": { + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "requires": { + "inflight": "1.0.5", + "inherits": "2.0.1", + "minimatch": "3.0.3", + "once": "1.3.3", + "path-is-absolute": "1.0.0" + } + } + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dev": true, + "requires": { + "for-in": "1.0.2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.3.tgz", + "integrity": "sha512-WIr7iDkdmdbxu/Gh6eKEZJL6KPE74/5MEsf2whTOFNxbIoIixogroLdKYqB6FDav4Wavh/lZdzzd3b2KxIXC5Q==", + "dev": true, + "optional": true, + "requires": { + "nan": "2.8.0", + "node-pre-gyp": "0.6.39" + }, + "dependencies": { + "abbrev": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "ajv": { + "version": "4.11.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "co": "4.6.0", + "json-stable-stringify": "1.0.1" + } + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "aproba": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "1.0.0", + "readable-stream": "2.2.9" + } + }, + "asn1": { + "version": "0.2.3", + "bundled": true, + "dev": true, + "optional": true + }, + "assert-plus": { + "version": "0.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "asynckit": { + "version": "0.4.0", + "bundled": true, + "dev": true, + "optional": true + }, + "aws-sign2": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "aws4": { + "version": "1.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "balanced-match": { + "version": "0.4.2", + "bundled": true, + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "tweetnacl": "0.14.5" + } + }, + "block-stream": { + "version": "0.0.9", + "bundled": true, + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "boom": { + "version": "2.10.1", + "bundled": true, + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, + "brace-expansion": { + "version": "1.1.7", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "0.4.2", + "concat-map": "0.0.1" + } + }, + "buffer-shims": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "caseless": { + "version": "0.12.0", + "bundled": true, + "dev": true, + "optional": true + }, + "co": { + "version": "4.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "combined-stream": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "requires": { + "delayed-stream": "1.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "cryptiles": { + "version": "2.0.5", + "bundled": true, + "dev": true, + "requires": { + "boom": "2.10.1" + } + }, + "dashdash": { + "version": "1.14.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "assert-plus": "1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "debug": { + "version": "2.6.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-extend": { + "version": "0.4.2", + "bundled": true, + "dev": true, + "optional": true + }, + "delayed-stream": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "ecc-jsbn": { + "version": "0.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "jsbn": "0.1.1" + } + }, + "extend": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "extsprintf": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "bundled": true, + "dev": true, + "optional": true + }, + "form-data": { + "version": "2.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.5", + "mime-types": "2.1.15" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "fstream": { + "version": "1.0.11", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "inherits": "2.0.3", + "mkdirp": "0.5.1", + "rimraf": "2.6.1" + } + }, + "fstream-ignore": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fstream": "1.0.11", + "inherits": "2.0.3", + "minimatch": "3.0.4" + } + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "1.1.1", + "console-control-strings": "1.1.0", + "has-unicode": "2.0.1", + "object-assign": "4.1.1", + "signal-exit": "3.0.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wide-align": "1.1.2" + } + }, + "getpass": { + "version": "0.1.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "assert-plus": "1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "glob": { + "version": "7.1.2", + "bundled": true, + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "graceful-fs": { + "version": "4.1.11", + "bundled": true, + "dev": true + }, + "har-schema": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "optional": true + }, + "har-validator": { + "version": "4.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ajv": "4.11.8", + "har-schema": "1.0.5" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "hawk": { + "version": "3.1.3", + "bundled": true, + "dev": true, + "requires": { + "boom": "2.10.1", + "cryptiles": "2.0.5", + "hoek": "2.16.3", + "sntp": "1.0.9" + } + }, + "hoek": { + "version": "2.16.3", + "bundled": true, + "dev": true + }, + "http-signature": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "assert-plus": "0.2.0", + "jsprim": "1.4.0", + "sshpk": "1.13.0" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "ini": { + "version": "1.3.4", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-typedarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "isstream": { + "version": "0.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "jodid25519": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "jsbn": "0.1.1" + } + }, + "jsbn": { + "version": "0.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "json-schema": { + "version": "0.2.3", + "bundled": true, + "dev": true, + "optional": true + }, + "json-stable-stringify": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "jsonify": "0.0.0" + } + }, + "json-stringify-safe": { + "version": "5.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "jsonify": { + "version": "0.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "jsprim": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.0.2", + "json-schema": "0.2.3", + "verror": "1.3.6" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "mime-db": { + "version": "1.27.0", + "bundled": true, + "dev": true + }, + "mime-types": { + "version": "2.1.15", + "bundled": true, + "dev": true, + "requires": { + "mime-db": "1.27.0" + } + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "node-pre-gyp": { + "version": "0.6.39", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "1.0.2", + "hawk": "3.1.3", + "mkdirp": "0.5.1", + "nopt": "4.0.1", + "npmlog": "4.1.0", + "rc": "1.2.1", + "request": "2.81.0", + "rimraf": "2.6.1", + "semver": "5.3.0", + "tar": "2.2.1", + "tar-pack": "3.4.0" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1.1.0", + "osenv": "0.1.4" + } + }, + "npmlog": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "1.1.4", + "console-control-strings": "1.1.0", + "gauge": "2.7.4", + "set-blocking": "2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "oauth-sign": { + "version": "0.8.2", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "performance-now": { + "version": "0.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "1.0.7", + "bundled": true, + "dev": true + }, + "punycode": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "optional": true + }, + "qs": { + "version": "6.4.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "0.4.2", + "ini": "1.3.4", + "minimist": "1.2.0", + "strip-json-comments": "2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.2.9", + "bundled": true, + "dev": true, + "requires": { + "buffer-shims": "1.0.0", + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "1.0.1", + "util-deprecate": "1.0.2" + } + }, + "request": { + "version": "2.81.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aws-sign2": "0.6.0", + "aws4": "1.6.0", + "caseless": "0.12.0", + "combined-stream": "1.0.5", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.1.4", + "har-validator": "4.2.1", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.15", + "oauth-sign": "0.8.2", + "performance-now": "0.2.0", + "qs": "6.4.0", + "safe-buffer": "5.0.1", + "stringstream": "0.0.5", + "tough-cookie": "2.3.2", + "tunnel-agent": "0.6.0", + "uuid": "3.0.1" + } + }, + "rimraf": { + "version": "2.6.1", + "bundled": true, + "dev": true, + "requires": { + "glob": "7.1.2" + } + }, + "safe-buffer": { + "version": "5.0.1", + "bundled": true, + "dev": true + }, + "semver": { + "version": "5.3.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sntp": { + "version": "1.0.9", + "bundled": true, + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, + "sshpk": { + "version": "1.13.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.1", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.1", + "getpass": "0.1.7", + "jodid25519": "1.0.2", + "jsbn": "0.1.1", + "tweetnacl": "0.14.5" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "string_decoder": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "5.0.1" + } + }, + "stringstream": { + "version": "0.0.5", + "bundled": true, + "dev": true, + "optional": true + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "2.2.1", + "bundled": true, + "dev": true, + "requires": { + "block-stream": "0.0.9", + "fstream": "1.0.11", + "inherits": "2.0.3" + } + }, + "tar-pack": { + "version": "3.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "2.6.8", + "fstream": "1.0.11", + "fstream-ignore": "1.0.5", + "once": "1.4.0", + "readable-stream": "2.2.9", + "rimraf": "2.6.1", + "tar": "2.2.1", + "uid-number": "0.0.6" + } + }, + "tough-cookie": { + "version": "2.3.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "punycode": "1.4.1" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "bundled": true, + "dev": true, + "optional": true + }, + "uid-number": { + "version": "0.0.6", + "bundled": true, + "dev": true, + "optional": true + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "uuid": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "verror": { + "version": "1.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "extsprintf": "1.0.2" + } + }, + "wide-align": { + "version": "1.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "1.0.2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + } + } + }, + "gaze": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.2.tgz", + "integrity": "sha1-hHIkZ3rbiHDWeSV+0ziP22HkAQU=", + "dev": true, + "requires": { + "globule": "1.2.0" + } + }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true + }, + "getobject": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz", + "integrity": "sha1-BHpEl4n6Fg0Bj1SG7ZEyC27HiFw=", + "dev": true + }, + "glob": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.5.tgz", + "integrity": "sha1-tCAqaQmbu00pKnwblbZoK2fr3JU=", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.5", + "inherits": "2.0.1", + "minimatch": "3.0.3", + "once": "1.3.3", + "path-is-absolute": "1.0.0" + } + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "dev": true, + "requires": { + "glob-parent": "2.0.0", + "is-glob": "2.0.1" + } + }, + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "requires": { + "is-glob": "2.0.1" + } + }, + "globule": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.2.0.tgz", + "integrity": "sha1-HcScaCLdnoovoAuiopUAboZkvQk=", + "dev": true, + "requires": { + "glob": "7.1.2", + "lodash": "4.17.4", + "minimatch": "3.0.3" + }, + "dependencies": { + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "dev": true, + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.5", + "inherits": "2.0.1", + "minimatch": "3.0.4", + "once": "1.3.3", + "path-is-absolute": "1.0.0" + }, + "dependencies": { + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", + "dev": true, + "requires": { + "brace-expansion": "1.1.8" + } + } + } + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true + } + } + }, + "graceful-fs": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.5.tgz", + "integrity": "sha1-9HRejK7V4N0u8hu14tIpoy6Ak8A=", + "dev": true + }, + "grunt": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.0.1.tgz", + "integrity": "sha1-6HeHZOlEsY8yuw8QuQeEdcnftWs=", + "dev": true, + "requires": { + "coffee-script": "1.10.0", + "dateformat": "1.0.12", + "eventemitter2": "0.4.14", + "exit": "0.1.2", + "findup-sync": "0.3.0", + "glob": "7.0.5", + "grunt-cli": "1.2.0", + "grunt-known-options": "1.1.0", + "grunt-legacy-log": "1.0.0", + "grunt-legacy-util": "1.0.0", + "iconv-lite": "0.4.13", + "js-yaml": "3.5.5", + "minimatch": "3.0.3", + "nopt": "3.0.6", + "path-is-absolute": "1.0.0", + "rimraf": "2.2.8" + }, + "dependencies": { + "grunt-cli": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.2.0.tgz", + "integrity": "sha1-VisRnrsGndtGSs4oRVAb6Xs1tqg=", + "dev": true, + "requires": { + "findup-sync": "0.3.0", + "grunt-known-options": "1.1.0", + "nopt": "3.0.6", + "resolve": "1.1.7" + } + } + } + }, + "grunt-contrib-jshint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/grunt-contrib-jshint/-/grunt-contrib-jshint-1.1.0.tgz", + "integrity": "sha1-Np2QmyWTxA6L55lAshNAhQx5Oaw=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "hooker": "0.2.3", + "jshint": "2.9.4" + } + }, + "grunt-contrib-uglify": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/grunt-contrib-uglify/-/grunt-contrib-uglify-3.2.1.tgz", + "integrity": "sha512-xBPwg8wuA/m+HiSh2uMADuadKEnFQt9N5OhEy35vIl945yG6095oY1H1Og3ucg0wBSOieIBn3raqStvIcwKqHg==", + "dev": true, + "requires": { + "chalk": "1.1.3", + "maxmin": "1.1.0", + "uglify-js": "3.2.2", + "uri-path": "1.0.0" + }, + "dependencies": { + "uglify-js": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.2.2.tgz", + "integrity": "sha512-++1NO/zZIEdWf6cDIGceSJQPX31SqIpbVAHwFG5+240MtZqPG/NIPoinj8zlXQtAfMBqEt1Jyv2FiLP3n9gVhQ==", + "dev": true, + "requires": { + "commander": "2.12.2", + "source-map": "0.6.1" + } + } + } + }, + "grunt-contrib-watch": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/grunt-contrib-watch/-/grunt-contrib-watch-1.0.0.tgz", + "integrity": "sha1-hKGnodar0m7VaEE0lscxM+mQAY8=", + "dev": true, + "requires": { + "async": "1.5.2", + "gaze": "1.1.2", + "lodash": "3.10.1", + "tiny-lr": "0.2.1" + } + }, + "grunt-known-options": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-1.1.0.tgz", + "integrity": "sha1-pCdO6zL6dl2lp6OxcSYXzjsUQUk=", + "dev": true + }, + "grunt-legacy-log": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-1.0.0.tgz", + "integrity": "sha1-+4bxgJhHvAfcR4Q/ns1srLYt8tU=", + "dev": true, + "requires": { + "colors": "1.1.2", + "grunt-legacy-log-utils": "1.0.0", + "hooker": "0.2.3", + "lodash": "3.10.1", + "underscore.string": "3.2.3" + } + }, + "grunt-legacy-log-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-1.0.0.tgz", + "integrity": "sha1-p7ji0Ps1taUPSvmG/BEnSevJbz0=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "lodash": "4.3.0" + }, + "dependencies": { + "lodash": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.3.0.tgz", + "integrity": "sha1-79nEpuxT87BUEkKZFcPkgk5NJaQ=", + "dev": true + } + } + }, + "grunt-legacy-util": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-1.0.0.tgz", + "integrity": "sha1-OGqnjcbtUJhsKxiVcmWxtIq7m4Y=", + "dev": true, + "requires": { + "async": "1.5.2", + "exit": "0.1.2", + "getobject": "0.1.0", + "hooker": "0.2.3", + "lodash": "4.3.0", + "underscore.string": "3.2.3", + "which": "1.2.10" + }, + "dependencies": { + "lodash": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.3.0.tgz", + "integrity": "sha1-79nEpuxT87BUEkKZFcPkgk5NJaQ=", + "dev": true + } + } + }, + "grunt-load-options": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/grunt-load-options/-/grunt-load-options-1.0.0.tgz", + "integrity": "sha1-dpNhyQJ3dgiIdNcojUfHrfanshU=", + "dev": true, + "requires": { + "require-directory": "2.1.1" + } + }, + "grunt-ts": { + "version": "6.0.0-beta.17", + "resolved": "https://registry.npmjs.org/grunt-ts/-/grunt-ts-6.0.0-beta.17.tgz", + "integrity": "sha1-IFjMk7CFEyFtxGyFN2LcHip1kXU=", + "dev": true, + "requires": { + "chokidar": "1.7.0", + "csproj2ts": "1.0.0", + "detect-indent": "4.0.0", + "detect-newline": "2.1.0", + "es6-promise": "0.1.2", + "jsmin2": "1.2.1", + "lodash": "4.17.4", + "ncp": "0.5.1", + "rimraf": "2.2.6", + "semver": "5.3.0", + "strip-bom": "2.0.0" + }, + "dependencies": { + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true + }, + "rimraf": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.6.tgz", + "integrity": "sha1-xZWXVpsU2VatKcrMQr3d9fDqT0w=", + "dev": true + } + } + }, + "gzip-size": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-1.0.0.tgz", + "integrity": "sha1-Zs+LEBBHInuVus5uodoMF37Vwi8=", + "dev": true, + "requires": { + "browserify-zlib": "0.1.4", + "concat-stream": "1.6.0" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "2.0.0" + } + }, + "hooker": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz", + "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=", + "dev": true + }, + "hosted-git-info": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.1.5.tgz", + "integrity": "sha1-C6gdkNouJas0ozLm7HeTbhWYEYs=", + "dev": true + }, + "htmlparser2": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", + "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=", + "dev": true, + "requires": { + "domelementtype": "1.3.0", + "domhandler": "2.3.0", + "domutils": "1.5.1", + "entities": "1.0.0", + "readable-stream": "1.1.14" + } + }, + "http-errors": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.3.1.tgz", + "integrity": "sha1-GX4izevUGYWF6GlO9nhhl7ke2UI=", + "dev": true, + "requires": { + "inherits": "2.0.1", + "statuses": "1.3.1" + } + }, + "iconv-lite": { + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", + "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=", + "dev": true + }, + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "dev": true, + "requires": { + "repeating": "2.0.1" + } + }, + "inflight": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.5.tgz", + "integrity": "sha1-2zIEzVqd4ubNiQuFxuL2a89PYgo=", + "dev": true, + "requires": { + "once": "1.3.3", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "1.11.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "dev": true, + "requires": { + "builtin-modules": "1.1.1" + } + }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", + "dev": true + }, + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "dev": true, + "requires": { + "is-primitive": "2.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-finite": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.1.tgz", + "integrity": "sha1-ZDhgPq6+J5OUj/SkJi7I2z1iWXs=", + "dev": true, + "requires": { + "number-is-nan": "1.0.0" + } + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", + "dev": true + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "dev": true + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "isexe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-1.1.2.tgz", + "integrity": "sha1-NvPiLmB1CSD15yQaR2qMakInWtA=", + "dev": true + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + } + } + }, + "js-yaml": { + "version": "3.5.5", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.5.5.tgz", + "integrity": "sha1-A3fDgBfKvHMisNH7zSWkkWQfL74=", + "dev": true, + "requires": { + "argparse": "1.0.7", + "esprima": "2.7.2" + } + }, + "jshint": { + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.9.4.tgz", + "integrity": "sha1-XjupeEjVKQJz21FK7kf+JM9ZKTQ=", + "dev": true, + "requires": { + "cli": "1.0.1", + "console-browserify": "1.1.0", + "exit": "0.1.2", + "htmlparser2": "3.8.3", + "lodash": "3.7.0", + "minimatch": "3.0.3", + "shelljs": "0.3.0", + "strip-json-comments": "1.0.4" + }, + "dependencies": { + "lodash": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.7.0.tgz", + "integrity": "sha1-Nni9irmVBXwHreg27S7wh9qBHUU=", + "dev": true + } + } + }, + "jsmin2": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/jsmin2/-/jsmin2-1.2.1.tgz", + "integrity": "sha1-iPvi+/dfCpH2YCD9mBzWk/S/5X4=", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + }, + "livereload-js": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.2.2.tgz", + "integrity": "sha1-bIclfmSKtHW8JOoldFftzB+NC8I=", + "dev": true + }, + "load-grunt-tasks": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/load-grunt-tasks/-/load-grunt-tasks-3.5.2.tgz", + "integrity": "sha1-ByhWEYD9IP+KaSdQWFL8WKrqDIg=", + "dev": true, + "requires": { + "arrify": "1.0.1", + "multimatch": "2.1.0", + "pkg-up": "1.0.0", + "resolve-pkg": "0.1.0" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "requires": { + "graceful-fs": "4.1.5", + "parse-json": "2.2.0", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "strip-bom": "2.0.0" + } + }, + "lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", + "dev": true + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true, + "requires": { + "currently-unhandled": "0.4.1", + "signal-exit": "3.0.0" + } + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + }, + "maxmin": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/maxmin/-/maxmin-1.1.0.tgz", + "integrity": "sha1-cTZehKmd2Piz99X94vANHn9zvmE=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "figures": "1.7.0", + "gzip-size": "1.0.0", + "pretty-bytes": "1.0.4" + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true + }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "dev": true, + "requires": { + "camelcase-keys": "2.1.0", + "decamelize": "1.2.0", + "loud-rejection": "1.6.0", + "map-obj": "1.0.1", + "minimist": "1.2.0", + "normalize-package-data": "2.3.5", + "object-assign": "4.1.0", + "read-pkg-up": "1.0.1", + "redent": "1.0.0", + "trim-newlines": "1.0.0" + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "requires": { + "arr-diff": "2.0.0", + "array-unique": "0.2.1", + "braces": "1.8.5", + "expand-brackets": "0.1.5", + "extglob": "0.3.2", + "filename-regex": "2.0.1", + "is-extglob": "1.0.0", + "is-glob": "2.0.1", + "kind-of": "3.2.2", + "normalize-path": "2.1.1", + "object.omit": "2.0.1", + "parse-glob": "3.0.4", + "regex-cache": "0.4.4" + } + }, + "mime-db": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.27.0.tgz", + "integrity": "sha1-gg9XIpa70g7CXtVeW13oaeVDbrE=", + "dev": true + }, + "mime-types": { + "version": "2.1.15", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.15.tgz", + "integrity": "sha1-pOv1BkCUVpI3uM9wBGd20J/JKu0=", + "dev": true, + "requires": { + "mime-db": "1.27.0" + } + }, + "minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q=", + "dev": true, + "requires": { + "brace-expansion": "1.1.6" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "dev": true + }, + "multimatch": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", + "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=", + "dev": true, + "requires": { + "array-differ": "1.0.0", + "array-union": "1.0.2", + "arrify": "1.0.1", + "minimatch": "3.0.3" + } + }, + "nan": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.8.0.tgz", + "integrity": "sha1-7XFfP+neArV6XmJS2QqWZ14fCFo=", + "dev": true, + "optional": true + }, + "ncp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/ncp/-/ncp-0.5.1.tgz", + "integrity": "sha1-dDmFMW49tFkoG1hxaehFc1oFQ58=", + "dev": true + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "requires": { + "abbrev": "1.0.9" + } + }, + "normalize-package-data": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.3.5.tgz", + "integrity": "sha1-jZJPFClg4Xd+f/4XBUNjHMfLAt8=", + "dev": true, + "requires": { + "hosted-git-info": "2.1.5", + "is-builtin-module": "1.0.0", + "semver": "5.3.0", + "validate-npm-package-license": "3.0.1" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "1.1.0" + } + }, + "number-is-nan": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.0.tgz", + "integrity": "sha1-wCD1KcUoKt/dIz2R1LGBw9aG3Es=", + "dev": true + }, + "object-assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz", + "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A=", + "dev": true + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "dev": true, + "requires": { + "for-own": "0.1.5", + "is-extendable": "0.1.1" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", + "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=", + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "pako": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", + "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", + "dev": true + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "dev": true, + "requires": { + "glob-base": "0.3.0", + "is-dotfile": "1.0.3", + "is-extglob": "1.0.0", + "is-glob": "2.0.1" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "1.3.0" + } + }, + "parseurl": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.1.tgz", + "integrity": "sha1-yKuMkiO6NIiKpkopeyiFO+wY2lY=", + "dev": true + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "2.0.1" + } + }, + "path-is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.0.tgz", + "integrity": "sha1-Jj2tpmqz8vsQv3+dJN2PPlcO+RI=", + "dev": true + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "4.1.5", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "2.0.4" + } + }, + "pkg-up": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-1.0.0.tgz", + "integrity": "sha1-Pgj7RhUlxEIWJKM7n35tCvWwWiY=", + "dev": true, + "requires": { + "find-up": "1.1.2" + } + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", + "dev": true + }, + "pretty-bytes": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-1.0.4.tgz", + "integrity": "sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ=", + "dev": true, + "requires": { + "get-stdin": "4.0.1", + "meow": "3.7.0" + } + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + }, + "qs": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-5.1.0.tgz", + "integrity": "sha1-TZMuXH6kEcynajEtOaYGIA/VDNk=", + "dev": true + }, + "randomatic": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", + "integrity": "sha1-x6vpzIuHwLqodrGf3oP9RkeX44w=", + "dev": true, + "requires": { + "is-number": "3.0.0", + "kind-of": "4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "raw-body": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.1.7.tgz", + "integrity": "sha1-rf6s4uT7MJgFgBTQjActzFl1h3Q=", + "dev": true, + "requires": { + "bytes": "2.4.0", + "iconv-lite": "0.4.13", + "unpipe": "1.0.0" + }, + "dependencies": { + "bytes": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz", + "integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk=", + "dev": true + } + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "1.1.0", + "normalize-package-data": "2.3.5", + "path-type": "1.1.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "1.1.2", + "read-pkg": "1.1.0" + } + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.1", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "readdirp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", + "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", + "dev": true, + "requires": { + "graceful-fs": "4.1.5", + "minimatch": "3.0.3", + "readable-stream": "2.3.3", + "set-immediate-shim": "1.0.1" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha1-No8lEtefnUb9/HE0mueHi7weuVw=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha1-D8Z9fBQYJd6UKC3VNr7GubzoYKs=", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "dev": true, + "requires": { + "indent-string": "2.1.0", + "strip-indent": "1.0.1" + } + }, + "regex-cache": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "dev": true, + "requires": { + "is-equal-shallow": "0.1.3" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true, + "requires": { + "is-finite": "1.0.1" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + }, + "resolve-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=", + "dev": true + }, + "resolve-pkg": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/resolve-pkg/-/resolve-pkg-0.1.0.tgz", + "integrity": "sha1-AsyZNBDik2livZcWahsHfalyVTE=", + "dev": true, + "requires": { + "resolve-from": "2.0.0" + } + }, + "rimraf": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", + "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", + "dev": true + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha1-iTMSr2myEj3vcfV4iQAWce6yyFM=", + "dev": true + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha1-KBYjTiN4vdxOU1T6tcqold9xANk=", + "dev": true + }, + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", + "dev": true + }, + "set-immediate-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", + "dev": true + }, + "shelljs": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", + "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=", + "dev": true + }, + "signal-exit": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.0.tgz", + "integrity": "sha1-PAVDtl17T7xgts2UWT2b9DZzm+g=", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "spdx-correct": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", + "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "dev": true, + "requires": { + "spdx-license-ids": "1.2.2" + } + }, + "spdx-exceptions": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-1.0.5.tgz", + "integrity": "sha1-nSGsTaS9tx0GD7dOWmdTHQMsu6Y=", + "dev": true + }, + "spdx-expression-parse": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.2.tgz", + "integrity": "sha1-1SsUtelnB3FECvIlvLVjEirEUvY=", + "dev": true, + "requires": { + "spdx-exceptions": "1.0.5", + "spdx-license-ids": "1.2.2" + } + }, + "spdx-license-ids": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", + "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.0.0" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "0.2.1" + } + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "dev": true, + "requires": { + "get-stdin": "4.0.1" + } + }, + "strip-json-comments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", + "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=", + "dev": true + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + }, + "tiny-lr": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-0.2.1.tgz", + "integrity": "sha1-s/26gC5dVqM8L28QeUsy5Hescp0=", + "dev": true, + "requires": { + "body-parser": "1.14.2", + "debug": "2.2.0", + "faye-websocket": "0.10.0", + "livereload-js": "2.2.2", + "parseurl": "1.3.1", + "qs": "5.1.0" + } + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "dev": true + }, + "type-is": { + "version": "1.6.15", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz", + "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "2.1.15" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "typescript": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.7.1.tgz", + "integrity": "sha512-bqB1yS6o9TNA9ZC/MJxM0FZzPnZdtHj0xWK/IZ5khzVqdpGul/R/EIiHRgFXlwTD7PSIaYVnGKq1QgMCu2mnqw==", + "dev": true + }, + "underscore.string": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.2.3.tgz", + "integrity": "sha1-gGmSYzZl1eX8tNsfs6hi62jp5to=", + "dev": true + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, + "uri-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/uri-path/-/uri-path-1.0.0.tgz", + "integrity": "sha1-l0fwGDWJM8Md4PzP2C0TjmcmLjI=", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", + "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "dev": true, + "requires": { + "spdx-correct": "1.0.2", + "spdx-expression-parse": "1.0.2" + } + }, + "websocket-driver": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.5.tgz", + "integrity": "sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY=", + "dev": true, + "requires": { + "websocket-extensions": "0.1.1" + } + }, + "websocket-extensions": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.1.tgz", + "integrity": "sha1-domUmcGEtu91Q3fC27DNbLVdKec=", + "dev": true + }, + "which": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/which/-/which-1.2.10.tgz", + "integrity": "sha1-kc2b0HUTIkEbZZtA8FSyHelXqy0=", + "dev": true, + "requires": { + "isexe": "1.1.2" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "xml2js": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", + "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", + "dev": true, + "requires": { + "sax": "1.2.4", + "xmlbuilder": "9.0.4" + } + }, + "xmlbuilder": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.4.tgz", + "integrity": "sha1-UZy0ymhtAFqEINNJbz8MruzKWA8=", + "dev": true + } + } +} diff --git a/package.json b/package.json index 75c707c4..2648ace9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "velocity-animate", - "version": "1.5.1", + "version": "2.0.0", "description": "Accelerated JavaScript animation.", "keywords": [ "velocity", @@ -36,8 +36,14 @@ "velocity.ui.min.js" ], "devDependencies": { + "@types/qunit": "^2.0.31", "grunt": "^1.0.1", "grunt-contrib-jshint": "~1.1.0", - "grunt-contrib-uglify": "~2.2.0" + "grunt-contrib-uglify": "~3.3.0", + "grunt-contrib-watch": "^1.0.0", + "grunt-load-options": "^1.0.0", + "grunt-ts": "^6.0.0-beta.17", + "load-grunt-tasks": "^3.5.2", + "typescript": "^2.7.1" } } diff --git a/src/Velocity/_all.d.ts b/src/Velocity/_all.d.ts new file mode 100644 index 00000000..278e4ef0 --- /dev/null +++ b/src/Velocity/_all.d.ts @@ -0,0 +1,20 @@ +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// diff --git a/src/Velocity/actions/_all.d.ts b/src/Velocity/actions/_all.d.ts new file mode 100644 index 00000000..65cfaefb --- /dev/null +++ b/src/Velocity/actions/_all.d.ts @@ -0,0 +1,9 @@ +/// +/// +/// +/// +/// +/// +/// +/// +/// diff --git a/src/Velocity/actions/actions.ts b/src/Velocity/actions/actions.ts new file mode 100644 index 00000000..d53415bf --- /dev/null +++ b/src/Velocity/actions/actions.ts @@ -0,0 +1,44 @@ +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + * + * Actions that can be performed by passing a string instead of a propertiesMap. + */ + +namespace VelocityStatic { + /** + * Actions cannot be replaced if they are internal (hasOwnProperty is false + * but they still exist). Otherwise they can be replaced by users. + * + * All external method calls should be using actions rather than sub-calls + * of Velocity itself. + */ + export const Actions: {[name: string]: VelocityActionFn} = Object.create(null); + + /** + * Used to register an action. This should never be called by users + * directly, instead it should be called via an action:
+ * Velocity("registerAction", "name", VelocityActionFn); + * + * @private + */ + export function registerAction(args?: [string, VelocityActionFn], internal?: boolean) { + const name: string = args[0], + callback = args[1]; + + if (!isString(name)) { + console.warn("VelocityJS: Trying to set 'registerAction' name to an invalid value:", name); + } else if (!isFunction(callback)) { + console.warn("VelocityJS: Trying to set 'registerAction' callback to an invalid value:", name, callback); + } else if (Actions[name] && !propertyIsEnumerable(Actions, name)) { + console.warn("VelocityJS: Trying to override internal 'registerAction' callback", name); + } else if (internal === true) { + defineProperty(Actions, name, callback); + } else { + Actions[name] = callback; + } + } + + registerAction(["registerAction", registerAction as any], true); +} diff --git a/src/Velocity/actions/defaultAction.ts b/src/Velocity/actions/defaultAction.ts new file mode 100644 index 00000000..956ec84e --- /dev/null +++ b/src/Velocity/actions/defaultAction.ts @@ -0,0 +1,81 @@ +/// +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + * + * Default action. + */ + +namespace VelocityStatic { + + /** + * When the stop action is triggered, the elements' currently active call is immediately stopped. The active call might have + * been applied to multiple elements, in which case all of the call's elements will be stopped. When an element + * is stopped, the next item in its animation queue is immediately triggered. + * An additional argument may be passed in to clear an element's remaining queued calls. Either true (which defaults to the "fx" queue) + * or a custom queue string can be passed in. + * Note: The stop command runs prior to Velocity's Queueing phase since its behavior is intended to take effect *immediately*, + * regardless of the element's current queue state. + * + * @param {HTMLorSVGElement[]} elements The collection of HTML or SVG elements + * @param {StrictVelocityOptions} The strict Velocity options + * @param {Promise} An optional promise if the user uses promises + * @param {(value?: (HTMLorSVGElement[] | VelocityResult)) => void} resolver The resolve method of the promise + */ + function defaultAction(args?: any[], elements?: HTMLorSVGElement[] | VelocityResult, promiseHandler?: VelocityPromise, action?: string): void { + // TODO: default is wrong, should be runSequence based, and needs all arguments + if (isString(action) && VelocityStatic.Redirects[action]) { + const options = isPlainObject(args[0]) ? args[0] as VelocityOptions : {}, + opts = {...options}, + durationOriginal = parseFloat(options.duration as any), + delayOriginal = parseFloat(options.delay as any) || 0; + + /* If the backwards option was passed in, reverse the element set so that elements animate from the last to the first. */ + if (opts.backwards === true) { + elements = elements.reverse(); + } + + /* Individually trigger the redirect for each element in the set to prevent users from having to handle iteration logic in their redirect. */ + elements.forEach(function(element, elementIndex) { + + /* If the stagger option was passed in, successively delay each element by the stagger value (in ms). Retain the original delay value. */ + if (parseFloat(opts.stagger as string)) { + opts.delay = delayOriginal + (parseFloat(opts.stagger as string) * elementIndex); + } else if (isFunction(opts.stagger)) { + opts.delay = delayOriginal + opts.stagger.call(element, elementIndex, elements.length); + } + + /* If the drag option was passed in, successively increase/decrease (depending on the presense of opts.backwards) + the duration of each element's animation, using floors to prevent producing very short durations. */ + if (opts.drag) { + /* Default the duration of UI pack effects (callouts and transitions) to 1000ms instead of the usual default duration of 400ms. */ + opts.duration = durationOriginal || (/^(callout|transition)/.test(action) ? 1000 : DEFAULT_DURATION); + + /* For each element, take the greater duration of: A) animation completion percentage relative to the original duration, + B) 75% of the original duration, or C) a 200ms fallback (in case duration is already set to a low value). + The end result is a baseline of 75% of the redirect's duration that increases/decreases as the end of the element set is approached. */ + opts.duration = Math.max(opts.duration * (opts.backwards ? 1 - elementIndex / elements.length : (elementIndex + 1) / elements.length), opts.duration * 0.75, 200); + } + + /* Pass in the call's opts object so that the redirect can optionally extend it. It defaults to an empty object instead of null to + reduce the opts checking logic required inside the redirect. */ + VelocityStatic.Redirects[action].call(element, element, opts, elementIndex, elements.length, elements, promiseHandler && promiseHandler._resolver); + }); + + /* Since the animation logic resides within the redirect's own code, abort the remainder of this call. + (The performance overhead up to this point is virtually non-existant.) */ + /* Note: The jQuery call chain is kept intact by returning the complete element set. */ + } else { + const abortError = "Velocity: First argument (" + action + ") was not a property map, a known action, or a registered redirect. Aborting."; + + if (promiseHandler) { + promiseHandler._rejecter(new Error(abortError)); + } else if (window.console) { + console.log(abortError); + } + } + } + + registerAction(["default", defaultAction], true); +} diff --git a/src/Velocity/actions/finish.ts b/src/Velocity/actions/finish.ts new file mode 100644 index 00000000..48b6fcba --- /dev/null +++ b/src/Velocity/actions/finish.ts @@ -0,0 +1,104 @@ +/// +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + * + * Finish all animation. + */ + +namespace VelocityStatic { + + /** + * Check if an animation should be finished, and if so we set the tweens to + * the final value for it, then call complete. + */ + function checkAnimationShouldBeFinished(animation: AnimationCall, queueName: false | string, defaultQueue: false | string) { + validateTweens(animation); + if (queueName === undefined || queueName === getValue(animation.queue, animation.options.queue, defaultQueue)) { + if (!(animation._flags & AnimationFlags.STARTED)) { + // Copied from tick.ts - ensure that the animation is completely + // valid and run begin() before complete(). + const options = animation.options; + + // The begin callback is fired once per call, not once per + // element, and is passed the full raw DOM element set as both + // its context and its first argument. + if (options._started++ === 0) { + options._first = animation; + if (options.begin) { + // Pass to an external fn with a try/catch block for optimisation + callBegin(animation); + // Only called once, even if reversed or repeated + options.begin = undefined; + } + } + animation._flags |= AnimationFlags.STARTED; + } + for (const property in animation.tweens) { + const tween = animation.tweens[property], + pattern = tween[Tween.PATTERN]; + let currentValue = "", + i = 0; + + if (pattern) { + for (; i < pattern.length; i++) { + const endValue = tween[Tween.END][i]; + + currentValue += endValue == null ? pattern[i] : endValue; + } + } + CSS.setPropertyValue(animation.element, property, currentValue); + } + completeCall(animation); + } + } + + /** + * When the finish action is triggered, the elements' currently active call is + * immediately finished. When an element is finished, the next item in its + * animation queue is immediately triggered. If passed via a chained call + * then this will only target the animations in that call, and not the + * elements linked to it. + * + * A queue name may be passed in to specify that only animations on the + * named queue are finished. The default queue is named "". In addition the + * value of `false` is allowed for the queue name. + * + * An final argument may be passed in to clear an element's remaining queued + * calls. This may only be the value `true`. + */ + function finish(args: any[], elements: VelocityResult, promiseHandler?: VelocityPromise): void { + const queueName: string | false = validateQueue(args[0], true), + defaultQueue: false | string = defaults.queue, + finishAll = args[queueName === undefined ? 0 : 1] === true; + + if (isVelocityResult(elements) && elements.velocity.animations) { + for (let i = 0, animations = elements.velocity.animations; i < animations.length; i++) { + checkAnimationShouldBeFinished(animations[i], queueName, defaultQueue); + } + } else { + let activeCall = State.first, + nextCall: AnimationCall; + + while ((activeCall = State.firstNew)) { + validateTweens(activeCall); + } + for (activeCall = State.first; activeCall && (finishAll || activeCall !== State.firstNew); activeCall = nextCall || State.firstNew) { + nextCall = activeCall._next; + if (!elements || _inArray(elements, activeCall.element)) { + checkAnimationShouldBeFinished(activeCall, queueName, defaultQueue); + } + } + } + if (promiseHandler) { + if (isVelocityResult(elements) && elements.velocity.animations && elements.then) { + elements.then(promiseHandler._resolver); + } else { + promiseHandler._resolver(elements); + } + } + } + + registerAction(["finish", finish], true); +} diff --git a/src/Velocity/actions/option.ts b/src/Velocity/actions/option.ts new file mode 100644 index 00000000..35aa57b3 --- /dev/null +++ b/src/Velocity/actions/option.ts @@ -0,0 +1,168 @@ +/// +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + * + * Get or set a value from one or more running animations. + */ + +namespace VelocityStatic { + /** + * Used to map getters for the various AnimationFlags. + */ + const animationFlags: {[key: string]: number} = { + "isExpanded": AnimationFlags.EXPANDED, + "isReady": AnimationFlags.READY, + "isStarted": AnimationFlags.STARTED, + "isStopped": AnimationFlags.STOPPED, + "isPaused": AnimationFlags.PAUSED, + "isSync": AnimationFlags.SYNC, + "isReverse": AnimationFlags.REVERSE + }; + + /** + * Get or set an option or running AnimationCall data value. If there is no + * value passed then it will get, otherwise we will set. + * + * NOTE: When using "get" this will not touch the Promise as it is never + * returned to the user. + */ + function option(args?: any[], elements?: VelocityResult, promiseHandler?: VelocityPromise, action?: string): any { + const key = args[0], + queue = action.indexOf(".") >= 0 ? action.replace(/^.*\./, "") : undefined, + queueName = queue === "false" ? false : validateQueue(queue, true); + let animations: AnimationCall[], + value = args[1]; + + if (!key) { + console.warn("VelocityJS: Cannot access a non-existant key!"); + return null; + } + // If we're chaining the return value from Velocity then we are only + // interested in the values related to that call + if (isVelocityResult(elements) && elements.velocity.animations) { + animations = elements.velocity.animations; + } else { + animations = []; + + for (let activeCall = State.first; activeCall; activeCall = activeCall._next) { + if (elements.indexOf(activeCall.element) >= 0 && getValue(activeCall.queue, activeCall.options.queue) === queueName) { + animations.push(activeCall); + } + } + // If we're dealing with multiple elements that are pointing at a + // single running animation, then instead treat them as a single + // animation. + if (elements.length > 1 && animations.length > 1) { + let i = 1, + options = animations[0].options; + + while (i < animations.length) { + if (animations[i++].options !== options) { + options = null; + break; + } + } + // TODO: this needs to check that they're actually a sync:true animation to merge the results, otherwise the individual values may be different + if (options) { + animations = [animations[0]]; + } + } + } + // GET + if (value === undefined) { + const result = [], + flag = animationFlags[key]; + + for (let i = 0; i < animations.length; i++) { + if (flag === undefined) { + // A normal key to get. + result.push(getValue(animations[i][key], animations[i].options[key])); + } else { + // A flag that we're checking against. + result.push((animations[i]._flags & flag) === 0); + } + } + if (elements.length === 1 && animations.length === 1) { + // If only a single animation is found and we're only targetting a + // single element, then return the value directly + return result[0]; + } + return result; + } + // SET + let isPercentComplete: boolean; + + switch (key) { + case "cache": + value = validateCache(value); + break; + case "begin": + value = validateBegin(value); + break; + case "complete": + value = validateComplete(value); + break; + case "delay": + value = validateDelay(value); + break; + case "duration": + value = validateDuration(value); + break; + case "fpsLimit": + value = validateFpsLimit(value); + break; + case "loop": + value = validateLoop(value); + break; + case "percentComplete": + isPercentComplete = true; + value = parseFloat(value); + break; + case "repeat": + case "repeatAgain": + value = validateRepeat(value); + break; + default: + if (key[0] !== "_") { + const num = parseFloat(value); + + if (value == num) { + value = num; + } + break; + } + // deliberate fallthrough + case "queue": + case "promise": + case "promiseRejectEmpty": + case "easing": + case "started": + console.warn("VelocityJS: Trying to set a read-only key:", key); + return; + } + if (value === undefined || value !== value) { + console.warn("VelocityJS: Trying to set an invalid value:", key, "=", value, "(" + args[1] + ")"); + return null; + } + for (let i = 0; i < animations.length; i++) { + const animation = animations[i]; + + if (isPercentComplete) { + animation.timeStart = lastTick - (getValue(animation.duration, animation.options.duration, defaults.duration) * value); + } else { + animation[key] = value; + } + } + if (promiseHandler) { + if (isVelocityResult(elements) && elements.velocity.animations && elements.then) { + elements.then(promiseHandler._resolver); + } else { + promiseHandler._resolver(elements); + } + } + } + + registerAction(["option", option], true); +} diff --git a/src/Velocity/actions/pauseResume.ts b/src/Velocity/actions/pauseResume.ts new file mode 100644 index 00000000..b23e65df --- /dev/null +++ b/src/Velocity/actions/pauseResume.ts @@ -0,0 +1,61 @@ +/// +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + * + * Pause and resume animation. + */ + +namespace VelocityStatic { + + /** + * Check if an animation should be paused / resumed. + */ + function checkAnimation(animation: AnimationCall, queueName: false | string, defaultQueue: false | string, isPaused: boolean) { + if (queueName === undefined || queueName === getValue(animation.queue, animation.options.queue, defaultQueue)) { + if (isPaused) { + animation._flags |= AnimationFlags.PAUSED; + } else { + animation._flags &= ~AnimationFlags.PAUSED; + } + } + }; + + /** + * Pause and Resume are call-wide (not on a per element basis). Thus, calling pause or resume on a + * single element will cause any calls that contain tweens for that element to be paused/resumed + * as well. + */ + function pauseResume(args?: any[], elements?: VelocityResult, promiseHandler?: VelocityPromise, action?: string) { + const isPaused = action.indexOf("pause") === 0, + queue = action.indexOf(".") >= 0 ? action.replace(/^.*\./, "") : undefined, + queueName = queue === "false" ? false : validateQueue(args[0]), + defaultQueue = defaults.queue; + + if (isVelocityResult(elements) && elements.velocity.animations) { + for (let i = 0, animations = elements.velocity.animations; i < animations.length; i++) { + checkAnimation(animations[i], queueName, defaultQueue, isPaused); + } + } else { + let activeCall: AnimationCall = State.first; + + while (activeCall) { + if (!elements || _inArray(elements, activeCall.element)) { + checkAnimation(activeCall, queueName, defaultQueue, isPaused); + } + activeCall = activeCall._next; + } + } + if (promiseHandler) { + if (isVelocityResult(elements) && elements.velocity.animations && elements.then) { + elements.then(promiseHandler._resolver); + } else { + promiseHandler._resolver(elements); + } + } + } + + registerAction(["pause", pauseResume], true); + registerAction(["resume", pauseResume], true); +} diff --git a/src/Velocity/actions/reverse.ts b/src/Velocity/actions/reverse.ts new file mode 100644 index 00000000..e0c74357 --- /dev/null +++ b/src/Velocity/actions/reverse.ts @@ -0,0 +1,15 @@ +/// +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + * + * Actions that can be performed by passing a string instead of a propertiesMap. + */ + +namespace VelocityStatic { + registerAction(["reverse", function(args?: any[], elements?: HTMLorSVGElement[] | VelocityResult, promiseHandler?: VelocityPromise, action?: string) { + // TODO: Code needs to split out before here - but this is needed to prevent it being overridden + throw new SyntaxError("VelocityJS: The 'reverse' action is private."); + }], true) +} diff --git a/src/Velocity/actions/stop.ts b/src/Velocity/actions/stop.ts new file mode 100644 index 00000000..bc06a838 --- /dev/null +++ b/src/Velocity/actions/stop.ts @@ -0,0 +1,75 @@ +/// +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + * + * Stop animation. + */ + +namespace VelocityStatic { + + /** + * Check if an animation should be stopped, and if so then set the STOPPED + * flag on it, then call complete. + */ + function checkAnimationShouldBeStopped(animation: AnimationCall, queueName: false | string, defaultQueue: false | string) { + validateTweens(animation); + if (queueName === undefined || queueName === getValue(animation.queue, animation.options.queue, defaultQueue)) { + animation._flags |= AnimationFlags.STOPPED; + completeCall(animation); + } + } + + /** + * When the stop action is triggered, the elements' currently active call is + * immediately stopped. When an element is stopped, the next item in its + * animation queue is immediately triggered. If passed via a chained call + * then this will only target the animations in that call, and not the + * elements linked to it. + * + * A queue name may be passed in to specify that only animations on the + * named queue are stopped. The default queue is named "". In addition the + * value of `false` is allowed for the queue name. + * + * An final argument may be passed in to clear an element's remaining queued + * calls. This may only be the value `true`. + * + * Note: The stop command runs prior to Velocity's Queueing phase since its + * behavior is intended to take effect *immediately*, regardless of the + * element's current queue state. + */ + function stop(args: any[], elements: VelocityResult, promiseHandler?: VelocityPromise, action?: string): void { + const queueName: string | false = validateQueue(args[0], true), + defaultQueue: false | string = defaults.queue, + finishAll = args[queueName === undefined ? 0 : 1] === true; + + if (isVelocityResult(elements) && elements.velocity.animations) { + for (let i = 0, animations = elements.velocity.animations; i < animations.length; i++) { + checkAnimationShouldBeStopped(animations[i], queueName, defaultQueue); + } + } else { + let activeCall = State.first, + nextCall: AnimationCall; + + while ((activeCall = State.firstNew)) { + validateTweens(activeCall); + } + for (activeCall = State.first; activeCall && (finishAll || activeCall !== State.firstNew); activeCall = nextCall || State.firstNew) { + nextCall = activeCall._next; + if (!elements || _inArray(elements, activeCall.element)) { + checkAnimationShouldBeStopped(activeCall, queueName, defaultQueue); + } + } + } + if (promiseHandler) { + if (isVelocityResult(elements) && elements.velocity.animations && elements.then) { + elements.then(promiseHandler._resolver); + } else { + promiseHandler._resolver(elements); + } + } + } + + registerAction(["stop", stop], true); +} diff --git a/src/Velocity/actions/style.ts b/src/Velocity/actions/style.ts new file mode 100644 index 00000000..6d0b319e --- /dev/null +++ b/src/Velocity/actions/style.ts @@ -0,0 +1,95 @@ +/// +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + * + * Get or set a property from one or more elements. + */ + +namespace VelocityStatic { + + /** + * Expose a style shortcut - can't be used with chaining, but might be of + * use to people. + */ + export function style(elements: VelocityResult, property: {[property: string]: string}): VelocityResult; + export function style(elements: VelocityResult, property: string): string | string[]; + export function style(elements: VelocityResult, property: string, value: string): VelocityResult; + export function style(elements: VelocityResult, property: string | {[property: string]: string}, value?: string) { + return styleAction([property, value], elements); + } + + /** + * Get or set a style of Nomralised property value on one or more elements. + * If there is no value passed then it will get, otherwise we will set. + * + * NOTE: When using "get" this will not touch the Promise as it is never + * returned to the user. + * + * This can fail to set, and will reject the Promise if it does so. + * + * Velocity(elements, "style", "property", "value") => elements; + * Velocity(elements, "style", {"property": "value", ...}) => elements; + * Velocity(element, "style", "property") => "value"; + * Velocity(elements, "style", "property") => ["value", ...]; + */ + function styleAction(args?: any[], elements?: VelocityResult, promiseHandler?: VelocityPromise, action?: string): any { + const property = args[0], + value = args[1]; + + if (!property) { + console.warn("VelocityJS: Cannot access a non-existant property!"); + return null; + } + // GET + if (value === undefined && !isPlainObject(property)) { + // If only a single animation is found and we're only targetting a + // single element, then return the value directly + if (elements.length === 1) { + return CSS.getPropertyValue(elements[0], property); + } + const result = []; + + for (let i = 0; i < elements.length; i++) { + result.push(CSS.getPropertyValue(elements[i], property)); + } + return result; + } + // SET + let error: string; + + if (isPlainObject(property)) { + for (const propertyName in property) { + for (let i = 0; i < elements.length; i++) { + const value = property[propertyName]; + + if (isString(value) || isNumber(value)) { + CSS.setPropertyValue(elements[i], propertyName, property[propertyName]); + } else { + error = (error ? error + ", " : "") + "Cannot set a property '" + propertyName + "' to an unknown type: " + (typeof value); + console.warn("VelocityJS: Cannot set a property '" + propertyName + "' to an unknown type:", value); + } + } + } + } else if (isString(value) || isNumber(value)) { + for (let i = 0; i < elements.length; i++) { + CSS.setPropertyValue(elements[i], property, String(value)); + } + } else { + error = "Cannot set a property '" + property + "' to an unknown type: " + (typeof value); + console.warn("VelocityJS: Cannot set a property '" + property + "' to an unknown type:", value); + } + if (promiseHandler) { + if (error) { + promiseHandler._rejecter(error); + } else if (isVelocityResult(elements) && elements.velocity.animations && elements.then) { + elements.then(promiseHandler._resolver); + } else { + promiseHandler._resolver(elements); + } + } + } + + registerAction(["style", styleAction], true); +} diff --git a/src/Velocity/actions/tween.ts b/src/Velocity/actions/tween.ts new file mode 100644 index 00000000..e6b16e45 --- /dev/null +++ b/src/Velocity/actions/tween.ts @@ -0,0 +1,120 @@ +/// +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + * + * Get or set a property from one or more elements. + */ + +namespace VelocityStatic { + + /** + * Expose a style shortcut - can't be used with chaining, but might be of + * use to people. + */ + export function tween(elements: HTMLorSVGElement[], percentComplete: number, properties: VelocityProperties, easing?: VelocityEasingType); + export function tween(elements: HTMLorSVGElement[], percentComplete: number, propertyName: string, property: VelocityProperty, easing?: VelocityEasingType); + export function tween(elements: HTMLorSVGElement[], percentComplete: number, properties: VelocityProperties | string, property?: VelocityProperty | VelocityEasingType, easing?: VelocityEasingType) { + return tweenAction(arguments as any, elements); + } + + /** + * + */ + function tweenAction(args?: any[], elements?: HTMLorSVGElement[], promiseHandler?: VelocityPromise, action?: string): any { + let requireForcefeeding: boolean; + + if (!elements) { + if (!args.length) { + console.info("Velocity(, \"tween\", percentComplete, property, end | [end, , ], ) => value\n" + + "Velocity(, \"tween\", percentComplete, {property: end | [end, , ], ...}, ) => {property: value, ...}"); + return null; + } + elements = [document.body]; + requireForcefeeding = true; + } else if (elements.length !== 1) { + // TODO: Allow more than a single element to return an array of results + throw new Error("VelocityJS: Cannot tween more than one element!"); + } + const percentComplete: number = args[0], + fakeAnimation = { + elements: elements, + element: elements[0], + queue: false, + options: { + duration: 1000 + }, + tweens: null as {[property: string]: VelocityTween} + }, + result: {[property: string]: string} = {}; + let properties: VelocityProperties = args[1], + singleResult: boolean, + easing: VelocityEasingType = args[2], + count = 0; + + if (isString(args[1])) { + singleResult = true; + properties = { + [args[1]]: args[2] + }; + easing = args[3]; + } else if (Array.isArray(args[1])) { + singleResult = true; + properties = { + "tween": args[1] + } as any; + easing = args[2]; + } + if (!isNumber(percentComplete) || percentComplete < 0 || percentComplete > 1) { + throw new Error("VelocityJS: Must tween a percentage from 0 to 1!"); + } + if (!isPlainObject(properties)) { + throw new Error("VelocityJS: Cannot tween an invalid property!"); + } + if (requireForcefeeding) { + for (const property in properties) { + if (properties.hasOwnProperty(property) && (!Array.isArray(properties[property]) || properties[property].length < 2)) { + throw new Error("VelocityJS: When not supplying an element you must force-feed values: " + property); + } + } + } + const activeEasing = validateEasing(getValue(easing, defaults.easing), 1000); + + expandProperties(fakeAnimation as AnimationCall, properties); + for (const property in fakeAnimation.tweens) { + // For every element, iterate through each property. + const tween = fakeAnimation.tweens[property], + easing = tween[Tween.EASING] || activeEasing, + pattern = tween[Tween.PATTERN], + rounding = tween[Tween.ROUNDING]; + let currentValue = ""; + + count++; + if (pattern) { + for (let i = 0; i < pattern.length; i++) { + const startValue = tween[Tween.START][i]; + + if (startValue == null) { + currentValue += pattern[i]; + } else { + const result = easing(percentComplete, startValue as number, tween[Tween.END][i] as number, property) + + currentValue += rounding && rounding[i] ? Math.round(result) : result; + } + } + } + result[property] = currentValue; + } + if (singleResult && count === 1) { + for (const property in result) { + if (result.hasOwnProperty(property)) { + return result[property]; + } + } + } + return result; + } + + registerAction(["tween", tweenAction], true); +} diff --git a/src/Velocity/complete.ts b/src/Velocity/complete.ts new file mode 100644 index 00000000..f8576269 --- /dev/null +++ b/src/Velocity/complete.ts @@ -0,0 +1,119 @@ +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + * + * Call Completion + */ + +namespace VelocityStatic { + /** + * Call the complete method of an animation in a separate function so it can + * benefit from JIT compiling while still having a try/catch block. + */ + function callComplete(activeCall: AnimationCall) { + try { + const elements = activeCall.elements; + + (activeCall.options.complete as VelocityCallback).call(elements, elements, activeCall); + } catch (error) { + setTimeout(function() { + throw error; + }, 1); + } + } + + /** + * Complete an animation. This might involve restarting (for loop or repeat + * options). Once it is finished we also check for any callbacks or Promises + * that need updating. + */ + export function completeCall(activeCall: AnimationCall) { + // console.log("complete", activeCall) + // TODO: Check if it's not been completed already + + const options = activeCall.options, + queue = getValue(activeCall.queue, options.queue), + isLoop = getValue(activeCall.loop, options.loop, defaults.loop), + isRepeat = getValue(activeCall.repeat, options.repeat, defaults.repeat), + isStopped = activeCall._flags & AnimationFlags.STOPPED; + + if (!isStopped && (isLoop || isRepeat)) { + + //////////////////// + // Option: Loop // + // Option: Repeat // + //////////////////// + + if (isRepeat && isRepeat !== true) { + activeCall.repeat = isRepeat - 1; + } else if (isLoop && isLoop !== true) { + activeCall.loop = isLoop - 1; + activeCall.repeat = getValue(activeCall.repeatAgain, options.repeatAgain, defaults.repeatAgain); + } + if (isLoop) { + activeCall._flags ^= AnimationFlags.REVERSE; + } + if (queue !== false) { + // Can't be called when stopped so no need for an extra check. + Data(activeCall.element).lastFinishList[queue] = activeCall.timeStart + getValue(activeCall.duration, options.duration, defaults.duration); + } + activeCall.timeStart = activeCall.ellapsedTime = activeCall.percentComplete = 0; + activeCall._flags &= ~AnimationFlags.STARTED; + } else { + const element = activeCall.element, + data = Data(element); + + if (!--data.count && !isStopped) { + + //////////////////////// + // Feature: Classname // + //////////////////////// + + removeClass(element, State.className); + } + + ////////////////////// + // Option: Complete // + ////////////////////// + + // If this is the last animation in this list then we can check for + // and complete calls or Promises. + // TODO: When deleting an element we need to adjust these values. + if (options && ++options._completed === options._total) { + if (!isStopped && options.complete) { + // We don't call the complete if the animation is stopped, + // and we clear the key to prevent it being called again. + callComplete(activeCall); + options.complete = null; + } + const resolver = options._resolver; + + if (resolver) { + // Fulfil the Promise + resolver(activeCall.elements as any); + delete options._resolver; + } + } + + /////////////////// + // Option: Queue // + /////////////////// + + if (queue !== false) { + // We only do clever things with queues... + if (!isStopped) { + // If we're not stopping an animation, we need to remember + // what time it finished so that the next animation in + // sequence gets the correct start time. + data.lastFinishList[queue] = activeCall.timeStart + getValue(activeCall.duration, options.duration, defaults.duration); + } + // Start the next animation in sequence, or delete the queue if + // this was the last one. + dequeue(element, queue); + } + // Cleanup any pointers, and remember the last animation etc. + freeAnimationCall(activeCall); + } + } +}; diff --git a/src/Velocity/css/_all.d.ts b/src/Velocity/css/_all.d.ts new file mode 100644 index 00000000..bdf85b63 --- /dev/null +++ b/src/Velocity/css/_all.d.ts @@ -0,0 +1,7 @@ +/// +/// +/// +/// +/// +/// +/// diff --git a/src/Velocity/css/camelCase.ts b/src/Velocity/css/camelCase.ts new file mode 100644 index 00000000..d6c664ae --- /dev/null +++ b/src/Velocity/css/camelCase.ts @@ -0,0 +1,29 @@ +/// +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + */ + +namespace VelocityStatic.CSS { + /** + * Cache every camelCase match to avoid repeating lookups. + */ + const cache: {[property: string]: string} = Object.create(null); + + /** + * Camelcase a property name into its JavaScript notation (e.g. + * "background-color" ==> "backgroundColor"). Camelcasing is used to + * normalize property names between and across calls. + */ + export function camelCase(property: string): string { + const fixed = cache[property]; + + if (fixed) { + return fixed; + } + return cache[property] = property.replace(/-([a-z])/g, function(match: string, subMatch: string) { + return subMatch.toUpperCase(); + }) + } +} \ No newline at end of file diff --git a/src/Velocity/css/colors.ts b/src/Velocity/css/colors.ts new file mode 100644 index 00000000..7a161b22 --- /dev/null +++ b/src/Velocity/css/colors.ts @@ -0,0 +1,169 @@ +/// +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + */ + +namespace VelocityStatic.CSS { + // Converting from hex as it makes for a smaller file. + // TODO: When build system changes to webpack, make this one optional. + const colorValues = { + "aliceblue": 0xf0f8ff, + "antiquewhite": 0xfaebd7, + "aqua": 0x00ffff, + "aquamarine": 0x7fffd4, + "azure": 0xf0ffff, + "beige": 0xf5f5dc, + "bisque": 0xffe4c4, + "black": 0x000000, + "blanchedalmond": 0xffebcd, + "blue": 0x0000ff, + "blueviolet": 0x8a2be2, + "brown": 0xa52a2a, + "burlywood": 0xdeb887, + "cadetblue": 0x5f9ea0, + "chartreuse": 0x7fff00, + "chocolate": 0xd2691e, + "coral": 0xff7f50, + "cornflowerblue": 0x6495ed, + "cornsilk": 0xfff8dc, + "crimson": 0xdc143c, + "cyan": 0x00ffff, + "darkblue": 0x00008b, + "darkcyan": 0x008b8b, + "darkgoldenrod": 0xb8860b, + "darkgray": 0xa9a9a9, + "darkgrey": 0xa9a9a9, + "darkgreen": 0x006400, + "darkkhaki": 0xbdb76b, + "darkmagenta": 0x8b008b, + "darkolivegreen": 0x556b2f, + "darkorange": 0xff8c00, + "darkorchid": 0x9932cc, + "darkred": 0x8b0000, + "darksalmon": 0xe9967a, + "darkseagreen": 0x8fbc8f, + "darkslateblue": 0x483d8b, + "darkslategray": 0x2f4f4f, + "darkslategrey": 0x2f4f4f, + "darkturquoise": 0x00ced1, + "darkviolet": 0x9400d3, + "deeppink": 0xff1493, + "deepskyblue": 0x00bfff, + "dimgray": 0x696969, + "dimgrey": 0x696969, + "dodgerblue": 0x1e90ff, + "firebrick": 0xb22222, + "floralwhite": 0xfffaf0, + "forestgreen": 0x228b22, + "fuchsia": 0xff00ff, + "gainsboro": 0xdcdcdc, + "ghostwhite": 0xf8f8ff, + "gold": 0xffd700, + "goldenrod": 0xdaa520, + "gray": 0x808080, + "grey": 0x808080, + "green": 0x008000, + "greenyellow": 0xadff2f, + "honeydew": 0xf0fff0, + "hotpink": 0xff69b4, + "indianred": 0xcd5c5c, + "indigo": 0x4b0082, + "ivory": 0xfffff0, + "khaki": 0xf0e68c, + "lavender": 0xe6e6fa, + "lavenderblush": 0xfff0f5, + "lawngreen": 0x7cfc00, + "lemonchiffon": 0xfffacd, + "lightblue": 0xadd8e6, + "lightcoral": 0xf08080, + "lightcyan": 0xe0ffff, + "lightgoldenrodyellow": 0xfafad2, + "lightgray": 0xd3d3d3, + "lightgrey": 0xd3d3d3, + "lightgreen": 0x90ee90, + "lightpink": 0xffb6c1, + "lightsalmon": 0xffa07a, + "lightseagreen": 0x20b2aa, + "lightskyblue": 0x87cefa, + "lightslategray": 0x778899, + "lightslategrey": 0x778899, + "lightsteelblue": 0xb0c4de, + "lightyellow": 0xffffe0, + "lime": 0x00ff00, + "limegreen": 0x32cd32, + "linen": 0xfaf0e6, + "magenta": 0xff00ff, + "maroon": 0x800000, + "mediumaquamarine": 0x66cdaa, + "mediumblue": 0x0000cd, + "mediumorchid": 0xba55d3, + "mediumpurple": 0x9370db, + "mediumseagreen": 0x3cb371, + "mediumslateblue": 0x7b68ee, + "mediumspringgreen": 0x00fa9a, + "mediumturquoise": 0x48d1cc, + "mediumvioletred": 0xc71585, + "midnightblue": 0x191970, + "mintcream": 0xf5fffa, + "mistyrose": 0xffe4e1, + "moccasin": 0xffe4b5, + "navajowhite": 0xffdead, + "navy": 0x000080, + "oldlace": 0xfdf5e6, + "olive": 0x808000, + "olivedrab": 0x6b8e23, + "orange": 0xffa500, + "orangered": 0xff4500, + "orchid": 0xda70d6, + "palegoldenrod": 0xeee8aa, + "palegreen": 0x98fb98, + "paleturquoise": 0xafeeee, + "palevioletred": 0xdb7093, + "papayawhip": 0xffefd5, + "peachpuff": 0xffdab9, + "peru": 0xcd853f, + "pink": 0xffc0cb, + "plum": 0xdda0dd, + "powderblue": 0xb0e0e6, + "purple": 0x800080, + "rebeccapurple": 0x663399, + "red": 0xff0000, + "rosybrown": 0xbc8f8f, + "royalblue": 0x4169e1, + "saddlebrown": 0x8b4513, + "salmon": 0xfa8072, + "sandybrown": 0xf4a460, + "seagreen": 0x2e8b57, + "seashell": 0xfff5ee, + "sienna": 0xa0522d, + "silver": 0xc0c0c0, + "skyblue": 0x87ceeb, + "slateblue": 0x6a5acd, + "slategray": 0x708090, + "slategrey": 0x708090, + "snow": 0xfffafa, + "springgreen": 0x00ff7f, + "steelblue": 0x4682b4, + "tan": 0xd2b48c, + "teal": 0x008080, + "thistle": 0xd8bfd8, + "tomato": 0xff6347, + "turquoise": 0x40e0d0, + "violet": 0xee82ee, + "wheat": 0xf5deb3, + "white": 0xffffff, + "whitesmoke": 0xf5f5f5, + "yellow": 0xffff00, + "yellowgreen": 0x9acd32 + }; + + for (let name in colorValues) { + if (colorValues.hasOwnProperty(name)) { + let color = colorValues[name]; + + ColorNames[name] = Math.floor(color / 65536) + "," + Math.floor(color / 256 % 256) + "," + (color % 256); + } + } +} diff --git a/src/Velocity/css/fixColors.ts b/src/Velocity/css/fixColors.ts new file mode 100644 index 00000000..4f6f03ff --- /dev/null +++ b/src/Velocity/css/fixColors.ts @@ -0,0 +1,48 @@ +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + */ + +namespace VelocityStatic.CSS { + /** + * This is the list of color names -> rgb values. The object is in here so + * that the actual name conversion can be in a separate file and not + * included for custom builds. + */ + export const ColorNames: {[name: string]: string} = Object.create(null); + + /** + * Convert a hex list to an rgba value. Designed to be used in replace. + */ + function makeRGBA(ignore: any, r: string, g: string, b: string): string { + return "rgba(" + parseInt(r, 16) + "," + parseInt(g, 16) + "," + parseInt(b, 16) + ",1)"; + } + + const rxColor6 = /#([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})/gi, + rxColor3 = /#([a-f\d])([a-f\d])([a-f\d])/gi, + rxColorName = /(rgba?\(\s*)?(\b[a-z]+\b)/g, + rxRGB = /rgba?\([^\)]+\)/gi, + rxSpaces = /\s+/g; + + /** + * Replace any css colour name with its rgba() value. It is possible to use + * the name within an "rgba(blue, 0.4)" string this way. + */ + export function fixColors(str: string): string { + return str + .replace(rxColor6, makeRGBA) + .replace(rxColor3, function($0, r, g, b) { + return makeRGBA($0, r + r, g + g, b + b); + }) + .replace(rxColorName, function($0, $1, $2) { + if (ColorNames[$2]) { + return ($1 ? $1 : "rgba(") + ColorNames[$2] + ($1 ? "" : ",1)"); + } + return $0; + }) + .replace(rxRGB, function($0) { + return $0.replace(rxSpaces, ""); + }); + } +} diff --git a/src/Velocity/css/getPropertyValue.ts b/src/Velocity/css/getPropertyValue.ts new file mode 100644 index 00000000..7f52e6d3 --- /dev/null +++ b/src/Velocity/css/getPropertyValue.ts @@ -0,0 +1,135 @@ +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + */ + +namespace VelocityStatic.CSS { + + // TODO: This is still a complete mess + export function computePropertyValue(element: HTMLorSVGElement, property: string): string { + const data = Data(element), + // If computedStyle is cached, use it. + computedStyle = data && data.computedStyle ? data.computedStyle : window.getComputedStyle(element, null); + let computedValue: string | number = 0; + + if (data && !data.computedStyle) { + data.computedStyle = computedStyle; + } + if (property === "width" || property === "height") { + // Browsers do not return height and width values for elements + // that are set to display:"none". Thus, we temporarily toggle + // display to the element type's default value. + const toggleDisplay: boolean = getPropertyValue(element, "display") === "none"; + + // When box-sizing isn't set to border-box, height and width + // style values are incorrectly computed when an element's + // scrollbars are visible (which expands the element's + // dimensions). Thus, we defer to the more accurate + // offsetHeight/Width property, which includes the total + // dimensions for interior, border, padding, and scrollbar. We + // subtract border and padding to get the sum of interior + + // scrollbar. + // TODO: offsetHeight does not exist on SVGElement + if (toggleDisplay) { + setPropertyValue(element, "display", "auto"); + } + computedValue = augmentDimension(element, property, true); + if (toggleDisplay) { + setPropertyValue(element, "display", "none"); + } + return String(computedValue); + } + + /* IE and Firefox do not return a value for the generic borderColor -- they only return individual values for each border side's color. + Also, in all browsers, when border colors aren't all the same, a compound value is returned that Velocity isn't setup to parse. + So, as a polyfill for querying individual border side colors, we just return the top border's color and animate all borders from that value. */ + /* TODO: There is a borderColor normalisation in legacy/ - figure out where this is needed... */ + // if (property === "borderColor") { + // property = "borderTopColor"; + // } + + computedValue = computedStyle[property]; + /* Fall back to the property's style value (if defined) when computedValue returns nothing, + which can happen when the element hasn't been painted. */ + if (!computedValue) { + computedValue = element.style[property]; + } + /* For top, right, bottom, and left (TRBL) values that are set to "auto" on elements of "fixed" or "absolute" position, + defer to jQuery for converting "auto" to a numeric value. (For elements with a "static" or "relative" position, "auto" has the same + effect as being set to 0, so no conversion is necessary.) */ + /* An example of why numeric conversion is necessary: When an element with "position:absolute" has an untouched "left" + property, which reverts to "auto", left's value is 0 relative to its parent element, but is often non-zero relative + to its *containing* (not parent) element, which is the nearest "position:relative" ancestor or the viewport (and always the viewport in the case of "position:fixed"). */ + if (computedValue === "auto") { + switch (property) { + case "top": + case "left": + let topLeft = true; + case "right": + case "bottom": + const position = getPropertyValue(element, "position"); /* GET */ + + if (position === "fixed" || (topLeft && position === "absolute")) { + // Note: this has no pixel unit on its returned values, + // we re-add it here to conform with + // computePropertyValue's behavior. + computedValue = element.getBoundingClientRect[property] + "px"; /* GET */ + break; + } + // Deliberate fallthrough! + default: + computedValue = "0px"; + break + } + } + return computedValue ? String(computedValue) : ""; + } + + /** + * Get a property value. This will grab via the cache if it exists, then + * via any normalisations, then it will check the css values directly. + */ + export function getPropertyValue(element: HTMLorSVGElement, propertyName: string, skipNormalisation?: boolean, skipCache?: boolean): string { + const data = Data(element); + let propertyValue: string; + + if (NoCacheNormalizations.has(propertyName)) { + skipCache = true; + } + if (!skipCache && data && data.cache[propertyName] != null) { + propertyValue = data.cache[propertyName]; + if (debug >= 2) { + console.info("Get " + propertyName + ": " + propertyValue); + } + return propertyValue; + } else { + let types = data.types, + best: VelocityNormalizationsFn; + + for (let index = 0; types; types >>= 1, index++) { + if (types & 1) { + best = Normalizations[index][propertyName] || best; + } + } + if (best) { + propertyValue = best(element); + } else { + // Note: Retrieving the value of a CSS property cannot simply be + // performed by checking an element's style attribute (which + // only reflects user-defined values). Instead, the browser must + // be queried for a property's *computed* value. You can read + // more about getComputedStyle here: + // https://developer.mozilla.org/en/docs/Web/API/window.getComputedStyle + propertyValue = computePropertyValue(element, propertyName); + } + } + if (debug >= 2) { + console.info("Get " + propertyName + ": " + propertyValue); + } + if (data) { + data.cache[propertyName] = propertyValue; + } + return propertyValue; + } +} diff --git a/src/Velocity/css/getUnit.ts b/src/Velocity/css/getUnit.ts new file mode 100644 index 00000000..0d10691f --- /dev/null +++ b/src/Velocity/css/getUnit.ts @@ -0,0 +1,44 @@ +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + */ + +namespace VelocityStatic.CSS { + /** + * All possible units in CSS. Used to recognise units when parsing tweens. + */ + const Units = [ + "%", // relative + "em", "ex", "ch", "rem", // font relative + "vw", "vh", "vmin", "vmax", // viewport relative + "cm", "mm", "Q", "in", "pc", "pt", "px", // absolute lengths + "deg", "grad", "rad", "turn", // angles + "s", "ms" // time + ]; + + /** + * Get the current unit for this property. Only used when parsing tweens + * to check if the unit is changing between the start and end values. + */ + export function getUnit(property: string, start?: number): string { + start = start || 0; + if (property[start] && property[start] !== " ") { + for (let i = 0, units = Units; i < units.length; i++) { + const unit = units[i]; + let j = 0; + + do { + if (j >= unit.length) { + return unit; + } + if (unit[j] !== property[start + j]) { + break; + } + } while (++j); + } + } + return ""; + } + +} diff --git a/src/Velocity/css/regex.ts b/src/Velocity/css/regex.ts new file mode 100644 index 00000000..26ac79b3 --- /dev/null +++ b/src/Velocity/css/regex.ts @@ -0,0 +1,19 @@ +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + * + * Regular Expressions - cached as they can be expensive to create. + */ + +namespace VelocityStatic.CSS { + + export const RegEx = { + isHex: /^#([A-f\d]{3}){1,2}$/i, + /* Unwrap a property value's surrounding text, e.g. "rgba(4, 3, 2, 1)" ==> "4, 3, 2, 1" and "rect(4px 3px 2px 1px)" ==> "4px 3px 2px 1px". */ + valueUnwrap: /^[A-z]+\((.*)\)$/i, + wrappedValueAlreadyExtracted: /[0-9.]+ [0-9.]+ [0-9.]+( [0-9.]+)?/, + /* Split a multi-value property into an array of subvalues, e.g. "rgba(4, 3, 2, 1) 4px 3px 2px 1px" ==> [ "rgba(4, 3, 2, 1)", "4px", "3px", "2px", "1px" ]. */ + valueSplit: /([A-z]+\(.+\))|(([A-z0-9#-.]+?)(?=\s|$))/ig + }; +} \ No newline at end of file diff --git a/src/Velocity/css/setPropertyValue.ts b/src/Velocity/css/setPropertyValue.ts new file mode 100644 index 00000000..4c400439 --- /dev/null +++ b/src/Velocity/css/setPropertyValue.ts @@ -0,0 +1,45 @@ +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + */ + +namespace VelocityStatic.CSS { + /** + * The singular setPropertyValue, which routes the logic for all + * normalizations, hooks, and standard CSS properties. + */ + export function setPropertyValue(element: HTMLorSVGElement, propertyName: string, propertyValue: any) { + const data = Data(element); + + if (isString(propertyValue) + && propertyValue[0] === "c" + && propertyValue[1] === "a" + && propertyValue[2] === "l" + && propertyValue[3] === "c" + && propertyValue[4] === "(" + && propertyValue[5] === "0") { + // Make sure we un-calc unit changing values - try not to trigger + // this code any more often than we have to since it's expensive + propertyValue = propertyValue.replace(/^calc\(0[^\d]* \+ ([^\(\)]+)\)$/, "$1"); + } + if (data && data.cache[propertyName] !== propertyValue) { + // By setting it to undefined we force a true "get" later + data.cache[propertyName] = propertyValue || undefined; + let types = data.types, + best: VelocityNormalizationsFn; + + for (let index = 0; types; types >>= 1, index++) { + if (types & 1) { + best = Normalizations[index][propertyName] || best; + } + } + if (!best || !best(element, propertyValue)) { + element.style[propertyName] = propertyValue; + } + if (debug >= 2) { + console.info("Set " + propertyName + ": " + propertyValue, element); + } + } + } +}; diff --git a/src/Velocity/data.ts b/src/Velocity/data.ts new file mode 100644 index 00000000..ec225bbd --- /dev/null +++ b/src/Velocity/data.ts @@ -0,0 +1,42 @@ +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + */ + +interface Element { + velocityData: ElementData; +} + +/** + * Get (and create) the internal data store for an element. + */ +function Data(element: HTMLorSVGElement): ElementData { + // Use a string member so Uglify doesn't mangle it. + const data = element["velocityData"]; + + if (data) { + return data; + } + let types = 0; + + for (let index = 0, constructors = VelocityStatic.constructors; index < constructors.length; index++) { + if (element instanceof constructors[index]) { + types |= 1 << index; + } + } + // Do it this way so it errors on incorrect data. + let newData: ElementData = { + types: types, + count: 0, + computedStyle: null, + cache: Object.create(null), + queueList: Object.create(null), + lastAnimationList: Object.create(null), + lastFinishList: Object.create(null) + }; + Object.defineProperty(element, "velocityData", { + value: newData + }); + return newData; +} diff --git a/src/Velocity/debug.ts b/src/Velocity/debug.ts new file mode 100644 index 00000000..c5d0752d --- /dev/null +++ b/src/Velocity/debug.ts @@ -0,0 +1,12 @@ +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + */ + +namespace VelocityStatic { + /** + * Set to true, 1 or 2 (most verbose) to output debug info to console. + */ + export let debug: boolean | 1 | 2 = false; +}; diff --git a/src/Velocity/defaults.ts b/src/Velocity/defaults.ts new file mode 100644 index 00000000..ac3f59b3 --- /dev/null +++ b/src/Velocity/defaults.ts @@ -0,0 +1,230 @@ +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + * + * Velocity option defaults, which can be overriden by the user. + */ + +namespace VelocityStatic { + // NOTE: Add the variable here, then add the default state in "reset" below. + let _cache: boolean, + _begin: VelocityCallback, + _complete: VelocityCallback, + _delay: number, + _duration: number, + _easing: VelocityEasingType, + _fpsLimit: number, + _loop: number | true, + _minFrameTime: number, + _promise: boolean, + _promiseRejectEmpty: boolean, + _queue: string | false, + _repeat: number | true, + _speed: number, + _sync: boolean; + + export const defaults: StrictVelocityOptions & {reset?: () => void} = { + mobileHA: true + }; + + // IMPORTANT: Make sure any new defaults get added to the actions/set.ts list + Object.defineProperties(defaults, { + reset: { + enumerable: true, + value: function() { + _cache = DEFAULT_CACHE; + _begin = undefined; + _complete = undefined; + _delay = DEFAULT_DELAY; + _duration = DEFAULT_DURATION; + _easing = validateEasing(DEFAULT_EASING, DEFAULT_DURATION); + _fpsLimit = DEFAULT_FPSLIMIT; + _loop = DEFAULT_LOOP; + _minFrameTime = FUZZY_MS_PER_SECOND / DEFAULT_FPSLIMIT; + _promise = DEFAULT_PROMISE; + _promiseRejectEmpty = DEFAULT_PROMISE_REJECT_EMPTY; + _queue = DEFAULT_QUEUE; + _repeat = DEFAULT_REPEAT; + _speed = DEFAULT_SPEED; + _sync = DEFAULT_SYNC; + } + }, + cache: { + enumerable: true, + get: function(): boolean { + return _cache; + }, + set: function(value: boolean) { + value = validateCache(value); + if (value !== undefined) { + _cache = value; + } + } + }, + begin: { + enumerable: true, + get: function(): VelocityCallback { + return _begin; + }, + set: function(value: VelocityCallback) { + value = validateBegin(value); + if (value !== undefined) { + _begin = value; + } + } + }, + complete: { + enumerable: true, + get: function(): VelocityCallback { + return _complete; + }, + set: function(value: VelocityCallback) { + value = validateComplete(value); + if (value !== undefined) { + _complete = value; + } + } + }, + delay: { + enumerable: true, + get: function(): "fast" | "normal" | "slow" | number { + return _delay; + }, + set: function(value: "fast" | "normal" | "slow" | number) { + value = validateDelay(value); + if (value !== undefined) { + _delay = value; + } + } + }, + duration: { + enumerable: true, + get: function(): "fast" | "normal" | "slow" | number { + return _duration; + }, + set: function(value: "fast" | "normal" | "slow" | number) { + value = validateDuration(value); + if (value !== undefined) { + _duration = value; + } + } + }, + easing: { + enumerable: true, + get: function(): VelocityEasingType { + return _easing; + }, + set: function(value: VelocityEasingType) { + value = validateEasing(value, _duration); + if (value !== undefined) { + _easing = value; + } + } + }, + fpsLimit: { + enumerable: true, + get: function(): number | false { + return _fpsLimit; + }, + set: function(value: number | false) { + value = validateFpsLimit(value); + if (value !== undefined) { + _fpsLimit = value; + _minFrameTime = FUZZY_MS_PER_SECOND / value; + } + } + }, + loop: { + enumerable: true, + get: function(): number | true { + return _loop; + }, + set: function(value: number | boolean) { + value = validateLoop(value); + if (value !== undefined) { + _loop = value; + } + } + }, + minFrameTime: { + enumerable: true, + get: function(): number | false { + return _minFrameTime; + } + }, + promise: { + enumerable: true, + get: function(): boolean { + return _promise; + }, + set: function(value: boolean) { + value = validatePromise(value); + if (value !== undefined) { + _promise = value; + } + } + }, + promiseRejectEmpty: { + enumerable: true, + get: function(): boolean { + return _promiseRejectEmpty; + }, + set: function(value: boolean) { + value = validatePromiseRejectEmpty(value); + if (value !== undefined) { + _promiseRejectEmpty = value; + } + } + }, + queue: { + enumerable: true, + get: function(): string | false { + return _queue; + }, + set: function(value: string | false) { + value = validateQueue(value); + if (value !== undefined) { + _queue = value; + } + } + }, + repeat: { + enumerable: true, + get: function(): number | true { + return _repeat; + }, + set: function(value: number | boolean) { + value = validateRepeat(value); + if (value !== undefined) { + _repeat = value; + } + } + }, + speed: { + enumerable: true, + get: function(): number { + return _speed; + }, + set: function(value: number) { + value = validateSpeed(value); + if (value !== undefined) { + _speed = value; + } + } + }, + sync: { + enumerable: true, + get: function(): boolean { + return _sync; + }, + set: function(value: boolean) { + value = validateSync(value); + if (value !== undefined) { + _sync = value; + } + } + } + }); + defaults.reset(); +}; diff --git a/src/Velocity/easing/_all.d.ts b/src/Velocity/easing/_all.d.ts new file mode 100644 index 00000000..8bf4c0b9 --- /dev/null +++ b/src/Velocity/easing/_all.d.ts @@ -0,0 +1,7 @@ +/// +/// +/// +/// +/// +/// +/// diff --git a/src/Velocity/easing/bezier.ts b/src/Velocity/easing/bezier.ts new file mode 100644 index 00000000..ce149ada --- /dev/null +++ b/src/Velocity/easing/bezier.ts @@ -0,0 +1,196 @@ +/// +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + * + * Bezier curve function generator. Copyright Gaetan Renaudeau. MIT License: http://en.wikipedia.org/wiki/MIT_License + */ + +namespace VelocityStatic.Easing { + /** + * Fix to a range of 0 <= num <= 1. + */ + function fixRange(num: number) { + return Math.min(Math.max(num, 0), 1); + } + + function A(aA1, aA2) { + return 1.0 - 3.0 * aA2 + 3.0 * aA1; + } + + function B(aA1, aA2) { + return 3.0 * aA2 - 6.0 * aA1; + } + + function C(aA1) { + return 3.0 * aA1; + } + + function calcBezier(aT, aA1, aA2) { + return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT; + } + + function getSlope(aT, aA1, aA2) { + return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1); + } + + export function generateBezier(mX1: number, mY1: number, mX2: number, mY2: number): VelocityEasingFn { + const NEWTON_ITERATIONS = 4, + NEWTON_MIN_SLOPE = 0.001, + SUBDIVISION_PRECISION = 0.0000001, + SUBDIVISION_MAX_ITERATIONS = 10, + kSplineTableSize = 11, + kSampleStepSize = 1.0 / (kSplineTableSize - 1.0), + float32ArraySupported = "Float32Array" in window; + + /* Must contain four arguments. */ + if (arguments.length !== 4) { + return; + } + + /* Arguments must be numbers. */ + for (let i = 0; i < 4; ++i) { + if (typeof arguments[i] !== "number" || isNaN(arguments[i]) || !isFinite(arguments[i])) { + return; + } + } + + /* X values must be in the [0, 1] range. */ + mX1 = fixRange(mX1); + mX2 = fixRange(mX2); + + const mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize); + + function newtonRaphsonIterate(aX, aGuessT) { + for (let i = 0; i < NEWTON_ITERATIONS; ++i) { + const currentSlope = getSlope(aGuessT, mX1, mX2); + + if (currentSlope === 0.0) { + return aGuessT; + } + + const currentX = calcBezier(aGuessT, mX1, mX2) - aX; + aGuessT -= currentX / currentSlope; + } + + return aGuessT; + } + + function calcSampleValues() { + for (let i = 0; i < kSplineTableSize; ++i) { + mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2); + } + } + + function binarySubdivide(aX, aA, aB) { + let currentX, currentT, i = 0; + + do { + currentT = aA + (aB - aA) / 2.0; + currentX = calcBezier(currentT, mX1, mX2) - aX; + if (currentX > 0.0) { + aB = currentT; + } else { + aA = currentT; + } + } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS); + + return currentT; + } + + function getTForX(aX) { + let intervalStart = 0.0, + currentSample = 1, + lastSample = kSplineTableSize - 1; + + for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) { + intervalStart += kSampleStepSize; + } + + --currentSample; + + const dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample + 1] - mSampleValues[currentSample]), + guessForT = intervalStart + dist * kSampleStepSize, + initialSlope = getSlope(guessForT, mX1, mX2); + + if (initialSlope >= NEWTON_MIN_SLOPE) { + return newtonRaphsonIterate(aX, guessForT); + } else if (initialSlope === 0.0) { + return guessForT; + } else { + return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize); + } + } + + let _precomputed = false; + + function precompute() { + _precomputed = true; + if (mX1 !== mY1 || mX2 !== mY2) { + calcSampleValues(); + } + } + + const f = function(percentComplete: number, startValue: number, endValue: number, property?: string) { + if (!_precomputed) { + precompute(); + } + if (percentComplete === 0) { + return startValue; + } + if (percentComplete === 1) { + return endValue; + } + if (mX1 === mY1 && mX2 === mY2) { + return startValue + percentComplete * (endValue - startValue); + } + return startValue + calcBezier(getTForX(percentComplete), mY1, mY2) * (endValue - startValue); + }; + + (f as any).getControlPoints = function() { + return [{x: mX1, y: mY1}, {x: mX2, y: mY2}]; + }; + + const str = "generateBezier(" + [mX1, mY1, mX2, mY2] + ")"; + f.toString = function() { + return str; + }; + + return f; + } + + /* Common easings */ + const easeIn = generateBezier(0.42, 0.0, 1.00, 1.0), + easeOut = generateBezier(0.00, 0.0, 0.58, 1.0), + easeInOut = generateBezier(0.42, 0.0, 0.58, 1.0); + + registerEasing(["ease", generateBezier(0.25, 0.1, 0.25, 1.0)]); + registerEasing(["easeIn", easeIn]); + registerEasing(["ease-in", easeIn]); + registerEasing(["easeOut", easeOut]); + registerEasing(["ease-out", easeOut]); + registerEasing(["easeInOut", easeInOut]); + registerEasing(["ease-in-out", easeInOut]); + registerEasing(["easeInSine", generateBezier(0.47, 0, 0.745, 0.715)]); + registerEasing(["easeOutSine", generateBezier(0.39, 0.575, 0.565, 1)]); + registerEasing(["easeInOutSine", generateBezier(0.445, 0.05, 0.55, 0.95)]); + registerEasing(["easeInQuad", generateBezier(0.55, 0.085, 0.68, 0.53)]); + registerEasing(["easeOutQuad", generateBezier(0.25, 0.46, 0.45, 0.94)]); + registerEasing(["easeInOutQuad", generateBezier(0.455, 0.03, 0.515, 0.955)]); + registerEasing(["easeInCubic", generateBezier(0.55, 0.055, 0.675, 0.19)]); + registerEasing(["easeOutCubic", generateBezier(0.215, 0.61, 0.355, 1)]); + registerEasing(["easeInOutCubic", generateBezier(0.645, 0.045, 0.355, 1)]); + registerEasing(["easeInQuart", generateBezier(0.895, 0.03, 0.685, 0.22)]); + registerEasing(["easeOutQuart", generateBezier(0.165, 0.84, 0.44, 1)]); + registerEasing(["easeInOutQuart", generateBezier(0.77, 0, 0.175, 1)]); + registerEasing(["easeInQuint", generateBezier(0.755, 0.05, 0.855, 0.06)]); + registerEasing(["easeOutQuint", generateBezier(0.23, 1, 0.32, 1)]); + registerEasing(["easeInOutQuint", generateBezier(0.86, 0, 0.07, 1)]); + registerEasing(["easeInExpo", generateBezier(0.95, 0.05, 0.795, 0.035)]); + registerEasing(["easeOutExpo", generateBezier(0.19, 1, 0.22, 1)]); + registerEasing(["easeInOutExpo", generateBezier(1, 0, 0, 1)]); + registerEasing(["easeInCirc", generateBezier(0.6, 0.04, 0.98, 0.335)]); + registerEasing(["easeOutCirc", generateBezier(0.075, 0.82, 0.165, 1)]); + registerEasing(["easeInOutCirc", generateBezier(0.785, 0.135, 0.15, 0.86)]); +}; diff --git a/src/Velocity/easing/bounce.ts b/src/Velocity/easing/bounce.ts new file mode 100644 index 00000000..b9fbe835 --- /dev/null +++ b/src/Velocity/easing/bounce.ts @@ -0,0 +1,57 @@ +/// +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + * + * Bounce easings, based on code from https://github.com/yuichiroharai/easeplus-velocity + */ + +namespace VelocityStatic.Easing { + function easeOutBounce(percentComplete: number): number { + if (percentComplete < 1 / 2.75) { + return (7.5625 * percentComplete * percentComplete); + } + if (percentComplete < 2 / 2.75) { + return (7.5625 * (percentComplete -= 1.5 / 2.75) * percentComplete + 0.75); + } + if (percentComplete < 2.5 / 2.75) { + return (7.5625 * (percentComplete -= 2.25 / 2.75) * percentComplete + 0.9375); + } + return (7.5625 * (percentComplete -= 2.625 / 2.75) * percentComplete + 0.984375); + }; + + function easeInBounce(percentComplete: number): number { + return 1 - easeOutBounce(1 - percentComplete); + }; + + registerEasing(["easeInBounce", function(percentComplete: number, startValue: number, endValue: number): number { + if (percentComplete === 0) { + return startValue; + } + if (percentComplete === 1) { + return endValue; + } + return easeInBounce(percentComplete) * (endValue - startValue); + }]); + + registerEasing(["easeOutBounce", function(percentComplete: number, startValue: number, endValue: number): number { + if (percentComplete === 0) { + return startValue; + } + if (percentComplete === 1) { + return endValue; + } + return easeOutBounce(percentComplete) * (endValue - startValue); + }]); + + registerEasing(["easeInOutBounce", function(percentComplete: number, startValue: number, endValue: number): number { + if (percentComplete === 0) { + return startValue; + } + if (percentComplete === 1) { + return endValue; + } + return (percentComplete < 0.5 ? easeInBounce(percentComplete * 2) * .5 : easeOutBounce(percentComplete * 2 - 1) * 0.5 + 0.5) * (endValue - startValue); + }]); +}; diff --git a/src/Velocity/easing/easings.ts b/src/Velocity/easing/easings.ts new file mode 100644 index 00000000..7515e9b5 --- /dev/null +++ b/src/Velocity/easing/easings.ts @@ -0,0 +1,45 @@ +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + */ + +namespace VelocityStatic.Easing { + export const Easings: {[name: string]: VelocityEasingFn} = Object.create(null); + + /** + * Used to register a easing. This should never be called by users + * directly, instead it should be called via an action:
+ * Velocity("registerEasing", "name", VelocityEasingFn); + * + * @private + */ + export function registerEasing(args?: [string, VelocityEasingFn]) { + const name: string = args[0], + callback = args[1]; + + if (!isString(name)) { + console.warn("VelocityJS: Trying to set 'registerEasing' name to an invalid value:", name); + } else if (!isFunction(callback)) { + console.warn("VelocityJS: Trying to set 'registerEasing' callback to an invalid value:", name, callback); + } else if (Easings[name]) { + console.warn("VelocityJS: Trying to override 'registerEasing' callback", name); + } else { + Easings[name] = callback; + } + } + + /* Basic (same as jQuery) easings. */ + registerEasing(["linear", function(percentComplete, startValue, endValue) { + return startValue + percentComplete * (endValue - startValue); + }]); + + registerEasing(["swing", function(percentComplete, startValue, endValue) { + return startValue + (0.5 - Math.cos(percentComplete * Math.PI) / 2) * (endValue - startValue); + }]); + + /* Bonus "spring" easing, which is a less exaggerated version of easeInOutElastic. */ + registerEasing(["spring", function(percentComplete, startValue, endValue) { + return startValue + (1 - (Math.cos(percentComplete * 4.5 * Math.PI) * Math.exp(-percentComplete * 6))) * (endValue - startValue); + }]); +}; diff --git a/src/Velocity/easing/elastic.ts b/src/Velocity/easing/elastic.ts new file mode 100644 index 00000000..4712c10d --- /dev/null +++ b/src/Velocity/easing/elastic.ts @@ -0,0 +1,60 @@ +/// +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + * + * Elastic easings, based on code from https://github.com/yuichiroharai/easeplus-velocity + */ + +namespace VelocityStatic.Easing { + const pi2 = Math.PI * 2; + + export function registerElasticIn(name: string, amplitude: number, period: number) { + registerEasing([name, function(percentComplete: number, startValue: number, endValue: number): number { + if (percentComplete === 0) { + return startValue; + } + if (percentComplete === 1) { + return endValue; + } + return -(amplitude * Math.pow(2, 10 * (percentComplete -= 1)) * Math.sin((percentComplete - (period / pi2 * Math.asin(1 / amplitude))) * pi2 / period)) * (endValue - startValue); + }]); + } + + export function registerElasticOut(name: string, amplitude: number, period: number) { + registerEasing([name, function(percentComplete: number, startValue: number, endValue: number): number { + if (percentComplete === 0) { + return startValue; + } + if (percentComplete === 1) { + return endValue; + } + return (amplitude * Math.pow(2, -10 * percentComplete) * Math.sin((percentComplete - (period / pi2 * Math.asin(1 / amplitude))) * pi2 / period) + 1) * (endValue - startValue); + }]); + } + + export function registerElasticInOut(name: string, amplitude: number, period: number) { + registerEasing([name, function(percentComplete: number, startValue: number, endValue: number): number { + if (percentComplete === 0) { + return startValue; + } + if (percentComplete === 1) { + return endValue; + } + const s = period / pi2 * Math.asin(1 / amplitude); + + percentComplete = percentComplete * 2 - 1; + if (percentComplete < 0) { + return -0.5 * (amplitude * Math.pow(2, 10 * percentComplete) * Math.sin((percentComplete - s) * pi2 / period)); + } + return amplitude * Math.pow(2, -10 * percentComplete) * Math.sin((percentComplete - s) * pi2 / period) * 0.5 + 1; + }]); + } + + registerElasticIn("easeInElastic", 1, 0.3); + registerElasticOut("easeOutElastic", 1, 0.3); + registerElasticInOut("easeInOutElastic", 1, 0.3 * 1.5); + + // TODO: Expose these as actions to register custom easings? +}; diff --git a/src/Velocity/easing/spring_rk4.ts b/src/Velocity/easing/spring_rk4.ts new file mode 100644 index 00000000..6a4fe884 --- /dev/null +++ b/src/Velocity/easing/spring_rk4.ts @@ -0,0 +1,111 @@ +/// +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + */ + +namespace VelocityStatic.Easing { + + interface springState { + x: number; + v: number; + tension: number; + friction: number; + }; + + interface springDelta { + dx: number; + dv: number; + }; + + /* Runge-Kutta spring physics function generator. Adapted from Framer.js, copyright Koen Bok. MIT License: http://en.wikipedia.org/wiki/MIT_License */ + /* Given a tension, friction, and duration, a simulation at 60FPS will first run without a defined duration in order to calculate the full path. A second pass + then adjusts the time delta -- using the relation between actual time and duration -- to calculate the path for the duration-constrained animation. */ + function springAccelerationForState(state: springState) { + return (-state.tension * state.x) - (state.friction * state.v); + } + + function springEvaluateStateWithDerivative(initialState: springState, dt: number, derivative: springDelta): springDelta { + const state = { + x: initialState.x + derivative.dx * dt, + v: initialState.v + derivative.dv * dt, + tension: initialState.tension, + friction: initialState.friction + }; + + return { + dx: state.v, + dv: springAccelerationForState(state) + }; + } + + function springIntegrateState(state: springState, dt: number) { + const a = { + dx: state.v, + dv: springAccelerationForState(state) + }, + b = springEvaluateStateWithDerivative(state, dt * 0.5, a), + c = springEvaluateStateWithDerivative(state, dt * 0.5, b), + d = springEvaluateStateWithDerivative(state, dt, c), + dxdt = 1.0 / 6.0 * (a.dx + 2.0 * (b.dx + c.dx) + d.dx), + dvdt = 1.0 / 6.0 * (a.dv + 2.0 * (b.dv + c.dv) + d.dv); + + state.x = state.x + dxdt * dt; + state.v = state.v + dvdt * dt; + + return state; + } + + export function generateSpringRK4(tension: number, friction: number): number; + export function generateSpringRK4(tension: number, friction: number, duration: number): VelocityEasingFn; + export function generateSpringRK4(tension: number, friction: number, duration?: number): any { + let initState: springState = { + x: -1, + v: 0, + tension: parseFloat(tension as any) || 500, + friction: parseFloat(friction as any) || 20 + }, + path = [0], + time_lapsed = 0, + tolerance = 1 / 10000, + DT = 16 / 1000, + have_duration = duration != null, // deliberate "==", as undefined == null != 0 + dt: number, + last_state: springState; + + /* Calculate the actual time it takes for this animation to complete with the provided conditions. */ + if (have_duration) { + /* Run the simulation without a duration. */ + time_lapsed = generateSpringRK4(initState.tension, initState.friction); + /* Compute the adjusted time delta. */ + dt = (time_lapsed as number) / duration * DT; + } else { + dt = DT; + } + + while (true) { + /* Next/step function .*/ + last_state = springIntegrateState(last_state || initState, dt); + /* Store the position. */ + path.push(1 + last_state.x); + time_lapsed += 16; + /* If the change threshold is reached, break. */ + if (!(Math.abs(last_state.x) > tolerance && Math.abs(last_state.v) > tolerance)) { + break; + } + } + + /* If duration is not defined, return the actual time required for completing this animation. Otherwise, return a closure that holds the + computed path and returns a snapshot of the position according to a given percentComplete. */ + return !have_duration ? time_lapsed : function(percentComplete: number, startValue: number, endValue: number) { + if (percentComplete === 0) { + return startValue; + } + if (percentComplete === 1) { + return endValue; + } + return startValue + path[(percentComplete * (path.length - 1)) | 0] * (endValue - startValue); + }; + }; +}; diff --git a/src/Velocity/easing/step.ts b/src/Velocity/easing/step.ts new file mode 100644 index 00000000..f6d6fc4f --- /dev/null +++ b/src/Velocity/easing/step.ts @@ -0,0 +1,29 @@ +/// +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details + * + * Step easing generator. + */ + +namespace VelocityStatic.Easing { + const cache: {[steps: number]: VelocityEasingFn} = {}; + + export function generateStep(steps): VelocityEasingFn { + const fn = cache[steps]; + + if (fn) { + return fn; + } + return cache[steps] = function(percentComplete: number, startValue: number, endValue: number) { + if (percentComplete === 0) { + return startValue; + } + if (percentComplete === 1) { + return endValue; + } + return startValue + Math.round(percentComplete * steps) * (1 / steps) * (endValue - startValue); + }; + } +}; diff --git a/src/Velocity/easing/string.ts b/src/Velocity/easing/string.ts new file mode 100644 index 00000000..696e6526 --- /dev/null +++ b/src/Velocity/easing/string.ts @@ -0,0 +1,40 @@ +/// +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + * + * Easings to act on strings, either set at the start or at the end depending on + * need. + */ + +namespace VelocityStatic.Easing { + /** + * Easing function that sets to the specified value immediately after the + * animation starts. + */ + registerEasing(["at-start", function(percentComplete: number, startValue: any, endValue: any): any { + return percentComplete === 0 + ? startValue + : endValue; + } as any]); + + /** + * Easing function that sets to the specified value while the animation is + * running. + */ + registerEasing(["during", function(percentComplete: number, startValue: any, endValue: any): any { + return percentComplete === 0 || percentComplete === 1 + ? startValue + : endValue; + } as any]); + + /** + * Easing function that sets to the specified value when the animation ends. + */ + registerEasing(["at-end", function(percentComplete: number, startValue: any, endValue: any): any { + return percentComplete === 1 + ? endValue + : startValue; + } as any]); +}; diff --git a/src/Velocity/mock.ts b/src/Velocity/mock.ts new file mode 100644 index 00000000..8cb3a848 --- /dev/null +++ b/src/Velocity/mock.ts @@ -0,0 +1,17 @@ +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + * + * Velocity-wide animation time remapping for testing purposes. + */ + +namespace VelocityStatic { + /** + * In mock mode, all animations are forced to complete immediately upon the + * next rAF tick. If there are further animations queued then they will each + * take one single frame in turn. Loops and repeats will be disabled while + * mock = true. + */ + export let mock: boolean = false; +}; diff --git a/src/Velocity/normalizations/_all.d.ts b/src/Velocity/normalizations/_all.d.ts new file mode 100644 index 00000000..148165dd --- /dev/null +++ b/src/Velocity/normalizations/_all.d.ts @@ -0,0 +1,8 @@ +/// +/// +/// +/// +/// +/// +/// + diff --git a/src/Velocity/normalizations/dimensions.ts b/src/Velocity/normalizations/dimensions.ts new file mode 100644 index 00000000..e14568d5 --- /dev/null +++ b/src/Velocity/normalizations/dimensions.ts @@ -0,0 +1,54 @@ +/// +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + */ + +namespace VelocityStatic { + + /** + * Figure out the dimensions for this width / height based on the + * potential borders and whether we care about them. + */ + export function augmentDimension(element: HTMLorSVGElement, name: string, wantInner: boolean): number { + const isBorderBox = CSS.getPropertyValue(element, "boxSizing").toString().toLowerCase() === "border-box"; + + if (isBorderBox === wantInner) { + // in box-sizing mode, the CSS width / height accessors already + // give the outerWidth / outerHeight. + const sides = name === "width" ? ["Left", "Right"] : ["Top", "Bottom"], + fields = ["padding" + sides[0], "padding" + sides[1], "border" + sides[0] + "Width", "border" + sides[1] + "Width"]; + let i: number, + value: number, + augment = 0; + + for (i = 0; i < fields.length; i++) { + value = parseFloat(CSS.getPropertyValue(element, fields[i]) as string); + if (!isNaN(value)) { + augment += value; + } + } + return wantInner ? -augment : augment; + } + return 0; + } + + /** + * Get/set the inner/outer dimension. + */ + function getDimension(name, wantInner: boolean) { + return function(element: HTMLorSVGElement, propertyValue?: string): string | boolean { + if (propertyValue === undefined) { + return augmentDimension(element, name, wantInner) + "px"; + } + CSS.setPropertyValue(element, name, (parseFloat(propertyValue) - augmentDimension(element, name, wantInner)) + "px"); + return true; + } as VelocityNormalizationsFn; + } + + registerNormalization([Element, "innerWidth", getDimension("width", true)]); + registerNormalization([Element, "innerHeight", getDimension("height", true)]); + registerNormalization([Element, "outerWidth", getDimension("width", false)]); + registerNormalization([Element, "outerHeight", getDimension("height", false)]); +} diff --git a/src/Velocity/normalizations/display.ts b/src/Velocity/normalizations/display.ts new file mode 100644 index 00000000..82f17058 --- /dev/null +++ b/src/Velocity/normalizations/display.ts @@ -0,0 +1,54 @@ +/// +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + */ + +namespace VelocityStatic { + export const inlineRx = /^(b|big|i|small|tt|abbr|acronym|cite|code|dfn|em|kbd|strong|samp|let|a|bdo|br|img|map|object|q|script|span|sub|sup|button|input|label|select|textarea)$/i, + listItemRx = /^(li)$/i, + tableRowRx = /^(tr)$/i, + tableRx = /^(table)$/i, + tableRowGroupRx = /^(tbody)$/i; + + /** + * Display has an extra value of "auto" that works out the correct value + * based on the type of element. + */ + function display(element: HTMLorSVGElement): string; + function display(element: HTMLorSVGElement, propertyValue: string): boolean; + function display(element: HTMLorSVGElement, propertyValue?: string): string | boolean { + const style = element.style; + + if (propertyValue === undefined) { + return CSS.computePropertyValue(element, "display"); + } + if (propertyValue === "auto") { + const nodeName = element && element.nodeName, + data = Data(element); + + if (inlineRx.test(nodeName)) { + propertyValue = "inline"; + } else if (listItemRx.test(nodeName)) { + propertyValue = "list-item"; + } else if (tableRowRx.test(nodeName)) { + propertyValue = "table-row"; + } else if (tableRx.test(nodeName)) { + propertyValue = "table"; + } else if (tableRowGroupRx.test(nodeName)) { + propertyValue = "table-row-group"; + } else { + // Default to "block" when no match is found. + propertyValue = "block"; + } + // IMPORTANT: We need to do this as getPropertyValue bypasses the + // Normalisation when it exists in the cache. + data.cache["display"] = propertyValue; + } + style.display = propertyValue; + return true; + } + + registerNormalization([Element, "display", display]); +} diff --git a/src/Velocity/normalizations/genericReordering.ts b/src/Velocity/normalizations/genericReordering.ts new file mode 100644 index 00000000..90eda035 --- /dev/null +++ b/src/Velocity/normalizations/genericReordering.ts @@ -0,0 +1,35 @@ +/// +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + */ + +namespace VelocityStatic { + function genericReordering(element: HTMLorSVGElement): string; + function genericReordering(element: HTMLorSVGElement, propertyValue: string): boolean; + function genericReordering(element: HTMLorSVGElement, propertyValue?: string): string | boolean { + if (propertyValue === undefined) { + propertyValue = CSS.getPropertyValue(element, "textShadow"); + const split = propertyValue.split(/\s/g), + firstPart = split[0]; + let newValue = ""; + + if (CSS.ColorNames[firstPart]) { + split.shift(); + split.push(firstPart); + newValue = split.join(" "); + } else if (firstPart.match(/^#|^hsl|^rgb|-gradient/)) { + const matchedString = propertyValue.match(/(hsl.*\)|#[\da-fA-F]+|rgb.*\)|.*gradient.*\))\s/g)[0]; + + newValue = propertyValue.replace(matchedString, "") + " " + matchedString.trim(); + } else { + newValue = propertyValue; + } + return newValue; + } + return false; + } + + registerNormalization([Element, "textShadow", genericReordering]); +} diff --git a/src/Velocity/normalizations/normalizations.ts b/src/Velocity/normalizations/normalizations.ts new file mode 100644 index 00000000..057e7eeb --- /dev/null +++ b/src/Velocity/normalizations/normalizations.ts @@ -0,0 +1,79 @@ +/// +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + * + * Normalisations are used when getting or setting a (normally css compound + * properties) value that can have a different order in different browsers. + * + * It can also be used to extend and create specific properties that otherwise + * don't exist (such as for scrolling, or inner/outer dimensions). + */ + +namespace VelocityStatic { + + /** + * Unlike "actions", normalizations can always be replaced by users. + */ + export const Normalizations: {[name: string]: VelocityNormalizationsFn}[] = []; + + /** + * Any normalisations that should never be cached are listed here. + * Faster than an array - https://jsperf.com/array-includes-and-find-methods-vs-set-has + */ + export const NoCacheNormalizations = new Set(); + + /** + * Used to define a constructor. + */ + interface ClassConstructor { + new(): Object; + } + + /** + * An array of classes used for the per-class normalizations. This + * translates into a bitwise enum for quick cross-reference, and so that + * the element doesn't need multiple instanceof calls every + * frame. + */ + export const constructors: ClassConstructor[] = []; + + /** + * Used to register a normalization. This should never be called by users + * directly, instead it should be called via an action:
+ * Velocity("registerNormalization", Element, "name", VelocityNormalizationsFn[, false]); + * + * The fourth argument can be an explicit false, which prevents + * the property from being cached. Please note that this can be dangerous + * for performance! + * + * @private + */ + export function registerNormalization(args?: [ClassConstructor, string, VelocityNormalizationsFn] | [ClassConstructor, string, VelocityNormalizationsFn, boolean]) { + const constructor = args[0], + name: string = args[1], + callback = args[2]; + + if (isString(constructor) || !(constructor instanceof Object)) { + console.warn("VelocityJS: Trying to set 'registerNormalization' constructor to an invalid value:", constructor); + } else if (!isString(name)) { + console.warn("VelocityJS: Trying to set 'registerNormalization' name to an invalid value:", name); + } else if (!isFunction(callback)) { + console.warn("VelocityJS: Trying to set 'registerNormalization' callback to an invalid value:", name, callback); + } else { + let index = constructors.indexOf(constructor); + + if (index < 0) { + index = constructors.push(constructor) - 1; + Normalizations[index] = Object.create(null); + } + Normalizations[index][name] = callback; + if (args[3] === false) { + NoCacheNormalizations.add(name); + } + } + } + + registerAction(["registerNormalization", registerNormalization as any]); +} diff --git a/src/Velocity/normalizations/scroll.ts b/src/Velocity/normalizations/scroll.ts new file mode 100644 index 00000000..84ffd8a3 --- /dev/null +++ b/src/Velocity/normalizations/scroll.ts @@ -0,0 +1,97 @@ +/// +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + */ + +namespace VelocityStatic { + /** + * Get the scrollWidth of an element. + */ + function clientWidth(element: HTMLorSVGElement): string; + function clientWidth(element: HTMLorSVGElement, propertyValue: string): boolean; + function clientWidth(element: HTMLorSVGElement, propertyValue?: string): string | boolean { + if (propertyValue == null) { + return element.clientWidth + "px"; + } + return false; + } + + /** + * Get the scrollWidth of an element. + */ + function scrollWidth(element: HTMLorSVGElement): string; + function scrollWidth(element: HTMLorSVGElement, propertyValue: string): boolean; + function scrollWidth(element: HTMLorSVGElement, propertyValue?: string): string | boolean { + if (propertyValue == null) { + return element.scrollWidth + "px"; + } + return false; + } + + /** + * Get the scrollHeight of an element. + */ + function clientHeight(element: HTMLorSVGElement): string; + function clientHeight(element: HTMLorSVGElement, propertyValue: string): boolean; + function clientHeight(element: HTMLorSVGElement, propertyValue?: string): string | boolean { + if (propertyValue == null) { + return element.clientHeight + "px"; + } + return false; + } + + /** + * Get the scrollHeight of an element. + */ + function scrollHeight(element: HTMLorSVGElement): string; + function scrollHeight(element: HTMLorSVGElement, propertyValue: string): boolean; + function scrollHeight(element: HTMLorSVGElement, propertyValue?: string): string | boolean { + if (propertyValue == null) { + return element.scrollHeight + "px"; + } + return false; + } + + /** + * Scroll an element (vertical). + */ + function scrollTop(element: HTMLorSVGElement): string; + function scrollTop(element: HTMLorSVGElement, propertyValue: string): boolean; + function scrollTop(element: HTMLorSVGElement, propertyValue?: string): string | boolean { + if (propertyValue == null) { + // getPropertyValue(element, "clientWidth", false, true); + // getPropertyValue(element, "scrollWidth", false, true); + // getPropertyValue(element, "scrollLeft", false, true); + CSS.getPropertyValue(element, "clientHeight", false, true); + CSS.getPropertyValue(element, "scrollHeight", false, true); + CSS.getPropertyValue(element, "scrollTop", false, true); + return element.scrollTop + "px"; + } + console.log("setScrollTop", propertyValue) + const value = parseFloat(propertyValue), + unit = propertyValue.replace(String(value), ""); + + switch (unit) { + case "": + case "px": + element.scrollTop = value; + break; + + case "%": + let clientHeight = parseFloat(CSS.getPropertyValue(element, "clientHeight")), + scrollHeight = parseFloat(CSS.getPropertyValue(element, "scrollHeight")); + + console.log("setScrollTop percent", scrollHeight, clientHeight, value, Math.max(0, scrollHeight - clientHeight) * value / 100) + element.scrollTop = Math.max(0, scrollHeight - clientHeight) * value / 100; + } + return false; + } + + registerNormalization([HTMLElement, "scrollTop", scrollTop, false]); + registerNormalization([HTMLElement, "scrollWidth", scrollWidth]); + registerNormalization([HTMLElement, "clientWidth", clientWidth]); + registerNormalization([HTMLElement, "scrollHeight", scrollHeight]); + registerNormalization([HTMLElement, "clientHeight", clientHeight]); +} diff --git a/src/Velocity/normalizations/svg/_all.d.ts b/src/Velocity/normalizations/svg/_all.d.ts new file mode 100644 index 00000000..fbd30064 --- /dev/null +++ b/src/Velocity/normalizations/svg/_all.d.ts @@ -0,0 +1,4 @@ +/// +/// +/// + diff --git a/src/Velocity/normalizations/svg/attributes.ts b/src/Velocity/normalizations/svg/attributes.ts new file mode 100644 index 00000000..c89518c3 --- /dev/null +++ b/src/Velocity/normalizations/svg/attributes.ts @@ -0,0 +1,49 @@ +/// +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + */ + +namespace VelocityStatic.CSS { + + /** + * Get/set an attribute. + */ + function getAttribute(name: string) { + return function(element: Element, propertyValue?: string): string | boolean { + if (propertyValue === undefined) { + return element.getAttribute(name); + } + element.setAttribute(name, propertyValue); + return true; + } as VelocityNormalizationsFn; + } + + const base = document.createElement("div"), + rxSubtype = /^SVG(.*)Element$/, + rxElement = /Element$/; + + Object.getOwnPropertyNames(window).forEach(function(globals) { + const subtype = rxSubtype.exec(globals); + + if (subtype) { + const element = document.createElementNS("http://www.w3.org/2000/svg", (subtype[1] || "svg").toLowerCase()), + constructor = element.constructor; + + for (let attribute in element) { + const value = element[attribute]; + + if (isString(attribute) + && !(attribute[0] === "o" && attribute[1] === "n") + && attribute !== attribute.toUpperCase() + && !rxElement.test(attribute) + && !(attribute in base) + && !isFunction(value)) { + // TODO: Should this all be set on the generic SVGElement, it would save space and time, but not as powerful + registerNormalization([constructor as any, attribute, getAttribute(attribute)]); + } + } + } + }); +} diff --git a/src/Velocity/normalizations/svg/dimensions.ts b/src/Velocity/normalizations/svg/dimensions.ts new file mode 100644 index 00000000..e2951e4d --- /dev/null +++ b/src/Velocity/normalizations/svg/dimensions.ts @@ -0,0 +1,30 @@ +/// +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + */ + +namespace VelocityStatic.CSS { + + /** + * Get/set the width or height. + */ + function getDimension(name: string) { + return function(element: HTMLorSVGElement, propertyValue?: string): string | boolean { + if (propertyValue === undefined) { + // Firefox throws an error if .getBBox() is called on an SVG that isn't attached to the DOM. + try { + return (element as SVGGraphicsElement).getBBox()[name] + "px"; + } catch (e) { + return "0px"; + } + } + element.setAttribute(name, propertyValue); + return true; + } as VelocityNormalizationsFn; + } + + registerNormalization([SVGElement, "width", getDimension("width")]); + registerNormalization([SVGElement, "height", getDimension("height")]); +} diff --git a/src/Velocity/normalizations/vendorPrefix.ts b/src/Velocity/normalizations/vendorPrefix.ts new file mode 100644 index 00000000..a3e640d7 --- /dev/null +++ b/src/Velocity/normalizations/vendorPrefix.ts @@ -0,0 +1,38 @@ +/// +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + */ + +namespace VelocityStatic { + + /** + * Return a Normalisation that can be used to set / get the vendor prefixed + * real name for a propery. + */ + function vendorPrefix(property: string, unprefixed: string) { + return function(element: HTMLorSVGElement, propertyValue?: string): string | boolean { + if (propertyValue === undefined) { + return element.style[unprefixed]; + } + CSS.setPropertyValue(element, property, propertyValue); + return true; + } as VelocityNormalizationsFn; + } + + const vendors = [/^webkit[A-Z]/, /^moz[A-Z]/, /^ms[A-Z]/, /^o[A-Z]/], + prefixElement = State.prefixElement; + + for (const property in prefixElement.style) { + for (let i = 0; i < vendors.length; i++) { + if (vendors[i].test(property)) { + let unprefixed = property.replace(/^[a-z]+([A-Z])/, ($, letter: string) => letter.toLowerCase()); + + if (ALL_VENDOR_PREFIXES || isString(prefixElement.style[unprefixed])) { + registerNormalization([Element, unprefixed, vendorPrefix(property, unprefixed)]); + } + } + } + } +} diff --git a/src/Velocity/patch.ts b/src/Velocity/patch.ts new file mode 100644 index 00000000..dbe0cae2 --- /dev/null +++ b/src/Velocity/patch.ts @@ -0,0 +1,27 @@ +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + */ + +namespace VelocityStatic { + /** + * Used to patch any object to allow Velocity chaining. In order to chain an + * object must either be treatable as an array - with a .length + * property, and each member a Node, or a Node directly. + * + * + * By default Velocity will try to patch window, + * jQuery, Zepto, and several classes that return + * Nodes or lists of Nodes. + * + * @public + */ + export function patch(proto: any, global?: boolean) { + try { + defineProperty(proto, (global ? "V" : "v") + "elocity", VelocityFn); + } catch (e) { + console.warn("VelocityJS: Error when trying to add prototype.", e); + } + } +}; diff --git a/src/Velocity/queue.ts b/src/Velocity/queue.ts new file mode 100644 index 00000000..cc40dd43 --- /dev/null +++ b/src/Velocity/queue.ts @@ -0,0 +1,137 @@ +/// +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + * + * AnimationCall queue + */ + +namespace VelocityStatic { + + /** + * Simple queue management. Un-named queue is directly within the element data, + * named queue is within an object within it. + */ + function animate(animation: AnimationCall) { + const prev = State.last; + + animation._prev = prev; + animation._next = undefined; + if (prev) { + prev._next = animation; + } else { + State.first = animation; + } + State.last = animation; + if (!State.firstNew) { + State.firstNew = animation; + } + const element = animation.element, + data = Data(element), + queue = animation.queue == null ? animation.options.queue : animation.queue; + + if (queue !== false) { + // Store the last animation added so we can use it for the + // beginning of the next one. + data.lastAnimationList[queue] = animation; + } + if (!data.count++) { + + //////////////////////// + // Feature: Classname // + //////////////////////// + + addClass(element, State.className); + } + } + + /** + * Add an item to an animation queue. + */ + export function queue(element: HTMLorSVGElement, animation: AnimationCall, queue?: string | false): void { + if (queue === false) { + animate(animation); + } else { + if (!isString(queue)) { + queue = ""; + } + const data = Data(element); + let last = data.queueList[queue]; + + if (!last) { + if (last === null) { + data.queueList[queue] = animation; + } else { + data.queueList[queue] = null; + animate(animation); + } + } else { + while (last._next) { + last = last._next; + } + last._next = animation; + animation._prev = last; + } + } + } + + /** + * Start the next animation on this element's queue (named or default). + * + * @returns the next animation that is starting. + */ + export function dequeue(element: HTMLorSVGElement, queue?: string | boolean, skip?: boolean): AnimationCall { + if (queue !== false) { + if (!isString(queue)) { + queue = ""; + } + const data = Data(element), + animation = data.queueList[queue]; + + if (animation) { + data.queueList[queue] = animation._next || null; + if (!skip) { + animate(animation); + } + } else if (animation === null) { + delete data.queueList[queue]; + } + return animation; + } + } + + /** + * Remove an animation from the active animation list. If it has a queue set + * then remember it as the last animation for that queue, and free the one + * that was previously there. If the animation list is completely empty then + * mark us as finished. + */ + export function freeAnimationCall(animation: AnimationCall): void { + const next = animation._next, + prev = animation._prev, + queue = animation.queue == null ? animation.options.queue : animation.queue; + + if (State.firstNew === animation) { + State.firstNew = next; + } + if (State.first === animation) { + State.first = next; + } else if (prev) { + prev._next = next; + } + if (State.last === animation) { + State.last = prev; + } else if (next) { + next._prev = prev; + } + if (queue) { + const data = Data(animation.element); + + if (data) { + data.lastAnimationList[queue] = animation; + animation._next = animation._prev = undefined; + } + } + } +} diff --git a/src/Velocity/redirects.ts b/src/Velocity/redirects.ts new file mode 100644 index 00000000..49b847c4 --- /dev/null +++ b/src/Velocity/redirects.ts @@ -0,0 +1,122 @@ +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + */ + +namespace VelocityStatic { + + /* Container for the user's custom animation redirects that are referenced by name in place of the properties map argument. */ + export let Redirects = {/* Manually registered by the user. */}; + + /*********************** + Packaged Redirects + ***********************/ + + /* slideUp, slideDown */ + ["Down", "Up"].forEach(function(direction) { + Redirects["slide" + direction] = function(element: HTMLorSVGElement, options: VelocityOptions, elementsIndex: number, elementsSize, elements: HTMLorSVGElement[], resolver: (value?: HTMLorSVGElement[] | VelocityResult) => void) { + let opts = {...options}, + begin = opts.begin, + complete = opts.complete, + inlineValues = {}, + computedValues = { + height: "", + marginTop: "", + marginBottom: "", + paddingTop: "", + paddingBottom: "" + }; + + if (opts.display === undefined) { + let isInline = inlineRx.test(element.nodeName.toLowerCase()); + + /* Show the element before slideDown begins and hide the element after slideUp completes. */ + /* Note: Inline elements cannot have dimensions animated, so they're reverted to inline-block. */ + opts.display = (direction === "Down" ? (isInline ? "inline-block" : "block") : "none"); + } + + opts.begin = function() { + /* If the user passed in a begin callback, fire it now. */ + if (elementsIndex === 0 && begin) { + begin.call(elements, elements); + } + + /* Cache the elements' original vertical dimensional property values so that we can animate back to them. */ + for (let property in computedValues) { + if (!computedValues.hasOwnProperty(property)) { + continue; + } + inlineValues[property] = element.style[property]; + + /* For slideDown, use forcefeeding to animate all vertical properties from 0. For slideUp, + use forcefeeding to start from computed values and animate down to 0. */ + let propertyValue = CSS.getPropertyValue(element, property); + computedValues[property] = (direction === "Down") ? [propertyValue, 0] : [0, propertyValue]; + } + + /* Force vertical overflow content to clip so that sliding works as expected. */ + (inlineValues as any).overflow = element.style.overflow; + element.style.overflow = "hidden"; + }; + + opts.complete = function() { + /* Reset element to its pre-slide inline values once its slide animation is complete. */ + for (let property in inlineValues) { + if (inlineValues.hasOwnProperty(property)) { + element.style[property] = inlineValues[property]; + } + } + + /* If the user passed in a complete callback, fire it now. */ + if (elementsIndex === elementsSize - 1) { + if (complete) { + complete.call(elements, elements); + } + if (resolver) { + resolver(elements); + } + } + }; + + (VelocityFn as any)(element, computedValues, opts); + }; + }); + + /* fadeIn, fadeOut */ + ["In", "Out"].forEach(function(direction) { + Redirects["fade" + direction] = function(element: HTMLorSVGElement, options: VelocityOptions, elementsIndex: number, elementsSize, elements: HTMLorSVGElement[], promiseData) { + let opts = {...options}, + complete = opts.complete, + propertiesMap = { + opacity: (direction === "In") ? 1 : 0 + }; + + /* Since redirects are triggered individually for each element in the animated set, avoid repeatedly triggering + callbacks by firing them only when the final element has been reached. */ + if (elementsIndex !== 0) { + opts.begin = null; + } + if (elementsIndex !== elementsSize - 1) { + opts.complete = null; + } else { + opts.complete = function() { + if (complete) { + complete.call(elements, elements); + } + if (promiseData) { + promiseData.resolver(elements); + } + }; + } + + /* If a display was passed in, use it. Otherwise, default to "none" for fadeOut or the element-specific default for fadeIn. */ + /* Note: We allow users to pass in "null" to skip display setting altogether. */ + if (opts.display === undefined) { + opts.display = (direction === "In" ? "auto" : "none"); + } + + (VelocityFn as any)(this, propertiesMap, opts); + }; + }); +}; diff --git a/src/Velocity/registereffect.ts b/src/Velocity/registereffect.ts new file mode 100644 index 00000000..a5d7498e --- /dev/null +++ b/src/Velocity/registereffect.ts @@ -0,0 +1,201 @@ +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + * + * Effect Registration + */ + +namespace VelocityStatic { + /* Animate the expansion/contraction of the elements' parent's height for In/Out effects. */ + function animateParentHeight(elements: HTMLorSVGElement | HTMLorSVGElement[], direction, totalDuration, stagger) { + let totalHeightDelta = 0, + parentNode: HTMLorSVGElement; + + /* Sum the total height (including padding and margin) of all targeted elements. */ + ((elements as HTMLorSVGElement).nodeType ? [elements as HTMLorSVGElement] : elements as HTMLorSVGElement[]).forEach(function(element: HTMLorSVGElement, i) { + if (stagger) { + /* Increase the totalDuration by the successive delay amounts produced by the stagger option. */ + totalDuration += i * stagger; + } + + parentNode = element.parentNode as HTMLorSVGElement; + + let propertiesToSum = ["height", "paddingTop", "paddingBottom", "marginTop", "marginBottom"]; + + /* If box-sizing is border-box, the height already includes padding and margin */ + if (CSS.getPropertyValue(element, "boxSizing").toString().toLowerCase() === "border-box") { + propertiesToSum = ["height"]; + } + + propertiesToSum.forEach(function(property) { + totalHeightDelta += parseFloat(CSS.getPropertyValue(element, property) as string); + }); + }); + + /* Animate the parent element's height adjustment (with a varying duration multiplier for aesthetic benefits). */ + // TODO: Get this typesafe again + (VelocityFn as any)( + parentNode, + {height: (direction === "In" ? "+" : "-") + "=" + totalHeightDelta}, + {queue: false, easing: "ease-in-out", duration: totalDuration * (direction === "In" ? 0.6 : 1)} + ); + } + + /* Note: RegisterUI is a legacy name. */ + export function RegisterEffect(effectName: string, properties): Velocity { + + /* Register a custom redirect for each effect. */ + Redirects[effectName] = function(element, redirectOptions, elementsIndex, elementsSize, elements, resolver: (value?: HTMLorSVGElement[] | VelocityResult) => void, loop) { + let finalElement = (elementsIndex === elementsSize - 1), + totalDuration = 0; + + loop = loop || properties.loop; + if (typeof properties.defaultDuration === "function") { + properties.defaultDuration = properties.defaultDuration.call(elements, elements); + } else { + properties.defaultDuration = parseFloat(properties.defaultDuration); + } + + /* Get the total duration used, so we can share it out with everything that doesn't have a duration */ + for (let callIndex = 0; callIndex < properties.calls.length; callIndex++) { + let durationPercentage = properties.calls[callIndex][1]; + if (typeof durationPercentage === "number") { + totalDuration += durationPercentage; + } + } + let shareDuration = totalDuration >= 1 ? 0 : properties.calls.length ? (1 - totalDuration) / properties.calls.length : 1; + + /* Iterate through each effect's call array. */ + for (let callIndex = 0; callIndex < properties.calls.length; callIndex++) { + let call = properties.calls[callIndex], + propertyMap = call[0], + redirectDuration = 1000, + durationPercentage = call[1], + callOptions = call[2] || {}, + opts: VelocityOptions = {}; + + if (redirectOptions.duration !== undefined) { + redirectDuration = redirectOptions.duration; + } else if (properties.defaultDuration !== undefined) { + redirectDuration = properties.defaultDuration; + } + + /* Assign the whitelisted per-call options. */ + opts.duration = redirectDuration * (typeof durationPercentage === "number" ? durationPercentage : shareDuration); + opts.queue = redirectOptions.queue || ""; + opts.easing = callOptions.easing || "ease"; + opts.delay = parseFloat(callOptions.delay) || 0; + opts.loop = !properties.loop && callOptions.loop; + opts.cache = callOptions.cache || true; + + /* Special processing for the first effect call. */ + if (callIndex === 0) { + /* If a delay was passed into the redirect, combine it with the first call's delay. */ + opts.delay += (parseFloat(redirectOptions.delay) || 0); + + if (elementsIndex === 0) { + opts.begin = function() { + /* Only trigger a begin callback on the first effect call with the first element in the set. */ + if (redirectOptions.begin) { + redirectOptions.begin.call(elements, elements); + } + + let direction = effectName.match(/(In|Out)$/); + + /* Make "in" transitioning elements invisible immediately so that there's no FOUC between now + and the first RAF tick. */ + if ((direction && direction[0] === "In") && propertyMap.opacity !== undefined) { + (elements.nodeType ? [elements] : elements).forEach(function(element) { + CSS.setPropertyValue(element, "opacity", 0); + }); + } + + /* Only trigger animateParentHeight() if we're using an In/Out transition. */ + if (redirectOptions.animateParentHeight && direction) { + animateParentHeight(elements, direction[0], redirectDuration + (opts.delay as number), redirectOptions.stagger); + } + }; + } + + /* If the user isn't overriding the display option, default to "auto" for "In"-suffixed transitions. */ + // if (redirectOptions.display !== null) { + // if (redirectOptions.display !== undefined && redirectOptions.display !== "none") { + // opts.display = redirectOptions.display; + // } else if (/In$/.test(effectName)) { + // /* Inline elements cannot be subjected to transforms, so we switch them to inline-block. */ + // let defaultDisplay = CSS.Values.getDisplayType(element); + // opts.display = (defaultDisplay === "inline") ? "inline-block" : defaultDisplay; + // } + // } + + if (redirectOptions.visibility && redirectOptions.visibility !== "hidden") { + opts.visibility = redirectOptions.visibility; + } + } + + /* Special processing for the last effect call. */ + if (callIndex === properties.calls.length - 1) { + /* Append promise resolving onto the user's redirect callback. */ + let injectFinalCallbacks = function() { + if ((redirectOptions.display === undefined || redirectOptions.display === "none") && /Out$/.test(effectName)) { + (elements.nodeType ? [elements] : elements).forEach(function(element) { + CSS.setPropertyValue(element, "display", "none"); + }); + } + if (redirectOptions.complete) { + redirectOptions.complete.call(elements, elements); + } + if (resolver) { + resolver(elements || element); + } + }; + + opts.complete = function() { + if (loop) { + Redirects[effectName](element, redirectOptions, elementsIndex, elementsSize, elements, resolver, loop === true ? true : Math.max(0, loop - 1)); + } + if (properties.reset) { + for (let resetProperty in properties.reset) { + if (!properties.reset.hasOwnProperty(resetProperty)) { + continue; + } + let resetValue = properties.reset[resetProperty]; + + /* Format each non-array value in the reset property map to [ value, value ] so that changes apply + immediately and DOM querying is avoided (via forcefeeding). */ + /* Note: Don't forcefeed hooks, otherwise their hook roots will be defaulted to their null values. */ + // TODO: Fix this + // if (CSS.Hooks.registered[resetProperty] === undefined && (typeof resetValue === "string" || typeof resetValue === "number")) { + // properties.reset[resetProperty] = [properties.reset[resetProperty], properties.reset[resetProperty]]; + // } + } + + /* So that the reset values are applied instantly upon the next rAF tick, use a zero duration and parallel queueing. */ + let resetOptions: VelocityOptions = {duration: 0, queue: false}; + + /* Since the reset option uses up the complete callback, we trigger the user's complete callback at the end of ours. */ + if (finalElement) { + resetOptions.complete = injectFinalCallbacks; + } + + VelocityFn(element, properties.reset, resetOptions); + /* Only trigger the user's complete callback on the last effect call with the last element in the set. */ + } else if (finalElement) { + injectFinalCallbacks(); + } + }; + + if (redirectOptions.visibility === "hidden") { + opts.visibility = redirectOptions.visibility; + } + } + + VelocityFn(element, propertyMap, opts); + } + }; + + /* Return the Velocity object so that RegisterUI calls can be chained. */ + return VelocityFn as any; + }; +}; \ No newline at end of file diff --git a/src/Velocity/runsequence.ts b/src/Velocity/runsequence.ts new file mode 100644 index 00000000..a65312d8 --- /dev/null +++ b/src/Velocity/runsequence.ts @@ -0,0 +1,52 @@ +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + * + * Sequence Running + */ + +namespace VelocityStatic { + /* Note: Sequence calls must use Velocity's single-object arguments syntax. */ + export function RunSequence(originalSequence): void { + let sequence = _deepCopyObject([], originalSequence); + + if (sequence.length > 1) { + sequence.reverse().forEach(function(currentCall, i) { + let nextCall = sequence[i + 1]; + + if (nextCall) { + /* Parallel sequence calls (indicated via sequenceQueue:false) are triggered + in the previous call's begin callback. Otherwise, chained calls are normally triggered + in the previous call's complete callback. */ + let currentCallOptions = currentCall.o || currentCall.options, + nextCallOptions = nextCall.o || nextCall.options; + + let timing = (currentCallOptions && currentCallOptions.sequenceQueue === false) ? "begin" : "complete", + callbackOriginal = nextCallOptions && nextCallOptions[timing], + options = {}; + + options[timing] = function() { + let nextCallElements = nextCall.e || nextCall.elements; + let elements = nextCallElements.nodeType ? [nextCallElements] : nextCallElements; + + if (callbackOriginal) { + callbackOriginal.call(elements, elements); + } + VelocityFn(currentCall); + }; + + if (nextCall.o) { + nextCall.o = {...nextCallOptions, ...options}; + } else { + nextCall.options = {...nextCallOptions, ...options}; + } + } + }); + + sequence.reverse(); + } + + VelocityFn(sequence[0]); + }; +}; diff --git a/src/Velocity/state.ts b/src/Velocity/state.ts new file mode 100644 index 00000000..9180b52e --- /dev/null +++ b/src/Velocity/state.ts @@ -0,0 +1,86 @@ +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + */ + +namespace VelocityStatic { + /** + * Container for page-wide Velocity state data. + */ + export namespace State { + export let + /** + * Detect if this is a NodeJS or web browser + */ + isClient = window && window === window.window, + /** + * Detect mobile devices to determine if mobileHA should be turned + * on. + */ + isMobile = isClient && /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent), + /** + * The mobileHA option's behavior changes on older Android devices + * (Gingerbread, versions 2.3.3-2.3.7). + */ + isAndroid = isClient && /Android/i.test(navigator.userAgent), + /** + * The mobileHA option's behavior changes on older Android devices + * (Gingerbread, versions 2.3.3-2.3.7). + */ + isGingerbread = isClient && /Android 2\.3\.[3-7]/i.test(navigator.userAgent), + /** + * Chrome browser + */ + isChrome = isClient && (window as any).chrome, + /** + * Firefox browser + */ + isFirefox = isClient && /Firefox/i.test(navigator.userAgent), + /** + * Create a cached element for re-use when checking for CSS property + * prefixes. + */ + prefixElement = isClient && document.createElement("div"), + /** + * Retrieve the appropriate scroll anchor and property name for the + * browser: https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY + */ + windowScrollAnchor = isClient && window.pageYOffset !== undefined, + /** + * Cache the anchor used for animating window scrolling. + */ + scrollAnchor = windowScrollAnchor ? window : (!isClient || document.documentElement || document.body.parentNode || document.body), + /** + * Cache the browser-specific property names associated with the + * scroll anchor. + */ + scrollPropertyLeft = windowScrollAnchor ? "pageXOffset" : "scrollLeft", + /** + * Cache the browser-specific property names associated with the + * scroll anchor. + */ + scrollPropertyTop = windowScrollAnchor ? "pageYOffset" : "scrollTop", + /** + * The className we add / remove when animating. + */ + className = CLASSNAME, + /** + * Keep track of whether our RAF tick is running. + */ + isTicking = false, + /** + * Container for every in-progress call to Velocity. + */ + first: AnimationCall, + /** + * Container for every in-progress call to Velocity. + */ + last: AnimationCall, + /** + * First new animation - to shortcut starting them all up and push + * any css reads to the start of the tick + */ + firstNew: AnimationCall + }; +}; diff --git a/src/Velocity/tick.ts b/src/Velocity/tick.ts new file mode 100644 index 00000000..81dbd409 --- /dev/null +++ b/src/Velocity/tick.ts @@ -0,0 +1,357 @@ +/// +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + * + * Tick + */ + +namespace VelocityStatic { + + /** + * Call the begin method of an animation in a separate function so it can + * benefit from JIT compiling while still having a try/catch block. + */ + export function callBegin(activeCall: AnimationCall) { + try { + const elements = activeCall.elements; + + (activeCall.options.begin as VelocityCallback).call(elements, elements, activeCall); + } catch (error) { + setTimeout(function() { + throw error; + }, 1); + } + } + + /** + * Call the progress method of an animation in a separate function so it can + * benefit from JIT compiling while still having a try/catch block. + */ + function callProgress(activeCall: AnimationCall, timeCurrent: number) { + try { + const elements = activeCall.elements, + percentComplete = activeCall.percentComplete, + options = activeCall.options, + tweenValue = activeCall.tween; + + (activeCall.options.progress as VelocityProgress).call(elements, + elements, + percentComplete, + Math.max(0, activeCall.timeStart + (activeCall.duration != null ? activeCall.duration : options.duration != null ? options.duration : defaults.duration) - timeCurrent), + tweenValue !== undefined ? tweenValue : String(percentComplete * 100), + activeCall); + } catch (error) { + setTimeout(function() { + throw error; + }, 1); + } + } + + let firstProgress: AnimationCall, + firstComplete: AnimationCall; + + function asyncCallbacks() { + let activeCall: AnimationCall, + nextCall: AnimationCall; + // Callbacks and complete that might read the DOM again. + + // Progress callback + for (activeCall = firstProgress; activeCall; activeCall = nextCall) { + nextCall = activeCall._nextProgress; + // Pass to an external fn with a try/catch block for optimisation + callProgress(activeCall, lastTick); + } + // Complete animations, including complete callback or looping + for (activeCall = firstComplete; activeCall; activeCall = nextCall) { + nextCall = activeCall._nextComplete; + /* If this call has finished tweening, pass it to complete() to handle call cleanup. */ + completeCall(activeCall); + } + } + + /************** + Timing + **************/ + + const FRAME_TIME = 1000 / 60, + /** + * Shim for window.performance in case it doesn't exist + */ + performance = (function() { + const perf = window.performance || {} as Performance; + + if (typeof perf.now !== "function") { + const nowOffset = perf.timing && perf.timing.navigationStart ? perf.timing.navigationStart : _now(); + + perf.now = function() { + return _now() - nowOffset; + }; + } + return perf; + })(), + /** + * Proxy function for when rAF is not available - try to be as accurate + * as possible with the setTimeout calls, however they are far less + * accurate than rAF can be - so try not to use normally (unless the tab + * is in the background). + */ + rAFProxy = function(callback: FrameRequestCallback) { + console.log("rAFProxy", Math.max(0, FRAME_TIME - (performance.now() - lastTick)), performance.now(), lastTick, FRAME_TIME) + return setTimeout(function() { + callback(performance.now()); + }, Math.max(0, FRAME_TIME - (performance.now() - lastTick))); + }, + /* rAF shim. Gist: https://gist.github.com/julianshapiro/9497513 */ + rAFShim = window.requestAnimationFrame || rAFProxy; + /** + * The ticker function being used, either rAF, or a function that + * emulates it. + */ + let ticker: (callback: FrameRequestCallback) => number = document.hidden ? rAFProxy : rAFShim; + /** + * The time that the last animation frame ran at. Set from tick(), and used + * for missing rAF (ie, when not in focus etc). + */ + export let lastTick: number = 0; + + /* Inactive browser tabs pause rAF, which results in all active animations immediately sprinting to their completion states when the tab refocuses. + To get around this, we dynamically switch rAF to setTimeout (which the browser *doesn't* pause) when the tab loses focus. We skip this for mobile + devices to avoid wasting battery power on inactive tabs. */ + /* Note: Tab focus detection doesn't work on older versions of IE, but that's okay since they don't support rAF to begin with. */ + if (!State.isMobile && document.hidden !== undefined) { + document.addEventListener("visibilitychange", function updateTicker(event?: Event) { + let hidden = document.hidden; + + ticker = hidden ? rAFProxy : rAFShim; + if (event) { + setTimeout(tick, 2000); + } + tick(); + }); + } + + let ticking: boolean; + + /** + * Called on every tick, preferably through rAF. This is reponsible for + * initialising any new animations, then starting any that need starting. + * Finally it will expand any tweens and set the properties relating to + * them. If there are any callbacks relating to the animations then they + * will attempt to call at the end (with the exception of "begin"). + */ + export function tick(timestamp?: number | boolean) { + if (ticking) { + // Should never happen - but if we've swapped back from hidden to + // visibile then we want to make sure + return; + } + ticking = true; + /* An empty timestamp argument indicates that this is the first tick occurence since ticking was turned on. + We leverage this metadata to fully ignore the first tick pass since RAF's initial pass is fired whenever + the browser's next tick sync time occurs, which results in the first elements subjected to Velocity + calls being animated out of sync with any elements animated immediately thereafter. In short, we ignore + the first RAF tick pass so that elements being immediately consecutively animated -- instead of simultaneously animated + by the same Velocity call -- are properly batched into the same initial RAF tick and consequently remain in sync thereafter. */ + if (timestamp) { + /* We normally use RAF's high resolution timestamp but as it can be significantly offset when the browser is + under high stress we give the option for choppiness over allowing the browser to drop huge chunks of frames. + We use performance.now() and shim it if it doesn't exist for when the tab is hidden. */ + const timeCurrent = timestamp && timestamp !== true ? timestamp : performance.now(), + deltaTime = lastTick ? timeCurrent - lastTick : FRAME_TIME, + defaultSpeed = defaults.speed, + defaultEasing = defaults.easing, + defaultDuration = defaults.duration; + let activeCall: AnimationCall, + nextCall: AnimationCall, + lastProgress: AnimationCall, + lastComplete: AnimationCall; + + firstProgress = null; + firstComplete = null; + if (deltaTime >= defaults.minFrameTime || !lastTick) { + lastTick = timeCurrent; + + /******************** + Call Iteration + ********************/ + + // Expand any tweens that might need it. + while ((activeCall = State.firstNew)) { + validateTweens(activeCall); + } + // Iterate through each active call. + for (activeCall = State.first; activeCall && activeCall !== State.firstNew; activeCall = activeCall._next) { + const element = activeCall.element; + let data: ElementData; + + // Check to see if this element has been deleted midway + // through the animation. If it's gone then end this + // animation. + if (!element.parentNode || !(data = Data(element))) { + // TODO: Remove safely - decrease count, delete data, remove from arrays + freeAnimationCall(activeCall); + continue; + } + // Don't bother getting until we can use these. + const options = activeCall.options, + flags = activeCall._flags; + let timeStart = activeCall.timeStart; + + // If this is the first time that this call has been + // processed by tick() then we assign timeStart now so that + // it's value is as close to the real animation start time + // as possible. + if (!timeStart) { + const queue = activeCall.queue != null ? activeCall.queue : options.queue; + + timeStart = timeCurrent - deltaTime; + if (queue !== false) { + timeStart = Math.max(timeStart, data.lastFinishList[queue] || 0); + } + activeCall.timeStart = timeStart; + } + // If this animation is paused then skip processing unless + // it has been set to resume. + if (flags & AnimationFlags.PAUSED) { + // Update the time start to accomodate the paused + // completion amount. + activeCall.timeStart += deltaTime; + continue; + } + // Check if this animation is ready - if it's synced then it + // needs to wait for all other animations in the sync + if (!(flags & AnimationFlags.READY)) { + activeCall._flags |= AnimationFlags.READY; + options._ready++; + } + } + // Need to split the loop, as ready sync animations must all get + // the same start time. + for (activeCall = State.first; activeCall && activeCall !== State.firstNew; activeCall = nextCall) { + const flags = activeCall._flags; + + nextCall = activeCall._next; + if (!(flags & AnimationFlags.READY) || (flags & AnimationFlags.PAUSED)) { + continue; + } + const options = activeCall.options; + + if ((flags & AnimationFlags.SYNC) && options._ready < options._total) { + activeCall.timeStart += deltaTime; + continue; + } + const speed = activeCall.speed != null ? activeCall.speed : options.speed != null ? options.speed : defaultSpeed; + let timeStart = activeCall.timeStart; + + // Don't bother getting until we can use these. + if (!(flags & AnimationFlags.STARTED)) { + const delay = activeCall.delay != null ? activeCall.delay : options.delay; + + // Make sure anything we've delayed doesn't start + // animating yet, there might still be an active delay + // after something has been un-paused + if (delay) { + if (timeStart + (delay / speed) > timeCurrent) { + continue; + } + activeCall.timeStart = timeStart += delay / (delay > 0 ? speed : 1); + } + activeCall._flags |= AnimationFlags.STARTED; + // The begin callback is fired once per call, not once + // per element, and is passed the full raw DOM element + // set as both its context and its first argument. + if (options._started++ === 0) { + options._first = activeCall; + if (options.begin) { + // Pass to an external fn with a try/catch block for optimisation + callBegin(activeCall); + // Only called once, even if reversed or repeated + options.begin = undefined; + } + } + } + if (speed !== 1) { + // On the first frame we may have a shorter delta + const delta = Math.min(deltaTime, timeCurrent - timeStart); + activeCall.timeStart = timeStart += delta * (1 - speed); + } + + if (options._first === activeCall && options.progress) { + activeCall._nextProgress = undefined; + if (lastProgress) { + lastProgress._nextProgress = lastProgress = activeCall; + } else { + firstProgress = lastProgress = activeCall; + } + } + + const activeEasing = activeCall.easing != null ? activeCall.easing : options.easing != null ? options.easing : defaultEasing, + millisecondsEllapsed = activeCall.ellapsedTime = timeCurrent - timeStart, + duration = activeCall.duration != null ? activeCall.duration : options.duration != null ? options.duration : defaultDuration, + percentComplete = activeCall.percentComplete = mock ? 1 : Math.min(millisecondsEllapsed / duration, 1), + tweens = activeCall.tweens, + reverse = flags & AnimationFlags.REVERSE; + + if (percentComplete === 1) { + activeCall._nextComplete = undefined; + if (lastComplete) { + lastComplete._nextComplete = lastComplete = activeCall; + } else { + firstComplete = lastComplete = activeCall; + } + } + + for (const property in tweens) { + // For every element, iterate through each property. + const tween = tweens[property], + easing = tween[Tween.EASING] || activeEasing, + pattern = tween[Tween.PATTERN], + rounding = tween[Tween.ROUNDING]; + let currentValue = "", + i = 0; + + if (pattern) { + for (; i < pattern.length; i++) { + const startValue = tween[Tween.START][i]; + + if (startValue == null) { + currentValue += pattern[i]; + } else { + // All easings must deal with numbers except for + // our internal ones + const result = easing(reverse ? 1 - percentComplete : percentComplete, startValue as number, tween[Tween.END][i] as number, property) + + currentValue += rounding && rounding[i] ? Math.round(result) : result; + } + } + if (property !== "tween") { + // TODO: To solve an IE<=8 positioning bug, the unit type must be dropped when setting a property value of 0 - add normalisations to legacy + CSS.setPropertyValue(activeCall.element, property, currentValue); + } else { + // Skip the fake 'tween' property as that is only + // passed into the progress callback. + activeCall.tween = currentValue; + } + } else { + console.warn("VelocityJS: Missing pattern:", property, JSON.stringify(tween[property])) + delete tweens[property]; + } + } + } + if (firstProgress || firstComplete) { + setTimeout(asyncCallbacks, 1); + } + } + } + if (State.first) { + State.isTicking = true; + ticker(tick); + } else { + State.isTicking = false; + lastTick = 0; + } + ticking = false; + } +} diff --git a/src/Velocity/timestamp.ts b/src/Velocity/timestamp.ts new file mode 100644 index 00000000..da960883 --- /dev/null +++ b/src/Velocity/timestamp.ts @@ -0,0 +1,11 @@ +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + * + * Use rAF high resolution timestamp when available. + */ + +namespace VelocityStatic { + export let timestamp: boolean = true; +}; diff --git a/src/Velocity/tweens.ts b/src/Velocity/tweens.ts new file mode 100644 index 00000000..ef0bcb50 --- /dev/null +++ b/src/Velocity/tweens.ts @@ -0,0 +1,435 @@ +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + * + * Tweens + */ + +const enum Tween { + END, + EASING, + START, + PATTERN, + ROUNDING, + length +}; + +namespace VelocityStatic { + let commands = new Map string>(); + + commands.set("function", function(value: any, element: HTMLorSVGElement, elements: HTMLorSVGElement[], elementArrayIndex: number) { + return (value as any as VelocityPropertyValueFn).call(element, elementArrayIndex, elements.length); + }) + commands.set("number", function(value, element, elements, elementArrayIndex, propertyName) { + return value + (element instanceof HTMLElement ? getUnitType(propertyName) : ""); + }); + commands.set("string", function(value, element, elements, elementArrayIndex, propertyName) { + return CSS.fixColors(value); + }); + commands.set("undefined", function(value, element, elements, elementArrayIndex, propertyName) { + return CSS.fixColors(CSS.getPropertyValue(element, propertyName) || ""); + }); + + const + /** + * Properties that take "deg" as the default numeric suffix. + */ + degree = [ + // "azimuth" // Deprecated + ], + /** + * Properties that take no default numeric suffix. + */ + unitless = [ + "borderImageSlice", + "columnCount", + "counterIncrement", + "counterReset", + "flex", + "flexGrow", + "flexShrink", + "floodOpacity", + "fontSizeAdjust", + "fontWeight", + "lineHeight", + "opacity", + "order", + "orphans", + "shapeImageThreshold", + "tabSize", + "widows", + "zIndex" + ]; + + /** + * Retrieve a property's default unit type. Used for assigning a unit + * type when one is not supplied by the user. These are only valid for + * HTMLElement style properties. + */ + function getUnitType(property: string): string { + if (_inArray(degree, property)) { + return "deg"; + } + if (_inArray(unitless, property)) { + return ""; + } + return "px"; + } + + /** + * Expand a VelocityProperty argument into a valid sparse Tween array. This + * pre-allocates the array as it is then the correct size and slightly + * faster to access. + */ + export function expandProperties(animation: AnimationCall, properties: VelocityProperties) { + const tweens = animation.tweens = Object.create(null), + elements = animation.elements, + element = animation.element, + elementArrayIndex = elements.indexOf(element), + data = Data(element), + queue = getValue(animation.queue, animation.options.queue), + duration = getValue(animation.options.duration, defaults.duration); + + for (const property in properties) { + const propertyName = CSS.camelCase(property); + let valueData = properties[property], + types = data.types, + found: boolean = propertyName === "tween"; + + for (let index = 0; types && !found; types >>= 1, index++) { + found = !!(types & 1 && Normalizations[index][propertyName]); + } + if (!found + && (!State.prefixElement + || !isString(State.prefixElement.style[propertyName]))) { + if (debug) { + console.log("Skipping [" + property + "] due to a lack of browser support."); + } + continue; + } + if (valueData == null) { + if (debug) { + console.log("Skipping [" + property + "] due to no value supplied."); + } + continue; + } + const tween: VelocityTween = tweens[propertyName] = new Array(Tween.length) as any; + let endValue: string, + startValue: string; + + if (isFunction(valueData)) { + // If we have a function as the main argument then resolve + // it first, in case it returns an array that needs to be + // split. + valueData = (valueData as VelocityPropertyFn).call(element, elementArrayIndex, elements.length, elements); + } + if (Array.isArray(valueData)) { + // valueData is an array in the form of + // [ endValue, [, easing] [, startValue] ] + const arr1 = valueData[1], + arr2 = valueData[2]; + + endValue = valueData[0] as any; + if ((isString(arr1) && (/^[\d-]/.test(arr1) || CSS.RegEx.isHex.test(arr1))) || isFunction(arr1) || isNumber(arr1)) { + startValue = arr1 as any; + } else if ((isString(arr1) && Easing.Easings[arr1]) || Array.isArray(arr1)) { + tween[Tween.EASING] = arr1 as any; + startValue = arr2 as any; + } else { + startValue = arr1 || arr2 as any; + } + } else { + endValue = valueData as any; + } + tween[Tween.END] = commands.get(typeof endValue)(endValue, element, elements, elementArrayIndex, propertyName) as any; + if (startValue != null || (queue === false || data.queueList[queue] === undefined)) { + tween[Tween.START] = commands.get(typeof startValue)(startValue, element, elements, elementArrayIndex, propertyName) as any; + } + explodeTween(propertyName, tween, duration, !!startValue); + } + } + + /** + * Convert a string-based tween with start and end strings, into a pattern + * based tween with arrays. + */ + function explodeTween(propertyName: string, tween: VelocityTween, duration: number, isForcefeed?: boolean) { + const endValue: string = tween[Tween.END] as any as string; + let startValue: string = tween[Tween.START] as any as string; + + if (!isString(endValue) || !isString(startValue)) { + return; + } + let runAgain = false; // Can only be set once if the Start value doesn't match the End value and it's not forcefed + do { + runAgain = false; + const arrayStart: (string | number)[] = tween[Tween.START] = [null], + arrayEnd: (string | number)[] = tween[Tween.END] = [null], + pattern: (string | number)[] = tween[Tween.PATTERN] = [""]; + let easing = tween[Tween.EASING] as any, + rounding: boolean[], + indexStart = 0, // index in startValue + indexEnd = 0, // index in endValue + inCalc = 0, // Keep track of being inside a "calc()" so we don't duplicate it + inRGB = 0, // Keep track of being inside an RGB as we can't use fractional values + inRGBA = 0, // Keep track of being inside an RGBA as we must pass fractional for the alpha channel + isStringValue: boolean; + + // TODO: Relative Values + + /* Operator logic must be performed last since it requires unit-normalized start and end values. */ + /* Note: Relative *percent values* do not behave how most people think; while one would expect "+=50%" + to increase the property 1.5x its current value, it in fact increases the percent units in absolute terms: + 50 points is added on top of the current % value. */ + // switch (operator as any as string) { + // case "+": + // endValue = startValue + endValue; + // break; + // + // case "-": + // endValue = startValue - endValue; + // break; + // + // case "*": + // endValue = startValue * endValue; + // break; + // + // case "/": + // endValue = startValue / endValue; + // break; + // } + + // TODO: Leading from a calc value + while (indexStart < startValue.length && indexEnd < endValue.length) { + let charStart = startValue[indexStart], + charEnd = endValue[indexEnd]; + + // If they're both numbers, then parse them as a whole + if (TWEEN_NUMBER_REGEX.test(charStart) && TWEEN_NUMBER_REGEX.test(charEnd)) { + let tempStart = charStart, // temporary character buffer + tempEnd = charEnd, // temporary character buffer + dotStart = ".", // Make sure we can only ever match a single dot in a decimal + dotEnd = "."; // Make sure we can only ever match a single dot in a decimal + + while (++indexStart < startValue.length) { + charStart = startValue[indexStart]; + if (charStart === dotStart) { + dotStart = ".."; // Can never match two characters + } else if (!isNumberWhenParsed(charStart)) { + break; + } + tempStart += charStart; + } + while (++indexEnd < endValue.length) { + charEnd = endValue[indexEnd]; + if (charEnd === dotEnd) { + dotEnd = ".."; // Can never match two characters + } else if (!isNumberWhenParsed(charEnd)) { + break; + } + tempEnd += charEnd; + } + let unitStart = CSS.getUnit(startValue, indexStart), // temporary unit type + unitEnd = CSS.getUnit(endValue, indexEnd); // temporary unit type + + indexStart += unitStart.length; + indexEnd += unitEnd.length; + if (unitEnd.length === 0) { + // This order as it's most common for the user supplied + // value to be a number. + unitEnd = unitStart; + } else if (unitStart.length === 0) { + unitStart = unitEnd; + } + if (unitStart === unitEnd) { + // Same units + if (tempStart === tempEnd) { + // Same numbers, so just copy over + pattern[pattern.length - 1] += tempStart + unitStart; + } else { + if (inRGB) { + if (!rounding) { + rounding = tween[Tween.ROUNDING] = []; + } + rounding[arrayStart.length] = true; + } + pattern.push(0, unitStart); + arrayStart.push(parseFloat(tempStart), null); + arrayEnd.push(parseFloat(tempEnd), null); + } + } else { + // Different units, so put into a "calc(from + to)" and + // animate each side to/from zero. setPropertyValue will + // look out for the final "calc(0 + " prefix and remove + // it from the value when it finds it. + pattern[pattern.length - 1] += inCalc ? "+ (" : "calc("; + pattern.push(0, unitStart + " + ", 0, unitEnd + ")"); + arrayStart.push(parseFloat(tempStart) || 0, null, 0, null); + arrayEnd.push(0, null, parseFloat(tempEnd) || 0, null); + } + } else if (charStart === charEnd) { + pattern[pattern.length - 1] += charStart; + indexStart++; + indexEnd++; + // Keep track of being inside a calc() + if (inCalc === 0 && charStart === "c" + || inCalc === 1 && charStart === "a" + || inCalc === 2 && charStart === "l" + || inCalc === 3 && charStart === "c" + || inCalc >= 4 && charStart === "(" + ) { + inCalc++; + } else if ((inCalc && inCalc < 5) + || inCalc >= 4 && charStart === ")" && --inCalc < 5) { + inCalc = 0; + } + // Keep track of being inside an rgb() / rgba() + // The opacity must not be rounded. + if (inRGB === 0 && charStart === "r" + || inRGB === 1 && charStart === "g" + || inRGB === 2 && charStart === "b" + || inRGB === 3 && charStart === "a" + || inRGB >= 3 && charStart === "(" + ) { + if (inRGB === 3 && charStart === "a") { + inRGBA = 1; + } + inRGB++; + } else if (inRGBA && charStart === ",") { + if (++inRGBA > 3) { + inRGB = inRGBA = 0; + } + } else if ((inRGBA && inRGB < (inRGBA ? 5 : 4)) + || inRGB >= (inRGBA ? 4 : 3) && charStart === ")" && --inRGB < (inRGBA ? 5 : 4)) { + inRGB = inRGBA = 0; + } + } else if (charStart || charEnd) { + // Different letters, so we're going to push them into start + // and end until the next word + isStringValue = true; + if (!isString(arrayStart[arrayStart.length - 1])) { + if (pattern.length === 1 && !pattern[0]) { + arrayStart[0] = arrayEnd[0] = ""; + } else { + pattern.push(""); + arrayStart.push(""); + arrayEnd.push(""); + } + } + while (indexStart < startValue.length) { + charStart = startValue[indexStart++]; + if (charStart === " ") { + break; + } else { + arrayStart[arrayStart.length - 1] += charStart; + } + } + while (indexEnd < endValue.length) { + charEnd = endValue[indexEnd++]; + if (charEnd === " ") { + break; + } else { + arrayEnd[arrayEnd.length - 1] += charEnd; + } + } + } + if (!isForcefeed && (indexStart === startValue.length) !== (indexEnd === endValue.length)) { + // This little piece will take a startValue, split out the + // various numbers in it, then copy the endValue into the + // startValue while replacing the numbers in it to match the + // original start numbers as a repeating sequence. + // Finally this function will run again with the new + // startValue and a now matching pattern. + let startNumbers = startValue.match(/\d\.?\d*/g) || ["0"], + count = startNumbers.length, + index = 0; + + startValue = endValue.replace(/\d+\.?\d*/g, function() { + return startNumbers[index++ % count]; + }); + runAgain = isForcefeed = true; + break; + } + } + if (!runAgain) { + // TODO: These two would be slightly better to not add the array indices in the first place + if (pattern[0] === "" && arrayEnd[0] == null) { + pattern.shift(); + arrayStart.shift(); + arrayEnd.shift(); + } + if (pattern[pattern.length] === "" && arrayEnd[arrayEnd.length] == null) { + pattern.pop(); + arrayStart.pop(); + arrayEnd.pop(); + } + if (indexStart < startValue.length || indexEnd < endValue.length) { + // NOTE: We should never be able to reach this code unless a + // bad forcefed value is supplied. + console.error("Velocity: Trying to pattern match mis-matched strings " + propertyName + ":[\"" + endValue + "\", \"" + startValue + "\"]"); + } + if (debug) { + console.log("Velocity: Pattern found:", pattern, " -> ", arrayStart, arrayEnd, "[" + startValue + "," + endValue + "]"); + } + if (propertyName === "display") { + if (!/^(at-start|at-end|during)$/.test(easing)) { + easing = endValue === "none" ? "at-end" : "at-start"; + } + } else if (propertyName === "visibility") { + if (!/^(at-start|at-end|during)$/.test(easing)) { + easing = endValue === "hidden" ? "at-end" : "at-start"; + } + } else if (isStringValue + && easing !== "at-start" && easing !== "during" && easing !== "at-end" + && easing !== Easing.Easings["at-Start"] && easing !== Easing.Easings["during"] && easing !== Easing.Easings["at-end"]) { + console.warn("Velocity: String easings must use one of 'at-start', 'during' or 'at-end': {" + propertyName + ": [\"" + endValue + "\", " + easing + ", \"" + startValue + "\"]}"); + easing = "at-start"; + } + tween[Tween.EASING] = validateEasing(easing, duration); + } + // This can only run a second time once - if going from automatic startValue to "fixed" pattern from endValue with startValue numbers + } while (runAgain); + } + + /** + * Expand all queued animations that haven't gone yet + * + * This will automatically expand the properties map for any recently added + * animations so that the start and end values are correct. + */ + export function validateTweens(activeCall: AnimationCall) { + // This might be called on an already-ready animation + if (State.firstNew === activeCall) { + State.firstNew = activeCall._next; + } + // Check if we're actually already ready + if (activeCall._flags & AnimationFlags.EXPANDED) { + return; + } + + let element = activeCall.element, + tweens = activeCall.tweens, + duration = getValue(activeCall.options.duration, defaults.duration); + + for (const propertyName in tweens) { + const tween = tweens[propertyName]; + + if (tween[Tween.START] == null) { + // Get the start value as it's not been passed in + const startValue = CSS.getPropertyValue(activeCall.element, propertyName); + + if (isString(startValue)) { + tween[Tween.START] = CSS.fixColors(startValue) as any; + explodeTween(propertyName, tween, duration); + } else if (!Array.isArray(startValue)) { + console.warn("bad type", tween, propertyName, startValue) + } + } + if (debug) { + console.log("tweensContainer (" + propertyName + "): " + JSON.stringify(tween), element); + } + } + activeCall._flags |= AnimationFlags.EXPANDED; + } +} diff --git a/src/Velocity/validate.ts b/src/Velocity/validate.ts new file mode 100644 index 00000000..4883eeb3 --- /dev/null +++ b/src/Velocity/validate.ts @@ -0,0 +1,271 @@ +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + * + * Validation functions used for various types of data that can be supplied. + * All errors are reported in the non-minified version for development. If a + * validation fails then it should return undefined. + */ + +/** + * Parse a duration value and return an ms number. Optionally return a + * default value if the number is not valid. + */ +function parseDuration(duration: "fast" | "normal" | "slow" | number, def?: "fast" | "normal" | "slow" | number): number { + if (isNumber(duration)) { + return duration; + } + + if (isString(duration)) { + return Duration[duration.toLowerCase()] || parseFloat(duration.replace("ms", "").replace("s", "000")); + } + + return def == null ? undefined : parseDuration(def); +} + +/** + * Validate a cache option. + * @private + */ +function validateCache(value: boolean): boolean { + if (isBoolean(value)) { + return value; + } + if (value != null) { + console.warn("VelocityJS: Trying to set 'cache' to an invalid value:", value); + } +} + +/** + * Validate a begin option. + * @private + */ +function validateBegin(value: VelocityCallback): VelocityCallback { + if (isFunction(value)) { + return value; + } + if (value != null) { + console.warn("VelocityJS: Trying to set 'begin' to an invalid value:", value); + } +} + +/** + * Validate a complete option. + * @private + */ +function validateComplete(value: VelocityCallback, noError?: true): VelocityCallback { + if (isFunction(value)) { + return value; + } + if (value != null && !noError) { + console.warn("VelocityJS: Trying to set 'complete' to an invalid value:", value); + } +} + +/** + * Validate a delay option. + * @private + */ +function validateDelay(value: "fast" | "normal" | "slow" | number): number { + const parsed = parseDuration(value); + + if (!isNaN(parsed)) { + return parsed; + } + if (value != null) { + console.error("VelocityJS: Trying to set 'delay' to an invalid value:", value); + } +} + +/** + * Validate a duration option. + * @private + */ +function validateDuration(value: "fast" | "normal" | "slow" | number, noError?: true): number { + const parsed = parseDuration(value); + + if (!isNaN(parsed) && parsed >= 0) { + return parsed; + } + if (value != null && !noError) { + console.error("VelocityJS: Trying to set 'duration' to an invalid value:", value); + } +} + +/** + * Validate a easing option. + * @private + */ +function validateEasing(value: VelocityEasingType, duration: number, noError?: true): VelocityEasingFn { + const Easing = VelocityStatic.Easing; + + if (isString(value)) { + // Named easing + return Easing.Easings[value]; + } + if (isFunction(value)) { + return value; + } + if (Array.isArray(value)) { + if (value.length === 1) { + // Steps + return Easing.generateStep(value[0]); + } + if (value.length === 2) { + // springRK4 must be passed the animation's duration. + // Note: If the springRK4 array contains non-numbers, + // generateSpringRK4() returns an easing function generated with + // default tension and friction values. + return Easing.generateSpringRK4(value[0], value[1], duration); + } + if (value.length === 4) { + // Note: If the bezier array contains non-numbers, generateBezier() + // returns undefined. + return Easing.generateBezier.apply(null, value) || false; + } + } + if (value != null && !noError) { + console.error("VelocityJS: Trying to set 'easing' to an invalid value:", value); + } +} + +/** + * Validate a fpsLimit option. + * @private + */ +function validateFpsLimit(value: number | false): number { + if (value === false) { + return 0; + } else { + const parsed = parseInt(value as any, 10); + + if (!isNaN(parsed) && parsed >= 0) { + return Math.min(parsed, 60); + } + } + if (value != null) { + console.warn("VelocityJS: Trying to set 'fpsLimit' to an invalid value:", value); + } +} + + +/** + * Validate a loop option. + * @private + */ +function validateLoop(value: number | boolean): number | true { + if (value === false) { + return 0; + } else if (value === true) { + return true; + } else { + const parsed = parseInt(value as any, 10); + + if (!isNaN(parsed) && parsed >= 0) { + return parsed; + } + } + if (value != null) { + console.warn("VelocityJS: Trying to set 'loop' to an invalid value:", value); + } +} + +/** + * Validate a progress option. + * @private + */ +function validateProgress(value: VelocityProgress): VelocityProgress { + if (isFunction(value)) { + return value; + } + if (value != null) { + console.warn("VelocityJS: Trying to set 'progress' to an invalid value:", value); + } +} + +/** + * Validate a promise option. + * @private + */ +function validatePromise(value: boolean): boolean { + if (isBoolean(value)) { + return value; + } + if (value != null) { + console.warn("VelocityJS: Trying to set 'promise' to an invalid value:", value); + } +} + +/** + * Validate a promiseRejectEmpty option. + * @private + */ +function validatePromiseRejectEmpty(value: boolean): boolean { + if (isBoolean(value)) { + return value; + } + if (value != null) { + console.warn("VelocityJS: Trying to set 'promiseRejectEmpty' to an invalid value:", value); + } +} + +/** + * Validate a queue option. + * @private + */ +function validateQueue(value: string | false, noError?: true): string | false { + if (value === false || isString(value)) { + return value; + } + if (value != null && !noError) { + console.warn("VelocityJS: Trying to set 'queue' to an invalid value:", value); + } +} + +/** + * Validate a repeat option. + * @private + */ +function validateRepeat(value: number | boolean): number | true { + if (value === false) { + return 0; + } else if (value === true) { + return true; + } else { + const parsed = parseInt(value as any, 10); + + if (!isNaN(parsed) && parsed >= 0) { + return parsed; + } + } + if (value != null) { + console.warn("VelocityJS: Trying to set 'repeat' to an invalid value:", value); + } +} + +/** + * Validate a speed option. + * @private + */ +function validateSpeed(value: number): number { + if (isNumber(value)) { + return value; + } + if (value != null) { + console.error("VelocityJS: Trying to set 'speed' to an invalid value:", value); + } +} + +/** + * Validate a sync option. + * @private + */ +function validateSync(value: boolean): boolean { + if (isBoolean(value)) { + return value; + } + if (value != null) { + console.error("VelocityJS: Trying to set 'sync' to an invalid value:", value); + } +} diff --git a/src/Velocity/version.ts b/src/Velocity/version.ts new file mode 100644 index 00000000..d1381e87 --- /dev/null +++ b/src/Velocity/version.ts @@ -0,0 +1,11 @@ +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + * + * Velocity version (should grab from package.json during build). + */ + +namespace VelocityStatic { + export let version = VERSION; +}; diff --git a/src/app.ts b/src/app.ts new file mode 100644 index 00000000..cff539dc --- /dev/null +++ b/src/app.ts @@ -0,0 +1,25 @@ +/// +/// +/// +/// +/// +/// +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + * + * Merge the VelocityStatic namespace onto the Velocity function for external + * use. This is done as a read-only way. Any attempt to change these values will + * be allowed. + */ +for (const key in VelocityStatic) { + Object.defineProperty(VelocityFn, key, { + enumerable: PUBLIC_MEMBERS.indexOf(key) >= 0, + get: function() { + return VelocityStatic[key]; + } + }); +} + +// console.log("Velocity keys", Object.keys(VelocityStatic)); diff --git a/src/constants.ts b/src/constants.ts new file mode 100644 index 00000000..515848ec --- /dev/null +++ b/src/constants.ts @@ -0,0 +1,46 @@ +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + * + * Constants and defaults. These values should never change without a MINOR + * version bump. + */ + +//["completeCall", "CSS", "State", "getEasing", "Easings", "data", "debug", "defaults", "hook", "init", "mock", "pauseAll", "queue", "dequeue", "freeAnimationCall", "Redirects", "RegisterEffect", "resumeAll", "RunSequence", "lastTick", "tick", "timestamp", "expandTween", "version"] +const PUBLIC_MEMBERS = ["version", "RegisterEffect", "style", "patch", "timestamp"]; +/** + * Without this it will only un-prefix properties that have a valid "normal" + * version. + */ +const ALL_VENDOR_PREFIXES = true; + +const DURATION_FAST = 200; +const DURATION_NORMAL = 400; +const DURATION_SLOW = 600; + +const FUZZY_MS_PER_SECOND = 980; + +const DEFAULT_CACHE = true; +const DEFAULT_DELAY = 0; +const DEFAULT_DURATION = DURATION_NORMAL; +const DEFAULT_EASING = "swing"; +const DEFAULT_FPSLIMIT = 60; +const DEFAULT_LOOP = 0; +const DEFAULT_PROMISE = true; +const DEFAULT_PROMISE_REJECT_EMPTY = true; +const DEFAULT_QUEUE = ""; +const DEFAULT_REPEAT = 0; +const DEFAULT_SPEED = 1; +const DEFAULT_SYNC = true; +const TWEEN_NUMBER_REGEX = /[\d\.-]/; + +const CLASSNAME = "velocity-animating"; + +const VERSION = "2.0.0"; + +const Duration = { + "fast": DURATION_FAST, + "normal": DURATION_NORMAL, + "slow": DURATION_SLOW, +}; diff --git a/src/core.ts b/src/core.ts new file mode 100644 index 00000000..6385729d --- /dev/null +++ b/src/core.ts @@ -0,0 +1,465 @@ +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + * + * Core "Velocity" function. + */ + +interface Document { + documentMode: any; // IE +} + +/** + * The main Velocity function. Acts as a gateway to everything else. + */ +function VelocityFn(options: VelocityObjectArgs): VelocityResult; +function VelocityFn(elements: VelocityElements, propertyMap: string | VelocityProperties, options?: VelocityOptions): VelocityResult; +function VelocityFn(elements: VelocityElements, propertyMap: string | VelocityProperties, duration?: number | "fast" | "normal" | "slow", complete?: () => void): VelocityResult; +function VelocityFn(elements: VelocityElements, propertyMap: string | VelocityProperties, complete?: () => void): VelocityResult; +function VelocityFn(elements: VelocityElements, propertyMap: string | VelocityProperties, easing?: string | number[], complete?: () => void): VelocityResult; +function VelocityFn(elements: VelocityElements, propertyMap: string | VelocityProperties, duration?: number | "fast" | "normal" | "slow", easing?: string | number[], complete?: () => void): VelocityResult; +function VelocityFn(this: VelocityElements, propertyMap: string | VelocityProperties, duration?: number | "fast" | "normal" | "slow", complete?: () => void): VelocityResult; +function VelocityFn(this: VelocityElements, propertyMap: string | VelocityProperties, complete?: () => void): VelocityResult; +function VelocityFn(this: VelocityElements, propertyMap: string | VelocityProperties, easing?: string | number[], complete?: () => void): VelocityResult; +function VelocityFn(this: VelocityElements, propertyMap: string | VelocityProperties, duration?: number | "fast" | "normal" | "slow", easing?: string | number[], complete?: () => void): VelocityResult; +function VelocityFn(this: VelocityElements | void, ...__args: any[]): VelocityResult { + const + /** + * A shortcut to the default options. + */ + defaults = VelocityStatic.defaults, + /** + * Shortcut to arguments for file size. + */ + _arguments = arguments, + /** + * Cache of the first argument - this is used often enough to be saved. + */ + args0 = _arguments[0] as VelocityObjectArgs, + /** + * To allow for expressive CoffeeScript code, Velocity supports an + * alternative syntax in which "elements" (or "e"), "properties" (or + * "p"), and "options" (or "o") objects are defined on a container + * object that's passed in as Velocity's sole argument. + * + * Note: Some browsers automatically populate arguments with a + * "properties" object. We detect it by checking for its default + * "names" property. + */ + // TODO: Confirm which browsers - if <=IE8 the we can drop completely + syntacticSugar = isPlainObject(args0) && (args0.p || ((isPlainObject(args0.properties) && !(args0.properties as any).names) || isString(args0.properties))); + let + /** + * When Velocity is called via the utility function (Velocity()), + * elements are explicitly passed in as the first parameter. Thus, + * argument positioning varies. + */ + argumentIndex: number = 0, + /** + * The list of elements, extended with Promise and Velocity. + */ + elements: VelocityResult, + /** + * The properties being animated. This can be a string, in which case it + * is either a function for these elements, or it is a "named" animation + * sequence to use instead. Named sequences start with either "callout." + * or "transition.". When used as a callout the values will be reset + * after finishing. When used as a transtition then there is no special + * handling after finishing. + */ + propertiesMap: string | VelocityProperties, + /** + * Options supplied, this will be mapped and validated into + * options. + */ + optionsMap: VelocityOptions, + /** + * If called via a chain then this contains the last calls + * animations. If this does not have a value then any access to the + * element's animations needs to be to the currently-running ones. + */ + animations: AnimationCall[], + /** + * The promise that is returned. + */ + promise: Promise, + // Used when the animation is finished + resolver: (value?: VelocityResult) => void, + // Used when there was an issue with one or more of the Velocity arguments + rejecter: (reason: any) => void; + + //console.log("Velocity", _arguments) + // First get the elements, and the animations connected to the last call if + // this is chained. + // TODO: Clean this up a bit + // TODO: Throw error if the chain is called with elements as the first argument. isVelocityResult(this) && ( (isNode(arg0) || isWrapped(arg0)) && arg0 == this) + if (isNode(this)) { + // This is from a chain such as document.getElementById("").velocity(...) + elements = [this as HTMLorSVGElement] as VelocityResult; + } else if (isWrapped(this)) { + // This might be a chain from something else, but if chained from a + // previous Velocity() call then grab the animations it's related to. + elements = Object.assign([], this as HTMLorSVGElement[]) as VelocityResult; + if (isVelocityResult(this)) { + animations = (this as VelocityResult).velocity.animations; + } + } else if (syntacticSugar) { + elements = Object.assign([], args0.elements || args0.e) as VelocityResult; + argumentIndex++; + } else if (isNode(args0)) { + elements = Object.assign([], [args0]) as VelocityResult; + argumentIndex++; + } else if (isWrapped(args0)) { + elements = Object.assign([], args0) as VelocityResult; + argumentIndex++; + } + // Allow elements to be chained. + if (elements) { + defineProperty(elements, "velocity", VelocityFn.bind(elements)); + if (animations) { + defineProperty(elements.velocity, "animations", animations); + } + } + // Next get the propertiesMap and options. + if (syntacticSugar) { + propertiesMap = getValue(args0.properties, args0.p); + } else { + // TODO: Should be possible to call Velocity("pauseAll") - currently not possible + propertiesMap = _arguments[argumentIndex++] as string | VelocityProperties; + } + // Get any options map passed in as arguments first, expand any direct + // options if possible. + const isAction = isString(propertiesMap), + opts = syntacticSugar ? getValue(args0.options, args0.o) : _arguments[argumentIndex]; + + if (isPlainObject(opts)) { + optionsMap = opts; + } + // Create the promise if supported and wanted. + if (Promise && getValue(optionsMap && optionsMap.promise, defaults.promise)) { + promise = new Promise(function(_resolve, _reject) { + rejecter = _reject; + // IMPORTANT: + // If a resolver tries to run on a Promise then it will wait until + // that Promise resolves - but in this case we're running on our own + // Promise, so need to make sure it's not seen as one. Setting these + // values to undefined for the duration of the resolve. + // Due to being an async call, they should be back to "normal" + // before the .then() function gets called. + resolver = function(args: VelocityResult) { + if (isVelocityResult(args)) { + const _then = args && args.then; + + if (_then) { + args.then = undefined; // Preserving enumeration etc + } + _resolve(args); + if (_then) { + args.then = _then; + } + } else { + _resolve(args); + } + }; + }); + if (elements) { + defineProperty(elements, "then", promise.then.bind(promise)); + defineProperty(elements, "catch", promise.catch.bind(promise)); + if ((promise as any).finally) { + // Semi-standard + defineProperty(elements, "finally", (promise as any).finally.bind(promise)); + } + } + } + const promiseRejectEmpty: boolean = getValue(optionsMap && optionsMap.promiseRejectEmpty, defaults.promiseRejectEmpty); + + if (promise) { + if (!elements && !isAction) { + if (promiseRejectEmpty) { + rejecter("Velocity: No elements supplied, if that is deliberate then pass `promiseRejectEmpty:false` as an option. Aborting."); + } else { + resolver(); + } + } else if (!propertiesMap) { + if (promiseRejectEmpty) { + rejecter("Velocity: No properties supplied, if that is deliberate then pass `promiseRejectEmpty:false` as an option. Aborting."); + } else { + resolver(); + } + } + } + if ((!elements && !isAction) || !propertiesMap) { + return promise as any; + } + + // TODO: exception for the special "reverse" property + // NOTE: Can't use isAction here due to type inference - there are callbacks + // between so the type isn't considered safe. + if (isString(propertiesMap)) { + const args: any[] = [], + promiseHandler: VelocityPromise = promise && { + _promise: promise, + _resolver: resolver, + _rejecter: rejecter + }; + + while (argumentIndex < _arguments.length) { + args.push(_arguments[argumentIndex++]); + } + + // Velocity's behavior is categorized into "actions". If a string is + // passed in instead of a propertiesMap then that will call a function + // to do something special to the animation linked. + // There is one special case - "reverse" - which is handled differently, + // by being stored on the animation and then expanded when the animation + // starts. + const action = propertiesMap.replace(/\..*$/, ""), + callback = VelocityStatic.Actions[action] || VelocityStatic.Actions["default"]; + + if (callback) { + const result = callback(args, elements, promiseHandler, propertiesMap); + + if (result !== undefined) { + return result; + } + } else { + console.warn("VelocityJS: Unknown action:", propertiesMap); + } + } else if (isPlainObject(propertiesMap)) { + /** + * The options for this set of animations. + */ + const options: StrictVelocityOptions = {}; + let isSync = defaults.sync; + + // Private options first - set as non-enumerable, and starting with an + // underscore so we can filter them out. + if (promise) { + defineProperty(options, "_promise", promise); + defineProperty(options, "_rejecter", rejecter); + defineProperty(options, "_resolver", resolver); + } + defineProperty(options, "_ready", 0); + defineProperty(options, "_started", 0); + defineProperty(options, "_completed", 0); + defineProperty(options, "_total", 0); + + // Now check the optionsMap + if (isPlainObject(optionsMap)) { + options.duration = getValue(validateDuration(optionsMap.duration), defaults.duration); + options.delay = getValue(validateDelay(optionsMap.delay), defaults.delay); + // Need the extra fallback here in case it supplies an invalid + // easing that we need to overrride with the default. + options.easing = validateEasing(getValue(optionsMap.easing, defaults.easing), options.duration) || validateEasing(defaults.easing, options.duration); + options.loop = getValue(validateLoop(optionsMap.loop), defaults.loop); + options.repeat = options.repeatAgain = getValue(validateRepeat(optionsMap.repeat), defaults.repeat); + if (optionsMap.speed != null) { + options.speed = getValue(validateSpeed(optionsMap.speed), 1); + } + if (isBoolean(optionsMap.promise)) { + options.promise = optionsMap.promise; + } + options.queue = getValue(validateQueue(optionsMap.queue), defaults.queue); + if (optionsMap.mobileHA && !VelocityStatic.State.isGingerbread) { + /* When set to true, and if this is a mobile device, mobileHA automatically enables hardware acceleration (via a null transform hack) + on animating elements. HA is removed from the element at the completion of its animation. */ + /* Note: Android Gingerbread doesn't support HA. If a null transform hack (mobileHA) is in fact set, it will prevent other tranform subproperties from taking effect. */ + /* Note: You can read more about the use of mobileHA in Velocity's documentation: VelocityJS.org/#mobileHA. */ + options.mobileHA = true; + } + if (optionsMap.display != null) { + (propertiesMap as VelocityProperties).display = optionsMap.display as string; + console.error("Deprecated 'options.display' used, this is now a property:", optionsMap.display); + } + if (optionsMap.visibility != null) { + (propertiesMap as VelocityProperties).visibility = optionsMap.visibility as string; + console.error("Deprecated 'options.visibility' used, this is now a property:", optionsMap.visibility); + } + // TODO: Allow functional options for different options per element + const optionsBegin = validateBegin(optionsMap.begin), + optionsComplete = validateComplete(optionsMap.complete), + optionsProgress = validateProgress(optionsMap.progress), + optionsSync = validateSync(optionsMap.sync); + + if (optionsBegin != null) { + options.begin = optionsBegin; + } + if (optionsComplete != null) { + options.complete = optionsComplete; + } + if (optionsProgress != null) { + options.progress = optionsProgress; + } + if (optionsSync != null) { + isSync = optionsSync; + } + } else if (!syntacticSugar) { + // Expand any direct options if possible. + const duration = validateDuration(_arguments[argumentIndex], true); + let offset = 0; + + if (duration !== undefined) { + offset++; + options.duration = duration; + } + if (!isFunction(_arguments[argumentIndex + offset])) { + // Despite coming before Complete, we can't pass a fn easing + const easing = validateEasing(_arguments[argumentIndex + offset], getValue(options && validateDuration(options.duration), defaults.duration) as number, true); + + if (easing !== undefined) { + offset++; + options.easing = easing; + } + } + const complete = validateComplete(_arguments[argumentIndex + offset], true); + + if (complete !== undefined) { + options.complete = complete; + } + options.loop = defaults.loop; + options.repeat = options.repeatAgain = defaults.repeat; + } + + /* When a set of elements is targeted by a Velocity call, the set is broken up and each element has the current Velocity call individually queued onto it. + In this way, each element's existing queue is respected; some elements may already be animating and accordingly should not have this current Velocity call triggered immediately. */ + /* In each queue, tween data is processed for each animating property then pushed onto the call-wide calls array. When the last element in the set has had its tweens processed, + the call array is pushed to VelocityStatic.State.calls for live processing by the requestAnimationFrame tick. */ + + const rootAnimation: AnimationCall = { + _prev: undefined, + _next: undefined, + _flags: isSync ? AnimationFlags.SYNC : 0, + options: options, + percentComplete: 0, + //element: element, + elements: elements, + ellapsedTime: 0, + timeStart: 0 + }; + + animations = []; + for (let index = 0; index < elements.length; index++) { + const element = elements[index]; + + if (isNode(element)) { + const tweens = Object.create(null), + animation: AnimationCall = Object.assign({ + element: element, + tweens: tweens + }, rootAnimation); + + options._total++; + animations.push(animation); + VelocityStatic.expandProperties(animation, propertiesMap); + VelocityStatic.queue(element, animation, getValue(animation.queue, options.queue)); + } + } + if (VelocityStatic.State.isTicking === false) { + // If the animation tick isn't running, start it. (Velocity shuts it + // off when there are no active calls to process.) + VelocityStatic.tick(); + } + if (animations) { + defineProperty(elements.velocity, "animations", animations); + } + } + /*************** + Chaining + ***************/ + + /* Return the elements back to the call chain, with wrapped elements taking precedence in case Velocity was called via the $.fn. extension. */ + return elements || promise as any; +}; + + +/*************** + Summary + ***************/ + +/* + - CSS: CSS stack that works independently from the rest of Velocity. + - animate(): Core animation method that iterates over the targeted elements and queues the incoming call onto each element individually. + - Pre-Queueing: Prepare the element for animation by instantiating its data cache and processing the call's options. + - Queueing: The logic that runs once the call has reached its point of execution in the element's queue stack. + Most logic is placed here to avoid risking it becoming stale (if the element's properties have changed). + - Pushing: Consolidation of the tween data followed by its push onto the global in-progress calls container. + - tick(): The single requestAnimationFrame loop responsible for tweening all in-progress calls. + - completeCall(): Handles the cleanup process for each Velocity call. + */ + +/********************* + Helper Functions + *********************/ + +/* IE detection. Gist: https://gist.github.com/julianshapiro/9098609 */ +var IE = (function() { + if (document.documentMode) { + return document.documentMode; + } else { + for (let i = 7; i > 4; i--) { + let div = document.createElement("div"); + + div.innerHTML = ""; + if (div.getElementsByTagName("span").length) { + div = null; + return i; + } + } + } + + return undefined; +})(); + +/****************** + Unsupported + ******************/ + +if (IE <= 8) { + throw new Error("VelocityJS cannot run on Internet Explorer 8 or earlier"); +} + +/****************** + Frameworks + ******************/ + +interface Window { + jQuery: {fn?: any}; + Zepto: {fn?: any}; + Velocity: any; +} + +if (window === this) { + /* + * Both jQuery and Zepto allow their $.fn object to be extended to allow + * wrapped elements to be subjected to plugin calls. If either framework is + * loaded, register a "velocity" extension pointing to Velocity's core + * animate() method. Velocity also registers itself onto a global container + * (window.jQuery || window.Zepto || window) so that certain features are + * accessible beyond just a per-element scope. Accordingly, Velocity can + * both act on wrapped DOM elements and stand alone for targeting raw DOM + * elements. + */ + const patch = VelocityStatic.patch, + jQuery = window.jQuery, + Zepto = window.Zepto; + + patch(window, true); + patch(Element && Element.prototype); + patch(NodeList && NodeList.prototype); + patch(HTMLCollection && HTMLCollection.prototype); + + patch(jQuery, true); + patch(jQuery && jQuery.fn); + + patch(Zepto, true); + patch(Zepto && Zepto.fn); +} + +/****************** + Known Issues + ******************/ + +/* The CSS spec mandates that the translateX/Y/Z transforms are %-relative to the element itself -- not its parent. + Velocity, however, doesn't make this distinction. Thus, converting to or from the % unit with these subproperties + will produce an inaccurate conversion value. The same issue exists with the cx/cy attributes of SVG circles and ellipses. */ diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 00000000..3442a7da --- /dev/null +++ b/src/types.ts @@ -0,0 +1,79 @@ +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + * + * Runtime type checking methods. + */ + +function isBoolean(variable): variable is boolean { + return variable === true || variable === false; +} + +function isNumber(variable): variable is number { + return typeof variable === "number"; +} + +/** + * Faster way to parse a string/number as a number https://jsperf.com/number-vs-parseint-vs-plus/3 + * @param variable The given string or number + * @returns {variable is number} Returns boolean true if it is a number, false otherwise + */ +function isNumberWhenParsed(variable: string | number): variable is number { + return !isNaN(Number(variable)); +} + +function isString(variable): variable is string { + return typeof variable === "string"; +} + +function isFunction(variable): variable is Function { + return Object.prototype.toString.call(variable) === "[object Function]"; +} + +function isNode(variable): variable is HTMLorSVGElement { + return !!(variable && variable.nodeType); +} + +function isVelocityResult(variable): variable is VelocityResult { + return variable && isNumber(variable.length) && isFunction((variable as VelocityResult).velocity); +} + +function propertyIsEnumerable(object: Object, property: string): boolean { + return Object.prototype.propertyIsEnumerable.call(object, property); +} + +/* Determine if variable is an array-like wrapped jQuery, Zepto or similar element, or even a NodeList etc. */ + +/* NOTE: HTMLFormElements also have a length. */ +function isWrapped(variable): variable is HTMLorSVGElement[] { + return variable + && variable !== window + && isNumber(variable.length) + && !isString(variable) + && !isFunction(variable) + && !isNode(variable) + && (variable.length === 0 || isNode(variable[0])); +} + +function isSVG(variable): variable is SVGElement { + return SVGElement && variable instanceof SVGElement; +} + +function isPlainObject(variable): variable is {} { + if (!variable || typeof variable !== "object" || variable.nodeType || Object.prototype.toString.call(variable) !== "[object Object]") { + return false; + } + let proto = Object.getPrototypeOf(variable) as Object; + + return !proto || (proto.hasOwnProperty("constructor") && proto.constructor === Object); +} + +function isEmptyObject(variable): variable is {} { + for (let name in variable) { + if (variable.hasOwnProperty(name)) { + return false; + } + } + return true; +} diff --git a/src/utility.ts b/src/utility.ts new file mode 100644 index 00000000..a9514a1b --- /dev/null +++ b/src/utility.ts @@ -0,0 +1,131 @@ +/* + * VelocityJS.org (C) 2014-2017 Julian Shapiro. + * + * Licensed under the MIT license. See LICENSE file in the project root for details. + */ + +/** + * The defineProperty() function provides a + * shortcut to defining a property that cannot be accidentally iterated across. + */ +function defineProperty(proto: any, name: string, value: Function | any) { + if (proto) { + Object.defineProperty(proto, name, { + configurable: true, + writable: true, + value: value + }); + } +} + +/** + * Perform a deep copy of an object - also copies children so they're not + * going to be affected by changing original. + */ +function _deepCopyObject(target: T, ...sources: U[]): T & U { + if (target == null) { // TypeError if undefined or null + throw new TypeError("Cannot convert undefined or null to object"); + } + const to = Object(target), + hasOwnProperty = Object.prototype.hasOwnProperty; + let source: any; + + while ((source = sources.shift())) { + if (source != null) { + for (const key in source) { + if (hasOwnProperty.call(source, key)) { + const value = source[key]; + + if (Array.isArray(value)) { + _deepCopyObject(to[key] = [], value); + } else if (isPlainObject(value)) { + _deepCopyObject(to[key] = {}, value); + } else { + to[key] = value; + } + } + } + } + } + return to; +} + +/** + * Shim to get the current milliseconds - on anything except old IE it'll use + * Date.now() and save creating an object. If that doesn't exist then it'll + * create one that gets GC. + */ +const _now = Date.now ? Date.now : function() { + return (new Date()).getTime(); +}; + +/** + * Check whether a value belongs to an array + * https://jsperf.com/includes-vs-indexof-vs-while-loop/6 + * @param array The given array + * @param value The given element to check if it is part of the array + * @returns {boolean} True if it exists, false otherwise + */ +function _inArray(array: T[], value: T): boolean { + let i = 0; + + while (i < array.length) { + if (array[i++] === value) { + return true; + } + } + return false; +} + +/** + * Convert an element or array-like element list into an array if needed. + */ +function sanitizeElements(elements: HTMLorSVGElement | HTMLorSVGElement[]): HTMLorSVGElement[] { + if (isNode(elements)) { + return [elements]; + } + return elements as HTMLorSVGElement[]; +} + +/** + * When there are multiple locations for a value pass them all in, then get the + * first value that is valid. + */ +function getValue(...args: T[]): T; +function getValue(args: any): T { + for (let i = 0, _args = arguments; i < _args.length; i++) { + const _arg = _args[i]; + + if (_arg !== undefined && _arg === _arg) { + return _arg; + } + } +} + +/** + * Add a single className to an Element. + */ +function addClass(element: HTMLorSVGElement, className: string): void { + if (element instanceof Element) { + if (element.classList) { + element.classList.add(className); + } else { + removeClass(element, className); + element.className += (element.className.length ? " " : "") + className; + } + } +} + +/** + * Remove a single className from an Element. + */ +function removeClass(element: HTMLorSVGElement, className: string): void { + if (element instanceof Element) { + if (element.classList) { + element.classList.remove(className); + } else { + // TODO: Need some jsperf tests on performance - can we get rid of the regex and maybe use split / array manipulation? + element.className = element.className.toString().replace(new RegExp("(^|\\s)" + className + "(\\s|$)", "gi"), " "); + } + } +} diff --git a/test/bluebird.js b/test/bluebird.js deleted file mode 100644 index ec656afc..00000000 --- a/test/bluebird.js +++ /dev/null @@ -1,5176 +0,0 @@ -/** - * bluebird build version 2.2.1 - * Features enabled: core, race, call_get, generators, map, nodeify, promisify, props, reduce, settle, some, progress, cancel, using, filter, any, each, timers -*/ -/** - * @preserve Copyright (c) 2014 Petka Antonov - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions:

- * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ -!function(e){"object"==typeof exports?module.exports=e():"function"==typeof define&&define.amd?define(e):"undefined"!=typeof window?window.Promise=e():"undefined"!=typeof global?global.Promise=e():"undefined"!=typeof self&&(self.Promise=e())}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o - * - * 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. - * - */ -"use strict"; -module.exports = function(Promise) { -var SomePromiseArray = Promise._SomePromiseArray; -function Promise$_Any(promises) { - var ret = new SomePromiseArray(promises); - var promise = ret.promise(); - if (promise.isRejected()) { - return promise; - } - ret.setHowMany(1); - ret.setUnwrap(); - ret.init(); - return promise; -} - -Promise.any = function Promise$Any(promises) { - return Promise$_Any(promises); -}; - -Promise.prototype.any = function Promise$any() { - return Promise$_Any(this); -}; - -}; - -},{}],2:[function(require,module,exports){ -/** - * Copyright (c) 2014 Petka Antonov - * - * 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. - * - */ -"use strict"; -var schedule = require("./schedule.js"); -var Queue = require("./queue.js"); -var errorObj = require("./util.js").errorObj; -var tryCatch1 = require("./util.js").tryCatch1; -var _process = typeof process !== "undefined" ? process : void 0; - -function Async() { - this._isTickUsed = false; - this._schedule = schedule; - this._length = 0; - this._lateBuffer = new Queue(16); - this._functionBuffer = new Queue(65536); - var self = this; - this.consumeFunctionBuffer = function Async$consumeFunctionBuffer() { - self._consumeFunctionBuffer(); - }; -} - -Async.prototype.haveItemsQueued = function Async$haveItemsQueued() { - return this._length > 0; -}; - -Async.prototype.invokeLater = function Async$invokeLater(fn, receiver, arg) { - if (_process !== void 0 && - _process.domain != null && - !fn.domain) { - fn = _process.domain.bind(fn); - } - this._lateBuffer.push(fn, receiver, arg); - this._queueTick(); -}; - -Async.prototype.invoke = function Async$invoke(fn, receiver, arg) { - if (_process !== void 0 && - _process.domain != null && - !fn.domain) { - fn = _process.domain.bind(fn); - } - var functionBuffer = this._functionBuffer; - functionBuffer.push(fn, receiver, arg); - this._length = functionBuffer.length(); - this._queueTick(); -}; - -Async.prototype._consumeFunctionBuffer = -function Async$_consumeFunctionBuffer() { - var functionBuffer = this._functionBuffer; - while (functionBuffer.length() > 0) { - var fn = functionBuffer.shift(); - var receiver = functionBuffer.shift(); - var arg = functionBuffer.shift(); - fn.call(receiver, arg); - } - this._reset(); - this._consumeLateBuffer(); -}; - -Async.prototype._consumeLateBuffer = function Async$_consumeLateBuffer() { - var buffer = this._lateBuffer; - while(buffer.length() > 0) { - var fn = buffer.shift(); - var receiver = buffer.shift(); - var arg = buffer.shift(); - var res = tryCatch1(fn, receiver, arg); - if (res === errorObj) { - this._queueTick(); - if (fn.domain != null) { - fn.domain.emit("error", res.e); - } else { - throw res.e; - } - } - } -}; - -Async.prototype._queueTick = function Async$_queue() { - if (!this._isTickUsed) { - this._schedule(this.consumeFunctionBuffer); - this._isTickUsed = true; - } -}; - -Async.prototype._reset = function Async$_reset() { - this._isTickUsed = false; - this._length = 0; -}; - -module.exports = new Async(); - -},{"./queue.js":25,"./schedule.js":28,"./util.js":35}],3:[function(require,module,exports){ -/** - * Copyright (c) 2014 Petka Antonov - * - * 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. - * - */ -"use strict"; -var Promise = require("./promise.js")(); -module.exports = Promise; -},{"./promise.js":20}],4:[function(require,module,exports){ -/** - * Copyright (c) 2014 Petka Antonov - * - * 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. - * - */ -"use strict"; -var cr = Object.create; -var callerCache = cr && cr(null); -var getterCache = cr && cr(null); -callerCache[" size"] = getterCache[" size"] = 0; -module.exports = function(Promise) { -var util = require("./util.js"); -var canEvaluate = util.canEvaluate; -var isIdentifier = util.isIdentifier; - -function makeMethodCaller (methodName) { - return new Function("obj", " \n\ - 'use strict' \n\ - var len = this.length; \n\ - switch(len) { \n\ - case 1: return obj.methodName(this[0]); \n\ - case 2: return obj.methodName(this[0], this[1]); \n\ - case 3: return obj.methodName(this[0], this[1], this[2]); \n\ - case 0: return obj.methodName(); \n\ - default: return obj.methodName.apply(obj, this); \n\ - } \n\ - ".replace(/methodName/g, methodName)); -} - -function makeGetter (propertyName) { - return new Function("obj", " \n\ - 'use strict'; \n\ - return obj.propertyName; \n\ - ".replace("propertyName", propertyName)); -} - -function getCompiled(name, compiler, cache) { - var ret = cache[name]; - if (typeof ret !== "function") { - if (!isIdentifier(name)) { - return null; - } - ret = compiler(name); - cache[name] = ret; - cache[" size"]++; - if (cache[" size"] > 512) { - var keys = Object.keys(cache); - for (var i = 0; i < 256; ++i) delete cache[keys[i]]; - cache[" size"] = keys.length - 256; - } - } - return ret; -} - -function getMethodCaller(name) { - return getCompiled(name, makeMethodCaller, callerCache); -} - -function getGetter(name) { - return getCompiled(name, makeGetter, getterCache); -} - -function caller(obj) { - return obj[this.pop()].apply(obj, this); -} -Promise.prototype.call = function Promise$call(methodName) { - var $_len = arguments.length;var args = new Array($_len - 1); for(var $_i = 1; $_i < $_len; ++$_i) {args[$_i - 1] = arguments[$_i];} - if (canEvaluate) { - var maybeCaller = getMethodCaller(methodName); - if (maybeCaller !== null) { - return this._then(maybeCaller, void 0, void 0, args, void 0); - } - } - args.push(methodName); - return this._then(caller, void 0, void 0, args, void 0); -}; - -function namedGetter(obj) { - return obj[this]; -} -function indexedGetter(obj) { - return obj[this]; -} -Promise.prototype.get = function Promise$get(propertyName) { - var isIndex = (typeof propertyName === "number"); - var getter; - if (!isIndex) { - if (canEvaluate) { - var maybeGetter = getGetter(propertyName); - getter = maybeGetter !== null ? maybeGetter : namedGetter; - } else { - getter = namedGetter; - } - } else { - getter = indexedGetter; - } - return this._then(getter, void 0, void 0, propertyName, void 0); -}; -}; - -},{"./util.js":35}],5:[function(require,module,exports){ -/** - * Copyright (c) 2014 Petka Antonov - * - * 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. - * - */ -"use strict"; -module.exports = function(Promise, INTERNAL) { -var errors = require("./errors.js"); -var canAttach = errors.canAttach; -var async = require("./async.js"); -var CancellationError = errors.CancellationError; - -Promise.prototype._cancel = function Promise$_cancel(reason) { - if (!this.isCancellable()) return this; - var parent; - var promiseToReject = this; - while ((parent = promiseToReject._cancellationParent) !== void 0 && - parent.isCancellable()) { - promiseToReject = parent; - } - promiseToReject._attachExtraTrace(reason); - promiseToReject._rejectUnchecked(reason); -}; - -Promise.prototype.cancel = function Promise$cancel(reason) { - if (!this.isCancellable()) return this; - reason = reason !== void 0 - ? (canAttach(reason) ? reason : new Error(reason + "")) - : new CancellationError(); - async.invokeLater(this._cancel, this, reason); - return this; -}; - -Promise.prototype.cancellable = function Promise$cancellable() { - if (this._cancellable()) return this; - this._setCancellable(); - this._cancellationParent = void 0; - return this; -}; - -Promise.prototype.uncancellable = function Promise$uncancellable() { - var ret = new Promise(INTERNAL); - ret._propagateFrom(this, 2 | 4); - ret._follow(this); - ret._unsetCancellable(); - return ret; -}; - -Promise.prototype.fork = -function Promise$fork(didFulfill, didReject, didProgress) { - var ret = this._then(didFulfill, didReject, didProgress, - void 0, void 0); - - ret._setCancellable(); - ret._cancellationParent = void 0; - return ret; -}; -}; - -},{"./async.js":2,"./errors.js":10}],6:[function(require,module,exports){ -/** - * Copyright (c) 2014 Petka Antonov - * - * 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. - * - */ -"use strict"; -module.exports = function() { -var inherits = require("./util.js").inherits; -var defineProperty = require("./es5.js").defineProperty; - -var rignore = new RegExp( - "\\b(?:[a-zA-Z0-9.]+\\$_\\w+|" + - "tryCatch(?:1|2|3|4|Apply)|new \\w*PromiseArray|" + - "\\w*PromiseArray\\.\\w*PromiseArray|" + - "setTimeout|CatchFilter\\$_\\w+|makeNodePromisified|processImmediate|" + - "process._tickCallback|nextTick|Async\\$\\w+)\\b" -); - -var rtraceline = null; -var formatStack = null; - -function formatNonError(obj) { - var str; - if (typeof obj === "function") { - str = "[function " + - (obj.name || "anonymous") + - "]"; - } else { - str = obj.toString(); - var ruselessToString = /\[object [a-zA-Z0-9$_]+\]/; - if (ruselessToString.test(str)) { - try { - var newStr = JSON.stringify(obj); - str = newStr; - } - catch(e) { - - } - } - if (str.length === 0) { - str = "(empty array)"; - } - } - return ("(<" + snip(str) + ">, no stack trace)"); -} - -function snip(str) { - var maxChars = 41; - if (str.length < maxChars) { - return str; - } - return str.substr(0, maxChars - 3) + "..."; -} - -function CapturedTrace(ignoreUntil, isTopLevel) { - this.captureStackTrace(CapturedTrace, isTopLevel); - -} -inherits(CapturedTrace, Error); - -CapturedTrace.prototype.captureStackTrace = -function CapturedTrace$captureStackTrace(ignoreUntil, isTopLevel) { - captureStackTrace(this, ignoreUntil, isTopLevel); -}; - -CapturedTrace.possiblyUnhandledRejection = -function CapturedTrace$PossiblyUnhandledRejection(reason) { - if (typeof console === "object") { - var message; - if (typeof reason === "object" || typeof reason === "function") { - var stack = reason.stack; - message = "Possibly unhandled " + formatStack(stack, reason); - } else { - message = "Possibly unhandled " + String(reason); - } - if (typeof console.error === "function" || - typeof console.error === "object") { - console.error(message); - } else if (typeof console.log === "function" || - typeof console.log === "object") { - console.log(message); - } - } -}; - -CapturedTrace.combine = function CapturedTrace$Combine(current, prev) { - var curLast = current.length - 1; - for (var i = prev.length - 1; i >= 0; --i) { - var line = prev[i]; - if (current[curLast] === line) { - current.pop(); - curLast--; - } else { - break; - } - } - - current.push("From previous event:"); - var lines = current.concat(prev); - - var ret = []; - - for (var i = 0, len = lines.length; i < len; ++i) { - - if ((rignore.test(lines[i]) || - (i > 0 && !rtraceline.test(lines[i])) && - lines[i] !== "From previous event:") - ) { - continue; - } - ret.push(lines[i]); - } - return ret; -}; - -CapturedTrace.protectErrorMessageNewlines = function(stack) { - for (var i = 0; i < stack.length; ++i) { - if (rtraceline.test(stack[i])) { - break; - } - } - - if (i <= 1) return; - - var errorMessageLines = []; - for (var j = 0; j < i; ++j) { - errorMessageLines.push(stack.shift()); - } - stack.unshift(errorMessageLines.join("\u0002\u0000\u0001")); -}; - -CapturedTrace.isSupported = function CapturedTrace$IsSupported() { - return typeof captureStackTrace === "function"; -}; - -var captureStackTrace = (function stackDetection() { - if (typeof Error.stackTraceLimit === "number" && - typeof Error.captureStackTrace === "function") { - rtraceline = /^\s*at\s*/; - formatStack = function(stack, error) { - if (typeof stack === "string") return stack; - - if (error.name !== void 0 && - error.message !== void 0) { - return error.name + ". " + error.message; - } - return formatNonError(error); - - - }; - var captureStackTrace = Error.captureStackTrace; - return function CapturedTrace$_captureStackTrace( - receiver, ignoreUntil) { - captureStackTrace(receiver, ignoreUntil); - }; - } - var err = new Error(); - - if (typeof err.stack === "string" && - typeof "".startsWith === "function" && - (err.stack.startsWith("stackDetection@")) && - stackDetection.name === "stackDetection") { - - defineProperty(Error, "stackTraceLimit", { - writable: true, - enumerable: false, - configurable: false, - value: 25 - }); - rtraceline = /@/; - var rline = /[@\n]/; - - formatStack = function(stack, error) { - if (typeof stack === "string") { - return (error.name + ". " + error.message + "\n" + stack); - } - - if (error.name !== void 0 && - error.message !== void 0) { - return error.name + ". " + error.message; - } - return formatNonError(error); - }; - - return function captureStackTrace(o) { - var stack = new Error().stack; - var split = stack.split(rline); - var len = split.length; - var ret = ""; - for (var i = 0; i < len; i += 2) { - ret += split[i]; - ret += "@"; - ret += split[i + 1]; - ret += "\n"; - } - o.stack = ret; - }; - } else { - formatStack = function(stack, error) { - if (typeof stack === "string") return stack; - - if ((typeof error === "object" || - typeof error === "function") && - error.name !== void 0 && - error.message !== void 0) { - return error.name + ". " + error.message; - } - return formatNonError(error); - }; - - return null; - } -})(); - -return CapturedTrace; -}; - -},{"./es5.js":12,"./util.js":35}],7:[function(require,module,exports){ -/** - * Copyright (c) 2014 Petka Antonov - * - * 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. - * - */ -"use strict"; -module.exports = function(NEXT_FILTER) { -var util = require("./util.js"); -var errors = require("./errors.js"); -var tryCatch1 = util.tryCatch1; -var errorObj = util.errorObj; -var keys = require("./es5.js").keys; -var TypeError = errors.TypeError; - -function CatchFilter(instances, callback, promise) { - this._instances = instances; - this._callback = callback; - this._promise = promise; -} - -function CatchFilter$_safePredicate(predicate, e) { - var safeObject = {}; - var retfilter = tryCatch1(predicate, safeObject, e); - - if (retfilter === errorObj) return retfilter; - - var safeKeys = keys(safeObject); - if (safeKeys.length) { - errorObj.e = new TypeError( - "Catch filter must inherit from Error " - + "or be a simple predicate function"); - return errorObj; - } - return retfilter; -} - -CatchFilter.prototype.doFilter = function CatchFilter$_doFilter(e) { - var cb = this._callback; - var promise = this._promise; - var boundTo = promise._boundTo; - for (var i = 0, len = this._instances.length; i < len; ++i) { - var item = this._instances[i]; - var itemIsErrorType = item === Error || - (item != null && item.prototype instanceof Error); - - if (itemIsErrorType && e instanceof item) { - var ret = tryCatch1(cb, boundTo, e); - if (ret === errorObj) { - NEXT_FILTER.e = ret.e; - return NEXT_FILTER; - } - return ret; - } else if (typeof item === "function" && !itemIsErrorType) { - var shouldHandle = CatchFilter$_safePredicate(item, e); - if (shouldHandle === errorObj) { - var trace = errors.canAttach(errorObj.e) - ? errorObj.e - : new Error(errorObj.e + ""); - this._promise._attachExtraTrace(trace); - e = errorObj.e; - break; - } else if (shouldHandle) { - var ret = tryCatch1(cb, boundTo, e); - if (ret === errorObj) { - NEXT_FILTER.e = ret.e; - return NEXT_FILTER; - } - return ret; - } - } - } - NEXT_FILTER.e = e; - return NEXT_FILTER; -}; - -return CatchFilter; -}; - -},{"./errors.js":10,"./es5.js":12,"./util.js":35}],8:[function(require,module,exports){ -/** - * Copyright (c) 2014 Petka Antonov - * - * 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. - * - */ -"use strict"; -var util = require("./util.js"); -var isPrimitive = util.isPrimitive; -var wrapsPrimitiveReceiver = util.wrapsPrimitiveReceiver; - -module.exports = function(Promise) { -var returner = function Promise$_returner() { - return this; -}; -var thrower = function Promise$_thrower() { - throw this; -}; - -var wrapper = function Promise$_wrapper(value, action) { - if (action === 1) { - return function Promise$_thrower() { - throw value; - }; - } else if (action === 2) { - return function Promise$_returner() { - return value; - }; - } -}; - - -Promise.prototype["return"] = -Promise.prototype.thenReturn = -function Promise$thenReturn(value) { - if (wrapsPrimitiveReceiver && isPrimitive(value)) { - return this._then( - wrapper(value, 2), - void 0, - void 0, - void 0, - void 0 - ); - } - return this._then(returner, void 0, void 0, value, void 0); -}; - -Promise.prototype["throw"] = -Promise.prototype.thenThrow = -function Promise$thenThrow(reason) { - if (wrapsPrimitiveReceiver && isPrimitive(reason)) { - return this._then( - wrapper(reason, 1), - void 0, - void 0, - void 0, - void 0 - ); - } - return this._then(thrower, void 0, void 0, reason, void 0); -}; -}; - -},{"./util.js":35}],9:[function(require,module,exports){ -/** - * Copyright (c) 2014 Petka Antonov - * - * 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. - * - */ -"use strict"; -module.exports = function(Promise, INTERNAL) { -var PromiseReduce = Promise.reduce; - -Promise.prototype.each = function Promise$each(fn) { - return PromiseReduce(this, fn, null, INTERNAL); -}; - -Promise.each = function Promise$Each(promises, fn) { - return PromiseReduce(promises, fn, null, INTERNAL); -}; -}; - -},{}],10:[function(require,module,exports){ -/** - * Copyright (c) 2014 Petka Antonov - * - * 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. - * - */ -"use strict"; -var Objectfreeze = require("./es5.js").freeze; -var util = require("./util.js"); -var inherits = util.inherits; -var notEnumerableProp = util.notEnumerableProp; - -function markAsOriginatingFromRejection(e) { - try { - notEnumerableProp(e, "isOperational", true); - } - catch(ignore) {} -} - -function originatesFromRejection(e) { - if (e == null) return false; - return ((e instanceof OperationalError) || - e["isOperational"] === true); -} - -function isError(obj) { - return obj instanceof Error; -} - -function canAttach(obj) { - return isError(obj); -} - -function subError(nameProperty, defaultMessage) { - function SubError(message) { - if (!(this instanceof SubError)) return new SubError(message); - this.message = typeof message === "string" ? message : defaultMessage; - this.name = nameProperty; - if (Error.captureStackTrace) { - Error.captureStackTrace(this, this.constructor); - } - } - inherits(SubError, Error); - return SubError; -} - -var _TypeError, _RangeError; -var CancellationError = subError("CancellationError", "cancellation error"); -var TimeoutError = subError("TimeoutError", "timeout error"); -var AggregateError = subError("AggregateError", "aggregate error"); -try { - _TypeError = TypeError; - _RangeError = RangeError; -} catch(e) { - _TypeError = subError("TypeError", "type error"); - _RangeError = subError("RangeError", "range error"); -} - -var methods = ("join pop push shift unshift slice filter forEach some " + - "every map indexOf lastIndexOf reduce reduceRight sort reverse").split(" "); - -for (var i = 0; i < methods.length; ++i) { - if (typeof Array.prototype[methods[i]] === "function") { - AggregateError.prototype[methods[i]] = Array.prototype[methods[i]]; - } -} - -AggregateError.prototype.length = 0; -AggregateError.prototype["isOperational"] = true; -var level = 0; -AggregateError.prototype.toString = function() { - var indent = Array(level * 4 + 1).join(" "); - var ret = "\n" + indent + "AggregateError of:" + "\n"; - level++; - indent = Array(level * 4 + 1).join(" "); - for (var i = 0; i < this.length; ++i) { - var str = this[i] === this ? "[Circular AggregateError]" : this[i] + ""; - var lines = str.split("\n"); - for (var j = 0; j < lines.length; ++j) { - lines[j] = indent + lines[j]; - } - str = lines.join("\n"); - ret += str + "\n"; - } - level--; - return ret; -}; - -function OperationalError(message) { - this.name = "OperationalError"; - this.message = message; - this.cause = message; - this["isOperational"] = true; - - if (message instanceof Error) { - this.message = message.message; - this.stack = message.stack; - } else if (Error.captureStackTrace) { - Error.captureStackTrace(this, this.constructor); - } - -} -inherits(OperationalError, Error); - -var key = "__BluebirdErrorTypes__"; -var errorTypes = Error[key]; -if (!errorTypes) { - errorTypes = Objectfreeze({ - CancellationError: CancellationError, - TimeoutError: TimeoutError, - OperationalError: OperationalError, - RejectionError: OperationalError, - AggregateError: AggregateError - }); - notEnumerableProp(Error, key, errorTypes); -} - -module.exports = { - Error: Error, - TypeError: _TypeError, - RangeError: _RangeError, - CancellationError: errorTypes.CancellationError, - OperationalError: errorTypes.OperationalError, - TimeoutError: errorTypes.TimeoutError, - AggregateError: errorTypes.AggregateError, - originatesFromRejection: originatesFromRejection, - markAsOriginatingFromRejection: markAsOriginatingFromRejection, - canAttach: canAttach -}; - -},{"./es5.js":12,"./util.js":35}],11:[function(require,module,exports){ -/** - * Copyright (c) 2014 Petka Antonov - * - * 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. - * - */ -"use strict"; -module.exports = function(Promise) { -var TypeError = require('./errors.js').TypeError; - -function apiRejection(msg) { - var error = new TypeError(msg); - var ret = Promise.rejected(error); - var parent = ret._peekContext(); - if (parent != null) { - parent._attachExtraTrace(error); - } - return ret; -} - -return apiRejection; -}; - -},{"./errors.js":10}],12:[function(require,module,exports){ -/** - * Copyright (c) 2014 Petka Antonov - * - * 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. - * - */ -var isES5 = (function(){ - "use strict"; - return this === void 0; -})(); - -if (isES5) { - module.exports = { - freeze: Object.freeze, - defineProperty: Object.defineProperty, - keys: Object.keys, - getPrototypeOf: Object.getPrototypeOf, - isArray: Array.isArray, - isES5: isES5 - }; -} else { - var has = {}.hasOwnProperty; - var str = {}.toString; - var proto = {}.constructor.prototype; - - var ObjectKeys = function ObjectKeys(o) { - var ret = []; - for (var key in o) { - if (has.call(o, key)) { - ret.push(key); - } - } - return ret; - } - - var ObjectDefineProperty = function ObjectDefineProperty(o, key, desc) { - o[key] = desc.value; - return o; - } - - var ObjectFreeze = function ObjectFreeze(obj) { - return obj; - } - - var ObjectGetPrototypeOf = function ObjectGetPrototypeOf(obj) { - try { - return Object(obj).constructor.prototype; - } - catch (e) { - return proto; - } - } - - var ArrayIsArray = function ArrayIsArray(obj) { - try { - return str.call(obj) === "[object Array]"; - } - catch(e) { - return false; - } - } - - module.exports = { - isArray: ArrayIsArray, - keys: ObjectKeys, - defineProperty: ObjectDefineProperty, - freeze: ObjectFreeze, - getPrototypeOf: ObjectGetPrototypeOf, - isES5: isES5 - }; -} - -},{}],13:[function(require,module,exports){ -/** - * Copyright (c) 2014 Petka Antonov - * - * 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. - * - */ -"use strict"; -module.exports = function(Promise, INTERNAL) { -var PromiseMap = Promise.map; - -Promise.prototype.filter = function Promise$filter(fn, options) { - return PromiseMap(this, fn, options, INTERNAL); -}; - -Promise.filter = function Promise$Filter(promises, fn, options) { - return PromiseMap(promises, fn, options, INTERNAL); -}; -}; - -},{}],14:[function(require,module,exports){ -/** - * Copyright (c) 2014 Petka Antonov - * - * 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. - * - */ -"use strict"; -module.exports = function(Promise, NEXT_FILTER, cast) { -var util = require("./util.js"); -var wrapsPrimitiveReceiver = util.wrapsPrimitiveReceiver; -var isPrimitive = util.isPrimitive; -var thrower = util.thrower; - -function returnThis() { - return this; -} -function throwThis() { - throw this; -} -function return$(r) { - return function Promise$_returner() { - return r; - }; -} -function throw$(r) { - return function Promise$_thrower() { - throw r; - }; -} -function promisedFinally(ret, reasonOrValue, isFulfilled) { - var then; - if (wrapsPrimitiveReceiver && isPrimitive(reasonOrValue)) { - then = isFulfilled ? return$(reasonOrValue) : throw$(reasonOrValue); - } else { - then = isFulfilled ? returnThis : throwThis; - } - return ret._then(then, thrower, void 0, reasonOrValue, void 0); -} - -function finallyHandler(reasonOrValue) { - var promise = this.promise; - var handler = this.handler; - - var ret = promise._isBound() - ? handler.call(promise._boundTo) - : handler(); - - if (ret !== void 0) { - var maybePromise = cast(ret, void 0); - if (maybePromise instanceof Promise) { - return promisedFinally(maybePromise, reasonOrValue, - promise.isFulfilled()); - } - } - - if (promise.isRejected()) { - NEXT_FILTER.e = reasonOrValue; - return NEXT_FILTER; - } else { - return reasonOrValue; - } -} - -function tapHandler(value) { - var promise = this.promise; - var handler = this.handler; - - var ret = promise._isBound() - ? handler.call(promise._boundTo, value) - : handler(value); - - if (ret !== void 0) { - var maybePromise = cast(ret, void 0); - if (maybePromise instanceof Promise) { - return promisedFinally(maybePromise, value, true); - } - } - return value; -} - -Promise.prototype._passThroughHandler = -function Promise$_passThroughHandler(handler, isFinally) { - if (typeof handler !== "function") return this.then(); - - var promiseAndHandler = { - promise: this, - handler: handler - }; - - return this._then( - isFinally ? finallyHandler : tapHandler, - isFinally ? finallyHandler : void 0, void 0, - promiseAndHandler, void 0); -}; - -Promise.prototype.lastly = -Promise.prototype["finally"] = function Promise$finally(handler) { - return this._passThroughHandler(handler, true); -}; - -Promise.prototype.tap = function Promise$tap(handler) { - return this._passThroughHandler(handler, false); -}; -}; - -},{"./util.js":35}],15:[function(require,module,exports){ -/** - * Copyright (c) 2014 Petka Antonov - * - * 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. - * - */ -"use strict"; -module.exports = function(Promise, apiRejection, INTERNAL, cast) { -var errors = require("./errors.js"); -var TypeError = errors.TypeError; -var deprecated = require("./util.js").deprecated; -var util = require("./util.js"); -var errorObj = util.errorObj; -var tryCatch1 = util.tryCatch1; -var yieldHandlers = []; - -function promiseFromYieldHandler(value, yieldHandlers) { - var _errorObj = errorObj; - var _Promise = Promise; - var len = yieldHandlers.length; - for (var i = 0; i < len; ++i) { - var result = tryCatch1(yieldHandlers[i], void 0, value); - if (result === _errorObj) { - return _Promise.reject(_errorObj.e); - } - var maybePromise = cast(result, promiseFromYieldHandler); - if (maybePromise instanceof _Promise) return maybePromise; - } - return null; -} - -function PromiseSpawn(generatorFunction, receiver, yieldHandler) { - var promise = this._promise = new Promise(INTERNAL); - promise._setTrace(void 0); - this._generatorFunction = generatorFunction; - this._receiver = receiver; - this._generator = void 0; - this._yieldHandlers = typeof yieldHandler === "function" - ? [yieldHandler].concat(yieldHandlers) - : yieldHandlers; -} - -PromiseSpawn.prototype.promise = function PromiseSpawn$promise() { - return this._promise; -}; - -PromiseSpawn.prototype._run = function PromiseSpawn$_run() { - this._generator = this._generatorFunction.call(this._receiver); - this._receiver = - this._generatorFunction = void 0; - this._next(void 0); -}; - -PromiseSpawn.prototype._continue = function PromiseSpawn$_continue(result) { - if (result === errorObj) { - this._generator = void 0; - var trace = errors.canAttach(result.e) - ? result.e : new Error(result.e + ""); - this._promise._attachExtraTrace(trace); - this._promise._reject(result.e, trace); - return; - } - - var value = result.value; - if (result.done === true) { - this._generator = void 0; - if (!this._promise._tryFollow(value)) { - this._promise._fulfill(value); - } - } else { - var maybePromise = cast(value, void 0); - if (!(maybePromise instanceof Promise)) { - maybePromise = - promiseFromYieldHandler(maybePromise, this._yieldHandlers); - if (maybePromise === null) { - this._throw(new TypeError("A value was yielded that could not be treated as a promise")); - return; - } - } - maybePromise._then( - this._next, - this._throw, - void 0, - this, - null - ); - } -}; - -PromiseSpawn.prototype._throw = function PromiseSpawn$_throw(reason) { - if (errors.canAttach(reason)) - this._promise._attachExtraTrace(reason); - this._continue( - tryCatch1(this._generator["throw"], this._generator, reason) - ); -}; - -PromiseSpawn.prototype._next = function PromiseSpawn$_next(value) { - this._continue( - tryCatch1(this._generator.next, this._generator, value) - ); -}; - -Promise.coroutine = -function Promise$Coroutine(generatorFunction, options) { - if (typeof generatorFunction !== "function") { - throw new TypeError("generatorFunction must be a function"); - } - var yieldHandler = Object(options).yieldHandler; - var PromiseSpawn$ = PromiseSpawn; - return function () { - var generator = generatorFunction.apply(this, arguments); - var spawn = new PromiseSpawn$(void 0, void 0, yieldHandler); - spawn._generator = generator; - spawn._next(void 0); - return spawn.promise(); - }; -}; - -Promise.coroutine.addYieldHandler = function(fn) { - if (typeof fn !== "function") throw new TypeError("fn must be a function"); - yieldHandlers.push(fn); -}; - -Promise.spawn = function Promise$Spawn(generatorFunction) { - deprecated("Promise.spawn is deprecated. Use Promise.coroutine instead."); - if (typeof generatorFunction !== "function") { - return apiRejection("generatorFunction must be a function"); - } - var spawn = new PromiseSpawn(generatorFunction, this); - var ret = spawn.promise(); - spawn._run(Promise.spawn); - return ret; -}; -}; - -},{"./errors.js":10,"./util.js":35}],16:[function(require,module,exports){ -/** - * Copyright (c) 2014 Petka Antonov - * - * 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. - * - */ -"use strict"; -module.exports = -function(Promise, PromiseArray, cast, INTERNAL) { -var util = require("./util.js"); -var canEvaluate = util.canEvaluate; -var tryCatch1 = util.tryCatch1; -var errorObj = util.errorObj; - - -if (canEvaluate) { - var thenCallback = function(i) { - return new Function("value", "holder", " \n\ - 'use strict'; \n\ - holder.pIndex = value; \n\ - holder.checkFulfillment(this); \n\ - ".replace(/Index/g, i)); - }; - - var caller = function(count) { - var values = []; - for (var i = 1; i <= count; ++i) values.push("holder.p" + i); - return new Function("holder", " \n\ - 'use strict'; \n\ - var callback = holder.fn; \n\ - return callback(values); \n\ - ".replace(/values/g, values.join(", "))); - }; - var thenCallbacks = []; - var callers = [void 0]; - for (var i = 1; i <= 5; ++i) { - thenCallbacks.push(thenCallback(i)); - callers.push(caller(i)); - } - - var Holder = function(total, fn) { - this.p1 = this.p2 = this.p3 = this.p4 = this.p5 = null; - this.fn = fn; - this.total = total; - this.now = 0; - }; - - Holder.prototype.callers = callers; - Holder.prototype.checkFulfillment = function(promise) { - var now = this.now; - now++; - var total = this.total; - if (now >= total) { - var handler = this.callers[total]; - var ret = tryCatch1(handler, void 0, this); - if (ret === errorObj) { - promise._rejectUnchecked(ret.e); - } else if (!promise._tryFollow(ret)) { - promise._fulfillUnchecked(ret); - } - } else { - this.now = now; - } - }; -} - - - - -Promise.join = function Promise$Join() { - var last = arguments.length - 1; - var fn; - if (last > 0 && typeof arguments[last] === "function") { - fn = arguments[last]; - if (last < 6 && canEvaluate) { - var ret = new Promise(INTERNAL); - ret._setTrace(void 0); - var holder = new Holder(last, fn); - var reject = ret._reject; - var callbacks = thenCallbacks; - for (var i = 0; i < last; ++i) { - var maybePromise = cast(arguments[i], void 0); - if (maybePromise instanceof Promise) { - if (maybePromise.isPending()) { - maybePromise._then(callbacks[i], reject, - void 0, ret, holder); - } else if (maybePromise.isFulfilled()) { - callbacks[i].call(ret, - maybePromise._settledValue, holder); - } else { - ret._reject(maybePromise._settledValue); - maybePromise._unsetRejectionIsUnhandled(); - } - } else { - callbacks[i].call(ret, maybePromise, holder); - } - } - return ret; - } - } - var $_len = arguments.length;var args = new Array($_len); for(var $_i = 0; $_i < $_len; ++$_i) {args[$_i] = arguments[$_i];} - var ret = new PromiseArray(args).promise(); - return fn !== void 0 ? ret.spread(fn) : ret; -}; - -}; - -},{"./util.js":35}],17:[function(require,module,exports){ -/** - * Copyright (c) 2014 Petka Antonov - * - * 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. - * - */ -"use strict"; -module.exports = function(Promise, PromiseArray, apiRejection, cast, INTERNAL) { -var util = require("./util.js"); -var tryCatch3 = util.tryCatch3; -var errorObj = util.errorObj; -var PENDING = {}; -var EMPTY_ARRAY = []; - -function MappingPromiseArray(promises, fn, limit, _filter) { - this.constructor$(promises); - this._callback = fn; - this._preservedValues = _filter === INTERNAL - ? new Array(this.length()) - : null; - this._limit = limit; - this._inFlight = 0; - this._queue = limit >= 1 ? [] : EMPTY_ARRAY; - this._init$(void 0, -2); -} -util.inherits(MappingPromiseArray, PromiseArray); - -MappingPromiseArray.prototype._init = function MappingPromiseArray$_init() {}; - -MappingPromiseArray.prototype._promiseFulfilled = -function MappingPromiseArray$_promiseFulfilled(value, index) { - var values = this._values; - if (values === null) return; - - var length = this.length(); - var preservedValues = this._preservedValues; - var limit = this._limit; - if (values[index] === PENDING) { - values[index] = value; - if (limit >= 1) { - this._inFlight--; - this._drainQueue(); - if (this._isResolved()) return; - } - } else { - if (limit >= 1 && this._inFlight >= limit) { - values[index] = value; - this._queue.push(index); - return; - } - if (preservedValues !== null) preservedValues[index] = value; - - var callback = this._callback; - var receiver = this._promise._boundTo; - var ret = tryCatch3(callback, receiver, value, index, length); - if (ret === errorObj) return this._reject(ret.e); - - var maybePromise = cast(ret, void 0); - if (maybePromise instanceof Promise) { - if (maybePromise.isPending()) { - if (limit >= 1) this._inFlight++; - values[index] = PENDING; - return maybePromise._proxyPromiseArray(this, index); - } else if (maybePromise.isFulfilled()) { - ret = maybePromise.value(); - } else { - maybePromise._unsetRejectionIsUnhandled(); - return this._reject(maybePromise.reason()); - } - } - values[index] = ret; - } - var totalResolved = ++this._totalResolved; - if (totalResolved >= length) { - if (preservedValues !== null) { - this._filter(values, preservedValues); - } else { - this._resolve(values); - } - - } -}; - -MappingPromiseArray.prototype._drainQueue = -function MappingPromiseArray$_drainQueue() { - var queue = this._queue; - var limit = this._limit; - var values = this._values; - while (queue.length > 0 && this._inFlight < limit) { - var index = queue.pop(); - this._promiseFulfilled(values[index], index); - } -}; - -MappingPromiseArray.prototype._filter = -function MappingPromiseArray$_filter(booleans, values) { - var len = values.length; - var ret = new Array(len); - var j = 0; - for (var i = 0; i < len; ++i) { - if (booleans[i]) ret[j++] = values[i]; - } - ret.length = j; - this._resolve(ret); -}; - -MappingPromiseArray.prototype.preservedValues = -function MappingPromiseArray$preserveValues() { - return this._preservedValues; -}; - -function map(promises, fn, options, _filter) { - var limit = typeof options === "object" && options !== null - ? options.concurrency - : 0; - limit = typeof limit === "number" && - isFinite(limit) && limit >= 1 ? limit : 0; - return new MappingPromiseArray(promises, fn, limit, _filter); -} - -Promise.prototype.map = function Promise$map(fn, options) { - if (typeof fn !== "function") return apiRejection("fn must be a function"); - - return map(this, fn, options, null).promise(); -}; - -Promise.map = function Promise$Map(promises, fn, options, _filter) { - if (typeof fn !== "function") return apiRejection("fn must be a function"); - return map(promises, fn, options, _filter).promise(); -}; - - -}; - -},{"./util.js":35}],18:[function(require,module,exports){ -/** - * Copyright (c) 2014 Petka Antonov - * - * 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. - * - */ -"use strict"; -module.exports = function(Promise) { -var util = require("./util.js"); -var async = require("./async.js"); -var tryCatch2 = util.tryCatch2; -var tryCatch1 = util.tryCatch1; -var errorObj = util.errorObj; - -function thrower(r) { - throw r; -} - -function Promise$_spreadAdapter(val, receiver) { - if (!util.isArray(val)) return Promise$_successAdapter(val, receiver); - var ret = util.tryCatchApply(this, [null].concat(val), receiver); - if (ret === errorObj) { - async.invokeLater(thrower, void 0, ret.e); - } -} - -function Promise$_successAdapter(val, receiver) { - var nodeback = this; - var ret = val === void 0 - ? tryCatch1(nodeback, receiver, null) - : tryCatch2(nodeback, receiver, null, val); - if (ret === errorObj) { - async.invokeLater(thrower, void 0, ret.e); - } -} -function Promise$_errorAdapter(reason, receiver) { - var nodeback = this; - var ret = tryCatch1(nodeback, receiver, reason); - if (ret === errorObj) { - async.invokeLater(thrower, void 0, ret.e); - } -} - -Promise.prototype.nodeify = function Promise$nodeify(nodeback, options) { - if (typeof nodeback == "function") { - var adapter = Promise$_successAdapter; - if (options !== void 0 && Object(options).spread) { - adapter = Promise$_spreadAdapter; - } - this._then( - adapter, - Promise$_errorAdapter, - void 0, - nodeback, - this._boundTo - ); - } - return this; -}; -}; - -},{"./async.js":2,"./util.js":35}],19:[function(require,module,exports){ -/** - * Copyright (c) 2014 Petka Antonov - * - * 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. - * - */ -"use strict"; -module.exports = function(Promise, PromiseArray) { -var util = require("./util.js"); -var async = require("./async.js"); -var errors = require("./errors.js"); -var tryCatch1 = util.tryCatch1; -var errorObj = util.errorObj; - -Promise.prototype.progressed = function Promise$progressed(handler) { - return this._then(void 0, void 0, handler, void 0, void 0); -}; - -Promise.prototype._progress = function Promise$_progress(progressValue) { - if (this._isFollowingOrFulfilledOrRejected()) return; - this._progressUnchecked(progressValue); - -}; - -Promise.prototype._progressHandlerAt = -function Promise$_progressHandlerAt(index) { - return index === 0 - ? this._progressHandler0 - : this[(index << 2) + index - 5 + 2]; -}; - -Promise.prototype._doProgressWith = -function Promise$_doProgressWith(progression) { - var progressValue = progression.value; - var handler = progression.handler; - var promise = progression.promise; - var receiver = progression.receiver; - - var ret = tryCatch1(handler, receiver, progressValue); - if (ret === errorObj) { - if (ret.e != null && - ret.e.name !== "StopProgressPropagation") { - var trace = errors.canAttach(ret.e) - ? ret.e : new Error(ret.e + ""); - promise._attachExtraTrace(trace); - promise._progress(ret.e); - } - } else if (ret instanceof Promise) { - ret._then(promise._progress, null, null, promise, void 0); - } else { - promise._progress(ret); - } -}; - - -Promise.prototype._progressUnchecked = -function Promise$_progressUnchecked(progressValue) { - if (!this.isPending()) return; - var len = this._length(); - var progress = this._progress; - for (var i = 0; i < len; i++) { - var handler = this._progressHandlerAt(i); - var promise = this._promiseAt(i); - if (!(promise instanceof Promise)) { - var receiver = this._receiverAt(i); - if (typeof handler === "function") { - handler.call(receiver, progressValue, promise); - } else if (receiver instanceof Promise && receiver._isProxied()) { - receiver._progressUnchecked(progressValue); - } else if (receiver instanceof PromiseArray) { - receiver._promiseProgressed(progressValue, promise); - } - continue; - } - - if (typeof handler === "function") { - async.invoke(this._doProgressWith, this, { - handler: handler, - promise: promise, - receiver: this._receiverAt(i), - value: progressValue - }); - } else { - async.invoke(progress, promise, progressValue); - } - } -}; -}; - -},{"./async.js":2,"./errors.js":10,"./util.js":35}],20:[function(require,module,exports){ -/** - * Copyright (c) 2014 Petka Antonov - * - * 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. - * - */ -"use strict"; -var old; -if (typeof Promise !== "undefined") old = Promise; -function noConflict(bluebird) { - try { if (Promise === bluebird) Promise = old; } - catch (e) {} - return bluebird; -} -module.exports = function() { -var util = require("./util.js"); -var async = require("./async.js"); -var errors = require("./errors.js"); - -var INTERNAL = function(){}; -var APPLY = {}; -var NEXT_FILTER = {e: null}; - -var cast = require("./thenables.js")(Promise, INTERNAL); -var PromiseArray = require("./promise_array.js")(Promise, INTERNAL, cast); -var CapturedTrace = require("./captured_trace.js")(); -var CatchFilter = require("./catch_filter.js")(NEXT_FILTER); -var PromiseResolver = require("./promise_resolver.js"); - -var isArray = util.isArray; - -var errorObj = util.errorObj; -var tryCatch1 = util.tryCatch1; -var tryCatch2 = util.tryCatch2; -var tryCatchApply = util.tryCatchApply; -var RangeError = errors.RangeError; -var TypeError = errors.TypeError; -var CancellationError = errors.CancellationError; -var TimeoutError = errors.TimeoutError; -var OperationalError = errors.OperationalError; -var originatesFromRejection = errors.originatesFromRejection; -var markAsOriginatingFromRejection = errors.markAsOriginatingFromRejection; -var canAttach = errors.canAttach; -var thrower = util.thrower; -var apiRejection = require("./errors_api_rejection")(Promise); - - -var makeSelfResolutionError = function Promise$_makeSelfResolutionError() { - return new TypeError("circular promise resolution chain"); -}; - -function Promise(resolver) { - if (typeof resolver !== "function") { - throw new TypeError("the promise constructor requires a resolver function"); - } - if (this.constructor !== Promise) { - throw new TypeError("the promise constructor cannot be invoked directly"); - } - this._bitField = 0; - this._fulfillmentHandler0 = void 0; - this._rejectionHandler0 = void 0; - this._promise0 = void 0; - this._receiver0 = void 0; - this._settledValue = void 0; - this._boundTo = void 0; - if (resolver !== INTERNAL) this._resolveFromResolver(resolver); -} - -Promise.prototype.bind = function Promise$bind(thisArg) { - var ret = new Promise(INTERNAL); - ret._follow(this); - ret._propagateFrom(this, 2 | 1); - ret._setBoundTo(thisArg); - return ret; -}; - -Promise.prototype.toString = function Promise$toString() { - return "[object Promise]"; -}; - -Promise.prototype.caught = Promise.prototype["catch"] = -function Promise$catch(fn) { - var len = arguments.length; - if (len > 1) { - var catchInstances = new Array(len - 1), - j = 0, i; - for (i = 0; i < len - 1; ++i) { - var item = arguments[i]; - if (typeof item === "function") { - catchInstances[j++] = item; - } else { - var catchFilterTypeError = - new TypeError( - "A catch filter must be an error constructor " - + "or a filter function"); - - this._attachExtraTrace(catchFilterTypeError); - async.invoke(this._reject, this, catchFilterTypeError); - return; - } - } - catchInstances.length = j; - fn = arguments[i]; - - this._resetTrace(); - var catchFilter = new CatchFilter(catchInstances, fn, this); - return this._then(void 0, catchFilter.doFilter, void 0, - catchFilter, void 0); - } - return this._then(void 0, fn, void 0, void 0, void 0); -}; - -Promise.prototype.then = -function Promise$then(didFulfill, didReject, didProgress) { - return this._then(didFulfill, didReject, didProgress, - void 0, void 0); -}; - - -Promise.prototype.done = -function Promise$done(didFulfill, didReject, didProgress) { - var promise = this._then(didFulfill, didReject, didProgress, - void 0, void 0); - promise._setIsFinal(); -}; - -Promise.prototype.spread = function Promise$spread(didFulfill, didReject) { - return this._then(didFulfill, didReject, void 0, - APPLY, void 0); -}; - -Promise.prototype.isCancellable = function Promise$isCancellable() { - return !this.isResolved() && - this._cancellable(); -}; - -Promise.prototype.toJSON = function Promise$toJSON() { - var ret = { - isFulfilled: false, - isRejected: false, - fulfillmentValue: void 0, - rejectionReason: void 0 - }; - if (this.isFulfilled()) { - ret.fulfillmentValue = this._settledValue; - ret.isFulfilled = true; - } else if (this.isRejected()) { - ret.rejectionReason = this._settledValue; - ret.isRejected = true; - } - return ret; -}; - -Promise.prototype.all = function Promise$all() { - return new PromiseArray(this).promise(); -}; - - -Promise.is = function Promise$Is(val) { - return val instanceof Promise; -}; - -Promise.all = function Promise$All(promises) { - return new PromiseArray(promises).promise(); -}; - -Promise.prototype.error = function Promise$_error(fn) { - return this.caught(originatesFromRejection, fn); -}; - -Promise.prototype._resolveFromSyncValue = -function Promise$_resolveFromSyncValue(value) { - if (value === errorObj) { - this._cleanValues(); - this._setRejected(); - this._settledValue = value.e; - this._ensurePossibleRejectionHandled(); - } else { - var maybePromise = cast(value, void 0); - if (maybePromise instanceof Promise) { - this._follow(maybePromise); - } else { - this._cleanValues(); - this._setFulfilled(); - this._settledValue = value; - } - } -}; - -Promise.method = function Promise$_Method(fn) { - if (typeof fn !== "function") { - throw new TypeError("fn must be a function"); - } - return function Promise$_method() { - var value; - switch(arguments.length) { - case 0: value = tryCatch1(fn, this, void 0); break; - case 1: value = tryCatch1(fn, this, arguments[0]); break; - case 2: value = tryCatch2(fn, this, arguments[0], arguments[1]); break; - default: - var $_len = arguments.length;var args = new Array($_len); for(var $_i = 0; $_i < $_len; ++$_i) {args[$_i] = arguments[$_i];} - value = tryCatchApply(fn, args, this); break; - } - var ret = new Promise(INTERNAL); - ret._setTrace(void 0); - ret._resolveFromSyncValue(value); - return ret; - }; -}; - -Promise.attempt = Promise["try"] = function Promise$_Try(fn, args, ctx) { - if (typeof fn !== "function") { - return apiRejection("fn must be a function"); - } - var value = isArray(args) - ? tryCatchApply(fn, args, ctx) - : tryCatch1(fn, ctx, args); - - var ret = new Promise(INTERNAL); - ret._setTrace(void 0); - ret._resolveFromSyncValue(value); - return ret; -}; - -Promise.defer = Promise.pending = function Promise$Defer() { - var promise = new Promise(INTERNAL); - promise._setTrace(void 0); - return new PromiseResolver(promise); -}; - -Promise.bind = function Promise$Bind(thisArg) { - var ret = new Promise(INTERNAL); - ret._setTrace(void 0); - ret._setFulfilled(); - ret._setBoundTo(thisArg); - return ret; -}; - -Promise.cast = function Promise$_Cast(obj) { - var ret = cast(obj, void 0); - if (!(ret instanceof Promise)) { - var val = ret; - ret = new Promise(INTERNAL); - ret._setTrace(void 0); - ret._setFulfilled(); - ret._cleanValues(); - ret._settledValue = val; - } - return ret; -}; - -Promise.resolve = Promise.fulfilled = Promise.cast; - -Promise.reject = Promise.rejected = function Promise$Reject(reason) { - var ret = new Promise(INTERNAL); - ret._setTrace(void 0); - markAsOriginatingFromRejection(reason); - ret._cleanValues(); - ret._setRejected(); - ret._settledValue = reason; - if (!canAttach(reason)) { - var trace = new Error(reason + ""); - ret._setCarriedStackTrace(trace); - } - ret._ensurePossibleRejectionHandled(); - return ret; -}; - -Promise.onPossiblyUnhandledRejection = -function Promise$OnPossiblyUnhandledRejection(fn) { - CapturedTrace.possiblyUnhandledRejection = typeof fn === "function" - ? fn : void 0; -}; - -var unhandledRejectionHandled; -Promise.onUnhandledRejectionHandled = -function Promise$onUnhandledRejectionHandled(fn) { - unhandledRejectionHandled = typeof fn === "function" ? fn : void 0; -}; - -var debugging = false || !!( - typeof process !== "undefined" && - typeof process.execPath === "string" && - typeof process.env === "object" && - (process.env["BLUEBIRD_DEBUG"] || - process.env["NODE_ENV"] === "development") -); - - -Promise.longStackTraces = function Promise$LongStackTraces() { - if (async.haveItemsQueued() && - debugging === false - ) { - throw new Error("cannot enable long stack traces after promises have been created"); - } - debugging = CapturedTrace.isSupported(); -}; - -Promise.hasLongStackTraces = function Promise$HasLongStackTraces() { - return debugging && CapturedTrace.isSupported(); -}; - -Promise.prototype._then = -function Promise$_then( - didFulfill, - didReject, - didProgress, - receiver, - internalData -) { - var haveInternalData = internalData !== void 0; - var ret = haveInternalData ? internalData : new Promise(INTERNAL); - - if (!haveInternalData) { - if (debugging) { - var haveSameContext = this._peekContext() === this._traceParent; - ret._traceParent = haveSameContext ? this._traceParent : this; - } - ret._propagateFrom(this, 7); - } - - var callbackIndex = - this._addCallbacks(didFulfill, didReject, didProgress, ret, receiver); - - if (this.isResolved()) { - async.invoke(this._queueSettleAt, this, callbackIndex); - } - - return ret; -}; - -Promise.prototype._length = function Promise$_length() { - return this._bitField & 262143; -}; - -Promise.prototype._isFollowingOrFulfilledOrRejected = -function Promise$_isFollowingOrFulfilledOrRejected() { - return (this._bitField & 939524096) > 0; -}; - -Promise.prototype._isFollowing = function Promise$_isFollowing() { - return (this._bitField & 536870912) === 536870912; -}; - -Promise.prototype._setLength = function Promise$_setLength(len) { - this._bitField = (this._bitField & -262144) | - (len & 262143); -}; - -Promise.prototype._setFulfilled = function Promise$_setFulfilled() { - this._bitField = this._bitField | 268435456; -}; - -Promise.prototype._setRejected = function Promise$_setRejected() { - this._bitField = this._bitField | 134217728; -}; - -Promise.prototype._setFollowing = function Promise$_setFollowing() { - this._bitField = this._bitField | 536870912; -}; - -Promise.prototype._setIsFinal = function Promise$_setIsFinal() { - this._bitField = this._bitField | 33554432; -}; - -Promise.prototype._isFinal = function Promise$_isFinal() { - return (this._bitField & 33554432) > 0; -}; - -Promise.prototype._cancellable = function Promise$_cancellable() { - return (this._bitField & 67108864) > 0; -}; - -Promise.prototype._setCancellable = function Promise$_setCancellable() { - this._bitField = this._bitField | 67108864; -}; - -Promise.prototype._unsetCancellable = function Promise$_unsetCancellable() { - this._bitField = this._bitField & (~67108864); -}; - -Promise.prototype._setRejectionIsUnhandled = -function Promise$_setRejectionIsUnhandled() { - this._bitField = this._bitField | 2097152; -}; - -Promise.prototype._unsetRejectionIsUnhandled = -function Promise$_unsetRejectionIsUnhandled() { - this._bitField = this._bitField & (~2097152); - if (this._isUnhandledRejectionNotified()) { - this._unsetUnhandledRejectionIsNotified(); - this._notifyUnhandledRejectionIsHandled(); - } -}; - -Promise.prototype._isRejectionUnhandled = -function Promise$_isRejectionUnhandled() { - return (this._bitField & 2097152) > 0; -}; - -Promise.prototype._setUnhandledRejectionIsNotified = -function Promise$_setUnhandledRejectionIsNotified() { - this._bitField = this._bitField | 524288; -}; - -Promise.prototype._unsetUnhandledRejectionIsNotified = -function Promise$_unsetUnhandledRejectionIsNotified() { - this._bitField = this._bitField & (~524288); -}; - -Promise.prototype._isUnhandledRejectionNotified = -function Promise$_isUnhandledRejectionNotified() { - return (this._bitField & 524288) > 0; -}; - -Promise.prototype._setCarriedStackTrace = -function Promise$_setCarriedStackTrace(capturedTrace) { - this._bitField = this._bitField | 1048576; - this._fulfillmentHandler0 = capturedTrace; -}; - -Promise.prototype._unsetCarriedStackTrace = -function Promise$_unsetCarriedStackTrace() { - this._bitField = this._bitField & (~1048576); - this._fulfillmentHandler0 = void 0; -}; - -Promise.prototype._isCarryingStackTrace = -function Promise$_isCarryingStackTrace() { - return (this._bitField & 1048576) > 0; -}; - -Promise.prototype._getCarriedStackTrace = -function Promise$_getCarriedStackTrace() { - return this._isCarryingStackTrace() - ? this._fulfillmentHandler0 - : void 0; -}; - -Promise.prototype._receiverAt = function Promise$_receiverAt(index) { - var ret = index === 0 - ? this._receiver0 - : this[(index << 2) + index - 5 + 4]; - if (this._isBound() && ret === void 0) { - return this._boundTo; - } - return ret; -}; - -Promise.prototype._promiseAt = function Promise$_promiseAt(index) { - return index === 0 - ? this._promise0 - : this[(index << 2) + index - 5 + 3]; -}; - -Promise.prototype._fulfillmentHandlerAt = -function Promise$_fulfillmentHandlerAt(index) { - return index === 0 - ? this._fulfillmentHandler0 - : this[(index << 2) + index - 5 + 0]; -}; - -Promise.prototype._rejectionHandlerAt = -function Promise$_rejectionHandlerAt(index) { - return index === 0 - ? this._rejectionHandler0 - : this[(index << 2) + index - 5 + 1]; -}; - -Promise.prototype._addCallbacks = function Promise$_addCallbacks( - fulfill, - reject, - progress, - promise, - receiver -) { - var index = this._length(); - - if (index >= 262143 - 5) { - index = 0; - this._setLength(0); - } - - if (index === 0) { - this._promise0 = promise; - if (receiver !== void 0) this._receiver0 = receiver; - if (typeof fulfill === "function" && !this._isCarryingStackTrace()) - this._fulfillmentHandler0 = fulfill; - if (typeof reject === "function") this._rejectionHandler0 = reject; - if (typeof progress === "function") this._progressHandler0 = progress; - } else { - var base = (index << 2) + index - 5; - this[base + 3] = promise; - this[base + 4] = receiver; - this[base + 0] = typeof fulfill === "function" - ? fulfill : void 0; - this[base + 1] = typeof reject === "function" - ? reject : void 0; - this[base + 2] = typeof progress === "function" - ? progress : void 0; - } - this._setLength(index + 1); - return index; -}; - -Promise.prototype._setProxyHandlers = -function Promise$_setProxyHandlers(receiver, promiseSlotValue) { - var index = this._length(); - - if (index >= 262143 - 5) { - index = 0; - this._setLength(0); - } - if (index === 0) { - this._promise0 = promiseSlotValue; - this._receiver0 = receiver; - } else { - var base = (index << 2) + index - 5; - this[base + 3] = promiseSlotValue; - this[base + 4] = receiver; - this[base + 0] = - this[base + 1] = - this[base + 2] = void 0; - } - this._setLength(index + 1); -}; - -Promise.prototype._proxyPromiseArray = -function Promise$_proxyPromiseArray(promiseArray, index) { - this._setProxyHandlers(promiseArray, index); -}; - -Promise.prototype._proxyPromise = function Promise$_proxyPromise(promise) { - promise._setProxied(); - this._setProxyHandlers(promise, -1); -}; - -Promise.prototype._setBoundTo = function Promise$_setBoundTo(obj) { - if (obj !== void 0) { - this._bitField = this._bitField | 8388608; - this._boundTo = obj; - } else { - this._bitField = this._bitField & (~8388608); - } -}; - -Promise.prototype._isBound = function Promise$_isBound() { - return (this._bitField & 8388608) === 8388608; -}; - -Promise.prototype._resolveFromResolver = -function Promise$_resolveFromResolver(resolver) { - var promise = this; - this._setTrace(void 0); - this._pushContext(); - - function Promise$_resolver(val) { - if (promise._tryFollow(val)) { - return; - } - promise._fulfill(val); - } - function Promise$_rejecter(val) { - var trace = canAttach(val) ? val : new Error(val + ""); - promise._attachExtraTrace(trace); - markAsOriginatingFromRejection(val); - promise._reject(val, trace === val ? void 0 : trace); - } - var r = tryCatch2(resolver, void 0, Promise$_resolver, Promise$_rejecter); - this._popContext(); - - if (r !== void 0 && r === errorObj) { - var e = r.e; - var trace = canAttach(e) ? e : new Error(e + ""); - promise._reject(e, trace); - } -}; - -Promise.prototype._spreadSlowCase = -function Promise$_spreadSlowCase(targetFn, promise, values, boundTo) { - var promiseForAll = new PromiseArray(values).promise(); - var promise2 = promiseForAll._then(function() { - return targetFn.apply(boundTo, arguments); - }, void 0, void 0, APPLY, void 0); - promise._follow(promise2); -}; - -Promise.prototype._callSpread = -function Promise$_callSpread(handler, promise, value) { - var boundTo = this._boundTo; - if (isArray(value)) { - for (var i = 0, len = value.length; i < len; ++i) { - if (cast(value[i], void 0) instanceof Promise) { - this._spreadSlowCase(handler, promise, value, boundTo); - return; - } - } - } - promise._pushContext(); - return tryCatchApply(handler, value, boundTo); -}; - -Promise.prototype._callHandler = -function Promise$_callHandler( - handler, receiver, promise, value) { - var x; - if (receiver === APPLY && !this.isRejected()) { - x = this._callSpread(handler, promise, value); - } else { - promise._pushContext(); - x = tryCatch1(handler, receiver, value); - } - promise._popContext(); - return x; -}; - -Promise.prototype._settlePromiseFromHandler = -function Promise$_settlePromiseFromHandler( - handler, receiver, value, promise -) { - if (!(promise instanceof Promise)) { - handler.call(receiver, value, promise); - return; - } - var x = this._callHandler(handler, receiver, promise, value); - if (promise._isFollowing()) return; - - if (x === errorObj || x === promise || x === NEXT_FILTER) { - var err = x === promise - ? makeSelfResolutionError() - : x.e; - var trace = canAttach(err) ? err : new Error(err + ""); - if (x !== NEXT_FILTER) promise._attachExtraTrace(trace); - promise._rejectUnchecked(err, trace); - } else { - var castValue = cast(x, promise); - if (castValue instanceof Promise) { - if (castValue.isRejected() && - !castValue._isCarryingStackTrace() && - !canAttach(castValue._settledValue)) { - var trace = new Error(castValue._settledValue + ""); - promise._attachExtraTrace(trace); - castValue._setCarriedStackTrace(trace); - } - promise._follow(castValue); - promise._propagateFrom(castValue, 1); - } else { - promise._fulfillUnchecked(x); - } - } -}; - -Promise.prototype._follow = -function Promise$_follow(promise) { - this._setFollowing(); - - if (promise.isPending()) { - this._propagateFrom(promise, 1); - promise._proxyPromise(this); - } else if (promise.isFulfilled()) { - this._fulfillUnchecked(promise._settledValue); - } else { - this._rejectUnchecked(promise._settledValue, - promise._getCarriedStackTrace()); - } - - if (promise._isRejectionUnhandled()) promise._unsetRejectionIsUnhandled(); - - if (debugging && - promise._traceParent == null) { - promise._traceParent = this; - } -}; - -Promise.prototype._tryFollow = -function Promise$_tryFollow(value) { - if (this._isFollowingOrFulfilledOrRejected() || - value === this) { - return false; - } - var maybePromise = cast(value, void 0); - if (!(maybePromise instanceof Promise)) { - return false; - } - this._follow(maybePromise); - return true; -}; - -Promise.prototype._resetTrace = function Promise$_resetTrace() { - if (debugging) { - this._trace = new CapturedTrace(this._peekContext() === void 0); - } -}; - -Promise.prototype._setTrace = function Promise$_setTrace(parent) { - if (debugging) { - var context = this._peekContext(); - this._traceParent = context; - var isTopLevel = context === void 0; - if (parent !== void 0 && - parent._traceParent === context) { - this._trace = parent._trace; - } else { - this._trace = new CapturedTrace(isTopLevel); - } - } - return this; -}; - -Promise.prototype._attachExtraTrace = -function Promise$_attachExtraTrace(error) { - if (debugging) { - var promise = this; - var stack = error.stack; - stack = typeof stack === "string" ? stack.split("\n") : []; - CapturedTrace.protectErrorMessageNewlines(stack); - var headerLineCount = 1; - var combinedTraces = 1; - while(promise != null && - promise._trace != null) { - stack = CapturedTrace.combine( - stack, - promise._trace.stack.split("\n") - ); - promise = promise._traceParent; - combinedTraces++; - } - - var stackTraceLimit = Error.stackTraceLimit || 10; - var max = (stackTraceLimit + headerLineCount) * combinedTraces; - var len = stack.length; - if (len > max) { - stack.length = max; - } - - if (len > 0) - stack[0] = stack[0].split("\u0002\u0000\u0001").join("\n"); - - if (stack.length <= headerLineCount) { - error.stack = "(No stack trace)"; - } else { - error.stack = stack.join("\n"); - } - } -}; - -Promise.prototype._cleanValues = function Promise$_cleanValues() { - if (this._cancellable()) { - this._cancellationParent = void 0; - } -}; - -Promise.prototype._propagateFrom = -function Promise$_propagateFrom(parent, flags) { - if ((flags & 1) > 0 && parent._cancellable()) { - this._setCancellable(); - this._cancellationParent = parent; - } - if ((flags & 4) > 0) { - this._setBoundTo(parent._boundTo); - } - if ((flags & 2) > 0) { - this._setTrace(parent); - } -}; - -Promise.prototype._fulfill = function Promise$_fulfill(value) { - if (this._isFollowingOrFulfilledOrRejected()) return; - this._fulfillUnchecked(value); -}; - -Promise.prototype._reject = -function Promise$_reject(reason, carriedStackTrace) { - if (this._isFollowingOrFulfilledOrRejected()) return; - this._rejectUnchecked(reason, carriedStackTrace); -}; - -Promise.prototype._settlePromiseAt = function Promise$_settlePromiseAt(index) { - var handler = this.isFulfilled() - ? this._fulfillmentHandlerAt(index) - : this._rejectionHandlerAt(index); - - var value = this._settledValue; - var receiver = this._receiverAt(index); - var promise = this._promiseAt(index); - - if (typeof handler === "function") { - this._settlePromiseFromHandler(handler, receiver, value, promise); - } else { - var done = false; - var isFulfilled = this.isFulfilled(); - if (receiver !== void 0) { - if (receiver instanceof Promise && - receiver._isProxied()) { - receiver._unsetProxied(); - - if (isFulfilled) receiver._fulfillUnchecked(value); - else receiver._rejectUnchecked(value, - this._getCarriedStackTrace()); - done = true; - } else if (receiver instanceof PromiseArray) { - if (isFulfilled) receiver._promiseFulfilled(value, promise); - else receiver._promiseRejected(value, promise); - done = true; - } - } - - if (!done) { - if (isFulfilled) promise._fulfill(value); - else promise._reject(value, this._getCarriedStackTrace()); - } - } - - if (index >= 256) { - this._queueGC(); - } -}; - -Promise.prototype._isProxied = function Promise$_isProxied() { - return (this._bitField & 4194304) === 4194304; -}; - -Promise.prototype._setProxied = function Promise$_setProxied() { - this._bitField = this._bitField | 4194304; -}; - -Promise.prototype._unsetProxied = function Promise$_unsetProxied() { - this._bitField = this._bitField & (~4194304); -}; - -Promise.prototype._isGcQueued = function Promise$_isGcQueued() { - return (this._bitField & -1073741824) === -1073741824; -}; - -Promise.prototype._setGcQueued = function Promise$_setGcQueued() { - this._bitField = this._bitField | -1073741824; -}; - -Promise.prototype._unsetGcQueued = function Promise$_unsetGcQueued() { - this._bitField = this._bitField & (~-1073741824); -}; - -Promise.prototype._queueGC = function Promise$_queueGC() { - if (this._isGcQueued()) return; - this._setGcQueued(); - async.invokeLater(this._gc, this, void 0); -}; - -Promise.prototype._gc = function Promise$gc() { - var len = this._length() * 5; - for (var i = 0; i < len; i++) { - delete this[i]; - } - this._setLength(0); - this._unsetGcQueued(); -}; - -Promise.prototype._queueSettleAt = function Promise$_queueSettleAt(index) { - if (this._isRejectionUnhandled()) this._unsetRejectionIsUnhandled(); - async.invoke(this._settlePromiseAt, this, index); -}; - -Promise.prototype._fulfillUnchecked = -function Promise$_fulfillUnchecked(value) { - if (!this.isPending()) return; - if (value === this) { - var err = makeSelfResolutionError(); - this._attachExtraTrace(err); - return this._rejectUnchecked(err, void 0); - } - this._cleanValues(); - this._setFulfilled(); - this._settledValue = value; - var len = this._length(); - - if (len > 0) { - async.invoke(this._settlePromises, this, len); - } -}; - -Promise.prototype._rejectUncheckedCheckError = -function Promise$_rejectUncheckedCheckError(reason) { - var trace = canAttach(reason) ? reason : new Error(reason + ""); - this._rejectUnchecked(reason, trace === reason ? void 0 : trace); -}; - -Promise.prototype._rejectUnchecked = -function Promise$_rejectUnchecked(reason, trace) { - if (!this.isPending()) return; - if (reason === this) { - var err = makeSelfResolutionError(); - this._attachExtraTrace(err); - return this._rejectUnchecked(err); - } - this._cleanValues(); - this._setRejected(); - this._settledValue = reason; - - if (this._isFinal()) { - async.invokeLater(thrower, void 0, trace === void 0 ? reason : trace); - return; - } - var len = this._length(); - - if (trace !== void 0) this._setCarriedStackTrace(trace); - - if (len > 0) { - async.invoke(this._rejectPromises, this, null); - } else { - this._ensurePossibleRejectionHandled(); - } -}; - -Promise.prototype._rejectPromises = function Promise$_rejectPromises() { - this._settlePromises(); - this._unsetCarriedStackTrace(); -}; - -Promise.prototype._settlePromises = function Promise$_settlePromises() { - var len = this._length(); - for (var i = 0; i < len; i++) { - this._settlePromiseAt(i); - } -}; - -Promise.prototype._ensurePossibleRejectionHandled = -function Promise$_ensurePossibleRejectionHandled() { - this._setRejectionIsUnhandled(); - if (CapturedTrace.possiblyUnhandledRejection !== void 0) { - async.invokeLater(this._notifyUnhandledRejection, this, void 0); - } -}; - -Promise.prototype._notifyUnhandledRejectionIsHandled = -function Promise$_notifyUnhandledRejectionIsHandled() { - if (typeof unhandledRejectionHandled === "function") { - async.invokeLater(unhandledRejectionHandled, void 0, this); - } -}; - -Promise.prototype._notifyUnhandledRejection = -function Promise$_notifyUnhandledRejection() { - if (this._isRejectionUnhandled()) { - var reason = this._settledValue; - var trace = this._getCarriedStackTrace(); - - this._setUnhandledRejectionIsNotified(); - - if (trace !== void 0) { - this._unsetCarriedStackTrace(); - reason = trace; - } - if (typeof CapturedTrace.possiblyUnhandledRejection === "function") { - CapturedTrace.possiblyUnhandledRejection(reason, this); - } - } -}; - -var contextStack = []; -Promise.prototype._peekContext = function Promise$_peekContext() { - var lastIndex = contextStack.length - 1; - if (lastIndex >= 0) { - return contextStack[lastIndex]; - } - return void 0; - -}; - -Promise.prototype._pushContext = function Promise$_pushContext() { - if (!debugging) return; - contextStack.push(this); -}; - -Promise.prototype._popContext = function Promise$_popContext() { - if (!debugging) return; - contextStack.pop(); -}; - -Promise.noConflict = function Promise$NoConflict() { - return noConflict(Promise); -}; - -Promise.setScheduler = function(fn) { - if (typeof fn !== "function") throw new TypeError("fn must be a function"); - async._schedule = fn; -}; - -if (!CapturedTrace.isSupported()) { - Promise.longStackTraces = function(){}; - debugging = false; -} - -Promise._makeSelfResolutionError = makeSelfResolutionError; -require("./finally.js")(Promise, NEXT_FILTER, cast); -require("./direct_resolve.js")(Promise); -require("./synchronous_inspection.js")(Promise); -require("./join.js")(Promise, PromiseArray, cast, INTERNAL); -Promise.RangeError = RangeError; -Promise.CancellationError = CancellationError; -Promise.TimeoutError = TimeoutError; -Promise.TypeError = TypeError; -Promise.OperationalError = OperationalError; -Promise.RejectionError = OperationalError; -Promise.AggregateError = errors.AggregateError; - -util.toFastProperties(Promise); -util.toFastProperties(Promise.prototype); -Promise.Promise = Promise; -require('./timers.js')(Promise,INTERNAL,cast); -require('./race.js')(Promise,INTERNAL,cast); -require('./call_get.js')(Promise); -require('./generators.js')(Promise,apiRejection,INTERNAL,cast); -require('./map.js')(Promise,PromiseArray,apiRejection,cast,INTERNAL); -require('./nodeify.js')(Promise); -require('./promisify.js')(Promise,INTERNAL); -require('./props.js')(Promise,PromiseArray,cast); -require('./reduce.js')(Promise,PromiseArray,apiRejection,cast,INTERNAL); -require('./settle.js')(Promise,PromiseArray); -require('./some.js')(Promise,PromiseArray,apiRejection); -require('./progress.js')(Promise,PromiseArray); -require('./cancel.js')(Promise,INTERNAL); -require('./filter.js')(Promise,INTERNAL); -require('./any.js')(Promise,PromiseArray); -require('./each.js')(Promise,INTERNAL); -require('./using.js')(Promise,apiRejection,cast); - -Promise.prototype = Promise.prototype; -return Promise; - -}; - -},{"./any.js":1,"./async.js":2,"./call_get.js":4,"./cancel.js":5,"./captured_trace.js":6,"./catch_filter.js":7,"./direct_resolve.js":8,"./each.js":9,"./errors.js":10,"./errors_api_rejection":11,"./filter.js":13,"./finally.js":14,"./generators.js":15,"./join.js":16,"./map.js":17,"./nodeify.js":18,"./progress.js":19,"./promise_array.js":21,"./promise_resolver.js":22,"./promisify.js":23,"./props.js":24,"./race.js":26,"./reduce.js":27,"./settle.js":29,"./some.js":30,"./synchronous_inspection.js":31,"./thenables.js":32,"./timers.js":33,"./using.js":34,"./util.js":35}],21:[function(require,module,exports){ -/** - * Copyright (c) 2014 Petka Antonov - * - * 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. - * - */ -"use strict"; -module.exports = function(Promise, INTERNAL, cast) { -var canAttach = require("./errors.js").canAttach; -var util = require("./util.js"); -var isArray = util.isArray; - -function toResolutionValue(val) { - switch(val) { - case -1: return void 0; - case -2: return []; - case -3: return {}; - } -} - -function PromiseArray(values) { - var promise = this._promise = new Promise(INTERNAL); - var parent = void 0; - if (values instanceof Promise) { - parent = values; - promise._propagateFrom(parent, 1 | 4); - } - promise._setTrace(parent); - this._values = values; - this._length = 0; - this._totalResolved = 0; - this._init(void 0, -2); -} -PromiseArray.prototype.length = function PromiseArray$length() { - return this._length; -}; - -PromiseArray.prototype.promise = function PromiseArray$promise() { - return this._promise; -}; - -PromiseArray.prototype._init = -function PromiseArray$_init(_, resolveValueIfEmpty) { - var values = cast(this._values, void 0); - if (values instanceof Promise) { - this._values = values; - values._setBoundTo(this._promise._boundTo); - if (values.isFulfilled()) { - values = values._settledValue; - if (!isArray(values)) { - var err = new Promise.TypeError("expecting an array, a promise or a thenable"); - this.__hardReject__(err); - return; - } - } else if (values.isPending()) { - values._then( - PromiseArray$_init, - this._reject, - void 0, - this, - resolveValueIfEmpty - ); - return; - } else { - values._unsetRejectionIsUnhandled(); - this._reject(values._settledValue); - return; - } - } else if (!isArray(values)) { - var err = new Promise.TypeError("expecting an array, a promise or a thenable"); - this.__hardReject__(err); - return; - } - - if (values.length === 0) { - if (resolveValueIfEmpty === -5) { - this._resolveEmptyArray(); - } - else { - this._resolve(toResolutionValue(resolveValueIfEmpty)); - } - return; - } - var len = this.getActualLength(values.length); - var newLen = len; - var newValues = this.shouldCopyValues() ? new Array(len) : this._values; - var isDirectScanNeeded = false; - for (var i = 0; i < len; ++i) { - var maybePromise = cast(values[i], void 0); - if (maybePromise instanceof Promise) { - if (maybePromise.isPending()) { - maybePromise._proxyPromiseArray(this, i); - } else { - maybePromise._unsetRejectionIsUnhandled(); - isDirectScanNeeded = true; - } - } else { - isDirectScanNeeded = true; - } - newValues[i] = maybePromise; - } - this._values = newValues; - this._length = newLen; - if (isDirectScanNeeded) { - this._scanDirectValues(len); - } -}; - -PromiseArray.prototype._settlePromiseAt = -function PromiseArray$_settlePromiseAt(index) { - var value = this._values[index]; - if (!(value instanceof Promise)) { - this._promiseFulfilled(value, index); - } else if (value.isFulfilled()) { - this._promiseFulfilled(value._settledValue, index); - } else if (value.isRejected()) { - this._promiseRejected(value._settledValue, index); - } -}; - -PromiseArray.prototype._scanDirectValues = -function PromiseArray$_scanDirectValues(len) { - for (var i = 0; i < len; ++i) { - if (this._isResolved()) { - break; - } - this._settlePromiseAt(i); - } -}; - -PromiseArray.prototype._isResolved = function PromiseArray$_isResolved() { - return this._values === null; -}; - -PromiseArray.prototype._resolve = function PromiseArray$_resolve(value) { - this._values = null; - this._promise._fulfill(value); -}; - -PromiseArray.prototype.__hardReject__ = -PromiseArray.prototype._reject = function PromiseArray$_reject(reason) { - this._values = null; - var trace = canAttach(reason) ? reason : new Error(reason + ""); - this._promise._attachExtraTrace(trace); - this._promise._reject(reason, trace); -}; - -PromiseArray.prototype._promiseProgressed = -function PromiseArray$_promiseProgressed(progressValue, index) { - if (this._isResolved()) return; - this._promise._progress({ - index: index, - value: progressValue - }); -}; - - -PromiseArray.prototype._promiseFulfilled = -function PromiseArray$_promiseFulfilled(value, index) { - if (this._isResolved()) return; - this._values[index] = value; - var totalResolved = ++this._totalResolved; - if (totalResolved >= this._length) { - this._resolve(this._values); - } -}; - -PromiseArray.prototype._promiseRejected = -function PromiseArray$_promiseRejected(reason, index) { - if (this._isResolved()) return; - this._totalResolved++; - this._reject(reason); -}; - -PromiseArray.prototype.shouldCopyValues = -function PromiseArray$_shouldCopyValues() { - return true; -}; - -PromiseArray.prototype.getActualLength = -function PromiseArray$getActualLength(len) { - return len; -}; - -return PromiseArray; -}; - -},{"./errors.js":10,"./util.js":35}],22:[function(require,module,exports){ -/** - * Copyright (c) 2014 Petka Antonov - * - * 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. - * - */ -"use strict"; -var util = require("./util.js"); -var maybeWrapAsError = util.maybeWrapAsError; -var errors = require("./errors.js"); -var TimeoutError = errors.TimeoutError; -var OperationalError = errors.OperationalError; -var async = require("./async.js"); -var haveGetters = util.haveGetters; -var es5 = require("./es5.js"); - -function isUntypedError(obj) { - return obj instanceof Error && - es5.getPrototypeOf(obj) === Error.prototype; -} - -function wrapAsOperationalError(obj) { - var ret; - if (isUntypedError(obj)) { - ret = new OperationalError(obj); - } else { - ret = obj; - } - errors.markAsOriginatingFromRejection(ret); - return ret; -} - -function nodebackForPromise(promise) { - function PromiseResolver$_callback(err, value) { - if (promise === null) return; - - if (err) { - var wrapped = wrapAsOperationalError(maybeWrapAsError(err)); - promise._attachExtraTrace(wrapped); - promise._reject(wrapped); - } else if (arguments.length > 2) { - var $_len = arguments.length;var args = new Array($_len - 1); for(var $_i = 1; $_i < $_len; ++$_i) {args[$_i - 1] = arguments[$_i];} - promise._fulfill(args); - } else { - promise._fulfill(value); - } - - promise = null; - } - return PromiseResolver$_callback; -} - - -var PromiseResolver; -if (!haveGetters) { - PromiseResolver = function PromiseResolver(promise) { - this.promise = promise; - this.asCallback = nodebackForPromise(promise); - this.callback = this.asCallback; - }; -} -else { - PromiseResolver = function PromiseResolver(promise) { - this.promise = promise; - }; -} -if (haveGetters) { - var prop = { - get: function() { - return nodebackForPromise(this.promise); - } - }; - es5.defineProperty(PromiseResolver.prototype, "asCallback", prop); - es5.defineProperty(PromiseResolver.prototype, "callback", prop); -} - -PromiseResolver._nodebackForPromise = nodebackForPromise; - -PromiseResolver.prototype.toString = function PromiseResolver$toString() { - return "[object PromiseResolver]"; -}; - -PromiseResolver.prototype.resolve = -PromiseResolver.prototype.fulfill = function PromiseResolver$resolve(value) { - if (!(this instanceof PromiseResolver)) { - throw new TypeError("Illegal invocation, resolver resolve/reject must be called within a resolver context. Consider using the promise constructor instead."); - } - - var promise = this.promise; - if (promise._tryFollow(value)) { - return; - } - async.invoke(promise._fulfill, promise, value); -}; - -PromiseResolver.prototype.reject = function PromiseResolver$reject(reason) { - if (!(this instanceof PromiseResolver)) { - throw new TypeError("Illegal invocation, resolver resolve/reject must be called within a resolver context. Consider using the promise constructor instead."); - } - - var promise = this.promise; - errors.markAsOriginatingFromRejection(reason); - var trace = errors.canAttach(reason) ? reason : new Error(reason + ""); - promise._attachExtraTrace(trace); - async.invoke(promise._reject, promise, reason); - if (trace !== reason) { - async.invoke(this._setCarriedStackTrace, this, trace); - } -}; - -PromiseResolver.prototype.progress = -function PromiseResolver$progress(value) { - if (!(this instanceof PromiseResolver)) { - throw new TypeError("Illegal invocation, resolver resolve/reject must be called within a resolver context. Consider using the promise constructor instead."); - } - async.invoke(this.promise._progress, this.promise, value); -}; - -PromiseResolver.prototype.cancel = function PromiseResolver$cancel() { - async.invoke(this.promise.cancel, this.promise, void 0); -}; - -PromiseResolver.prototype.timeout = function PromiseResolver$timeout() { - this.reject(new TimeoutError("timeout")); -}; - -PromiseResolver.prototype.isResolved = function PromiseResolver$isResolved() { - return this.promise.isResolved(); -}; - -PromiseResolver.prototype.toJSON = function PromiseResolver$toJSON() { - return this.promise.toJSON(); -}; - -PromiseResolver.prototype._setCarriedStackTrace = -function PromiseResolver$_setCarriedStackTrace(trace) { - if (this.promise.isRejected()) { - this.promise._setCarriedStackTrace(trace); - } -}; - -module.exports = PromiseResolver; - -},{"./async.js":2,"./errors.js":10,"./es5.js":12,"./util.js":35}],23:[function(require,module,exports){ -/** - * Copyright (c) 2014 Petka Antonov - * - * 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. - * - */ -"use strict"; -module.exports = function(Promise, INTERNAL) { -var THIS = {}; -var util = require("./util.js"); -var nodebackForPromise = require("./promise_resolver.js") - ._nodebackForPromise; -var withAppended = util.withAppended; -var maybeWrapAsError = util.maybeWrapAsError; -var canEvaluate = util.canEvaluate; -var TypeError = require("./errors").TypeError; -var defaultSuffix = "Async"; -var defaultFilter = function(name, func) { - return util.isIdentifier(name) && - name.charAt(0) !== "_" && - !util.isClass(func); -}; -var defaultPromisified = {__isPromisified__: true}; - - -function escapeIdentRegex(str) { - return str.replace(/([$])/, "\\$"); -} - -function isPromisified(fn) { - try { - return fn.__isPromisified__ === true; - } - catch (e) { - return false; - } -} - -function hasPromisified(obj, key, suffix) { - var val = util.getDataPropertyOrDefault(obj, key + suffix, - defaultPromisified); - return val ? isPromisified(val) : false; -} -function checkValid(ret, suffix, suffixRegexp) { - for (var i = 0; i < ret.length; i += 2) { - var key = ret[i]; - if (suffixRegexp.test(key)) { - var keyWithoutAsyncSuffix = key.replace(suffixRegexp, ""); - for (var j = 0; j < ret.length; j += 2) { - if (ret[j] === keyWithoutAsyncSuffix) { - throw new TypeError("Cannot promisify an API " + - "that has normal methods with '"+suffix+"'-suffix"); - } - } - } - } -} - -function promisifiableMethods(obj, suffix, suffixRegexp, filter) { - var keys = util.inheritedDataKeys(obj); - var ret = []; - for (var i = 0; i < keys.length; ++i) { - var key = keys[i]; - var value = obj[key]; - if (typeof value === "function" && - !isPromisified(value) && - !hasPromisified(obj, key, suffix) && - filter(key, value, obj)) { - ret.push(key, value); - } - } - checkValid(ret, suffix, suffixRegexp); - return ret; -} - -function switchCaseArgumentOrder(likelyArgumentCount) { - var ret = [likelyArgumentCount]; - var min = Math.max(0, likelyArgumentCount - 1 - 5); - for(var i = likelyArgumentCount - 1; i >= min; --i) { - if (i === likelyArgumentCount) continue; - ret.push(i); - } - for(var i = likelyArgumentCount + 1; i <= 5; ++i) { - ret.push(i); - } - return ret; -} - -function argumentSequence(argumentCount) { - return util.filledRange(argumentCount, "arguments[", "]"); -} - -function parameterDeclaration(parameterCount) { - return util.filledRange(parameterCount, "_arg", ""); -} - -function parameterCount(fn) { - if (typeof fn.length === "number") { - return Math.max(Math.min(fn.length, 1023 + 1), 0); - } - return 0; -} - -function generatePropertyAccess(key) { - if (util.isIdentifier(key)) { - return "." + key; - } - else return "['" + key.replace(/(['\\])/g, "\\$1") + "']"; -} - -function makeNodePromisifiedEval(callback, receiver, originalName, fn, suffix) { - var newParameterCount = Math.max(0, parameterCount(fn) - 1); - var argumentOrder = switchCaseArgumentOrder(newParameterCount); - var callbackName = - (typeof originalName === "string" && util.isIdentifier(originalName) - ? originalName + suffix - : "promisified"); - - function generateCallForArgumentCount(count) { - var args = argumentSequence(count).join(", "); - var comma = count > 0 ? ", " : ""; - var ret; - if (typeof callback === "string") { - ret = " \n\ - this.method(args, fn); \n\ - break; \n\ - ".replace(".method", generatePropertyAccess(callback)); - } else if (receiver === THIS) { - ret = " \n\ - callback.call(this, args, fn); \n\ - break; \n\ - "; - } else if (receiver !== void 0) { - ret = " \n\ - callback.call(receiver, args, fn); \n\ - break; \n\ - "; - } else { - ret = " \n\ - callback(args, fn); \n\ - break; \n\ - "; - } - return ret.replace("args", args).replace(", ", comma); - } - - function generateArgumentSwitchCase() { - var ret = ""; - for(var i = 0; i < argumentOrder.length; ++i) { - ret += "case " + argumentOrder[i] +":" + - generateCallForArgumentCount(argumentOrder[i]); - } - var codeForCall; - if (typeof callback === "string") { - codeForCall = " \n\ - this.property.apply(this, args); \n\ - " - .replace(".property", generatePropertyAccess(callback)); - } else if (receiver === THIS) { - codeForCall = " \n\ - callback.apply(this, args); \n\ - "; - } else { - codeForCall = " \n\ - callback.apply(receiver, args); \n\ - "; - } - - ret += " \n\ - default: \n\ - var args = new Array(len + 1); \n\ - var i = 0; \n\ - for (var i = 0; i < len; ++i) { \n\ - args[i] = arguments[i]; \n\ - } \n\ - args[i] = fn; \n\ - [CodeForCall] \n\ - break; \n\ - ".replace("[CodeForCall]", codeForCall); - return ret; - } - - return new Function("Promise", - "callback", - "receiver", - "withAppended", - "maybeWrapAsError", - "nodebackForPromise", - "INTERNAL"," \n\ - var ret = function FunctionName(Parameters) { \n\ - 'use strict'; \n\ - var len = arguments.length; \n\ - var promise = new Promise(INTERNAL); \n\ - promise._setTrace(void 0); \n\ - var fn = nodebackForPromise(promise); \n\ - try { \n\ - switch(len) { \n\ - [CodeForSwitchCase] \n\ - } \n\ - } catch (e) { \n\ - var wrapped = maybeWrapAsError(e); \n\ - promise._attachExtraTrace(wrapped); \n\ - promise._reject(wrapped); \n\ - } \n\ - return promise; \n\ - }; \n\ - ret.__isPromisified__ = true; \n\ - return ret; \n\ - " - .replace("FunctionName", callbackName) - .replace("Parameters", parameterDeclaration(newParameterCount)) - .replace("[CodeForSwitchCase]", generateArgumentSwitchCase()))( - Promise, - callback, - receiver, - withAppended, - maybeWrapAsError, - nodebackForPromise, - INTERNAL - ); -} - -function makeNodePromisifiedClosure(callback, receiver) { - function promisified() { - var _receiver = receiver; - if (receiver === THIS) _receiver = this; - if (typeof callback === "string") { - callback = _receiver[callback]; - } - var promise = new Promise(INTERNAL); - promise._setTrace(void 0); - var fn = nodebackForPromise(promise); - try { - callback.apply(_receiver, withAppended(arguments, fn)); - } catch(e) { - var wrapped = maybeWrapAsError(e); - promise._attachExtraTrace(wrapped); - promise._reject(wrapped); - } - return promise; - } - promisified.__isPromisified__ = true; - return promisified; -} - -var makeNodePromisified = canEvaluate - ? makeNodePromisifiedEval - : makeNodePromisifiedClosure; - -function promisifyAll(obj, suffix, filter, promisifier) { - var suffixRegexp = new RegExp(escapeIdentRegex(suffix) + "$"); - var methods = - promisifiableMethods(obj, suffix, suffixRegexp, filter); - - for (var i = 0, len = methods.length; i < len; i+= 2) { - var key = methods[i]; - var fn = methods[i+1]; - var promisifiedKey = key + suffix; - obj[promisifiedKey] = promisifier === makeNodePromisified - ? makeNodePromisified(key, THIS, key, fn, suffix) - : promisifier(fn); - } - util.toFastProperties(obj); - return obj; -} - -function promisify(callback, receiver) { - return makeNodePromisified(callback, receiver, void 0, callback); -} - -Promise.promisify = function Promise$Promisify(fn, receiver) { - if (typeof fn !== "function") { - throw new TypeError("fn must be a function"); - } - if (isPromisified(fn)) { - return fn; - } - return promisify(fn, arguments.length < 2 ? THIS : receiver); -}; - -Promise.promisifyAll = function Promise$PromisifyAll(target, options) { - if (typeof target !== "function" && typeof target !== "object") { - throw new TypeError("the target of promisifyAll must be an object or a function"); - } - options = Object(options); - var suffix = options.suffix; - if (typeof suffix !== "string") suffix = defaultSuffix; - var filter = options.filter; - if (typeof filter !== "function") filter = defaultFilter; - var promisifier = options.promisifier; - if (typeof promisifier !== "function") promisifier = makeNodePromisified; - - if (!util.isIdentifier(suffix)) { - throw new RangeError("suffix must be a valid identifier"); - } - - var keys = util.inheritedDataKeys(target, {includeHidden: true}); - for (var i = 0; i < keys.length; ++i) { - var value = target[keys[i]]; - if (keys[i] !== "constructor" && - util.isClass(value)) { - promisifyAll(value.prototype, suffix, filter, promisifier); - promisifyAll(value, suffix, filter, promisifier); - } - } - - return promisifyAll(target, suffix, filter, promisifier); -}; -}; - - -},{"./errors":10,"./promise_resolver.js":22,"./util.js":35}],24:[function(require,module,exports){ -/** - * Copyright (c) 2014 Petka Antonov - * - * 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. - * - */ -"use strict"; -module.exports = function(Promise, PromiseArray, cast) { -var util = require("./util.js"); -var apiRejection = require("./errors_api_rejection")(Promise); -var isObject = util.isObject; -var es5 = require("./es5.js"); - -function PropertiesPromiseArray(obj) { - var keys = es5.keys(obj); - var len = keys.length; - var values = new Array(len * 2); - for (var i = 0; i < len; ++i) { - var key = keys[i]; - values[i] = obj[key]; - values[i + len] = key; - } - this.constructor$(values); -} -util.inherits(PropertiesPromiseArray, PromiseArray); - -PropertiesPromiseArray.prototype._init = -function PropertiesPromiseArray$_init() { - this._init$(void 0, -3) ; -}; - -PropertiesPromiseArray.prototype._promiseFulfilled = -function PropertiesPromiseArray$_promiseFulfilled(value, index) { - if (this._isResolved()) return; - this._values[index] = value; - var totalResolved = ++this._totalResolved; - if (totalResolved >= this._length) { - var val = {}; - var keyOffset = this.length(); - for (var i = 0, len = this.length(); i < len; ++i) { - val[this._values[i + keyOffset]] = this._values[i]; - } - this._resolve(val); - } -}; - -PropertiesPromiseArray.prototype._promiseProgressed = -function PropertiesPromiseArray$_promiseProgressed(value, index) { - if (this._isResolved()) return; - - this._promise._progress({ - key: this._values[index + this.length()], - value: value - }); -}; - -PropertiesPromiseArray.prototype.shouldCopyValues = -function PropertiesPromiseArray$_shouldCopyValues() { - return false; -}; - -PropertiesPromiseArray.prototype.getActualLength = -function PropertiesPromiseArray$getActualLength(len) { - return len >> 1; -}; - -function Promise$_Props(promises) { - var ret; - var castValue = cast(promises, void 0); - - if (!isObject(castValue)) { - return apiRejection("cannot await properties of a non-object"); - } else if (castValue instanceof Promise) { - ret = castValue._then(Promise.props, void 0, void 0, void 0, void 0); - } else { - ret = new PropertiesPromiseArray(castValue).promise(); - } - - if (castValue instanceof Promise) { - ret._propagateFrom(castValue, 4); - } - return ret; -} - -Promise.prototype.props = function Promise$props() { - return Promise$_Props(this); -}; - -Promise.props = function Promise$Props(promises) { - return Promise$_Props(promises); -}; -}; - -},{"./errors_api_rejection":11,"./es5.js":12,"./util.js":35}],25:[function(require,module,exports){ -/** - * Copyright (c) 2014 Petka Antonov - * - * 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. - * - */ -"use strict"; -function arrayCopy(src, srcIndex, dst, dstIndex, len) { - for (var j = 0; j < len; ++j) { - dst[j + dstIndex] = src[j + srcIndex]; - } -} - -function Queue(capacity) { - this._capacity = capacity; - this._length = 0; - this._front = 0; - this._makeCapacity(); -} - -Queue.prototype._willBeOverCapacity = -function Queue$_willBeOverCapacity(size) { - return this._capacity < size; -}; - -Queue.prototype._pushOne = function Queue$_pushOne(arg) { - var length = this.length(); - this._checkCapacity(length + 1); - var i = (this._front + length) & (this._capacity - 1); - this[i] = arg; - this._length = length + 1; -}; - -Queue.prototype.push = function Queue$push(fn, receiver, arg) { - var length = this.length() + 3; - if (this._willBeOverCapacity(length)) { - this._pushOne(fn); - this._pushOne(receiver); - this._pushOne(arg); - return; - } - var j = this._front + length - 3; - this._checkCapacity(length); - var wrapMask = this._capacity - 1; - this[(j + 0) & wrapMask] = fn; - this[(j + 1) & wrapMask] = receiver; - this[(j + 2) & wrapMask] = arg; - this._length = length; -}; - -Queue.prototype.shift = function Queue$shift() { - var front = this._front, - ret = this[front]; - - this[front] = void 0; - this._front = (front + 1) & (this._capacity - 1); - this._length--; - return ret; -}; - -Queue.prototype.length = function Queue$length() { - return this._length; -}; - -Queue.prototype._makeCapacity = function Queue$_makeCapacity() { - var len = this._capacity; - for (var i = 0; i < len; ++i) { - this[i] = void 0; - } -}; - -Queue.prototype._checkCapacity = function Queue$_checkCapacity(size) { - if (this._capacity < size) { - this._resizeTo(this._capacity << 3); - } -}; - -Queue.prototype._resizeTo = function Queue$_resizeTo(capacity) { - var oldFront = this._front; - var oldCapacity = this._capacity; - var oldQueue = new Array(oldCapacity); - var length = this.length(); - - arrayCopy(this, 0, oldQueue, 0, oldCapacity); - this._capacity = capacity; - this._makeCapacity(); - this._front = 0; - if (oldFront + length <= oldCapacity) { - arrayCopy(oldQueue, oldFront, this, 0, length); - } else { var lengthBeforeWrapping = - length - ((oldFront + length) & (oldCapacity - 1)); - - arrayCopy(oldQueue, oldFront, this, 0, lengthBeforeWrapping); - arrayCopy(oldQueue, 0, this, lengthBeforeWrapping, - length - lengthBeforeWrapping); - } -}; - -module.exports = Queue; - -},{}],26:[function(require,module,exports){ -/** - * Copyright (c) 2014 Petka Antonov - * - * 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. - * - */ -"use strict"; -module.exports = function(Promise, INTERNAL, cast) { -var apiRejection = require("./errors_api_rejection.js")(Promise); -var isArray = require("./util.js").isArray; - -var raceLater = function Promise$_raceLater(promise) { - return promise.then(function(array) { - return Promise$_Race(array, promise); - }); -}; - -var hasOwn = {}.hasOwnProperty; -function Promise$_Race(promises, parent) { - var maybePromise = cast(promises, void 0); - - if (maybePromise instanceof Promise) { - return raceLater(maybePromise); - } else if (!isArray(promises)) { - return apiRejection("expecting an array, a promise or a thenable"); - } - - var ret = new Promise(INTERNAL); - if (parent !== void 0) { - ret._propagateFrom(parent, 7); - } else { - ret._setTrace(void 0); - } - var fulfill = ret._fulfill; - var reject = ret._reject; - for (var i = 0, len = promises.length; i < len; ++i) { - var val = promises[i]; - - if (val === void 0 && !(hasOwn.call(promises, i))) { - continue; - } - - Promise.cast(val)._then(fulfill, reject, void 0, ret, null); - } - return ret; -} - -Promise.race = function Promise$Race(promises) { - return Promise$_Race(promises, void 0); -}; - -Promise.prototype.race = function Promise$race() { - return Promise$_Race(this, void 0); -}; - -}; - -},{"./errors_api_rejection.js":11,"./util.js":35}],27:[function(require,module,exports){ -/** - * Copyright (c) 2014 Petka Antonov - * - * 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. - * - */ -"use strict"; -module.exports = function(Promise, PromiseArray, apiRejection, cast, INTERNAL) { -var util = require("./util.js"); -var tryCatch4 = util.tryCatch4; -var tryCatch3 = util.tryCatch3; -var errorObj = util.errorObj; -function ReductionPromiseArray(promises, fn, accum, _each) { - this.constructor$(promises); - this._preservedValues = _each === INTERNAL ? [] : null; - this._zerothIsAccum = (accum === void 0); - this._gotAccum = false; - this._reducingIndex = (this._zerothIsAccum ? 1 : 0); - this._valuesPhase = undefined; - - var maybePromise = cast(accum, void 0); - var rejected = false; - var isPromise = maybePromise instanceof Promise; - if (isPromise) { - if (maybePromise.isPending()) { - maybePromise._proxyPromiseArray(this, -1); - } else if (maybePromise.isFulfilled()) { - accum = maybePromise.value(); - this._gotAccum = true; - } else { - maybePromise._unsetRejectionIsUnhandled(); - this._reject(maybePromise.reason()); - rejected = true; - } - } - if (!(isPromise || this._zerothIsAccum)) this._gotAccum = true; - this._callback = fn; - this._accum = accum; - if (!rejected) this._init$(void 0, -5); -} -util.inherits(ReductionPromiseArray, PromiseArray); - -ReductionPromiseArray.prototype._init = -function ReductionPromiseArray$_init() {}; - -ReductionPromiseArray.prototype._resolveEmptyArray = -function ReductionPromiseArray$_resolveEmptyArray() { - if (this._gotAccum || this._zerothIsAccum) { - this._resolve(this._preservedValues !== null - ? [] : this._accum); - } -}; - -ReductionPromiseArray.prototype._promiseFulfilled = -function ReductionPromiseArray$_promiseFulfilled(value, index) { - var values = this._values; - if (values === null) return; - var length = this.length(); - var preservedValues = this._preservedValues; - var isEach = preservedValues !== null; - var gotAccum = this._gotAccum; - var valuesPhase = this._valuesPhase; - var valuesPhaseIndex; - if (!valuesPhase) { - valuesPhase = this._valuesPhase = Array(length); - for (valuesPhaseIndex=0; valuesPhaseIndex - * - * 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. - * - */ -"use strict"; -var schedule; -var _MutationObserver; -if (typeof process === "object" && typeof process.version === "string") { - schedule = function Promise$_Scheduler(fn) { - process.nextTick(fn); - }; -} -else if ((typeof MutationObserver !== "undefined" && - (_MutationObserver = MutationObserver)) || - (typeof WebKitMutationObserver !== "undefined" && - (_MutationObserver = WebKitMutationObserver))) { - schedule = (function() { - var div = document.createElement("div"); - var queuedFn = void 0; - var observer = new _MutationObserver( - function Promise$_Scheduler() { - var fn = queuedFn; - queuedFn = void 0; - fn(); - } - ); - observer.observe(div, { - attributes: true - }); - return function Promise$_Scheduler(fn) { - queuedFn = fn; - div.setAttribute("class", "foo"); - }; - - })(); -} -else if (typeof setTimeout !== "undefined") { - schedule = function Promise$_Scheduler(fn) { - setTimeout(fn, 0); - }; -} -else throw new Error("no async scheduler available"); -module.exports = schedule; - -},{}],29:[function(require,module,exports){ -/** - * Copyright (c) 2014 Petka Antonov - * - * 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. - * - */ -"use strict"; -module.exports = - function(Promise, PromiseArray) { -var PromiseInspection = Promise.PromiseInspection; -var util = require("./util.js"); - -function SettledPromiseArray(values) { - this.constructor$(values); -} -util.inherits(SettledPromiseArray, PromiseArray); - -SettledPromiseArray.prototype._promiseResolved = -function SettledPromiseArray$_promiseResolved(index, inspection) { - this._values[index] = inspection; - var totalResolved = ++this._totalResolved; - if (totalResolved >= this._length) { - this._resolve(this._values); - } -}; - -SettledPromiseArray.prototype._promiseFulfilled = -function SettledPromiseArray$_promiseFulfilled(value, index) { - if (this._isResolved()) return; - var ret = new PromiseInspection(); - ret._bitField = 268435456; - ret._settledValue = value; - this._promiseResolved(index, ret); -}; -SettledPromiseArray.prototype._promiseRejected = -function SettledPromiseArray$_promiseRejected(reason, index) { - if (this._isResolved()) return; - var ret = new PromiseInspection(); - ret._bitField = 134217728; - ret._settledValue = reason; - this._promiseResolved(index, ret); -}; - -Promise.settle = function Promise$Settle(promises) { - return new SettledPromiseArray(promises).promise(); -}; - -Promise.prototype.settle = function Promise$settle() { - return new SettledPromiseArray(this).promise(); -}; -}; - -},{"./util.js":35}],30:[function(require,module,exports){ -/** - * Copyright (c) 2014 Petka Antonov - * - * 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. - * - */ -"use strict"; -module.exports = -function(Promise, PromiseArray, apiRejection) { -var util = require("./util.js"); -var RangeError = require("./errors.js").RangeError; -var AggregateError = require("./errors.js").AggregateError; -var isArray = util.isArray; - - -function SomePromiseArray(values) { - this.constructor$(values); - this._howMany = 0; - this._unwrap = false; - this._initialized = false; -} -util.inherits(SomePromiseArray, PromiseArray); - -SomePromiseArray.prototype._init = function SomePromiseArray$_init() { - if (!this._initialized) { - return; - } - if (this._howMany === 0) { - this._resolve([]); - return; - } - this._init$(void 0, -5); - var isArrayResolved = isArray(this._values); - if (!this._isResolved() && - isArrayResolved && - this._howMany > this._canPossiblyFulfill()) { - this._reject(this._getRangeError(this.length())); - } -}; - -SomePromiseArray.prototype.init = function SomePromiseArray$init() { - this._initialized = true; - this._init(); -}; - -SomePromiseArray.prototype.setUnwrap = function SomePromiseArray$setUnwrap() { - this._unwrap = true; -}; - -SomePromiseArray.prototype.howMany = function SomePromiseArray$howMany() { - return this._howMany; -}; - -SomePromiseArray.prototype.setHowMany = -function SomePromiseArray$setHowMany(count) { - if (this._isResolved()) return; - this._howMany = count; -}; - -SomePromiseArray.prototype._promiseFulfilled = -function SomePromiseArray$_promiseFulfilled(value) { - if (this._isResolved()) return; - this._addFulfilled(value); - if (this._fulfilled() === this.howMany()) { - this._values.length = this.howMany(); - if (this.howMany() === 1 && this._unwrap) { - this._resolve(this._values[0]); - } else { - this._resolve(this._values); - } - } - -}; -SomePromiseArray.prototype._promiseRejected = -function SomePromiseArray$_promiseRejected(reason) { - if (this._isResolved()) return; - this._addRejected(reason); - if (this.howMany() > this._canPossiblyFulfill()) { - var e = new AggregateError(); - for (var i = this.length(); i < this._values.length; ++i) { - e.push(this._values[i]); - } - this._reject(e); - } -}; - -SomePromiseArray.prototype._fulfilled = function SomePromiseArray$_fulfilled() { - return this._totalResolved; -}; - -SomePromiseArray.prototype._rejected = function SomePromiseArray$_rejected() { - return this._values.length - this.length(); -}; - -SomePromiseArray.prototype._addRejected = -function SomePromiseArray$_addRejected(reason) { - this._values.push(reason); -}; - -SomePromiseArray.prototype._addFulfilled = -function SomePromiseArray$_addFulfilled(value) { - this._values[this._totalResolved++] = value; -}; - -SomePromiseArray.prototype._canPossiblyFulfill = -function SomePromiseArray$_canPossiblyFulfill() { - return this.length() - this._rejected(); -}; - -SomePromiseArray.prototype._getRangeError = -function SomePromiseArray$_getRangeError(count) { - var message = "Input array must contain at least " + - this._howMany + " items but contains only " + count + " items"; - return new RangeError(message); -}; - -SomePromiseArray.prototype._resolveEmptyArray = -function SomePromiseArray$_resolveEmptyArray() { - this._reject(this._getRangeError(0)); -}; - -function Promise$_Some(promises, howMany) { - if ((howMany | 0) !== howMany || howMany < 0) { - return apiRejection("expecting a positive integer"); - } - var ret = new SomePromiseArray(promises); - var promise = ret.promise(); - if (promise.isRejected()) { - return promise; - } - ret.setHowMany(howMany); - ret.init(); - return promise; -} - -Promise.some = function Promise$Some(promises, howMany) { - return Promise$_Some(promises, howMany); -}; - -Promise.prototype.some = function Promise$some(howMany) { - return Promise$_Some(this, howMany); -}; - -Promise._SomePromiseArray = SomePromiseArray; -}; - -},{"./errors.js":10,"./util.js":35}],31:[function(require,module,exports){ -/** - * Copyright (c) 2014 Petka Antonov - * - * 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. - * - */ -"use strict"; -module.exports = function(Promise) { -function PromiseInspection(promise) { - if (promise !== void 0) { - this._bitField = promise._bitField; - this._settledValue = promise.isResolved() - ? promise._settledValue - : void 0; - } - else { - this._bitField = 0; - this._settledValue = void 0; - } -} - -PromiseInspection.prototype.isFulfilled = -Promise.prototype.isFulfilled = function Promise$isFulfilled() { - return (this._bitField & 268435456) > 0; -}; - -PromiseInspection.prototype.isRejected = -Promise.prototype.isRejected = function Promise$isRejected() { - return (this._bitField & 134217728) > 0; -}; - -PromiseInspection.prototype.isPending = -Promise.prototype.isPending = function Promise$isPending() { - return (this._bitField & 402653184) === 0; -}; - -PromiseInspection.prototype.value = -Promise.prototype.value = function Promise$value() { - if (!this.isFulfilled()) { - throw new TypeError("cannot get fulfillment value of a non-fulfilled promise"); - } - return this._settledValue; -}; - -PromiseInspection.prototype.error = -PromiseInspection.prototype.reason = -Promise.prototype.reason = function Promise$reason() { - if (!this.isRejected()) { - throw new TypeError("cannot get rejection reason of a non-rejected promise"); - } - return this._settledValue; -}; - -PromiseInspection.prototype.isResolved = -Promise.prototype.isResolved = function Promise$isResolved() { - return (this._bitField & 402653184) > 0; -}; - -Promise.PromiseInspection = PromiseInspection; -}; - -},{}],32:[function(require,module,exports){ -/** - * Copyright (c) 2014 Petka Antonov - * - * 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. - * - */ -"use strict"; -module.exports = function(Promise, INTERNAL) { -var util = require("./util.js"); -var canAttach = require("./errors.js").canAttach; -var errorObj = util.errorObj; -var isObject = util.isObject; - -function getThen(obj) { - try { - return obj.then; - } - catch(e) { - errorObj.e = e; - return errorObj; - } -} - -function Promise$_Cast(obj, originalPromise) { - if (isObject(obj)) { - if (obj instanceof Promise) { - return obj; - } - else if (isAnyBluebirdPromise(obj)) { - var ret = new Promise(INTERNAL); - ret._setTrace(void 0); - obj._then( - ret._fulfillUnchecked, - ret._rejectUncheckedCheckError, - ret._progressUnchecked, - ret, - null - ); - ret._setFollowing(); - return ret; - } - var then = getThen(obj); - if (then === errorObj) { - if (originalPromise !== void 0 && canAttach(then.e)) { - originalPromise._attachExtraTrace(then.e); - } - return Promise.reject(then.e); - } else if (typeof then === "function") { - return Promise$_doThenable(obj, then, originalPromise); - } - } - return obj; -} - -var hasProp = {}.hasOwnProperty; -function isAnyBluebirdPromise(obj) { - return hasProp.call(obj, "_promise0"); -} - -function Promise$_doThenable(x, then, originalPromise) { - var resolver = Promise.defer(); - var called = false; - try { - then.call( - x, - Promise$_resolveFromThenable, - Promise$_rejectFromThenable, - Promise$_progressFromThenable - ); - } catch(e) { - if (!called) { - called = true; - var trace = canAttach(e) ? e : new Error(e + ""); - if (originalPromise !== void 0) { - originalPromise._attachExtraTrace(trace); - } - resolver.promise._reject(e, trace); - } - } - return resolver.promise; - - function Promise$_resolveFromThenable(y) { - if (called) return; - called = true; - - if (x === y) { - var e = Promise._makeSelfResolutionError(); - if (originalPromise !== void 0) { - originalPromise._attachExtraTrace(e); - } - resolver.promise._reject(e, void 0); - return; - } - resolver.resolve(y); - } - - function Promise$_rejectFromThenable(r) { - if (called) return; - called = true; - var trace = canAttach(r) ? r : new Error(r + ""); - if (originalPromise !== void 0) { - originalPromise._attachExtraTrace(trace); - } - resolver.promise._reject(r, trace); - } - - function Promise$_progressFromThenable(v) { - if (called) return; - var promise = resolver.promise; - if (typeof promise._progress === "function") { - promise._progress(v); - } - } -} - -return Promise$_Cast; -}; - -},{"./errors.js":10,"./util.js":35}],33:[function(require,module,exports){ -/** - * Copyright (c) 2014 Petka Antonov - * - * 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. - * - */ -"use strict"; -var _setTimeout = function(fn, ms) { - var len = arguments.length; - var arg0 = arguments[2]; - var arg1 = arguments[3]; - var arg2 = len >= 5 ? arguments[4] : void 0; - setTimeout(function() { - fn(arg0, arg1, arg2); - }, ms); -}; - -module.exports = function(Promise, INTERNAL, cast) { -var util = require("./util.js"); -var errors = require("./errors.js"); -var apiRejection = require("./errors_api_rejection")(Promise); -var TimeoutError = Promise.TimeoutError; - -var afterTimeout = function Promise$_afterTimeout(promise, message, ms) { - if (!promise.isPending()) return; - if (typeof message !== "string") { - message = "operation timed out after" + " " + ms + " ms" - } - var err = new TimeoutError(message); - errors.markAsOriginatingFromRejection(err); - promise._attachExtraTrace(err); - promise._cancel(err); -}; - -var afterDelay = function Promise$_afterDelay(value, promise) { - promise._fulfill(value); -}; - -var delay = Promise.delay = function Promise$Delay(value, ms) { - if (ms === void 0) { - ms = value; - value = void 0; - } - ms = +ms; - var maybePromise = cast(value, void 0); - var promise = new Promise(INTERNAL); - - if (maybePromise instanceof Promise) { - promise._propagateFrom(maybePromise, 7); - promise._follow(maybePromise); - return promise.then(function(value) { - return Promise.delay(value, ms); - }); - } else { - promise._setTrace(void 0); - _setTimeout(afterDelay, ms, value, promise); - } - return promise; -}; - -Promise.prototype.delay = function Promise$delay(ms) { - return delay(this, ms); -}; - -Promise.prototype.timeout = function Promise$timeout(ms, message) { - ms = +ms; - - var ret = new Promise(INTERNAL); - ret._propagateFrom(this, 7); - ret._follow(this); - _setTimeout(afterTimeout, ms, ret, message, ms); - return ret.cancellable(); -}; - -}; - -},{"./errors.js":10,"./errors_api_rejection":11,"./util.js":35}],34:[function(require,module,exports){ -/** - * Copyright (c) 2014 Petka Antonov - * - * 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. - * - */ -"use strict"; -module.exports = function (Promise, apiRejection, cast) { - var TypeError = require("./errors.js").TypeError; - var inherits = require("./util.js").inherits; - var PromiseInspection = Promise.PromiseInspection; - - function inspectionMapper(inspections) { - var len = inspections.length; - for (var i = 0; i < len; ++i) { - var inspection = inspections[i]; - if (inspection.isRejected()) { - return Promise.reject(inspection.error()); - } - inspections[i] = inspection.value(); - } - return inspections; - } - - function thrower(e) { - setTimeout(function(){throw e;}, 0); - } - - function dispose(resources, inspection) { - var i = 0; - var len = resources.length; - var ret = Promise.defer(); - function iterator() { - if (i >= len) return ret.resolve(); - var maybePromise = cast(resources[i++], void 0); - if (maybePromise instanceof Promise && - maybePromise._isDisposable()) { - try { - maybePromise = cast(maybePromise._getDisposer() - .tryDispose(inspection), void 0); - } catch (e) { - return thrower(e); - } - if (maybePromise instanceof Promise) { - return maybePromise._then(iterator, thrower, - null, null, null); - } - } - iterator(); - } - iterator(); - return ret.promise; - } - - function disposerSuccess(value) { - var inspection = new PromiseInspection(); - inspection._settledValue = value; - inspection._bitField = 268435456; - return dispose(this, inspection).thenReturn(value); - } - - function disposerFail(reason) { - var inspection = new PromiseInspection(); - inspection._settledValue = reason; - inspection._bitField = 134217728; - return dispose(this, inspection).thenThrow(reason); - } - - function Disposer(data, promise) { - this._data = data; - this._promise = promise; - } - - Disposer.prototype.data = function Disposer$data() { - return this._data; - }; - - Disposer.prototype.promise = function Disposer$promise() { - return this._promise; - }; - - Disposer.prototype.resource = function Disposer$resource() { - if (this.promise().isFulfilled()) { - return this.promise().value(); - } - return null; - }; - - Disposer.prototype.tryDispose = function(inspection) { - var resource = this.resource(); - var ret = resource !== null - ? this.doDispose(resource, inspection) : null; - this._promise._unsetDisposable(); - this._data = this._promise = null; - return ret; - }; - - function FunctionDisposer(fn, promise) { - this.constructor$(fn, promise); - } - inherits(FunctionDisposer, Disposer); - - FunctionDisposer.prototype.doDispose = function (resource, inspection) { - var fn = this.data(); - return fn.call(resource, resource, inspection); - }; - - Promise.using = function Promise$using() { - var len = arguments.length; - if (len < 2) return apiRejection( - "you must pass at least 2 arguments to Promise.using"); - var fn = arguments[len - 1]; - if (typeof fn !== "function") return apiRejection("fn must be a function"); - len--; - var resources = new Array(len); - for (var i = 0; i < len; ++i) { - var resource = arguments[i]; - if (resource instanceof Disposer) { - var disposer = resource; - resource = resource.promise(); - resource._setDisposable(disposer); - } - resources[i] = resource; - } - - return Promise.settle(resources) - .then(inspectionMapper) - .spread(fn) - ._then(disposerSuccess, disposerFail, void 0, resources, void 0); - }; - - Promise.prototype._setDisposable = - function Promise$_setDisposable(disposer) { - this._bitField = this._bitField | 262144; - this._disposer = disposer; - }; - - Promise.prototype._isDisposable = function Promise$_isDisposable() { - return (this._bitField & 262144) > 0; - }; - - Promise.prototype._getDisposer = function Promise$_getDisposer() { - return this._disposer; - }; - - Promise.prototype._unsetDisposable = function Promise$_unsetDisposable() { - this._bitField = this._bitField & (~262144); - this._disposer = void 0; - }; - - Promise.prototype.disposer = function Promise$disposer(fn) { - if (typeof fn === "function") { - return new FunctionDisposer(fn, this); - } - throw new TypeError(); - }; - -}; - -},{"./errors.js":10,"./util.js":35}],35:[function(require,module,exports){ -/** - * Copyright (c) 2014 Petka Antonov - * - * 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. - * - */ -"use strict"; -var es5 = require("./es5.js"); -var haveGetters = (function(){ - try { - var o = {}; - es5.defineProperty(o, "f", { - get: function () { - return 3; - } - }); - return o.f === 3; - } - catch (e) { - return false; - } - -})(); -var canEvaluate = typeof navigator == "undefined"; -var errorObj = {e: {}}; -function tryCatch1(fn, receiver, arg) { - try { return fn.call(receiver, arg); } - catch (e) { - errorObj.e = e; - return errorObj; - } -} - -function tryCatch2(fn, receiver, arg, arg2) { - try { return fn.call(receiver, arg, arg2); } - catch (e) { - errorObj.e = e; - return errorObj; - } -} - -function tryCatch3(fn, receiver, arg, arg2, arg3) { - try { return fn.call(receiver, arg, arg2, arg3); } - catch (e) { - errorObj.e = e; - return errorObj; - } -} - -function tryCatch4(fn, receiver, arg, arg2, arg3, arg4) { - try { return fn.call(receiver, arg, arg2, arg3, arg4); } - catch (e) { - errorObj.e = e; - return errorObj; - } -} - -function tryCatchApply(fn, args, receiver) { - try { return fn.apply(receiver, args); } - catch (e) { - errorObj.e = e; - return errorObj; - } -} - -var inherits = function(Child, Parent) { - var hasProp = {}.hasOwnProperty; - - function T() { - this.constructor = Child; - this.constructor$ = Parent; - for (var propertyName in Parent.prototype) { - if (hasProp.call(Parent.prototype, propertyName) && - propertyName.charAt(propertyName.length-1) !== "$" - ) { - this[propertyName + "$"] = Parent.prototype[propertyName]; - } - } - } - T.prototype = Parent.prototype; - Child.prototype = new T(); - return Child.prototype; -}; - -function asString(val) { - return typeof val === "string" ? val : ("" + val); -} - -function isPrimitive(val) { - return val == null || val === true || val === false || - typeof val === "string" || typeof val === "number"; - -} - -function isObject(value) { - return !isPrimitive(value); -} - -function maybeWrapAsError(maybeError) { - if (!isPrimitive(maybeError)) return maybeError; - - return new Error(asString(maybeError)); -} - -function withAppended(target, appendee) { - var len = target.length; - var ret = new Array(len + 1); - var i; - for (i = 0; i < len; ++i) { - ret[i] = target[i]; - } - ret[i] = appendee; - return ret; -} - -function getDataPropertyOrDefault(obj, key, defaultValue) { - if (es5.isES5) { - var desc = Object.getOwnPropertyDescriptor(obj, key); - if (desc != null) { - return desc.get == null && desc.set == null - ? desc.value - : defaultValue; - } - } else { - return {}.hasOwnProperty.call(obj, key) ? obj[key] : void 0; - } -} - -function notEnumerableProp(obj, name, value) { - if (isPrimitive(obj)) return obj; - var descriptor = { - value: value, - configurable: true, - enumerable: false, - writable: true - }; - es5.defineProperty(obj, name, descriptor); - return obj; -} - - -var wrapsPrimitiveReceiver = (function() { - return this !== "string"; -}).call("string"); - -function thrower(r) { - throw r; -} - -var inheritedDataKeys = (function() { - if (es5.isES5) { - return function(obj, opts) { - var ret = []; - var visitedKeys = Object.create(null); - var getKeys = Object(opts).includeHidden - ? Object.getOwnPropertyNames - : Object.keys; - while (obj != null) { - var keys; - try { - keys = getKeys(obj); - } catch (e) { - return ret; - } - for (var i = 0; i < keys.length; ++i) { - var key = keys[i]; - if (visitedKeys[key]) continue; - visitedKeys[key] = true; - var desc = Object.getOwnPropertyDescriptor(obj, key); - if (desc != null && desc.get == null && desc.set == null) { - ret.push(key); - } - } - obj = es5.getPrototypeOf(obj); - } - return ret; - }; - } else { - return function(obj) { - var ret = []; - /*jshint forin:false */ - for (var key in obj) { - ret.push(key); - } - return ret; - }; - } - -})(); - -function isClass(fn) { - try { - if (typeof fn === "function") { - var keys = es5.keys(fn.prototype); - return keys.length > 0 && - !(keys.length === 1 && keys[0] === "constructor"); - } - return false; - } catch (e) { - return false; - } -} - -function toFastProperties(obj) { - /*jshint -W027*/ - function f() {} - f.prototype = obj; - return f; - eval(obj); -} - -var rident = /^[a-z$_][a-z$_0-9]*$/i; -function isIdentifier(str) { - return rident.test(str); -} - -function filledRange(count, prefix, suffix) { - var ret = new Array(count); - for(var i = 0; i < count; ++i) { - ret[i] = prefix + i + suffix; - } - return ret; -} - -var ret = { - isClass: isClass, - isIdentifier: isIdentifier, - inheritedDataKeys: inheritedDataKeys, - getDataPropertyOrDefault: getDataPropertyOrDefault, - thrower: thrower, - isArray: es5.isArray, - haveGetters: haveGetters, - notEnumerableProp: notEnumerableProp, - isPrimitive: isPrimitive, - isObject: isObject, - canEvaluate: canEvaluate, - errorObj: errorObj, - tryCatch1: tryCatch1, - tryCatch2: tryCatch2, - tryCatch3: tryCatch3, - tryCatch4: tryCatch4, - tryCatchApply: tryCatchApply, - inherits: inherits, - withAppended: withAppended, - asString: asString, - maybeWrapAsError: maybeWrapAsError, - wrapsPrimitiveReceiver: wrapsPrimitiveReceiver, - toFastProperties: toFastProperties, - filledRange: filledRange -}; - -module.exports = ret; - -},{"./es5.js":12}]},{},[3]) -(3) -}); -; \ No newline at end of file diff --git a/test/index.html b/test/index.html index 4a7af15a..615c9ce7 100644 --- a/test/index.html +++ b/test/index.html @@ -2,1811 +2,54 @@ Velocity.js Tests - - - - - - - + + + + + + + -
    -
  • - Unit tests: current document. -
  • -
  • - Performance tests: See Performance pane in docs. -
  • -
  • - Property support tests: Run the Property Support pane's auto-cycler. -
  • -
  • - Visual tests: See demo. Read demo's source for intended behavior. -
  • -
+

+ Tests are still WIP - they do not match Velocity v2 internals yet +

+
- + \ No newline at end of file diff --git a/test/jquery-1.12.4.js b/test/jquery-1.12.4.js deleted file mode 100644 index 7fc60fca..00000000 --- a/test/jquery-1.12.4.js +++ /dev/null @@ -1,11008 +0,0 @@ -/*! - * jQuery JavaScript Library v1.12.4 - * http://jquery.com/ - * - * Includes Sizzle.js - * http://sizzlejs.com/ - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license - * http://jquery.org/license - * - * Date: 2016-05-20T17:17Z - */ - -(function( global, factory ) { - - if ( typeof module === "object" && typeof module.exports === "object" ) { - // For CommonJS and CommonJS-like environments where a proper `window` - // is present, execute the factory and get jQuery. - // For environments that do not have a `window` with a `document` - // (such as Node.js), expose a factory as module.exports. - // This accentuates the need for the creation of a real `window`. - // e.g. var jQuery = require("jquery")(window); - // See ticket #14549 for more info. - module.exports = global.document ? - factory( global, true ) : - function( w ) { - if ( !w.document ) { - throw new Error( "jQuery requires a window with a document" ); - } - return factory( w ); - }; - } else { - factory( global ); - } - -// Pass this if window is not defined yet -}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { - -// Support: Firefox 18+ -// Can't be in strict mode, several libs including ASP.NET trace -// the stack via arguments.caller.callee and Firefox dies if -// you try to trace through "use strict" call chains. (#13335) -//"use strict"; -var deletedIds = []; - -var document = window.document; - -var slice = deletedIds.slice; - -var concat = deletedIds.concat; - -var push = deletedIds.push; - -var indexOf = deletedIds.indexOf; - -var class2type = {}; - -var toString = class2type.toString; - -var hasOwn = class2type.hasOwnProperty; - -var support = {}; - - - -var - version = "1.12.4", - - // Define a local copy of jQuery - jQuery = function( selector, context ) { - - // The jQuery object is actually just the init constructor 'enhanced' - // Need init if jQuery is called (just allow error to be thrown if not included) - return new jQuery.fn.init( selector, context ); - }, - - // Support: Android<4.1, IE<9 - // Make sure we trim BOM and NBSP - rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, - - // Matches dashed string for camelizing - rmsPrefix = /^-ms-/, - rdashAlpha = /-([\da-z])/gi, - - // Used by jQuery.camelCase as callback to replace() - fcamelCase = function( all, letter ) { - return letter.toUpperCase(); - }; - -jQuery.fn = jQuery.prototype = { - - // The current version of jQuery being used - jquery: version, - - constructor: jQuery, - - // Start with an empty selector - selector: "", - - // The default length of a jQuery object is 0 - length: 0, - - toArray: function() { - return slice.call( this ); - }, - - // Get the Nth element in the matched element set OR - // Get the whole matched element set as a clean array - get: function( num ) { - return num != null ? - - // Return just the one element from the set - ( num < 0 ? this[ num + this.length ] : this[ num ] ) : - - // Return all the elements in a clean array - slice.call( this ); - }, - - // Take an array of elements and push it onto the stack - // (returning the new matched element set) - pushStack: function( elems ) { - - // Build a new jQuery matched element set - var ret = jQuery.merge( this.constructor(), elems ); - - // Add the old object onto the stack (as a reference) - ret.prevObject = this; - ret.context = this.context; - - // Return the newly-formed element set - return ret; - }, - - // Execute a callback for every element in the matched set. - each: function( callback ) { - return jQuery.each( this, callback ); - }, - - map: function( callback ) { - return this.pushStack( jQuery.map( this, function( elem, i ) { - return callback.call( elem, i, elem ); - } ) ); - }, - - slice: function() { - return this.pushStack( slice.apply( this, arguments ) ); - }, - - first: function() { - return this.eq( 0 ); - }, - - last: function() { - return this.eq( -1 ); - }, - - eq: function( i ) { - var len = this.length, - j = +i + ( i < 0 ? len : 0 ); - return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); - }, - - end: function() { - return this.prevObject || this.constructor(); - }, - - // For internal use only. - // Behaves like an Array's method, not like a jQuery method. - push: push, - sort: deletedIds.sort, - splice: deletedIds.splice -}; - -jQuery.extend = jQuery.fn.extend = function() { - var src, copyIsArray, copy, name, options, clone, - target = arguments[ 0 ] || {}, - i = 1, - length = arguments.length, - deep = false; - - // Handle a deep copy situation - if ( typeof target === "boolean" ) { - deep = target; - - // skip the boolean and the target - target = arguments[ i ] || {}; - i++; - } - - // Handle case when target is a string or something (possible in deep copy) - if ( typeof target !== "object" && !jQuery.isFunction( target ) ) { - target = {}; - } - - // extend jQuery itself if only one argument is passed - if ( i === length ) { - target = this; - i--; - } - - for ( ; i < length; i++ ) { - - // Only deal with non-null/undefined values - if ( ( options = arguments[ i ] ) != null ) { - - // Extend the base object - for ( name in options ) { - src = target[ name ]; - copy = options[ name ]; - - // Prevent never-ending loop - if ( target === copy ) { - continue; - } - - // Recurse if we're merging plain objects or arrays - if ( deep && copy && ( jQuery.isPlainObject( copy ) || - ( copyIsArray = jQuery.isArray( copy ) ) ) ) { - - if ( copyIsArray ) { - copyIsArray = false; - clone = src && jQuery.isArray( src ) ? src : []; - - } else { - clone = src && jQuery.isPlainObject( src ) ? src : {}; - } - - // Never move original objects, clone them - target[ name ] = jQuery.extend( deep, clone, copy ); - - // Don't bring in undefined values - } else if ( copy !== undefined ) { - target[ name ] = copy; - } - } - } - } - - // Return the modified object - return target; -}; - -jQuery.extend( { - - // Unique for each copy of jQuery on the page - expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), - - // Assume jQuery is ready without the ready module - isReady: true, - - error: function( msg ) { - throw new Error( msg ); - }, - - noop: function() {}, - - // See test/unit/core.js for details concerning isFunction. - // Since version 1.3, DOM methods and functions like alert - // aren't supported. They return false on IE (#2968). - isFunction: function( obj ) { - return jQuery.type( obj ) === "function"; - }, - - isArray: Array.isArray || function( obj ) { - return jQuery.type( obj ) === "array"; - }, - - isWindow: function( obj ) { - /* jshint eqeqeq: false */ - return obj != null && obj == obj.window; - }, - - isNumeric: function( obj ) { - - // parseFloat NaNs numeric-cast false positives (null|true|false|"") - // ...but misinterprets leading-number strings, particularly hex literals ("0x...") - // subtraction forces infinities to NaN - // adding 1 corrects loss of precision from parseFloat (#15100) - var realStringObj = obj && obj.toString(); - return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0; - }, - - isEmptyObject: function( obj ) { - var name; - for ( name in obj ) { - return false; - } - return true; - }, - - isPlainObject: function( obj ) { - var key; - - // Must be an Object. - // Because of IE, we also have to check the presence of the constructor property. - // Make sure that DOM nodes and window objects don't pass through, as well - if ( !obj || jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { - return false; - } - - try { - - // Not own constructor property must be Object - if ( obj.constructor && - !hasOwn.call( obj, "constructor" ) && - !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) { - return false; - } - } catch ( e ) { - - // IE8,9 Will throw exceptions on certain host objects #9897 - return false; - } - - // Support: IE<9 - // Handle iteration over inherited properties before own properties. - if ( !support.ownFirst ) { - for ( key in obj ) { - return hasOwn.call( obj, key ); - } - } - - // Own properties are enumerated firstly, so to speed up, - // if last one is own, then all properties are own. - for ( key in obj ) {} - - return key === undefined || hasOwn.call( obj, key ); - }, - - type: function( obj ) { - if ( obj == null ) { - return obj + ""; - } - return typeof obj === "object" || typeof obj === "function" ? - class2type[ toString.call( obj ) ] || "object" : - typeof obj; - }, - - // Workarounds based on findings by Jim Driscoll - // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context - globalEval: function( data ) { - if ( data && jQuery.trim( data ) ) { - - // We use execScript on Internet Explorer - // We use an anonymous function so that context is window - // rather than jQuery in Firefox - ( window.execScript || function( data ) { - window[ "eval" ].call( window, data ); // jscs:ignore requireDotNotation - } )( data ); - } - }, - - // Convert dashed to camelCase; used by the css and data modules - // Microsoft forgot to hump their vendor prefix (#9572) - camelCase: function( string ) { - return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); - }, - - nodeName: function( elem, name ) { - return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); - }, - - each: function( obj, callback ) { - var length, i = 0; - - if ( isArrayLike( obj ) ) { - length = obj.length; - for ( ; i < length; i++ ) { - if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { - break; - } - } - } else { - for ( i in obj ) { - if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { - break; - } - } - } - - return obj; - }, - - // Support: Android<4.1, IE<9 - trim: function( text ) { - return text == null ? - "" : - ( text + "" ).replace( rtrim, "" ); - }, - - // results is for internal usage only - makeArray: function( arr, results ) { - var ret = results || []; - - if ( arr != null ) { - if ( isArrayLike( Object( arr ) ) ) { - jQuery.merge( ret, - typeof arr === "string" ? - [ arr ] : arr - ); - } else { - push.call( ret, arr ); - } - } - - return ret; - }, - - inArray: function( elem, arr, i ) { - var len; - - if ( arr ) { - if ( indexOf ) { - return indexOf.call( arr, elem, i ); - } - - len = arr.length; - i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; - - for ( ; i < len; i++ ) { - - // Skip accessing in sparse arrays - if ( i in arr && arr[ i ] === elem ) { - return i; - } - } - } - - return -1; - }, - - merge: function( first, second ) { - var len = +second.length, - j = 0, - i = first.length; - - while ( j < len ) { - first[ i++ ] = second[ j++ ]; - } - - // Support: IE<9 - // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists) - if ( len !== len ) { - while ( second[ j ] !== undefined ) { - first[ i++ ] = second[ j++ ]; - } - } - - first.length = i; - - return first; - }, - - grep: function( elems, callback, invert ) { - var callbackInverse, - matches = [], - i = 0, - length = elems.length, - callbackExpect = !invert; - - // Go through the array, only saving the items - // that pass the validator function - for ( ; i < length; i++ ) { - callbackInverse = !callback( elems[ i ], i ); - if ( callbackInverse !== callbackExpect ) { - matches.push( elems[ i ] ); - } - } - - return matches; - }, - - // arg is for internal usage only - map: function( elems, callback, arg ) { - var length, value, - i = 0, - ret = []; - - // Go through the array, translating each of the items to their new values - if ( isArrayLike( elems ) ) { - length = elems.length; - for ( ; i < length; i++ ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret.push( value ); - } - } - - // Go through every key on the object, - } else { - for ( i in elems ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret.push( value ); - } - } - } - - // Flatten any nested arrays - return concat.apply( [], ret ); - }, - - // A global GUID counter for objects - guid: 1, - - // Bind a function to a context, optionally partially applying any - // arguments. - proxy: function( fn, context ) { - var args, proxy, tmp; - - if ( typeof context === "string" ) { - tmp = fn[ context ]; - context = fn; - fn = tmp; - } - - // Quick check to determine if target is callable, in the spec - // this throws a TypeError, but we will just return undefined. - if ( !jQuery.isFunction( fn ) ) { - return undefined; - } - - // Simulated bind - args = slice.call( arguments, 2 ); - proxy = function() { - return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); - }; - - // Set the guid of unique handler to the same of original handler, so it can be removed - proxy.guid = fn.guid = fn.guid || jQuery.guid++; - - return proxy; - }, - - now: function() { - return +( new Date() ); - }, - - // jQuery.support is not used in Core but other projects attach their - // properties to it so it needs to exist. - support: support -} ); - -// JSHint would error on this code due to the Symbol not being defined in ES5. -// Defining this global in .jshintrc would create a danger of using the global -// unguarded in another place, it seems safer to just disable JSHint for these -// three lines. -/* jshint ignore: start */ -if ( typeof Symbol === "function" ) { - jQuery.fn[ Symbol.iterator ] = deletedIds[ Symbol.iterator ]; -} -/* jshint ignore: end */ - -// Populate the class2type map -jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), -function( i, name ) { - class2type[ "[object " + name + "]" ] = name.toLowerCase(); -} ); - -function isArrayLike( obj ) { - - // Support: iOS 8.2 (not reproducible in simulator) - // `in` check used to prevent JIT error (gh-2145) - // hasOwn isn't used here due to false negatives - // regarding Nodelist length in IE - var length = !!obj && "length" in obj && obj.length, - type = jQuery.type( obj ); - - if ( type === "function" || jQuery.isWindow( obj ) ) { - return false; - } - - return type === "array" || length === 0 || - typeof length === "number" && length > 0 && ( length - 1 ) in obj; -} -var Sizzle = -/*! - * Sizzle CSS Selector Engine v2.2.1 - * http://sizzlejs.com/ - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license - * http://jquery.org/license - * - * Date: 2015-10-17 - */ -(function( window ) { - -var i, - support, - Expr, - getText, - isXML, - tokenize, - compile, - select, - outermostContext, - sortInput, - hasDuplicate, - - // Local document vars - setDocument, - document, - docElem, - documentIsHTML, - rbuggyQSA, - rbuggyMatches, - matches, - contains, - - // Instance-specific data - expando = "sizzle" + 1 * new Date(), - preferredDoc = window.document, - dirruns = 0, - done = 0, - classCache = createCache(), - tokenCache = createCache(), - compilerCache = createCache(), - sortOrder = function( a, b ) { - if ( a === b ) { - hasDuplicate = true; - } - return 0; - }, - - // General-purpose constants - MAX_NEGATIVE = 1 << 31, - - // Instance methods - hasOwn = ({}).hasOwnProperty, - arr = [], - pop = arr.pop, - push_native = arr.push, - push = arr.push, - slice = arr.slice, - // Use a stripped-down indexOf as it's faster than native - // http://jsperf.com/thor-indexof-vs-for/5 - indexOf = function( list, elem ) { - var i = 0, - len = list.length; - for ( ; i < len; i++ ) { - if ( list[i] === elem ) { - return i; - } - } - return -1; - }, - - booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", - - // Regular expressions - - // http://www.w3.org/TR/css3-selectors/#whitespace - whitespace = "[\\x20\\t\\r\\n\\f]", - - // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier - identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", - - // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors - attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + - // Operator (capture 2) - "*([*^$|!~]?=)" + whitespace + - // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" - "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + - "*\\]", - - pseudos = ":(" + identifier + ")(?:\\((" + - // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: - // 1. quoted (capture 3; capture 4 or capture 5) - "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + - // 2. simple (capture 6) - "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + - // 3. anything else (capture 2) - ".*" + - ")\\)|)", - - // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter - rwhitespace = new RegExp( whitespace + "+", "g" ), - rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), - - rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), - rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), - - rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), - - rpseudo = new RegExp( pseudos ), - ridentifier = new RegExp( "^" + identifier + "$" ), - - matchExpr = { - "ID": new RegExp( "^#(" + identifier + ")" ), - "CLASS": new RegExp( "^\\.(" + identifier + ")" ), - "TAG": new RegExp( "^(" + identifier + "|[*])" ), - "ATTR": new RegExp( "^" + attributes ), - "PSEUDO": new RegExp( "^" + pseudos ), - "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + - "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + - "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), - "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), - // For use in libraries implementing .is() - // We use this for POS matching in `select` - "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + - whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) - }, - - rinputs = /^(?:input|select|textarea|button)$/i, - rheader = /^h\d$/i, - - rnative = /^[^{]+\{\s*\[native \w/, - - // Easily-parseable/retrievable ID or TAG or CLASS selectors - rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, - - rsibling = /[+~]/, - rescape = /'|\\/g, - - // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters - runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), - funescape = function( _, escaped, escapedWhitespace ) { - var high = "0x" + escaped - 0x10000; - // NaN means non-codepoint - // Support: Firefox<24 - // Workaround erroneous numeric interpretation of +"0x" - return high !== high || escapedWhitespace ? - escaped : - high < 0 ? - // BMP codepoint - String.fromCharCode( high + 0x10000 ) : - // Supplemental Plane codepoint (surrogate pair) - String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); - }, - - // Used for iframes - // See setDocument() - // Removing the function wrapper causes a "Permission Denied" - // error in IE - unloadHandler = function() { - setDocument(); - }; - -// Optimize for push.apply( _, NodeList ) -try { - push.apply( - (arr = slice.call( preferredDoc.childNodes )), - preferredDoc.childNodes - ); - // Support: Android<4.0 - // Detect silently failing push.apply - arr[ preferredDoc.childNodes.length ].nodeType; -} catch ( e ) { - push = { apply: arr.length ? - - // Leverage slice if possible - function( target, els ) { - push_native.apply( target, slice.call(els) ); - } : - - // Support: IE<9 - // Otherwise append directly - function( target, els ) { - var j = target.length, - i = 0; - // Can't trust NodeList.length - while ( (target[j++] = els[i++]) ) {} - target.length = j - 1; - } - }; -} - -function Sizzle( selector, context, results, seed ) { - var m, i, elem, nid, nidselect, match, groups, newSelector, - newContext = context && context.ownerDocument, - - // nodeType defaults to 9, since context defaults to document - nodeType = context ? context.nodeType : 9; - - results = results || []; - - // Return early from calls with invalid selector or context - if ( typeof selector !== "string" || !selector || - nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { - - return results; - } - - // Try to shortcut find operations (as opposed to filters) in HTML documents - if ( !seed ) { - - if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { - setDocument( context ); - } - context = context || document; - - if ( documentIsHTML ) { - - // If the selector is sufficiently simple, try using a "get*By*" DOM method - // (excepting DocumentFragment context, where the methods don't exist) - if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { - - // ID selector - if ( (m = match[1]) ) { - - // Document context - if ( nodeType === 9 ) { - if ( (elem = context.getElementById( m )) ) { - - // Support: IE, Opera, Webkit - // TODO: identify versions - // getElementById can match elements by name instead of ID - if ( elem.id === m ) { - results.push( elem ); - return results; - } - } else { - return results; - } - - // Element context - } else { - - // Support: IE, Opera, Webkit - // TODO: identify versions - // getElementById can match elements by name instead of ID - if ( newContext && (elem = newContext.getElementById( m )) && - contains( context, elem ) && - elem.id === m ) { - - results.push( elem ); - return results; - } - } - - // Type selector - } else if ( match[2] ) { - push.apply( results, context.getElementsByTagName( selector ) ); - return results; - - // Class selector - } else if ( (m = match[3]) && support.getElementsByClassName && - context.getElementsByClassName ) { - - push.apply( results, context.getElementsByClassName( m ) ); - return results; - } - } - - // Take advantage of querySelectorAll - if ( support.qsa && - !compilerCache[ selector + " " ] && - (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { - - if ( nodeType !== 1 ) { - newContext = context; - newSelector = selector; - - // qSA looks outside Element context, which is not what we want - // Thanks to Andrew Dupont for this workaround technique - // Support: IE <=8 - // Exclude object elements - } else if ( context.nodeName.toLowerCase() !== "object" ) { - - // Capture the context ID, setting it first if necessary - if ( (nid = context.getAttribute( "id" )) ) { - nid = nid.replace( rescape, "\\$&" ); - } else { - context.setAttribute( "id", (nid = expando) ); - } - - // Prefix every selector in the list - groups = tokenize( selector ); - i = groups.length; - nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']"; - while ( i-- ) { - groups[i] = nidselect + " " + toSelector( groups[i] ); - } - newSelector = groups.join( "," ); - - // Expand context for sibling selectors - newContext = rsibling.test( selector ) && testContext( context.parentNode ) || - context; - } - - if ( newSelector ) { - try { - push.apply( results, - newContext.querySelectorAll( newSelector ) - ); - return results; - } catch ( qsaError ) { - } finally { - if ( nid === expando ) { - context.removeAttribute( "id" ); - } - } - } - } - } - } - - // All others - return select( selector.replace( rtrim, "$1" ), context, results, seed ); -} - -/** - * Create key-value caches of limited size - * @returns {function(string, object)} Returns the Object data after storing it on itself with - * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) - * deleting the oldest entry - */ -function createCache() { - var keys = []; - - function cache( key, value ) { - // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) - if ( keys.push( key + " " ) > Expr.cacheLength ) { - // Only keep the most recent entries - delete cache[ keys.shift() ]; - } - return (cache[ key + " " ] = value); - } - return cache; -} - -/** - * Mark a function for special use by Sizzle - * @param {Function} fn The function to mark - */ -function markFunction( fn ) { - fn[ expando ] = true; - return fn; -} - -/** - * Support testing using an element - * @param {Function} fn Passed the created div and expects a boolean result - */ -function assert( fn ) { - var div = document.createElement("div"); - - try { - return !!fn( div ); - } catch (e) { - return false; - } finally { - // Remove from its parent by default - if ( div.parentNode ) { - div.parentNode.removeChild( div ); - } - // release memory in IE - div = null; - } -} - -/** - * Adds the same handler for all of the specified attrs - * @param {String} attrs Pipe-separated list of attributes - * @param {Function} handler The method that will be applied - */ -function addHandle( attrs, handler ) { - var arr = attrs.split("|"), - i = arr.length; - - while ( i-- ) { - Expr.attrHandle[ arr[i] ] = handler; - } -} - -/** - * Checks document order of two siblings - * @param {Element} a - * @param {Element} b - * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b - */ -function siblingCheck( a, b ) { - var cur = b && a, - diff = cur && a.nodeType === 1 && b.nodeType === 1 && - ( ~b.sourceIndex || MAX_NEGATIVE ) - - ( ~a.sourceIndex || MAX_NEGATIVE ); - - // Use IE sourceIndex if available on both nodes - if ( diff ) { - return diff; - } - - // Check if b follows a - if ( cur ) { - while ( (cur = cur.nextSibling) ) { - if ( cur === b ) { - return -1; - } - } - } - - return a ? 1 : -1; -} - -/** - * Returns a function to use in pseudos for input types - * @param {String} type - */ -function createInputPseudo( type ) { - return function( elem ) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && elem.type === type; - }; -} - -/** - * Returns a function to use in pseudos for buttons - * @param {String} type - */ -function createButtonPseudo( type ) { - return function( elem ) { - var name = elem.nodeName.toLowerCase(); - return (name === "input" || name === "button") && elem.type === type; - }; -} - -/** - * Returns a function to use in pseudos for positionals - * @param {Function} fn - */ -function createPositionalPseudo( fn ) { - return markFunction(function( argument ) { - argument = +argument; - return markFunction(function( seed, matches ) { - var j, - matchIndexes = fn( [], seed.length, argument ), - i = matchIndexes.length; - - // Match elements found at the specified indexes - while ( i-- ) { - if ( seed[ (j = matchIndexes[i]) ] ) { - seed[j] = !(matches[j] = seed[j]); - } - } - }); - }); -} - -/** - * Checks a node for validity as a Sizzle context - * @param {Element|Object=} context - * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value - */ -function testContext( context ) { - return context && typeof context.getElementsByTagName !== "undefined" && context; -} - -// Expose support vars for convenience -support = Sizzle.support = {}; - -/** - * Detects XML nodes - * @param {Element|Object} elem An element or a document - * @returns {Boolean} True iff elem is a non-HTML XML node - */ -isXML = Sizzle.isXML = function( elem ) { - // documentElement is verified for cases where it doesn't yet exist - // (such as loading iframes in IE - #4833) - var documentElement = elem && (elem.ownerDocument || elem).documentElement; - return documentElement ? documentElement.nodeName !== "HTML" : false; -}; - -/** - * Sets document-related variables once based on the current document - * @param {Element|Object} [doc] An element or document object to use to set the document - * @returns {Object} Returns the current document - */ -setDocument = Sizzle.setDocument = function( node ) { - var hasCompare, parent, - doc = node ? node.ownerDocument || node : preferredDoc; - - // Return early if doc is invalid or already selected - if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { - return document; - } - - // Update global variables - document = doc; - docElem = document.documentElement; - documentIsHTML = !isXML( document ); - - // Support: IE 9-11, Edge - // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) - if ( (parent = document.defaultView) && parent.top !== parent ) { - // Support: IE 11 - if ( parent.addEventListener ) { - parent.addEventListener( "unload", unloadHandler, false ); - - // Support: IE 9 - 10 only - } else if ( parent.attachEvent ) { - parent.attachEvent( "onunload", unloadHandler ); - } - } - - /* Attributes - ---------------------------------------------------------------------- */ - - // Support: IE<8 - // Verify that getAttribute really returns attributes and not properties - // (excepting IE8 booleans) - support.attributes = assert(function( div ) { - div.className = "i"; - return !div.getAttribute("className"); - }); - - /* getElement(s)By* - ---------------------------------------------------------------------- */ - - // Check if getElementsByTagName("*") returns only elements - support.getElementsByTagName = assert(function( div ) { - div.appendChild( document.createComment("") ); - return !div.getElementsByTagName("*").length; - }); - - // Support: IE<9 - support.getElementsByClassName = rnative.test( document.getElementsByClassName ); - - // Support: IE<10 - // Check if getElementById returns elements by name - // The broken getElementById methods don't pick up programatically-set names, - // so use a roundabout getElementsByName test - support.getById = assert(function( div ) { - docElem.appendChild( div ).id = expando; - return !document.getElementsByName || !document.getElementsByName( expando ).length; - }); - - // ID find and filter - if ( support.getById ) { - Expr.find["ID"] = function( id, context ) { - if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { - var m = context.getElementById( id ); - return m ? [ m ] : []; - } - }; - Expr.filter["ID"] = function( id ) { - var attrId = id.replace( runescape, funescape ); - return function( elem ) { - return elem.getAttribute("id") === attrId; - }; - }; - } else { - // Support: IE6/7 - // getElementById is not reliable as a find shortcut - delete Expr.find["ID"]; - - Expr.filter["ID"] = function( id ) { - var attrId = id.replace( runescape, funescape ); - return function( elem ) { - var node = typeof elem.getAttributeNode !== "undefined" && - elem.getAttributeNode("id"); - return node && node.value === attrId; - }; - }; - } - - // Tag - Expr.find["TAG"] = support.getElementsByTagName ? - function( tag, context ) { - if ( typeof context.getElementsByTagName !== "undefined" ) { - return context.getElementsByTagName( tag ); - - // DocumentFragment nodes don't have gEBTN - } else if ( support.qsa ) { - return context.querySelectorAll( tag ); - } - } : - - function( tag, context ) { - var elem, - tmp = [], - i = 0, - // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too - results = context.getElementsByTagName( tag ); - - // Filter out possible comments - if ( tag === "*" ) { - while ( (elem = results[i++]) ) { - if ( elem.nodeType === 1 ) { - tmp.push( elem ); - } - } - - return tmp; - } - return results; - }; - - // Class - Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { - if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { - return context.getElementsByClassName( className ); - } - }; - - /* QSA/matchesSelector - ---------------------------------------------------------------------- */ - - // QSA and matchesSelector support - - // matchesSelector(:active) reports false when true (IE9/Opera 11.5) - rbuggyMatches = []; - - // qSa(:focus) reports false when true (Chrome 21) - // We allow this because of a bug in IE8/9 that throws an error - // whenever `document.activeElement` is accessed on an iframe - // So, we allow :focus to pass through QSA all the time to avoid the IE error - // See http://bugs.jquery.com/ticket/13378 - rbuggyQSA = []; - - if ( (support.qsa = rnative.test( document.querySelectorAll )) ) { - // Build QSA regex - // Regex strategy adopted from Diego Perini - assert(function( div ) { - // Select is set to empty string on purpose - // This is to test IE's treatment of not explicitly - // setting a boolean content attribute, - // since its presence should be enough - // http://bugs.jquery.com/ticket/12359 - docElem.appendChild( div ).innerHTML = "" + - ""; - - // Support: IE8, Opera 11-12.16 - // Nothing should be selected when empty strings follow ^= or $= or *= - // The test attribute must be unknown in Opera but "safe" for WinRT - // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section - if ( div.querySelectorAll("[msallowcapture^='']").length ) { - rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); - } - - // Support: IE8 - // Boolean attributes and "value" are not treated correctly - if ( !div.querySelectorAll("[selected]").length ) { - rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); - } - - // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ - if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) { - rbuggyQSA.push("~="); - } - - // Webkit/Opera - :checked should return selected option elements - // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked - // IE8 throws error here and will not see later tests - if ( !div.querySelectorAll(":checked").length ) { - rbuggyQSA.push(":checked"); - } - - // Support: Safari 8+, iOS 8+ - // https://bugs.webkit.org/show_bug.cgi?id=136851 - // In-page `selector#id sibing-combinator selector` fails - if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) { - rbuggyQSA.push(".#.+[+~]"); - } - }); - - assert(function( div ) { - // Support: Windows 8 Native Apps - // The type and name attributes are restricted during .innerHTML assignment - var input = document.createElement("input"); - input.setAttribute( "type", "hidden" ); - div.appendChild( input ).setAttribute( "name", "D" ); - - // Support: IE8 - // Enforce case-sensitivity of name attribute - if ( div.querySelectorAll("[name=d]").length ) { - rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); - } - - // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) - // IE8 throws error here and will not see later tests - if ( !div.querySelectorAll(":enabled").length ) { - rbuggyQSA.push( ":enabled", ":disabled" ); - } - - // Opera 10-11 does not throw on post-comma invalid pseudos - div.querySelectorAll("*,:x"); - rbuggyQSA.push(",.*:"); - }); - } - - if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || - docElem.webkitMatchesSelector || - docElem.mozMatchesSelector || - docElem.oMatchesSelector || - docElem.msMatchesSelector) )) ) { - - assert(function( div ) { - // Check to see if it's possible to do matchesSelector - // on a disconnected node (IE 9) - support.disconnectedMatch = matches.call( div, "div" ); - - // This should fail with an exception - // Gecko does not error, returns false instead - matches.call( div, "[s!='']:x" ); - rbuggyMatches.push( "!=", pseudos ); - }); - } - - rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); - rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); - - /* Contains - ---------------------------------------------------------------------- */ - hasCompare = rnative.test( docElem.compareDocumentPosition ); - - // Element contains another - // Purposefully self-exclusive - // As in, an element does not contain itself - contains = hasCompare || rnative.test( docElem.contains ) ? - function( a, b ) { - var adown = a.nodeType === 9 ? a.documentElement : a, - bup = b && b.parentNode; - return a === bup || !!( bup && bup.nodeType === 1 && ( - adown.contains ? - adown.contains( bup ) : - a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 - )); - } : - function( a, b ) { - if ( b ) { - while ( (b = b.parentNode) ) { - if ( b === a ) { - return true; - } - } - } - return false; - }; - - /* Sorting - ---------------------------------------------------------------------- */ - - // Document order sorting - sortOrder = hasCompare ? - function( a, b ) { - - // Flag for duplicate removal - if ( a === b ) { - hasDuplicate = true; - return 0; - } - - // Sort on method existence if only one input has compareDocumentPosition - var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; - if ( compare ) { - return compare; - } - - // Calculate position if both inputs belong to the same document - compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? - a.compareDocumentPosition( b ) : - - // Otherwise we know they are disconnected - 1; - - // Disconnected nodes - if ( compare & 1 || - (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { - - // Choose the first element that is related to our preferred document - if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { - return -1; - } - if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { - return 1; - } - - // Maintain original order - return sortInput ? - ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : - 0; - } - - return compare & 4 ? -1 : 1; - } : - function( a, b ) { - // Exit early if the nodes are identical - if ( a === b ) { - hasDuplicate = true; - return 0; - } - - var cur, - i = 0, - aup = a.parentNode, - bup = b.parentNode, - ap = [ a ], - bp = [ b ]; - - // Parentless nodes are either documents or disconnected - if ( !aup || !bup ) { - return a === document ? -1 : - b === document ? 1 : - aup ? -1 : - bup ? 1 : - sortInput ? - ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : - 0; - - // If the nodes are siblings, we can do a quick check - } else if ( aup === bup ) { - return siblingCheck( a, b ); - } - - // Otherwise we need full lists of their ancestors for comparison - cur = a; - while ( (cur = cur.parentNode) ) { - ap.unshift( cur ); - } - cur = b; - while ( (cur = cur.parentNode) ) { - bp.unshift( cur ); - } - - // Walk down the tree looking for a discrepancy - while ( ap[i] === bp[i] ) { - i++; - } - - return i ? - // Do a sibling check if the nodes have a common ancestor - siblingCheck( ap[i], bp[i] ) : - - // Otherwise nodes in our document sort first - ap[i] === preferredDoc ? -1 : - bp[i] === preferredDoc ? 1 : - 0; - }; - - return document; -}; - -Sizzle.matches = function( expr, elements ) { - return Sizzle( expr, null, null, elements ); -}; - -Sizzle.matchesSelector = function( elem, expr ) { - // Set document vars if needed - if ( ( elem.ownerDocument || elem ) !== document ) { - setDocument( elem ); - } - - // Make sure that attribute selectors are quoted - expr = expr.replace( rattributeQuotes, "='$1']" ); - - if ( support.matchesSelector && documentIsHTML && - !compilerCache[ expr + " " ] && - ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && - ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { - - try { - var ret = matches.call( elem, expr ); - - // IE 9's matchesSelector returns false on disconnected nodes - if ( ret || support.disconnectedMatch || - // As well, disconnected nodes are said to be in a document - // fragment in IE 9 - elem.document && elem.document.nodeType !== 11 ) { - return ret; - } - } catch (e) {} - } - - return Sizzle( expr, document, null, [ elem ] ).length > 0; -}; - -Sizzle.contains = function( context, elem ) { - // Set document vars if needed - if ( ( context.ownerDocument || context ) !== document ) { - setDocument( context ); - } - return contains( context, elem ); -}; - -Sizzle.attr = function( elem, name ) { - // Set document vars if needed - if ( ( elem.ownerDocument || elem ) !== document ) { - setDocument( elem ); - } - - var fn = Expr.attrHandle[ name.toLowerCase() ], - // Don't get fooled by Object.prototype properties (jQuery #13807) - val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? - fn( elem, name, !documentIsHTML ) : - undefined; - - return val !== undefined ? - val : - support.attributes || !documentIsHTML ? - elem.getAttribute( name ) : - (val = elem.getAttributeNode(name)) && val.specified ? - val.value : - null; -}; - -Sizzle.error = function( msg ) { - throw new Error( "Syntax error, unrecognized expression: " + msg ); -}; - -/** - * Document sorting and removing duplicates - * @param {ArrayLike} results - */ -Sizzle.uniqueSort = function( results ) { - var elem, - duplicates = [], - j = 0, - i = 0; - - // Unless we *know* we can detect duplicates, assume their presence - hasDuplicate = !support.detectDuplicates; - sortInput = !support.sortStable && results.slice( 0 ); - results.sort( sortOrder ); - - if ( hasDuplicate ) { - while ( (elem = results[i++]) ) { - if ( elem === results[ i ] ) { - j = duplicates.push( i ); - } - } - while ( j-- ) { - results.splice( duplicates[ j ], 1 ); - } - } - - // Clear input after sorting to release objects - // See https://github.com/jquery/sizzle/pull/225 - sortInput = null; - - return results; -}; - -/** - * Utility function for retrieving the text value of an array of DOM nodes - * @param {Array|Element} elem - */ -getText = Sizzle.getText = function( elem ) { - var node, - ret = "", - i = 0, - nodeType = elem.nodeType; - - if ( !nodeType ) { - // If no nodeType, this is expected to be an array - while ( (node = elem[i++]) ) { - // Do not traverse comment nodes - ret += getText( node ); - } - } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { - // Use textContent for elements - // innerText usage removed for consistency of new lines (jQuery #11153) - if ( typeof elem.textContent === "string" ) { - return elem.textContent; - } else { - // Traverse its children - for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { - ret += getText( elem ); - } - } - } else if ( nodeType === 3 || nodeType === 4 ) { - return elem.nodeValue; - } - // Do not include comment or processing instruction nodes - - return ret; -}; - -Expr = Sizzle.selectors = { - - // Can be adjusted by the user - cacheLength: 50, - - createPseudo: markFunction, - - match: matchExpr, - - attrHandle: {}, - - find: {}, - - relative: { - ">": { dir: "parentNode", first: true }, - " ": { dir: "parentNode" }, - "+": { dir: "previousSibling", first: true }, - "~": { dir: "previousSibling" } - }, - - preFilter: { - "ATTR": function( match ) { - match[1] = match[1].replace( runescape, funescape ); - - // Move the given value to match[3] whether quoted or unquoted - match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); - - if ( match[2] === "~=" ) { - match[3] = " " + match[3] + " "; - } - - return match.slice( 0, 4 ); - }, - - "CHILD": function( match ) { - /* matches from matchExpr["CHILD"] - 1 type (only|nth|...) - 2 what (child|of-type) - 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) - 4 xn-component of xn+y argument ([+-]?\d*n|) - 5 sign of xn-component - 6 x of xn-component - 7 sign of y-component - 8 y of y-component - */ - match[1] = match[1].toLowerCase(); - - if ( match[1].slice( 0, 3 ) === "nth" ) { - // nth-* requires argument - if ( !match[3] ) { - Sizzle.error( match[0] ); - } - - // numeric x and y parameters for Expr.filter.CHILD - // remember that false/true cast respectively to 0/1 - match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); - match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); - - // other types prohibit arguments - } else if ( match[3] ) { - Sizzle.error( match[0] ); - } - - return match; - }, - - "PSEUDO": function( match ) { - var excess, - unquoted = !match[6] && match[2]; - - if ( matchExpr["CHILD"].test( match[0] ) ) { - return null; - } - - // Accept quoted arguments as-is - if ( match[3] ) { - match[2] = match[4] || match[5] || ""; - - // Strip excess characters from unquoted arguments - } else if ( unquoted && rpseudo.test( unquoted ) && - // Get excess from tokenize (recursively) - (excess = tokenize( unquoted, true )) && - // advance to the next closing parenthesis - (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { - - // excess is a negative index - match[0] = match[0].slice( 0, excess ); - match[2] = unquoted.slice( 0, excess ); - } - - // Return only captures needed by the pseudo filter method (type and argument) - return match.slice( 0, 3 ); - } - }, - - filter: { - - "TAG": function( nodeNameSelector ) { - var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); - return nodeNameSelector === "*" ? - function() { return true; } : - function( elem ) { - return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; - }; - }, - - "CLASS": function( className ) { - var pattern = classCache[ className + " " ]; - - return pattern || - (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && - classCache( className, function( elem ) { - return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); - }); - }, - - "ATTR": function( name, operator, check ) { - return function( elem ) { - var result = Sizzle.attr( elem, name ); - - if ( result == null ) { - return operator === "!="; - } - if ( !operator ) { - return true; - } - - result += ""; - - return operator === "=" ? result === check : - operator === "!=" ? result !== check : - operator === "^=" ? check && result.indexOf( check ) === 0 : - operator === "*=" ? check && result.indexOf( check ) > -1 : - operator === "$=" ? check && result.slice( -check.length ) === check : - operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : - operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : - false; - }; - }, - - "CHILD": function( type, what, argument, first, last ) { - var simple = type.slice( 0, 3 ) !== "nth", - forward = type.slice( -4 ) !== "last", - ofType = what === "of-type"; - - return first === 1 && last === 0 ? - - // Shortcut for :nth-*(n) - function( elem ) { - return !!elem.parentNode; - } : - - function( elem, context, xml ) { - var cache, uniqueCache, outerCache, node, nodeIndex, start, - dir = simple !== forward ? "nextSibling" : "previousSibling", - parent = elem.parentNode, - name = ofType && elem.nodeName.toLowerCase(), - useCache = !xml && !ofType, - diff = false; - - if ( parent ) { - - // :(first|last|only)-(child|of-type) - if ( simple ) { - while ( dir ) { - node = elem; - while ( (node = node[ dir ]) ) { - if ( ofType ? - node.nodeName.toLowerCase() === name : - node.nodeType === 1 ) { - - return false; - } - } - // Reverse direction for :only-* (if we haven't yet done so) - start = dir = type === "only" && !start && "nextSibling"; - } - return true; - } - - start = [ forward ? parent.firstChild : parent.lastChild ]; - - // non-xml :nth-child(...) stores cache data on `parent` - if ( forward && useCache ) { - - // Seek `elem` from a previously-cached index - - // ...in a gzip-friendly way - node = parent; - outerCache = node[ expando ] || (node[ expando ] = {}); - - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[ node.uniqueID ] || - (outerCache[ node.uniqueID ] = {}); - - cache = uniqueCache[ type ] || []; - nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; - diff = nodeIndex && cache[ 2 ]; - node = nodeIndex && parent.childNodes[ nodeIndex ]; - - while ( (node = ++nodeIndex && node && node[ dir ] || - - // Fallback to seeking `elem` from the start - (diff = nodeIndex = 0) || start.pop()) ) { - - // When found, cache indexes on `parent` and break - if ( node.nodeType === 1 && ++diff && node === elem ) { - uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; - break; - } - } - - } else { - // Use previously-cached element index if available - if ( useCache ) { - // ...in a gzip-friendly way - node = elem; - outerCache = node[ expando ] || (node[ expando ] = {}); - - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[ node.uniqueID ] || - (outerCache[ node.uniqueID ] = {}); - - cache = uniqueCache[ type ] || []; - nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; - diff = nodeIndex; - } - - // xml :nth-child(...) - // or :nth-last-child(...) or :nth(-last)?-of-type(...) - if ( diff === false ) { - // Use the same loop as above to seek `elem` from the start - while ( (node = ++nodeIndex && node && node[ dir ] || - (diff = nodeIndex = 0) || start.pop()) ) { - - if ( ( ofType ? - node.nodeName.toLowerCase() === name : - node.nodeType === 1 ) && - ++diff ) { - - // Cache the index of each encountered element - if ( useCache ) { - outerCache = node[ expando ] || (node[ expando ] = {}); - - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[ node.uniqueID ] || - (outerCache[ node.uniqueID ] = {}); - - uniqueCache[ type ] = [ dirruns, diff ]; - } - - if ( node === elem ) { - break; - } - } - } - } - } - - // Incorporate the offset, then check against cycle size - diff -= last; - return diff === first || ( diff % first === 0 && diff / first >= 0 ); - } - }; - }, - - "PSEUDO": function( pseudo, argument ) { - // pseudo-class names are case-insensitive - // http://www.w3.org/TR/selectors/#pseudo-classes - // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters - // Remember that setFilters inherits from pseudos - var args, - fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || - Sizzle.error( "unsupported pseudo: " + pseudo ); - - // The user may use createPseudo to indicate that - // arguments are needed to create the filter function - // just as Sizzle does - if ( fn[ expando ] ) { - return fn( argument ); - } - - // But maintain support for old signatures - if ( fn.length > 1 ) { - args = [ pseudo, pseudo, "", argument ]; - return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? - markFunction(function( seed, matches ) { - var idx, - matched = fn( seed, argument ), - i = matched.length; - while ( i-- ) { - idx = indexOf( seed, matched[i] ); - seed[ idx ] = !( matches[ idx ] = matched[i] ); - } - }) : - function( elem ) { - return fn( elem, 0, args ); - }; - } - - return fn; - } - }, - - pseudos: { - // Potentially complex pseudos - "not": markFunction(function( selector ) { - // Trim the selector passed to compile - // to avoid treating leading and trailing - // spaces as combinators - var input = [], - results = [], - matcher = compile( selector.replace( rtrim, "$1" ) ); - - return matcher[ expando ] ? - markFunction(function( seed, matches, context, xml ) { - var elem, - unmatched = matcher( seed, null, xml, [] ), - i = seed.length; - - // Match elements unmatched by `matcher` - while ( i-- ) { - if ( (elem = unmatched[i]) ) { - seed[i] = !(matches[i] = elem); - } - } - }) : - function( elem, context, xml ) { - input[0] = elem; - matcher( input, null, xml, results ); - // Don't keep the element (issue #299) - input[0] = null; - return !results.pop(); - }; - }), - - "has": markFunction(function( selector ) { - return function( elem ) { - return Sizzle( selector, elem ).length > 0; - }; - }), - - "contains": markFunction(function( text ) { - text = text.replace( runescape, funescape ); - return function( elem ) { - return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; - }; - }), - - // "Whether an element is represented by a :lang() selector - // is based solely on the element's language value - // being equal to the identifier C, - // or beginning with the identifier C immediately followed by "-". - // The matching of C against the element's language value is performed case-insensitively. - // The identifier C does not have to be a valid language name." - // http://www.w3.org/TR/selectors/#lang-pseudo - "lang": markFunction( function( lang ) { - // lang value must be a valid identifier - if ( !ridentifier.test(lang || "") ) { - Sizzle.error( "unsupported lang: " + lang ); - } - lang = lang.replace( runescape, funescape ).toLowerCase(); - return function( elem ) { - var elemLang; - do { - if ( (elemLang = documentIsHTML ? - elem.lang : - elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { - - elemLang = elemLang.toLowerCase(); - return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; - } - } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); - return false; - }; - }), - - // Miscellaneous - "target": function( elem ) { - var hash = window.location && window.location.hash; - return hash && hash.slice( 1 ) === elem.id; - }, - - "root": function( elem ) { - return elem === docElem; - }, - - "focus": function( elem ) { - return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); - }, - - // Boolean properties - "enabled": function( elem ) { - return elem.disabled === false; - }, - - "disabled": function( elem ) { - return elem.disabled === true; - }, - - "checked": function( elem ) { - // In CSS3, :checked should return both checked and selected elements - // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked - var nodeName = elem.nodeName.toLowerCase(); - return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); - }, - - "selected": function( elem ) { - // Accessing this property makes selected-by-default - // options in Safari work properly - if ( elem.parentNode ) { - elem.parentNode.selectedIndex; - } - - return elem.selected === true; - }, - - // Contents - "empty": function( elem ) { - // http://www.w3.org/TR/selectors/#empty-pseudo - // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), - // but not by others (comment: 8; processing instruction: 7; etc.) - // nodeType < 6 works because attributes (2) do not appear as children - for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { - if ( elem.nodeType < 6 ) { - return false; - } - } - return true; - }, - - "parent": function( elem ) { - return !Expr.pseudos["empty"]( elem ); - }, - - // Element/input types - "header": function( elem ) { - return rheader.test( elem.nodeName ); - }, - - "input": function( elem ) { - return rinputs.test( elem.nodeName ); - }, - - "button": function( elem ) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && elem.type === "button" || name === "button"; - }, - - "text": function( elem ) { - var attr; - return elem.nodeName.toLowerCase() === "input" && - elem.type === "text" && - - // Support: IE<8 - // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" - ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); - }, - - // Position-in-collection - "first": createPositionalPseudo(function() { - return [ 0 ]; - }), - - "last": createPositionalPseudo(function( matchIndexes, length ) { - return [ length - 1 ]; - }), - - "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { - return [ argument < 0 ? argument + length : argument ]; - }), - - "even": createPositionalPseudo(function( matchIndexes, length ) { - var i = 0; - for ( ; i < length; i += 2 ) { - matchIndexes.push( i ); - } - return matchIndexes; - }), - - "odd": createPositionalPseudo(function( matchIndexes, length ) { - var i = 1; - for ( ; i < length; i += 2 ) { - matchIndexes.push( i ); - } - return matchIndexes; - }), - - "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { - var i = argument < 0 ? argument + length : argument; - for ( ; --i >= 0; ) { - matchIndexes.push( i ); - } - return matchIndexes; - }), - - "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { - var i = argument < 0 ? argument + length : argument; - for ( ; ++i < length; ) { - matchIndexes.push( i ); - } - return matchIndexes; - }) - } -}; - -Expr.pseudos["nth"] = Expr.pseudos["eq"]; - -// Add button/input type pseudos -for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { - Expr.pseudos[ i ] = createInputPseudo( i ); -} -for ( i in { submit: true, reset: true } ) { - Expr.pseudos[ i ] = createButtonPseudo( i ); -} - -// Easy API for creating new setFilters -function setFilters() {} -setFilters.prototype = Expr.filters = Expr.pseudos; -Expr.setFilters = new setFilters(); - -tokenize = Sizzle.tokenize = function( selector, parseOnly ) { - var matched, match, tokens, type, - soFar, groups, preFilters, - cached = tokenCache[ selector + " " ]; - - if ( cached ) { - return parseOnly ? 0 : cached.slice( 0 ); - } - - soFar = selector; - groups = []; - preFilters = Expr.preFilter; - - while ( soFar ) { - - // Comma and first run - if ( !matched || (match = rcomma.exec( soFar )) ) { - if ( match ) { - // Don't consume trailing commas as valid - soFar = soFar.slice( match[0].length ) || soFar; - } - groups.push( (tokens = []) ); - } - - matched = false; - - // Combinators - if ( (match = rcombinators.exec( soFar )) ) { - matched = match.shift(); - tokens.push({ - value: matched, - // Cast descendant combinators to space - type: match[0].replace( rtrim, " " ) - }); - soFar = soFar.slice( matched.length ); - } - - // Filters - for ( type in Expr.filter ) { - if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || - (match = preFilters[ type ]( match ))) ) { - matched = match.shift(); - tokens.push({ - value: matched, - type: type, - matches: match - }); - soFar = soFar.slice( matched.length ); - } - } - - if ( !matched ) { - break; - } - } - - // Return the length of the invalid excess - // if we're just parsing - // Otherwise, throw an error or return tokens - return parseOnly ? - soFar.length : - soFar ? - Sizzle.error( selector ) : - // Cache the tokens - tokenCache( selector, groups ).slice( 0 ); -}; - -function toSelector( tokens ) { - var i = 0, - len = tokens.length, - selector = ""; - for ( ; i < len; i++ ) { - selector += tokens[i].value; - } - return selector; -} - -function addCombinator( matcher, combinator, base ) { - var dir = combinator.dir, - checkNonElements = base && dir === "parentNode", - doneName = done++; - - return combinator.first ? - // Check against closest ancestor/preceding element - function( elem, context, xml ) { - while ( (elem = elem[ dir ]) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - return matcher( elem, context, xml ); - } - } - } : - - // Check against all ancestor/preceding elements - function( elem, context, xml ) { - var oldCache, uniqueCache, outerCache, - newCache = [ dirruns, doneName ]; - - // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching - if ( xml ) { - while ( (elem = elem[ dir ]) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - if ( matcher( elem, context, xml ) ) { - return true; - } - } - } - } else { - while ( (elem = elem[ dir ]) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - outerCache = elem[ expando ] || (elem[ expando ] = {}); - - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {}); - - if ( (oldCache = uniqueCache[ dir ]) && - oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { - - // Assign to newCache so results back-propagate to previous elements - return (newCache[ 2 ] = oldCache[ 2 ]); - } else { - // Reuse newcache so results back-propagate to previous elements - uniqueCache[ dir ] = newCache; - - // A match means we're done; a fail means we have to keep checking - if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { - return true; - } - } - } - } - } - }; -} - -function elementMatcher( matchers ) { - return matchers.length > 1 ? - function( elem, context, xml ) { - var i = matchers.length; - while ( i-- ) { - if ( !matchers[i]( elem, context, xml ) ) { - return false; - } - } - return true; - } : - matchers[0]; -} - -function multipleContexts( selector, contexts, results ) { - var i = 0, - len = contexts.length; - for ( ; i < len; i++ ) { - Sizzle( selector, contexts[i], results ); - } - return results; -} - -function condense( unmatched, map, filter, context, xml ) { - var elem, - newUnmatched = [], - i = 0, - len = unmatched.length, - mapped = map != null; - - for ( ; i < len; i++ ) { - if ( (elem = unmatched[i]) ) { - if ( !filter || filter( elem, context, xml ) ) { - newUnmatched.push( elem ); - if ( mapped ) { - map.push( i ); - } - } - } - } - - return newUnmatched; -} - -function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { - if ( postFilter && !postFilter[ expando ] ) { - postFilter = setMatcher( postFilter ); - } - if ( postFinder && !postFinder[ expando ] ) { - postFinder = setMatcher( postFinder, postSelector ); - } - return markFunction(function( seed, results, context, xml ) { - var temp, i, elem, - preMap = [], - postMap = [], - preexisting = results.length, - - // Get initial elements from seed or context - elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), - - // Prefilter to get matcher input, preserving a map for seed-results synchronization - matcherIn = preFilter && ( seed || !selector ) ? - condense( elems, preMap, preFilter, context, xml ) : - elems, - - matcherOut = matcher ? - // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, - postFinder || ( seed ? preFilter : preexisting || postFilter ) ? - - // ...intermediate processing is necessary - [] : - - // ...otherwise use results directly - results : - matcherIn; - - // Find primary matches - if ( matcher ) { - matcher( matcherIn, matcherOut, context, xml ); - } - - // Apply postFilter - if ( postFilter ) { - temp = condense( matcherOut, postMap ); - postFilter( temp, [], context, xml ); - - // Un-match failing elements by moving them back to matcherIn - i = temp.length; - while ( i-- ) { - if ( (elem = temp[i]) ) { - matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); - } - } - } - - if ( seed ) { - if ( postFinder || preFilter ) { - if ( postFinder ) { - // Get the final matcherOut by condensing this intermediate into postFinder contexts - temp = []; - i = matcherOut.length; - while ( i-- ) { - if ( (elem = matcherOut[i]) ) { - // Restore matcherIn since elem is not yet a final match - temp.push( (matcherIn[i] = elem) ); - } - } - postFinder( null, (matcherOut = []), temp, xml ); - } - - // Move matched elements from seed to results to keep them synchronized - i = matcherOut.length; - while ( i-- ) { - if ( (elem = matcherOut[i]) && - (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { - - seed[temp] = !(results[temp] = elem); - } - } - } - - // Add elements to results, through postFinder if defined - } else { - matcherOut = condense( - matcherOut === results ? - matcherOut.splice( preexisting, matcherOut.length ) : - matcherOut - ); - if ( postFinder ) { - postFinder( null, results, matcherOut, xml ); - } else { - push.apply( results, matcherOut ); - } - } - }); -} - -function matcherFromTokens( tokens ) { - var checkContext, matcher, j, - len = tokens.length, - leadingRelative = Expr.relative[ tokens[0].type ], - implicitRelative = leadingRelative || Expr.relative[" "], - i = leadingRelative ? 1 : 0, - - // The foundational matcher ensures that elements are reachable from top-level context(s) - matchContext = addCombinator( function( elem ) { - return elem === checkContext; - }, implicitRelative, true ), - matchAnyContext = addCombinator( function( elem ) { - return indexOf( checkContext, elem ) > -1; - }, implicitRelative, true ), - matchers = [ function( elem, context, xml ) { - var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( - (checkContext = context).nodeType ? - matchContext( elem, context, xml ) : - matchAnyContext( elem, context, xml ) ); - // Avoid hanging onto element (issue #299) - checkContext = null; - return ret; - } ]; - - for ( ; i < len; i++ ) { - if ( (matcher = Expr.relative[ tokens[i].type ]) ) { - matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; - } else { - matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); - - // Return special upon seeing a positional matcher - if ( matcher[ expando ] ) { - // Find the next relative operator (if any) for proper handling - j = ++i; - for ( ; j < len; j++ ) { - if ( Expr.relative[ tokens[j].type ] ) { - break; - } - } - return setMatcher( - i > 1 && elementMatcher( matchers ), - i > 1 && toSelector( - // If the preceding token was a descendant combinator, insert an implicit any-element `*` - tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) - ).replace( rtrim, "$1" ), - matcher, - i < j && matcherFromTokens( tokens.slice( i, j ) ), - j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), - j < len && toSelector( tokens ) - ); - } - matchers.push( matcher ); - } - } - - return elementMatcher( matchers ); -} - -function matcherFromGroupMatchers( elementMatchers, setMatchers ) { - var bySet = setMatchers.length > 0, - byElement = elementMatchers.length > 0, - superMatcher = function( seed, context, xml, results, outermost ) { - var elem, j, matcher, - matchedCount = 0, - i = "0", - unmatched = seed && [], - setMatched = [], - contextBackup = outermostContext, - // We must always have either seed elements or outermost context - elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), - // Use integer dirruns iff this is the outermost matcher - dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), - len = elems.length; - - if ( outermost ) { - outermostContext = context === document || context || outermost; - } - - // Add elements passing elementMatchers directly to results - // Support: IE<9, Safari - // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id - for ( ; i !== len && (elem = elems[i]) != null; i++ ) { - if ( byElement && elem ) { - j = 0; - if ( !context && elem.ownerDocument !== document ) { - setDocument( elem ); - xml = !documentIsHTML; - } - while ( (matcher = elementMatchers[j++]) ) { - if ( matcher( elem, context || document, xml) ) { - results.push( elem ); - break; - } - } - if ( outermost ) { - dirruns = dirrunsUnique; - } - } - - // Track unmatched elements for set filters - if ( bySet ) { - // They will have gone through all possible matchers - if ( (elem = !matcher && elem) ) { - matchedCount--; - } - - // Lengthen the array for every element, matched or not - if ( seed ) { - unmatched.push( elem ); - } - } - } - - // `i` is now the count of elements visited above, and adding it to `matchedCount` - // makes the latter nonnegative. - matchedCount += i; - - // Apply set filters to unmatched elements - // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` - // equals `i`), unless we didn't visit _any_ elements in the above loop because we have - // no element matchers and no seed. - // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that - // case, which will result in a "00" `matchedCount` that differs from `i` but is also - // numerically zero. - if ( bySet && i !== matchedCount ) { - j = 0; - while ( (matcher = setMatchers[j++]) ) { - matcher( unmatched, setMatched, context, xml ); - } - - if ( seed ) { - // Reintegrate element matches to eliminate the need for sorting - if ( matchedCount > 0 ) { - while ( i-- ) { - if ( !(unmatched[i] || setMatched[i]) ) { - setMatched[i] = pop.call( results ); - } - } - } - - // Discard index placeholder values to get only actual matches - setMatched = condense( setMatched ); - } - - // Add matches to results - push.apply( results, setMatched ); - - // Seedless set matches succeeding multiple successful matchers stipulate sorting - if ( outermost && !seed && setMatched.length > 0 && - ( matchedCount + setMatchers.length ) > 1 ) { - - Sizzle.uniqueSort( results ); - } - } - - // Override manipulation of globals by nested matchers - if ( outermost ) { - dirruns = dirrunsUnique; - outermostContext = contextBackup; - } - - return unmatched; - }; - - return bySet ? - markFunction( superMatcher ) : - superMatcher; -} - -compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { - var i, - setMatchers = [], - elementMatchers = [], - cached = compilerCache[ selector + " " ]; - - if ( !cached ) { - // Generate a function of recursive functions that can be used to check each element - if ( !match ) { - match = tokenize( selector ); - } - i = match.length; - while ( i-- ) { - cached = matcherFromTokens( match[i] ); - if ( cached[ expando ] ) { - setMatchers.push( cached ); - } else { - elementMatchers.push( cached ); - } - } - - // Cache the compiled function - cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); - - // Save selector and tokenization - cached.selector = selector; - } - return cached; -}; - -/** - * A low-level selection function that works with Sizzle's compiled - * selector functions - * @param {String|Function} selector A selector or a pre-compiled - * selector function built with Sizzle.compile - * @param {Element} context - * @param {Array} [results] - * @param {Array} [seed] A set of elements to match against - */ -select = Sizzle.select = function( selector, context, results, seed ) { - var i, tokens, token, type, find, - compiled = typeof selector === "function" && selector, - match = !seed && tokenize( (selector = compiled.selector || selector) ); - - results = results || []; - - // Try to minimize operations if there is only one selector in the list and no seed - // (the latter of which guarantees us context) - if ( match.length === 1 ) { - - // Reduce context if the leading compound selector is an ID - tokens = match[0] = match[0].slice( 0 ); - if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && - support.getById && context.nodeType === 9 && documentIsHTML && - Expr.relative[ tokens[1].type ] ) { - - context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; - if ( !context ) { - return results; - - // Precompiled matchers will still verify ancestry, so step up a level - } else if ( compiled ) { - context = context.parentNode; - } - - selector = selector.slice( tokens.shift().value.length ); - } - - // Fetch a seed set for right-to-left matching - i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; - while ( i-- ) { - token = tokens[i]; - - // Abort if we hit a combinator - if ( Expr.relative[ (type = token.type) ] ) { - break; - } - if ( (find = Expr.find[ type ]) ) { - // Search, expanding context for leading sibling combinators - if ( (seed = find( - token.matches[0].replace( runescape, funescape ), - rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context - )) ) { - - // If seed is empty or no tokens remain, we can return early - tokens.splice( i, 1 ); - selector = seed.length && toSelector( tokens ); - if ( !selector ) { - push.apply( results, seed ); - return results; - } - - break; - } - } - } - } - - // Compile and execute a filtering function if one is not provided - // Provide `match` to avoid retokenization if we modified the selector above - ( compiled || compile( selector, match ) )( - seed, - context, - !documentIsHTML, - results, - !context || rsibling.test( selector ) && testContext( context.parentNode ) || context - ); - return results; -}; - -// One-time assignments - -// Sort stability -support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; - -// Support: Chrome 14-35+ -// Always assume duplicates if they aren't passed to the comparison function -support.detectDuplicates = !!hasDuplicate; - -// Initialize against the default document -setDocument(); - -// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) -// Detached nodes confoundingly follow *each other* -support.sortDetached = assert(function( div1 ) { - // Should return 1, but returns 4 (following) - return div1.compareDocumentPosition( document.createElement("div") ) & 1; -}); - -// Support: IE<8 -// Prevent attribute/property "interpolation" -// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx -if ( !assert(function( div ) { - div.innerHTML = ""; - return div.firstChild.getAttribute("href") === "#" ; -}) ) { - addHandle( "type|href|height|width", function( elem, name, isXML ) { - if ( !isXML ) { - return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); - } - }); -} - -// Support: IE<9 -// Use defaultValue in place of getAttribute("value") -if ( !support.attributes || !assert(function( div ) { - div.innerHTML = ""; - div.firstChild.setAttribute( "value", "" ); - return div.firstChild.getAttribute( "value" ) === ""; -}) ) { - addHandle( "value", function( elem, name, isXML ) { - if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { - return elem.defaultValue; - } - }); -} - -// Support: IE<9 -// Use getAttributeNode to fetch booleans when getAttribute lies -if ( !assert(function( div ) { - return div.getAttribute("disabled") == null; -}) ) { - addHandle( booleans, function( elem, name, isXML ) { - var val; - if ( !isXML ) { - return elem[ name ] === true ? name.toLowerCase() : - (val = elem.getAttributeNode( name )) && val.specified ? - val.value : - null; - } - }); -} - -return Sizzle; - -})( window ); - - - -jQuery.find = Sizzle; -jQuery.expr = Sizzle.selectors; -jQuery.expr[ ":" ] = jQuery.expr.pseudos; -jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; -jQuery.text = Sizzle.getText; -jQuery.isXMLDoc = Sizzle.isXML; -jQuery.contains = Sizzle.contains; - - - -var dir = function( elem, dir, until ) { - var matched = [], - truncate = until !== undefined; - - while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { - if ( elem.nodeType === 1 ) { - if ( truncate && jQuery( elem ).is( until ) ) { - break; - } - matched.push( elem ); - } - } - return matched; -}; - - -var siblings = function( n, elem ) { - var matched = []; - - for ( ; n; n = n.nextSibling ) { - if ( n.nodeType === 1 && n !== elem ) { - matched.push( n ); - } - } - - return matched; -}; - - -var rneedsContext = jQuery.expr.match.needsContext; - -var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ ); - - - -var risSimple = /^.[^:#\[\.,]*$/; - -// Implement the identical functionality for filter and not -function winnow( elements, qualifier, not ) { - if ( jQuery.isFunction( qualifier ) ) { - return jQuery.grep( elements, function( elem, i ) { - /* jshint -W018 */ - return !!qualifier.call( elem, i, elem ) !== not; - } ); - - } - - if ( qualifier.nodeType ) { - return jQuery.grep( elements, function( elem ) { - return ( elem === qualifier ) !== not; - } ); - - } - - if ( typeof qualifier === "string" ) { - if ( risSimple.test( qualifier ) ) { - return jQuery.filter( qualifier, elements, not ); - } - - qualifier = jQuery.filter( qualifier, elements ); - } - - return jQuery.grep( elements, function( elem ) { - return ( jQuery.inArray( elem, qualifier ) > -1 ) !== not; - } ); -} - -jQuery.filter = function( expr, elems, not ) { - var elem = elems[ 0 ]; - - if ( not ) { - expr = ":not(" + expr + ")"; - } - - return elems.length === 1 && elem.nodeType === 1 ? - jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : - jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { - return elem.nodeType === 1; - } ) ); -}; - -jQuery.fn.extend( { - find: function( selector ) { - var i, - ret = [], - self = this, - len = self.length; - - if ( typeof selector !== "string" ) { - return this.pushStack( jQuery( selector ).filter( function() { - for ( i = 0; i < len; i++ ) { - if ( jQuery.contains( self[ i ], this ) ) { - return true; - } - } - } ) ); - } - - for ( i = 0; i < len; i++ ) { - jQuery.find( selector, self[ i ], ret ); - } - - // Needed because $( selector, context ) becomes $( context ).find( selector ) - ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); - ret.selector = this.selector ? this.selector + " " + selector : selector; - return ret; - }, - filter: function( selector ) { - return this.pushStack( winnow( this, selector || [], false ) ); - }, - not: function( selector ) { - return this.pushStack( winnow( this, selector || [], true ) ); - }, - is: function( selector ) { - return !!winnow( - this, - - // If this is a positional/relative selector, check membership in the returned set - // so $("p:first").is("p:last") won't return true for a doc with two "p". - typeof selector === "string" && rneedsContext.test( selector ) ? - jQuery( selector ) : - selector || [], - false - ).length; - } -} ); - - -// Initialize a jQuery object - - -// A central reference to the root jQuery(document) -var rootjQuery, - - // A simple way to check for HTML strings - // Prioritize #id over to avoid XSS via location.hash (#9521) - // Strict HTML recognition (#11290: must start with <) - rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, - - init = jQuery.fn.init = function( selector, context, root ) { - var match, elem; - - // HANDLE: $(""), $(null), $(undefined), $(false) - if ( !selector ) { - return this; - } - - // init accepts an alternate rootjQuery - // so migrate can support jQuery.sub (gh-2101) - root = root || rootjQuery; - - // Handle HTML strings - if ( typeof selector === "string" ) { - if ( selector.charAt( 0 ) === "<" && - selector.charAt( selector.length - 1 ) === ">" && - selector.length >= 3 ) { - - // Assume that strings that start and end with <> are HTML and skip the regex check - match = [ null, selector, null ]; - - } else { - match = rquickExpr.exec( selector ); - } - - // Match html or make sure no context is specified for #id - if ( match && ( match[ 1 ] || !context ) ) { - - // HANDLE: $(html) -> $(array) - if ( match[ 1 ] ) { - context = context instanceof jQuery ? context[ 0 ] : context; - - // scripts is true for back-compat - // Intentionally let the error be thrown if parseHTML is not present - jQuery.merge( this, jQuery.parseHTML( - match[ 1 ], - context && context.nodeType ? context.ownerDocument || context : document, - true - ) ); - - // HANDLE: $(html, props) - if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { - for ( match in context ) { - - // Properties of context are called as methods if possible - if ( jQuery.isFunction( this[ match ] ) ) { - this[ match ]( context[ match ] ); - - // ...and otherwise set as attributes - } else { - this.attr( match, context[ match ] ); - } - } - } - - return this; - - // HANDLE: $(#id) - } else { - elem = document.getElementById( match[ 2 ] ); - - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - if ( elem && elem.parentNode ) { - - // Handle the case where IE and Opera return items - // by name instead of ID - if ( elem.id !== match[ 2 ] ) { - return rootjQuery.find( selector ); - } - - // Otherwise, we inject the element directly into the jQuery object - this.length = 1; - this[ 0 ] = elem; - } - - this.context = document; - this.selector = selector; - return this; - } - - // HANDLE: $(expr, $(...)) - } else if ( !context || context.jquery ) { - return ( context || root ).find( selector ); - - // HANDLE: $(expr, context) - // (which is just equivalent to: $(context).find(expr) - } else { - return this.constructor( context ).find( selector ); - } - - // HANDLE: $(DOMElement) - } else if ( selector.nodeType ) { - this.context = this[ 0 ] = selector; - this.length = 1; - return this; - - // HANDLE: $(function) - // Shortcut for document ready - } else if ( jQuery.isFunction( selector ) ) { - return typeof root.ready !== "undefined" ? - root.ready( selector ) : - - // Execute immediately if ready is not present - selector( jQuery ); - } - - if ( selector.selector !== undefined ) { - this.selector = selector.selector; - this.context = selector.context; - } - - return jQuery.makeArray( selector, this ); - }; - -// Give the init function the jQuery prototype for later instantiation -init.prototype = jQuery.fn; - -// Initialize central reference -rootjQuery = jQuery( document ); - - -var rparentsprev = /^(?:parents|prev(?:Until|All))/, - - // methods guaranteed to produce a unique set when starting from a unique set - guaranteedUnique = { - children: true, - contents: true, - next: true, - prev: true - }; - -jQuery.fn.extend( { - has: function( target ) { - var i, - targets = jQuery( target, this ), - len = targets.length; - - return this.filter( function() { - for ( i = 0; i < len; i++ ) { - if ( jQuery.contains( this, targets[ i ] ) ) { - return true; - } - } - } ); - }, - - closest: function( selectors, context ) { - var cur, - i = 0, - l = this.length, - matched = [], - pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? - jQuery( selectors, context || this.context ) : - 0; - - for ( ; i < l; i++ ) { - for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { - - // Always skip document fragments - if ( cur.nodeType < 11 && ( pos ? - pos.index( cur ) > -1 : - - // Don't pass non-elements to Sizzle - cur.nodeType === 1 && - jQuery.find.matchesSelector( cur, selectors ) ) ) { - - matched.push( cur ); - break; - } - } - } - - return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); - }, - - // Determine the position of an element within - // the matched set of elements - index: function( elem ) { - - // No argument, return index in parent - if ( !elem ) { - return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; - } - - // index in selector - if ( typeof elem === "string" ) { - return jQuery.inArray( this[ 0 ], jQuery( elem ) ); - } - - // Locate the position of the desired element - return jQuery.inArray( - - // If it receives a jQuery object, the first element is used - elem.jquery ? elem[ 0 ] : elem, this ); - }, - - add: function( selector, context ) { - return this.pushStack( - jQuery.uniqueSort( - jQuery.merge( this.get(), jQuery( selector, context ) ) - ) - ); - }, - - addBack: function( selector ) { - return this.add( selector == null ? - this.prevObject : this.prevObject.filter( selector ) - ); - } -} ); - -function sibling( cur, dir ) { - do { - cur = cur[ dir ]; - } while ( cur && cur.nodeType !== 1 ); - - return cur; -} - -jQuery.each( { - parent: function( elem ) { - var parent = elem.parentNode; - return parent && parent.nodeType !== 11 ? parent : null; - }, - parents: function( elem ) { - return dir( elem, "parentNode" ); - }, - parentsUntil: function( elem, i, until ) { - return dir( elem, "parentNode", until ); - }, - next: function( elem ) { - return sibling( elem, "nextSibling" ); - }, - prev: function( elem ) { - return sibling( elem, "previousSibling" ); - }, - nextAll: function( elem ) { - return dir( elem, "nextSibling" ); - }, - prevAll: function( elem ) { - return dir( elem, "previousSibling" ); - }, - nextUntil: function( elem, i, until ) { - return dir( elem, "nextSibling", until ); - }, - prevUntil: function( elem, i, until ) { - return dir( elem, "previousSibling", until ); - }, - siblings: function( elem ) { - return siblings( ( elem.parentNode || {} ).firstChild, elem ); - }, - children: function( elem ) { - return siblings( elem.firstChild ); - }, - contents: function( elem ) { - return jQuery.nodeName( elem, "iframe" ) ? - elem.contentDocument || elem.contentWindow.document : - jQuery.merge( [], elem.childNodes ); - } -}, function( name, fn ) { - jQuery.fn[ name ] = function( until, selector ) { - var ret = jQuery.map( this, fn, until ); - - if ( name.slice( -5 ) !== "Until" ) { - selector = until; - } - - if ( selector && typeof selector === "string" ) { - ret = jQuery.filter( selector, ret ); - } - - if ( this.length > 1 ) { - - // Remove duplicates - if ( !guaranteedUnique[ name ] ) { - ret = jQuery.uniqueSort( ret ); - } - - // Reverse order for parents* and prev-derivatives - if ( rparentsprev.test( name ) ) { - ret = ret.reverse(); - } - } - - return this.pushStack( ret ); - }; -} ); -var rnotwhite = ( /\S+/g ); - - - -// Convert String-formatted options into Object-formatted ones -function createOptions( options ) { - var object = {}; - jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { - object[ flag ] = true; - } ); - return object; -} - -/* - * Create a callback list using the following parameters: - * - * options: an optional list of space-separated options that will change how - * the callback list behaves or a more traditional option object - * - * By default a callback list will act like an event callback list and can be - * "fired" multiple times. - * - * Possible options: - * - * once: will ensure the callback list can only be fired once (like a Deferred) - * - * memory: will keep track of previous values and will call any callback added - * after the list has been fired right away with the latest "memorized" - * values (like a Deferred) - * - * unique: will ensure a callback can only be added once (no duplicate in the list) - * - * stopOnFalse: interrupt callings when a callback returns false - * - */ -jQuery.Callbacks = function( options ) { - - // Convert options from String-formatted to Object-formatted if needed - // (we check in cache first) - options = typeof options === "string" ? - createOptions( options ) : - jQuery.extend( {}, options ); - - var // Flag to know if list is currently firing - firing, - - // Last fire value for non-forgettable lists - memory, - - // Flag to know if list was already fired - fired, - - // Flag to prevent firing - locked, - - // Actual callback list - list = [], - - // Queue of execution data for repeatable lists - queue = [], - - // Index of currently firing callback (modified by add/remove as needed) - firingIndex = -1, - - // Fire callbacks - fire = function() { - - // Enforce single-firing - locked = options.once; - - // Execute callbacks for all pending executions, - // respecting firingIndex overrides and runtime changes - fired = firing = true; - for ( ; queue.length; firingIndex = -1 ) { - memory = queue.shift(); - while ( ++firingIndex < list.length ) { - - // Run callback and check for early termination - if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && - options.stopOnFalse ) { - - // Jump to end and forget the data so .add doesn't re-fire - firingIndex = list.length; - memory = false; - } - } - } - - // Forget the data if we're done with it - if ( !options.memory ) { - memory = false; - } - - firing = false; - - // Clean up if we're done firing for good - if ( locked ) { - - // Keep an empty list if we have data for future add calls - if ( memory ) { - list = []; - - // Otherwise, this object is spent - } else { - list = ""; - } - } - }, - - // Actual Callbacks object - self = { - - // Add a callback or a collection of callbacks to the list - add: function() { - if ( list ) { - - // If we have memory from a past run, we should fire after adding - if ( memory && !firing ) { - firingIndex = list.length - 1; - queue.push( memory ); - } - - ( function add( args ) { - jQuery.each( args, function( _, arg ) { - if ( jQuery.isFunction( arg ) ) { - if ( !options.unique || !self.has( arg ) ) { - list.push( arg ); - } - } else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) { - - // Inspect recursively - add( arg ); - } - } ); - } )( arguments ); - - if ( memory && !firing ) { - fire(); - } - } - return this; - }, - - // Remove a callback from the list - remove: function() { - jQuery.each( arguments, function( _, arg ) { - var index; - while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { - list.splice( index, 1 ); - - // Handle firing indexes - if ( index <= firingIndex ) { - firingIndex--; - } - } - } ); - return this; - }, - - // Check if a given callback is in the list. - // If no argument is given, return whether or not list has callbacks attached. - has: function( fn ) { - return fn ? - jQuery.inArray( fn, list ) > -1 : - list.length > 0; - }, - - // Remove all callbacks from the list - empty: function() { - if ( list ) { - list = []; - } - return this; - }, - - // Disable .fire and .add - // Abort any current/pending executions - // Clear all callbacks and values - disable: function() { - locked = queue = []; - list = memory = ""; - return this; - }, - disabled: function() { - return !list; - }, - - // Disable .fire - // Also disable .add unless we have memory (since it would have no effect) - // Abort any pending executions - lock: function() { - locked = true; - if ( !memory ) { - self.disable(); - } - return this; - }, - locked: function() { - return !!locked; - }, - - // Call all callbacks with the given context and arguments - fireWith: function( context, args ) { - if ( !locked ) { - args = args || []; - args = [ context, args.slice ? args.slice() : args ]; - queue.push( args ); - if ( !firing ) { - fire(); - } - } - return this; - }, - - // Call all the callbacks with the given arguments - fire: function() { - self.fireWith( this, arguments ); - return this; - }, - - // To know if the callbacks have already been called at least once - fired: function() { - return !!fired; - } - }; - - return self; -}; - - -jQuery.extend( { - - Deferred: function( func ) { - var tuples = [ - - // action, add listener, listener list, final state - [ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ], - [ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ], - [ "notify", "progress", jQuery.Callbacks( "memory" ) ] - ], - state = "pending", - promise = { - state: function() { - return state; - }, - always: function() { - deferred.done( arguments ).fail( arguments ); - return this; - }, - then: function( /* fnDone, fnFail, fnProgress */ ) { - var fns = arguments; - return jQuery.Deferred( function( newDefer ) { - jQuery.each( tuples, function( i, tuple ) { - var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; - - // deferred[ done | fail | progress ] for forwarding actions to newDefer - deferred[ tuple[ 1 ] ]( function() { - var returned = fn && fn.apply( this, arguments ); - if ( returned && jQuery.isFunction( returned.promise ) ) { - returned.promise() - .progress( newDefer.notify ) - .done( newDefer.resolve ) - .fail( newDefer.reject ); - } else { - newDefer[ tuple[ 0 ] + "With" ]( - this === promise ? newDefer.promise() : this, - fn ? [ returned ] : arguments - ); - } - } ); - } ); - fns = null; - } ).promise(); - }, - - // Get a promise for this deferred - // If obj is provided, the promise aspect is added to the object - promise: function( obj ) { - return obj != null ? jQuery.extend( obj, promise ) : promise; - } - }, - deferred = {}; - - // Keep pipe for back-compat - promise.pipe = promise.then; - - // Add list-specific methods - jQuery.each( tuples, function( i, tuple ) { - var list = tuple[ 2 ], - stateString = tuple[ 3 ]; - - // promise[ done | fail | progress ] = list.add - promise[ tuple[ 1 ] ] = list.add; - - // Handle state - if ( stateString ) { - list.add( function() { - - // state = [ resolved | rejected ] - state = stateString; - - // [ reject_list | resolve_list ].disable; progress_list.lock - }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); - } - - // deferred[ resolve | reject | notify ] - deferred[ tuple[ 0 ] ] = function() { - deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments ); - return this; - }; - deferred[ tuple[ 0 ] + "With" ] = list.fireWith; - } ); - - // Make the deferred a promise - promise.promise( deferred ); - - // Call given func if any - if ( func ) { - func.call( deferred, deferred ); - } - - // All done! - return deferred; - }, - - // Deferred helper - when: function( subordinate /* , ..., subordinateN */ ) { - var i = 0, - resolveValues = slice.call( arguments ), - length = resolveValues.length, - - // the count of uncompleted subordinates - remaining = length !== 1 || - ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, - - // the master Deferred. - // If resolveValues consist of only a single Deferred, just use that. - deferred = remaining === 1 ? subordinate : jQuery.Deferred(), - - // Update function for both resolve and progress values - updateFunc = function( i, contexts, values ) { - return function( value ) { - contexts[ i ] = this; - values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; - if ( values === progressValues ) { - deferred.notifyWith( contexts, values ); - - } else if ( !( --remaining ) ) { - deferred.resolveWith( contexts, values ); - } - }; - }, - - progressValues, progressContexts, resolveContexts; - - // add listeners to Deferred subordinates; treat others as resolved - if ( length > 1 ) { - progressValues = new Array( length ); - progressContexts = new Array( length ); - resolveContexts = new Array( length ); - for ( ; i < length; i++ ) { - if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { - resolveValues[ i ].promise() - .progress( updateFunc( i, progressContexts, progressValues ) ) - .done( updateFunc( i, resolveContexts, resolveValues ) ) - .fail( deferred.reject ); - } else { - --remaining; - } - } - } - - // if we're not waiting on anything, resolve the master - if ( !remaining ) { - deferred.resolveWith( resolveContexts, resolveValues ); - } - - return deferred.promise(); - } -} ); - - -// The deferred used on DOM ready -var readyList; - -jQuery.fn.ready = function( fn ) { - - // Add the callback - jQuery.ready.promise().done( fn ); - - return this; -}; - -jQuery.extend( { - - // Is the DOM ready to be used? Set to true once it occurs. - isReady: false, - - // A counter to track how many items to wait for before - // the ready event fires. See #6781 - readyWait: 1, - - // Hold (or release) the ready event - holdReady: function( hold ) { - if ( hold ) { - jQuery.readyWait++; - } else { - jQuery.ready( true ); - } - }, - - // Handle when the DOM is ready - ready: function( wait ) { - - // Abort if there are pending holds or we're already ready - if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { - return; - } - - // Remember that the DOM is ready - jQuery.isReady = true; - - // If a normal DOM Ready event fired, decrement, and wait if need be - if ( wait !== true && --jQuery.readyWait > 0 ) { - return; - } - - // If there are functions bound, to execute - readyList.resolveWith( document, [ jQuery ] ); - - // Trigger any bound ready events - if ( jQuery.fn.triggerHandler ) { - jQuery( document ).triggerHandler( "ready" ); - jQuery( document ).off( "ready" ); - } - } -} ); - -/** - * Clean-up method for dom ready events - */ -function detach() { - if ( document.addEventListener ) { - document.removeEventListener( "DOMContentLoaded", completed ); - window.removeEventListener( "load", completed ); - - } else { - document.detachEvent( "onreadystatechange", completed ); - window.detachEvent( "onload", completed ); - } -} - -/** - * The ready event handler and self cleanup method - */ -function completed() { - - // readyState === "complete" is good enough for us to call the dom ready in oldIE - if ( document.addEventListener || - window.event.type === "load" || - document.readyState === "complete" ) { - - detach(); - jQuery.ready(); - } -} - -jQuery.ready.promise = function( obj ) { - if ( !readyList ) { - - readyList = jQuery.Deferred(); - - // Catch cases where $(document).ready() is called - // after the browser event has already occurred. - // Support: IE6-10 - // Older IE sometimes signals "interactive" too soon - if ( document.readyState === "complete" || - ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { - - // Handle it asynchronously to allow scripts the opportunity to delay ready - window.setTimeout( jQuery.ready ); - - // Standards-based browsers support DOMContentLoaded - } else if ( document.addEventListener ) { - - // Use the handy event callback - document.addEventListener( "DOMContentLoaded", completed ); - - // A fallback to window.onload, that will always work - window.addEventListener( "load", completed ); - - // If IE event model is used - } else { - - // Ensure firing before onload, maybe late but safe also for iframes - document.attachEvent( "onreadystatechange", completed ); - - // A fallback to window.onload, that will always work - window.attachEvent( "onload", completed ); - - // If IE and not a frame - // continually check to see if the document is ready - var top = false; - - try { - top = window.frameElement == null && document.documentElement; - } catch ( e ) {} - - if ( top && top.doScroll ) { - ( function doScrollCheck() { - if ( !jQuery.isReady ) { - - try { - - // Use the trick by Diego Perini - // http://javascript.nwbox.com/IEContentLoaded/ - top.doScroll( "left" ); - } catch ( e ) { - return window.setTimeout( doScrollCheck, 50 ); - } - - // detach all dom ready events - detach(); - - // and execute any waiting functions - jQuery.ready(); - } - } )(); - } - } - } - return readyList.promise( obj ); -}; - -// Kick off the DOM ready check even if the user does not -jQuery.ready.promise(); - - - - -// Support: IE<9 -// Iteration over object's inherited properties before its own -var i; -for ( i in jQuery( support ) ) { - break; -} -support.ownFirst = i === "0"; - -// Note: most support tests are defined in their respective modules. -// false until the test is run -support.inlineBlockNeedsLayout = false; - -// Execute ASAP in case we need to set body.style.zoom -jQuery( function() { - - // Minified: var a,b,c,d - var val, div, body, container; - - body = document.getElementsByTagName( "body" )[ 0 ]; - if ( !body || !body.style ) { - - // Return for frameset docs that don't have a body - return; - } - - // Setup - div = document.createElement( "div" ); - container = document.createElement( "div" ); - container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px"; - body.appendChild( container ).appendChild( div ); - - if ( typeof div.style.zoom !== "undefined" ) { - - // Support: IE<8 - // Check if natively block-level elements act like inline-block - // elements when setting their display to 'inline' and giving - // them layout - div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1"; - - support.inlineBlockNeedsLayout = val = div.offsetWidth === 3; - if ( val ) { - - // Prevent IE 6 from affecting layout for positioned elements #11048 - // Prevent IE from shrinking the body in IE 7 mode #12869 - // Support: IE<8 - body.style.zoom = 1; - } - } - - body.removeChild( container ); -} ); - - -( function() { - var div = document.createElement( "div" ); - - // Support: IE<9 - support.deleteExpando = true; - try { - delete div.test; - } catch ( e ) { - support.deleteExpando = false; - } - - // Null elements to avoid leaks in IE. - div = null; -} )(); -var acceptData = function( elem ) { - var noData = jQuery.noData[ ( elem.nodeName + " " ).toLowerCase() ], - nodeType = +elem.nodeType || 1; - - // Do not set data on non-element DOM nodes because it will not be cleared (#8335). - return nodeType !== 1 && nodeType !== 9 ? - false : - - // Nodes accept data unless otherwise specified; rejection can be conditional - !noData || noData !== true && elem.getAttribute( "classid" ) === noData; -}; - - - - -var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, - rmultiDash = /([A-Z])/g; - -function dataAttr( elem, key, data ) { - - // If nothing was found internally, try to fetch any - // data from the HTML5 data-* attribute - if ( data === undefined && elem.nodeType === 1 ) { - - var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); - - data = elem.getAttribute( name ); - - if ( typeof data === "string" ) { - try { - data = data === "true" ? true : - data === "false" ? false : - data === "null" ? null : - - // Only convert to a number if it doesn't change the string - +data + "" === data ? +data : - rbrace.test( data ) ? jQuery.parseJSON( data ) : - data; - } catch ( e ) {} - - // Make sure we set the data so it isn't changed later - jQuery.data( elem, key, data ); - - } else { - data = undefined; - } - } - - return data; -} - -// checks a cache object for emptiness -function isEmptyDataObject( obj ) { - var name; - for ( name in obj ) { - - // if the public data object is empty, the private is still empty - if ( name === "data" && jQuery.isEmptyObject( obj[ name ] ) ) { - continue; - } - if ( name !== "toJSON" ) { - return false; - } - } - - return true; -} - -function internalData( elem, name, data, pvt /* Internal Use Only */ ) { - if ( !acceptData( elem ) ) { - return; - } - - var ret, thisCache, - internalKey = jQuery.expando, - - // We have to handle DOM nodes and JS objects differently because IE6-7 - // can't GC object references properly across the DOM-JS boundary - isNode = elem.nodeType, - - // Only DOM nodes need the global jQuery cache; JS object data is - // attached directly to the object so GC can occur automatically - cache = isNode ? jQuery.cache : elem, - - // Only defining an ID for JS objects if its cache already exists allows - // the code to shortcut on the same path as a DOM node with no cache - id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey; - - // Avoid doing any more work than we need to when trying to get data on an - // object that has no data at all - if ( ( !id || !cache[ id ] || ( !pvt && !cache[ id ].data ) ) && - data === undefined && typeof name === "string" ) { - return; - } - - if ( !id ) { - - // Only DOM nodes need a new unique ID for each element since their data - // ends up in the global cache - if ( isNode ) { - id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++; - } else { - id = internalKey; - } - } - - if ( !cache[ id ] ) { - - // Avoid exposing jQuery metadata on plain JS objects when the object - // is serialized using JSON.stringify - cache[ id ] = isNode ? {} : { toJSON: jQuery.noop }; - } - - // An object can be passed to jQuery.data instead of a key/value pair; this gets - // shallow copied over onto the existing cache - if ( typeof name === "object" || typeof name === "function" ) { - if ( pvt ) { - cache[ id ] = jQuery.extend( cache[ id ], name ); - } else { - cache[ id ].data = jQuery.extend( cache[ id ].data, name ); - } - } - - thisCache = cache[ id ]; - - // jQuery data() is stored in a separate object inside the object's internal data - // cache in order to avoid key collisions between internal data and user-defined - // data. - if ( !pvt ) { - if ( !thisCache.data ) { - thisCache.data = {}; - } - - thisCache = thisCache.data; - } - - if ( data !== undefined ) { - thisCache[ jQuery.camelCase( name ) ] = data; - } - - // Check for both converted-to-camel and non-converted data property names - // If a data property was specified - if ( typeof name === "string" ) { - - // First Try to find as-is property data - ret = thisCache[ name ]; - - // Test for null|undefined property data - if ( ret == null ) { - - // Try to find the camelCased property - ret = thisCache[ jQuery.camelCase( name ) ]; - } - } else { - ret = thisCache; - } - - return ret; -} - -function internalRemoveData( elem, name, pvt ) { - if ( !acceptData( elem ) ) { - return; - } - - var thisCache, i, - isNode = elem.nodeType, - - // See jQuery.data for more information - cache = isNode ? jQuery.cache : elem, - id = isNode ? elem[ jQuery.expando ] : jQuery.expando; - - // If there is already no cache entry for this object, there is no - // purpose in continuing - if ( !cache[ id ] ) { - return; - } - - if ( name ) { - - thisCache = pvt ? cache[ id ] : cache[ id ].data; - - if ( thisCache ) { - - // Support array or space separated string names for data keys - if ( !jQuery.isArray( name ) ) { - - // try the string as a key before any manipulation - if ( name in thisCache ) { - name = [ name ]; - } else { - - // split the camel cased version by spaces unless a key with the spaces exists - name = jQuery.camelCase( name ); - if ( name in thisCache ) { - name = [ name ]; - } else { - name = name.split( " " ); - } - } - } else { - - // If "name" is an array of keys... - // When data is initially created, via ("key", "val") signature, - // keys will be converted to camelCase. - // Since there is no way to tell _how_ a key was added, remove - // both plain key and camelCase key. #12786 - // This will only penalize the array argument path. - name = name.concat( jQuery.map( name, jQuery.camelCase ) ); - } - - i = name.length; - while ( i-- ) { - delete thisCache[ name[ i ] ]; - } - - // If there is no data left in the cache, we want to continue - // and let the cache object itself get destroyed - if ( pvt ? !isEmptyDataObject( thisCache ) : !jQuery.isEmptyObject( thisCache ) ) { - return; - } - } - } - - // See jQuery.data for more information - if ( !pvt ) { - delete cache[ id ].data; - - // Don't destroy the parent cache unless the internal data object - // had been the only thing left in it - if ( !isEmptyDataObject( cache[ id ] ) ) { - return; - } - } - - // Destroy the cache - if ( isNode ) { - jQuery.cleanData( [ elem ], true ); - - // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) - /* jshint eqeqeq: false */ - } else if ( support.deleteExpando || cache != cache.window ) { - /* jshint eqeqeq: true */ - delete cache[ id ]; - - // When all else fails, undefined - } else { - cache[ id ] = undefined; - } -} - -jQuery.extend( { - cache: {}, - - // The following elements (space-suffixed to avoid Object.prototype collisions) - // throw uncatchable exceptions if you attempt to set expando properties - noData: { - "applet ": true, - "embed ": true, - - // ...but Flash objects (which have this classid) *can* handle expandos - "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" - }, - - hasData: function( elem ) { - elem = elem.nodeType ? jQuery.cache[ elem[ jQuery.expando ] ] : elem[ jQuery.expando ]; - return !!elem && !isEmptyDataObject( elem ); - }, - - data: function( elem, name, data ) { - return internalData( elem, name, data ); - }, - - removeData: function( elem, name ) { - return internalRemoveData( elem, name ); - }, - - // For internal use only. - _data: function( elem, name, data ) { - return internalData( elem, name, data, true ); - }, - - _removeData: function( elem, name ) { - return internalRemoveData( elem, name, true ); - } -} ); - -jQuery.fn.extend( { - data: function( key, value ) { - var i, name, data, - elem = this[ 0 ], - attrs = elem && elem.attributes; - - // Special expections of .data basically thwart jQuery.access, - // so implement the relevant behavior ourselves - - // Gets all values - if ( key === undefined ) { - if ( this.length ) { - data = jQuery.data( elem ); - - if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { - i = attrs.length; - while ( i-- ) { - - // Support: IE11+ - // The attrs elements can be null (#14894) - if ( attrs[ i ] ) { - name = attrs[ i ].name; - if ( name.indexOf( "data-" ) === 0 ) { - name = jQuery.camelCase( name.slice( 5 ) ); - dataAttr( elem, name, data[ name ] ); - } - } - } - jQuery._data( elem, "parsedAttrs", true ); - } - } - - return data; - } - - // Sets multiple values - if ( typeof key === "object" ) { - return this.each( function() { - jQuery.data( this, key ); - } ); - } - - return arguments.length > 1 ? - - // Sets one value - this.each( function() { - jQuery.data( this, key, value ); - } ) : - - // Gets one value - // Try to fetch any internally stored data first - elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined; - }, - - removeData: function( key ) { - return this.each( function() { - jQuery.removeData( this, key ); - } ); - } -} ); - - -jQuery.extend( { - queue: function( elem, type, data ) { - var queue; - - if ( elem ) { - type = ( type || "fx" ) + "queue"; - queue = jQuery._data( elem, type ); - - // Speed up dequeue by getting out quickly if this is just a lookup - if ( data ) { - if ( !queue || jQuery.isArray( data ) ) { - queue = jQuery._data( elem, type, jQuery.makeArray( data ) ); - } else { - queue.push( data ); - } - } - return queue || []; - } - }, - - dequeue: function( elem, type ) { - type = type || "fx"; - - var queue = jQuery.queue( elem, type ), - startLength = queue.length, - fn = queue.shift(), - hooks = jQuery._queueHooks( elem, type ), - next = function() { - jQuery.dequeue( elem, type ); - }; - - // If the fx queue is dequeued, always remove the progress sentinel - if ( fn === "inprogress" ) { - fn = queue.shift(); - startLength--; - } - - if ( fn ) { - - // Add a progress sentinel to prevent the fx queue from being - // automatically dequeued - if ( type === "fx" ) { - queue.unshift( "inprogress" ); - } - - // clear up the last queue stop function - delete hooks.stop; - fn.call( elem, next, hooks ); - } - - if ( !startLength && hooks ) { - hooks.empty.fire(); - } - }, - - // not intended for public consumption - generates a queueHooks object, - // or returns the current one - _queueHooks: function( elem, type ) { - var key = type + "queueHooks"; - return jQuery._data( elem, key ) || jQuery._data( elem, key, { - empty: jQuery.Callbacks( "once memory" ).add( function() { - jQuery._removeData( elem, type + "queue" ); - jQuery._removeData( elem, key ); - } ) - } ); - } -} ); - -jQuery.fn.extend( { - queue: function( type, data ) { - var setter = 2; - - if ( typeof type !== "string" ) { - data = type; - type = "fx"; - setter--; - } - - if ( arguments.length < setter ) { - return jQuery.queue( this[ 0 ], type ); - } - - return data === undefined ? - this : - this.each( function() { - var queue = jQuery.queue( this, type, data ); - - // ensure a hooks for this queue - jQuery._queueHooks( this, type ); - - if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { - jQuery.dequeue( this, type ); - } - } ); - }, - dequeue: function( type ) { - return this.each( function() { - jQuery.dequeue( this, type ); - } ); - }, - clearQueue: function( type ) { - return this.queue( type || "fx", [] ); - }, - - // Get a promise resolved when queues of a certain type - // are emptied (fx is the type by default) - promise: function( type, obj ) { - var tmp, - count = 1, - defer = jQuery.Deferred(), - elements = this, - i = this.length, - resolve = function() { - if ( !( --count ) ) { - defer.resolveWith( elements, [ elements ] ); - } - }; - - if ( typeof type !== "string" ) { - obj = type; - type = undefined; - } - type = type || "fx"; - - while ( i-- ) { - tmp = jQuery._data( elements[ i ], type + "queueHooks" ); - if ( tmp && tmp.empty ) { - count++; - tmp.empty.add( resolve ); - } - } - resolve(); - return defer.promise( obj ); - } -} ); - - -( function() { - var shrinkWrapBlocksVal; - - support.shrinkWrapBlocks = function() { - if ( shrinkWrapBlocksVal != null ) { - return shrinkWrapBlocksVal; - } - - // Will be changed later if needed. - shrinkWrapBlocksVal = false; - - // Minified: var b,c,d - var div, body, container; - - body = document.getElementsByTagName( "body" )[ 0 ]; - if ( !body || !body.style ) { - - // Test fired too early or in an unsupported environment, exit. - return; - } - - // Setup - div = document.createElement( "div" ); - container = document.createElement( "div" ); - container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px"; - body.appendChild( container ).appendChild( div ); - - // Support: IE6 - // Check if elements with layout shrink-wrap their children - if ( typeof div.style.zoom !== "undefined" ) { - - // Reset CSS: box-sizing; display; margin; border - div.style.cssText = - - // Support: Firefox<29, Android 2.3 - // Vendor-prefix box-sizing - "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" + - "box-sizing:content-box;display:block;margin:0;border:0;" + - "padding:1px;width:1px;zoom:1"; - div.appendChild( document.createElement( "div" ) ).style.width = "5px"; - shrinkWrapBlocksVal = div.offsetWidth !== 3; - } - - body.removeChild( container ); - - return shrinkWrapBlocksVal; - }; - -} )(); -var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; - -var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); - - -var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; - -var isHidden = function( elem, el ) { - - // isHidden might be called from jQuery#filter function; - // in that case, element will be second argument - elem = el || elem; - return jQuery.css( elem, "display" ) === "none" || - !jQuery.contains( elem.ownerDocument, elem ); - }; - - - -function adjustCSS( elem, prop, valueParts, tween ) { - var adjusted, - scale = 1, - maxIterations = 20, - currentValue = tween ? - function() { return tween.cur(); } : - function() { return jQuery.css( elem, prop, "" ); }, - initial = currentValue(), - unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), - - // Starting value computation is required for potential unit mismatches - initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && - rcssNum.exec( jQuery.css( elem, prop ) ); - - if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { - - // Trust units reported by jQuery.css - unit = unit || initialInUnit[ 3 ]; - - // Make sure we update the tween properties later on - valueParts = valueParts || []; - - // Iteratively approximate from a nonzero starting point - initialInUnit = +initial || 1; - - do { - - // If previous iteration zeroed out, double until we get *something*. - // Use string for doubling so we don't accidentally see scale as unchanged below - scale = scale || ".5"; - - // Adjust and apply - initialInUnit = initialInUnit / scale; - jQuery.style( elem, prop, initialInUnit + unit ); - - // Update scale, tolerating zero or NaN from tween.cur() - // Break the loop if scale is unchanged or perfect, or if we've just had enough. - } while ( - scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations - ); - } - - if ( valueParts ) { - initialInUnit = +initialInUnit || +initial || 0; - - // Apply relative offset (+=/-=) if specified - adjusted = valueParts[ 1 ] ? - initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : - +valueParts[ 2 ]; - if ( tween ) { - tween.unit = unit; - tween.start = initialInUnit; - tween.end = adjusted; - } - } - return adjusted; -} - - -// Multifunctional method to get and set values of a collection -// The value/s can optionally be executed if it's a function -var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { - var i = 0, - length = elems.length, - bulk = key == null; - - // Sets many values - if ( jQuery.type( key ) === "object" ) { - chainable = true; - for ( i in key ) { - access( elems, fn, i, key[ i ], true, emptyGet, raw ); - } - - // Sets one value - } else if ( value !== undefined ) { - chainable = true; - - if ( !jQuery.isFunction( value ) ) { - raw = true; - } - - if ( bulk ) { - - // Bulk operations run against the entire set - if ( raw ) { - fn.call( elems, value ); - fn = null; - - // ...except when executing function values - } else { - bulk = fn; - fn = function( elem, key, value ) { - return bulk.call( jQuery( elem ), value ); - }; - } - } - - if ( fn ) { - for ( ; i < length; i++ ) { - fn( - elems[ i ], - key, - raw ? value : value.call( elems[ i ], i, fn( elems[ i ], key ) ) - ); - } - } - } - - return chainable ? - elems : - - // Gets - bulk ? - fn.call( elems ) : - length ? fn( elems[ 0 ], key ) : emptyGet; -}; -var rcheckableType = ( /^(?:checkbox|radio)$/i ); - -var rtagName = ( /<([\w:-]+)/ ); - -var rscriptType = ( /^$|\/(?:java|ecma)script/i ); - -var rleadingWhitespace = ( /^\s+/ ); - -var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|" + - "details|dialog|figcaption|figure|footer|header|hgroup|main|" + - "mark|meter|nav|output|picture|progress|section|summary|template|time|video"; - - - -function createSafeFragment( document ) { - var list = nodeNames.split( "|" ), - safeFrag = document.createDocumentFragment(); - - if ( safeFrag.createElement ) { - while ( list.length ) { - safeFrag.createElement( - list.pop() - ); - } - } - return safeFrag; -} - - -( function() { - var div = document.createElement( "div" ), - fragment = document.createDocumentFragment(), - input = document.createElement( "input" ); - - // Setup - div.innerHTML = "
a"; - - // IE strips leading whitespace when .innerHTML is used - support.leadingWhitespace = div.firstChild.nodeType === 3; - - // Make sure that tbody elements aren't automatically inserted - // IE will insert them into empty tables - support.tbody = !div.getElementsByTagName( "tbody" ).length; - - // Make sure that link elements get serialized correctly by innerHTML - // This requires a wrapper element in IE - support.htmlSerialize = !!div.getElementsByTagName( "link" ).length; - - // Makes sure cloning an html5 element does not cause problems - // Where outerHTML is undefined, this still works - support.html5Clone = - document.createElement( "nav" ).cloneNode( true ).outerHTML !== "<:nav>"; - - // Check if a disconnected checkbox will retain its checked - // value of true after appended to the DOM (IE6/7) - input.type = "checkbox"; - input.checked = true; - fragment.appendChild( input ); - support.appendChecked = input.checked; - - // Make sure textarea (and checkbox) defaultValue is properly cloned - // Support: IE6-IE11+ - div.innerHTML = ""; - support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; - - // #11217 - WebKit loses check when the name is after the checked attribute - fragment.appendChild( div ); - - // Support: Windows Web Apps (WWA) - // `name` and `type` must use .setAttribute for WWA (#14901) - input = document.createElement( "input" ); - input.setAttribute( "type", "radio" ); - input.setAttribute( "checked", "checked" ); - input.setAttribute( "name", "t" ); - - div.appendChild( input ); - - // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3 - // old WebKit doesn't clone checked state correctly in fragments - support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; - - // Support: IE<9 - // Cloned elements keep attachEvent handlers, we use addEventListener on IE9+ - support.noCloneEvent = !!div.addEventListener; - - // Support: IE<9 - // Since attributes and properties are the same in IE, - // cleanData must set properties to undefined rather than use removeAttribute - div[ jQuery.expando ] = 1; - support.attributes = !div.getAttribute( jQuery.expando ); -} )(); - - -// We have to close these tags to support XHTML (#13200) -var wrapMap = { - option: [ 1, "" ], - legend: [ 1, "
", "
" ], - area: [ 1, "", "" ], - - // Support: IE8 - param: [ 1, "", "" ], - thead: [ 1, "", "
" ], - tr: [ 2, "", "
" ], - col: [ 2, "", "
" ], - td: [ 3, "", "
" ], - - // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, - // unless wrapped in a div with non-breaking characters in front of it. - _default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X
", "
" ] -}; - -// Support: IE8-IE9 -wrapMap.optgroup = wrapMap.option; - -wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; -wrapMap.th = wrapMap.td; - - -function getAll( context, tag ) { - var elems, elem, - i = 0, - found = typeof context.getElementsByTagName !== "undefined" ? - context.getElementsByTagName( tag || "*" ) : - typeof context.querySelectorAll !== "undefined" ? - context.querySelectorAll( tag || "*" ) : - undefined; - - if ( !found ) { - for ( found = [], elems = context.childNodes || context; - ( elem = elems[ i ] ) != null; - i++ - ) { - if ( !tag || jQuery.nodeName( elem, tag ) ) { - found.push( elem ); - } else { - jQuery.merge( found, getAll( elem, tag ) ); - } - } - } - - return tag === undefined || tag && jQuery.nodeName( context, tag ) ? - jQuery.merge( [ context ], found ) : - found; -} - - -// Mark scripts as having already been evaluated -function setGlobalEval( elems, refElements ) { - var elem, - i = 0; - for ( ; ( elem = elems[ i ] ) != null; i++ ) { - jQuery._data( - elem, - "globalEval", - !refElements || jQuery._data( refElements[ i ], "globalEval" ) - ); - } -} - - -var rhtml = /<|&#?\w+;/, - rtbody = / from table fragments - if ( !support.tbody ) { - - // String was a , *may* have spurious - elem = tag === "table" && !rtbody.test( elem ) ? - tmp.firstChild : - - // String was a bare or - wrap[ 1 ] === "
" && !rtbody.test( elem ) ? - tmp : - 0; - - j = elem && elem.childNodes.length; - while ( j-- ) { - if ( jQuery.nodeName( ( tbody = elem.childNodes[ j ] ), "tbody" ) && - !tbody.childNodes.length ) { - - elem.removeChild( tbody ); - } - } - } - - jQuery.merge( nodes, tmp.childNodes ); - - // Fix #12392 for WebKit and IE > 9 - tmp.textContent = ""; - - // Fix #12392 for oldIE - while ( tmp.firstChild ) { - tmp.removeChild( tmp.firstChild ); - } - - // Remember the top-level container for proper cleanup - tmp = safe.lastChild; - } - } - } - - // Fix #11356: Clear elements from fragment - if ( tmp ) { - safe.removeChild( tmp ); - } - - // Reset defaultChecked for any radios and checkboxes - // about to be appended to the DOM in IE 6/7 (#8060) - if ( !support.appendChecked ) { - jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked ); - } - - i = 0; - while ( ( elem = nodes[ i++ ] ) ) { - - // Skip elements already in the context collection (trac-4087) - if ( selection && jQuery.inArray( elem, selection ) > -1 ) { - if ( ignored ) { - ignored.push( elem ); - } - - continue; - } - - contains = jQuery.contains( elem.ownerDocument, elem ); - - // Append to fragment - tmp = getAll( safe.appendChild( elem ), "script" ); - - // Preserve script evaluation history - if ( contains ) { - setGlobalEval( tmp ); - } - - // Capture executables - if ( scripts ) { - j = 0; - while ( ( elem = tmp[ j++ ] ) ) { - if ( rscriptType.test( elem.type || "" ) ) { - scripts.push( elem ); - } - } - } - } - - tmp = null; - - return safe; -} - - -( function() { - var i, eventName, - div = document.createElement( "div" ); - - // Support: IE<9 (lack submit/change bubble), Firefox (lack focus(in | out) events) - for ( i in { submit: true, change: true, focusin: true } ) { - eventName = "on" + i; - - if ( !( support[ i ] = eventName in window ) ) { - - // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP) - div.setAttribute( eventName, "t" ); - support[ i ] = div.attributes[ eventName ].expando === false; - } - } - - // Null elements to avoid leaks in IE. - div = null; -} )(); - - -var rformElems = /^(?:input|select|textarea)$/i, - rkeyEvent = /^key/, - rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, - rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, - rtypenamespace = /^([^.]*)(?:\.(.+)|)/; - -function returnTrue() { - return true; -} - -function returnFalse() { - return false; -} - -// Support: IE9 -// See #13393 for more info -function safeActiveElement() { - try { - return document.activeElement; - } catch ( err ) { } -} - -function on( elem, types, selector, data, fn, one ) { - var origFn, type; - - // Types can be a map of types/handlers - if ( typeof types === "object" ) { - - // ( types-Object, selector, data ) - if ( typeof selector !== "string" ) { - - // ( types-Object, data ) - data = data || selector; - selector = undefined; - } - for ( type in types ) { - on( elem, type, selector, data, types[ type ], one ); - } - return elem; - } - - if ( data == null && fn == null ) { - - // ( types, fn ) - fn = selector; - data = selector = undefined; - } else if ( fn == null ) { - if ( typeof selector === "string" ) { - - // ( types, selector, fn ) - fn = data; - data = undefined; - } else { - - // ( types, data, fn ) - fn = data; - data = selector; - selector = undefined; - } - } - if ( fn === false ) { - fn = returnFalse; - } else if ( !fn ) { - return elem; - } - - if ( one === 1 ) { - origFn = fn; - fn = function( event ) { - - // Can use an empty set, since event contains the info - jQuery().off( event ); - return origFn.apply( this, arguments ); - }; - - // Use same guid so caller can remove using origFn - fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); - } - return elem.each( function() { - jQuery.event.add( this, types, fn, data, selector ); - } ); -} - -/* - * Helper functions for managing events -- not part of the public interface. - * Props to Dean Edwards' addEvent library for many of the ideas. - */ -jQuery.event = { - - global: {}, - - add: function( elem, types, handler, data, selector ) { - var tmp, events, t, handleObjIn, - special, eventHandle, handleObj, - handlers, type, namespaces, origType, - elemData = jQuery._data( elem ); - - // Don't attach events to noData or text/comment nodes (but allow plain objects) - if ( !elemData ) { - return; - } - - // Caller can pass in an object of custom data in lieu of the handler - if ( handler.handler ) { - handleObjIn = handler; - handler = handleObjIn.handler; - selector = handleObjIn.selector; - } - - // Make sure that the handler has a unique ID, used to find/remove it later - if ( !handler.guid ) { - handler.guid = jQuery.guid++; - } - - // Init the element's event structure and main handler, if this is the first - if ( !( events = elemData.events ) ) { - events = elemData.events = {}; - } - if ( !( eventHandle = elemData.handle ) ) { - eventHandle = elemData.handle = function( e ) { - - // Discard the second event of a jQuery.event.trigger() and - // when an event is called after a page has unloaded - return typeof jQuery !== "undefined" && - ( !e || jQuery.event.triggered !== e.type ) ? - jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : - undefined; - }; - - // Add elem as a property of the handle fn to prevent a memory leak - // with IE non-native events - eventHandle.elem = elem; - } - - // Handle multiple events separated by a space - types = ( types || "" ).match( rnotwhite ) || [ "" ]; - t = types.length; - while ( t-- ) { - tmp = rtypenamespace.exec( types[ t ] ) || []; - type = origType = tmp[ 1 ]; - namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); - - // There *must* be a type, no attaching namespace-only handlers - if ( !type ) { - continue; - } - - // If event changes its type, use the special event handlers for the changed type - special = jQuery.event.special[ type ] || {}; - - // If selector defined, determine special event api type, otherwise given type - type = ( selector ? special.delegateType : special.bindType ) || type; - - // Update special based on newly reset type - special = jQuery.event.special[ type ] || {}; - - // handleObj is passed to all event handlers - handleObj = jQuery.extend( { - type: type, - origType: origType, - data: data, - handler: handler, - guid: handler.guid, - selector: selector, - needsContext: selector && jQuery.expr.match.needsContext.test( selector ), - namespace: namespaces.join( "." ) - }, handleObjIn ); - - // Init the event handler queue if we're the first - if ( !( handlers = events[ type ] ) ) { - handlers = events[ type ] = []; - handlers.delegateCount = 0; - - // Only use addEventListener/attachEvent if the special events handler returns false - if ( !special.setup || - special.setup.call( elem, data, namespaces, eventHandle ) === false ) { - - // Bind the global event handler to the element - if ( elem.addEventListener ) { - elem.addEventListener( type, eventHandle, false ); - - } else if ( elem.attachEvent ) { - elem.attachEvent( "on" + type, eventHandle ); - } - } - } - - if ( special.add ) { - special.add.call( elem, handleObj ); - - if ( !handleObj.handler.guid ) { - handleObj.handler.guid = handler.guid; - } - } - - // Add to the element's handler list, delegates in front - if ( selector ) { - handlers.splice( handlers.delegateCount++, 0, handleObj ); - } else { - handlers.push( handleObj ); - } - - // Keep track of which events have ever been used, for event optimization - jQuery.event.global[ type ] = true; - } - - // Nullify elem to prevent memory leaks in IE - elem = null; - }, - - // Detach an event or set of events from an element - remove: function( elem, types, handler, selector, mappedTypes ) { - var j, handleObj, tmp, - origCount, t, events, - special, handlers, type, - namespaces, origType, - elemData = jQuery.hasData( elem ) && jQuery._data( elem ); - - if ( !elemData || !( events = elemData.events ) ) { - return; - } - - // Once for each type.namespace in types; type may be omitted - types = ( types || "" ).match( rnotwhite ) || [ "" ]; - t = types.length; - while ( t-- ) { - tmp = rtypenamespace.exec( types[ t ] ) || []; - type = origType = tmp[ 1 ]; - namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); - - // Unbind all events (on this namespace, if provided) for the element - if ( !type ) { - for ( type in events ) { - jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); - } - continue; - } - - special = jQuery.event.special[ type ] || {}; - type = ( selector ? special.delegateType : special.bindType ) || type; - handlers = events[ type ] || []; - tmp = tmp[ 2 ] && - new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); - - // Remove matching events - origCount = j = handlers.length; - while ( j-- ) { - handleObj = handlers[ j ]; - - if ( ( mappedTypes || origType === handleObj.origType ) && - ( !handler || handler.guid === handleObj.guid ) && - ( !tmp || tmp.test( handleObj.namespace ) ) && - ( !selector || selector === handleObj.selector || - selector === "**" && handleObj.selector ) ) { - handlers.splice( j, 1 ); - - if ( handleObj.selector ) { - handlers.delegateCount--; - } - if ( special.remove ) { - special.remove.call( elem, handleObj ); - } - } - } - - // Remove generic event handler if we removed something and no more handlers exist - // (avoids potential for endless recursion during removal of special event handlers) - if ( origCount && !handlers.length ) { - if ( !special.teardown || - special.teardown.call( elem, namespaces, elemData.handle ) === false ) { - - jQuery.removeEvent( elem, type, elemData.handle ); - } - - delete events[ type ]; - } - } - - // Remove the expando if it's no longer used - if ( jQuery.isEmptyObject( events ) ) { - delete elemData.handle; - - // removeData also checks for emptiness and clears the expando if empty - // so use it instead of delete - jQuery._removeData( elem, "events" ); - } - }, - - trigger: function( event, data, elem, onlyHandlers ) { - var handle, ontype, cur, - bubbleType, special, tmp, i, - eventPath = [ elem || document ], - type = hasOwn.call( event, "type" ) ? event.type : event, - namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; - - cur = tmp = elem = elem || document; - - // Don't do events on text and comment nodes - if ( elem.nodeType === 3 || elem.nodeType === 8 ) { - return; - } - - // focus/blur morphs to focusin/out; ensure we're not firing them right now - if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { - return; - } - - if ( type.indexOf( "." ) > -1 ) { - - // Namespaced trigger; create a regexp to match event type in handle() - namespaces = type.split( "." ); - type = namespaces.shift(); - namespaces.sort(); - } - ontype = type.indexOf( ":" ) < 0 && "on" + type; - - // Caller can pass in a jQuery.Event object, Object, or just an event type string - event = event[ jQuery.expando ] ? - event : - new jQuery.Event( type, typeof event === "object" && event ); - - // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) - event.isTrigger = onlyHandlers ? 2 : 3; - event.namespace = namespaces.join( "." ); - event.rnamespace = event.namespace ? - new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : - null; - - // Clean up the event in case it is being reused - event.result = undefined; - if ( !event.target ) { - event.target = elem; - } - - // Clone any incoming data and prepend the event, creating the handler arg list - data = data == null ? - [ event ] : - jQuery.makeArray( data, [ event ] ); - - // Allow special events to draw outside the lines - special = jQuery.event.special[ type ] || {}; - if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { - return; - } - - // Determine event propagation path in advance, per W3C events spec (#9951) - // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) - if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { - - bubbleType = special.delegateType || type; - if ( !rfocusMorph.test( bubbleType + type ) ) { - cur = cur.parentNode; - } - for ( ; cur; cur = cur.parentNode ) { - eventPath.push( cur ); - tmp = cur; - } - - // Only add window if we got to document (e.g., not plain obj or detached DOM) - if ( tmp === ( elem.ownerDocument || document ) ) { - eventPath.push( tmp.defaultView || tmp.parentWindow || window ); - } - } - - // Fire handlers on the event path - i = 0; - while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { - - event.type = i > 1 ? - bubbleType : - special.bindType || type; - - // jQuery handler - handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && - jQuery._data( cur, "handle" ); - - if ( handle ) { - handle.apply( cur, data ); - } - - // Native handler - handle = ontype && cur[ ontype ]; - if ( handle && handle.apply && acceptData( cur ) ) { - event.result = handle.apply( cur, data ); - if ( event.result === false ) { - event.preventDefault(); - } - } - } - event.type = type; - - // If nobody prevented the default action, do it now - if ( !onlyHandlers && !event.isDefaultPrevented() ) { - - if ( - ( !special._default || - special._default.apply( eventPath.pop(), data ) === false - ) && acceptData( elem ) - ) { - - // Call a native DOM method on the target with the same name name as the event. - // Can't use an .isFunction() check here because IE6/7 fails that test. - // Don't do default actions on window, that's where global variables be (#6170) - if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) { - - // Don't re-trigger an onFOO event when we call its FOO() method - tmp = elem[ ontype ]; - - if ( tmp ) { - elem[ ontype ] = null; - } - - // Prevent re-triggering of the same event, since we already bubbled it above - jQuery.event.triggered = type; - try { - elem[ type ](); - } catch ( e ) { - - // IE<9 dies on focus/blur to hidden element (#1486,#12518) - // only reproducible on winXP IE8 native, not IE9 in IE8 mode - } - jQuery.event.triggered = undefined; - - if ( tmp ) { - elem[ ontype ] = tmp; - } - } - } - } - - return event.result; - }, - - dispatch: function( event ) { - - // Make a writable jQuery.Event from the native event object - event = jQuery.event.fix( event ); - - var i, j, ret, matched, handleObj, - handlerQueue = [], - args = slice.call( arguments ), - handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [], - special = jQuery.event.special[ event.type ] || {}; - - // Use the fix-ed jQuery.Event rather than the (read-only) native event - args[ 0 ] = event; - event.delegateTarget = this; - - // Call the preDispatch hook for the mapped type, and let it bail if desired - if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { - return; - } - - // Determine handlers - handlerQueue = jQuery.event.handlers.call( this, event, handlers ); - - // Run delegates first; they may want to stop propagation beneath us - i = 0; - while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { - event.currentTarget = matched.elem; - - j = 0; - while ( ( handleObj = matched.handlers[ j++ ] ) && - !event.isImmediatePropagationStopped() ) { - - // Triggered event must either 1) have no namespace, or 2) have namespace(s) - // a subset or equal to those in the bound event (both can have no namespace). - if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) { - - event.handleObj = handleObj; - event.data = handleObj.data; - - ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || - handleObj.handler ).apply( matched.elem, args ); - - if ( ret !== undefined ) { - if ( ( event.result = ret ) === false ) { - event.preventDefault(); - event.stopPropagation(); - } - } - } - } - } - - // Call the postDispatch hook for the mapped type - if ( special.postDispatch ) { - special.postDispatch.call( this, event ); - } - - return event.result; - }, - - handlers: function( event, handlers ) { - var i, matches, sel, handleObj, - handlerQueue = [], - delegateCount = handlers.delegateCount, - cur = event.target; - - // Support (at least): Chrome, IE9 - // Find delegate handlers - // Black-hole SVG instance trees (#13180) - // - // Support: Firefox<=42+ - // Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343) - if ( delegateCount && cur.nodeType && - ( event.type !== "click" || isNaN( event.button ) || event.button < 1 ) ) { - - /* jshint eqeqeq: false */ - for ( ; cur != this; cur = cur.parentNode || this ) { - /* jshint eqeqeq: true */ - - // Don't check non-elements (#13208) - // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) - if ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== "click" ) ) { - matches = []; - for ( i = 0; i < delegateCount; i++ ) { - handleObj = handlers[ i ]; - - // Don't conflict with Object.prototype properties (#13203) - sel = handleObj.selector + " "; - - if ( matches[ sel ] === undefined ) { - matches[ sel ] = handleObj.needsContext ? - jQuery( sel, this ).index( cur ) > -1 : - jQuery.find( sel, this, null, [ cur ] ).length; - } - if ( matches[ sel ] ) { - matches.push( handleObj ); - } - } - if ( matches.length ) { - handlerQueue.push( { elem: cur, handlers: matches } ); - } - } - } - } - - // Add the remaining (directly-bound) handlers - if ( delegateCount < handlers.length ) { - handlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } ); - } - - return handlerQueue; - }, - - fix: function( event ) { - if ( event[ jQuery.expando ] ) { - return event; - } - - // Create a writable copy of the event object and normalize some properties - var i, prop, copy, - type = event.type, - originalEvent = event, - fixHook = this.fixHooks[ type ]; - - if ( !fixHook ) { - this.fixHooks[ type ] = fixHook = - rmouseEvent.test( type ) ? this.mouseHooks : - rkeyEvent.test( type ) ? this.keyHooks : - {}; - } - copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; - - event = new jQuery.Event( originalEvent ); - - i = copy.length; - while ( i-- ) { - prop = copy[ i ]; - event[ prop ] = originalEvent[ prop ]; - } - - // Support: IE<9 - // Fix target property (#1925) - if ( !event.target ) { - event.target = originalEvent.srcElement || document; - } - - // Support: Safari 6-8+ - // Target should not be a text node (#504, #13143) - if ( event.target.nodeType === 3 ) { - event.target = event.target.parentNode; - } - - // Support: IE<9 - // For mouse/key events, metaKey==false if it's undefined (#3368, #11328) - event.metaKey = !!event.metaKey; - - return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; - }, - - // Includes some event props shared by KeyEvent and MouseEvent - props: ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " + - "metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ), - - fixHooks: {}, - - keyHooks: { - props: "char charCode key keyCode".split( " " ), - filter: function( event, original ) { - - // Add which for key events - if ( event.which == null ) { - event.which = original.charCode != null ? original.charCode : original.keyCode; - } - - return event; - } - }, - - mouseHooks: { - props: ( "button buttons clientX clientY fromElement offsetX offsetY " + - "pageX pageY screenX screenY toElement" ).split( " " ), - filter: function( event, original ) { - var body, eventDoc, doc, - button = original.button, - fromElement = original.fromElement; - - // Calculate pageX/Y if missing and clientX/Y available - if ( event.pageX == null && original.clientX != null ) { - eventDoc = event.target.ownerDocument || document; - doc = eventDoc.documentElement; - body = eventDoc.body; - - event.pageX = original.clientX + - ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); - event.pageY = original.clientY + - ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - - ( doc && doc.clientTop || body && body.clientTop || 0 ); - } - - // Add relatedTarget, if necessary - if ( !event.relatedTarget && fromElement ) { - event.relatedTarget = fromElement === event.target ? - original.toElement : - fromElement; - } - - // Add which for click: 1 === left; 2 === middle; 3 === right - // Note: button is not normalized, so don't use it - if ( !event.which && button !== undefined ) { - event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); - } - - return event; - } - }, - - special: { - load: { - - // Prevent triggered image.load events from bubbling to window.load - noBubble: true - }, - focus: { - - // Fire native event if possible so blur/focus sequence is correct - trigger: function() { - if ( this !== safeActiveElement() && this.focus ) { - try { - this.focus(); - return false; - } catch ( e ) { - - // Support: IE<9 - // If we error on focus to hidden element (#1486, #12518), - // let .trigger() run the handlers - } - } - }, - delegateType: "focusin" - }, - blur: { - trigger: function() { - if ( this === safeActiveElement() && this.blur ) { - this.blur(); - return false; - } - }, - delegateType: "focusout" - }, - click: { - - // For checkbox, fire native event so checked state will be right - trigger: function() { - if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) { - this.click(); - return false; - } - }, - - // For cross-browser consistency, don't fire native .click() on links - _default: function( event ) { - return jQuery.nodeName( event.target, "a" ); - } - }, - - beforeunload: { - postDispatch: function( event ) { - - // Support: Firefox 20+ - // Firefox doesn't alert if the returnValue field is not set. - if ( event.result !== undefined && event.originalEvent ) { - event.originalEvent.returnValue = event.result; - } - } - } - }, - - // Piggyback on a donor event to simulate a different one - simulate: function( type, elem, event ) { - var e = jQuery.extend( - new jQuery.Event(), - event, - { - type: type, - isSimulated: true - - // Previously, `originalEvent: {}` was set here, so stopPropagation call - // would not be triggered on donor event, since in our own - // jQuery.event.stopPropagation function we had a check for existence of - // originalEvent.stopPropagation method, so, consequently it would be a noop. - // - // Guard for simulated events was moved to jQuery.event.stopPropagation function - // since `originalEvent` should point to the original event for the - // constancy with other events and for more focused logic - } - ); - - jQuery.event.trigger( e, null, elem ); - - if ( e.isDefaultPrevented() ) { - event.preventDefault(); - } - } -}; - -jQuery.removeEvent = document.removeEventListener ? - function( elem, type, handle ) { - - // This "if" is needed for plain objects - if ( elem.removeEventListener ) { - elem.removeEventListener( type, handle ); - } - } : - function( elem, type, handle ) { - var name = "on" + type; - - if ( elem.detachEvent ) { - - // #8545, #7054, preventing memory leaks for custom events in IE6-8 - // detachEvent needed property on element, by name of that event, - // to properly expose it to GC - if ( typeof elem[ name ] === "undefined" ) { - elem[ name ] = null; - } - - elem.detachEvent( name, handle ); - } - }; - -jQuery.Event = function( src, props ) { - - // Allow instantiation without the 'new' keyword - if ( !( this instanceof jQuery.Event ) ) { - return new jQuery.Event( src, props ); - } - - // Event object - if ( src && src.type ) { - this.originalEvent = src; - this.type = src.type; - - // Events bubbling up the document may have been marked as prevented - // by a handler lower down the tree; reflect the correct value. - this.isDefaultPrevented = src.defaultPrevented || - src.defaultPrevented === undefined && - - // Support: IE < 9, Android < 4.0 - src.returnValue === false ? - returnTrue : - returnFalse; - - // Event type - } else { - this.type = src; - } - - // Put explicitly provided properties onto the event object - if ( props ) { - jQuery.extend( this, props ); - } - - // Create a timestamp if incoming event doesn't have one - this.timeStamp = src && src.timeStamp || jQuery.now(); - - // Mark it as fixed - this[ jQuery.expando ] = true; -}; - -// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding -// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html -jQuery.Event.prototype = { - constructor: jQuery.Event, - isDefaultPrevented: returnFalse, - isPropagationStopped: returnFalse, - isImmediatePropagationStopped: returnFalse, - - preventDefault: function() { - var e = this.originalEvent; - - this.isDefaultPrevented = returnTrue; - if ( !e ) { - return; - } - - // If preventDefault exists, run it on the original event - if ( e.preventDefault ) { - e.preventDefault(); - - // Support: IE - // Otherwise set the returnValue property of the original event to false - } else { - e.returnValue = false; - } - }, - stopPropagation: function() { - var e = this.originalEvent; - - this.isPropagationStopped = returnTrue; - - if ( !e || this.isSimulated ) { - return; - } - - // If stopPropagation exists, run it on the original event - if ( e.stopPropagation ) { - e.stopPropagation(); - } - - // Support: IE - // Set the cancelBubble property of the original event to true - e.cancelBubble = true; - }, - stopImmediatePropagation: function() { - var e = this.originalEvent; - - this.isImmediatePropagationStopped = returnTrue; - - if ( e && e.stopImmediatePropagation ) { - e.stopImmediatePropagation(); - } - - this.stopPropagation(); - } -}; - -// Create mouseenter/leave events using mouseover/out and event-time checks -// so that event delegation works in jQuery. -// Do the same for pointerenter/pointerleave and pointerover/pointerout -// -// Support: Safari 7 only -// Safari sends mouseenter too often; see: -// https://code.google.com/p/chromium/issues/detail?id=470258 -// for the description of the bug (it existed in older Chrome versions as well). -jQuery.each( { - mouseenter: "mouseover", - mouseleave: "mouseout", - pointerenter: "pointerover", - pointerleave: "pointerout" -}, function( orig, fix ) { - jQuery.event.special[ orig ] = { - delegateType: fix, - bindType: fix, - - handle: function( event ) { - var ret, - target = this, - related = event.relatedTarget, - handleObj = event.handleObj; - - // For mouseenter/leave call the handler if related is outside the target. - // NB: No relatedTarget if the mouse left/entered the browser window - if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { - event.type = handleObj.origType; - ret = handleObj.handler.apply( this, arguments ); - event.type = fix; - } - return ret; - } - }; -} ); - -// IE submit delegation -if ( !support.submit ) { - - jQuery.event.special.submit = { - setup: function() { - - // Only need this for delegated form submit events - if ( jQuery.nodeName( this, "form" ) ) { - return false; - } - - // Lazy-add a submit handler when a descendant form may potentially be submitted - jQuery.event.add( this, "click._submit keypress._submit", function( e ) { - - // Node name check avoids a VML-related crash in IE (#9807) - var elem = e.target, - form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? - - // Support: IE <=8 - // We use jQuery.prop instead of elem.form - // to allow fixing the IE8 delegated submit issue (gh-2332) - // by 3rd party polyfills/workarounds. - jQuery.prop( elem, "form" ) : - undefined; - - if ( form && !jQuery._data( form, "submit" ) ) { - jQuery.event.add( form, "submit._submit", function( event ) { - event._submitBubble = true; - } ); - jQuery._data( form, "submit", true ); - } - } ); - - // return undefined since we don't need an event listener - }, - - postDispatch: function( event ) { - - // If form was submitted by the user, bubble the event up the tree - if ( event._submitBubble ) { - delete event._submitBubble; - if ( this.parentNode && !event.isTrigger ) { - jQuery.event.simulate( "submit", this.parentNode, event ); - } - } - }, - - teardown: function() { - - // Only need this for delegated form submit events - if ( jQuery.nodeName( this, "form" ) ) { - return false; - } - - // Remove delegated handlers; cleanData eventually reaps submit handlers attached above - jQuery.event.remove( this, "._submit" ); - } - }; -} - -// IE change delegation and checkbox/radio fix -if ( !support.change ) { - - jQuery.event.special.change = { - - setup: function() { - - if ( rformElems.test( this.nodeName ) ) { - - // IE doesn't fire change on a check/radio until blur; trigger it on click - // after a propertychange. Eat the blur-change in special.change.handle. - // This still fires onchange a second time for check/radio after blur. - if ( this.type === "checkbox" || this.type === "radio" ) { - jQuery.event.add( this, "propertychange._change", function( event ) { - if ( event.originalEvent.propertyName === "checked" ) { - this._justChanged = true; - } - } ); - jQuery.event.add( this, "click._change", function( event ) { - if ( this._justChanged && !event.isTrigger ) { - this._justChanged = false; - } - - // Allow triggered, simulated change events (#11500) - jQuery.event.simulate( "change", this, event ); - } ); - } - return false; - } - - // Delegated event; lazy-add a change handler on descendant inputs - jQuery.event.add( this, "beforeactivate._change", function( e ) { - var elem = e.target; - - if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "change" ) ) { - jQuery.event.add( elem, "change._change", function( event ) { - if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { - jQuery.event.simulate( "change", this.parentNode, event ); - } - } ); - jQuery._data( elem, "change", true ); - } - } ); - }, - - handle: function( event ) { - var elem = event.target; - - // Swallow native change events from checkbox/radio, we already triggered them above - if ( this !== elem || event.isSimulated || event.isTrigger || - ( elem.type !== "radio" && elem.type !== "checkbox" ) ) { - - return event.handleObj.handler.apply( this, arguments ); - } - }, - - teardown: function() { - jQuery.event.remove( this, "._change" ); - - return !rformElems.test( this.nodeName ); - } - }; -} - -// Support: Firefox -// Firefox doesn't have focus(in | out) events -// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 -// -// Support: Chrome, Safari -// focus(in | out) events fire after focus & blur events, -// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order -// Related ticket - https://code.google.com/p/chromium/issues/detail?id=449857 -if ( !support.focusin ) { - jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { - - // Attach a single capturing handler on the document while someone wants focusin/focusout - var handler = function( event ) { - jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); - }; - - jQuery.event.special[ fix ] = { - setup: function() { - var doc = this.ownerDocument || this, - attaches = jQuery._data( doc, fix ); - - if ( !attaches ) { - doc.addEventListener( orig, handler, true ); - } - jQuery._data( doc, fix, ( attaches || 0 ) + 1 ); - }, - teardown: function() { - var doc = this.ownerDocument || this, - attaches = jQuery._data( doc, fix ) - 1; - - if ( !attaches ) { - doc.removeEventListener( orig, handler, true ); - jQuery._removeData( doc, fix ); - } else { - jQuery._data( doc, fix, attaches ); - } - } - }; - } ); -} - -jQuery.fn.extend( { - - on: function( types, selector, data, fn ) { - return on( this, types, selector, data, fn ); - }, - one: function( types, selector, data, fn ) { - return on( this, types, selector, data, fn, 1 ); - }, - off: function( types, selector, fn ) { - var handleObj, type; - if ( types && types.preventDefault && types.handleObj ) { - - // ( event ) dispatched jQuery.Event - handleObj = types.handleObj; - jQuery( types.delegateTarget ).off( - handleObj.namespace ? - handleObj.origType + "." + handleObj.namespace : - handleObj.origType, - handleObj.selector, - handleObj.handler - ); - return this; - } - if ( typeof types === "object" ) { - - // ( types-object [, selector] ) - for ( type in types ) { - this.off( type, selector, types[ type ] ); - } - return this; - } - if ( selector === false || typeof selector === "function" ) { - - // ( types [, fn] ) - fn = selector; - selector = undefined; - } - if ( fn === false ) { - fn = returnFalse; - } - return this.each( function() { - jQuery.event.remove( this, types, fn, selector ); - } ); - }, - - trigger: function( type, data ) { - return this.each( function() { - jQuery.event.trigger( type, data, this ); - } ); - }, - triggerHandler: function( type, data ) { - var elem = this[ 0 ]; - if ( elem ) { - return jQuery.event.trigger( type, data, elem, true ); - } - } -} ); - - -var rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, - rnoshimcache = new RegExp( "<(?:" + nodeNames + ")[\\s/>]", "i" ), - rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi, - - // Support: IE 10-11, Edge 10240+ - // In IE/Edge using regex groups here causes severe slowdowns. - // See https://connect.microsoft.com/IE/feedback/details/1736512/ - rnoInnerhtml = /\s*$/g, - safeFragment = createSafeFragment( document ), - fragmentDiv = safeFragment.appendChild( document.createElement( "div" ) ); - -// Support: IE<8 -// Manipulating tables requires a tbody -function manipulationTarget( elem, content ) { - return jQuery.nodeName( elem, "table" ) && - jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ? - - elem.getElementsByTagName( "tbody" )[ 0 ] || - elem.appendChild( elem.ownerDocument.createElement( "tbody" ) ) : - elem; -} - -// Replace/restore the type attribute of script elements for safe DOM manipulation -function disableScript( elem ) { - elem.type = ( jQuery.find.attr( elem, "type" ) !== null ) + "/" + elem.type; - return elem; -} -function restoreScript( elem ) { - var match = rscriptTypeMasked.exec( elem.type ); - if ( match ) { - elem.type = match[ 1 ]; - } else { - elem.removeAttribute( "type" ); - } - return elem; -} - -function cloneCopyEvent( src, dest ) { - if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { - return; - } - - var type, i, l, - oldData = jQuery._data( src ), - curData = jQuery._data( dest, oldData ), - events = oldData.events; - - if ( events ) { - delete curData.handle; - curData.events = {}; - - for ( type in events ) { - for ( i = 0, l = events[ type ].length; i < l; i++ ) { - jQuery.event.add( dest, type, events[ type ][ i ] ); - } - } - } - - // make the cloned public data object a copy from the original - if ( curData.data ) { - curData.data = jQuery.extend( {}, curData.data ); - } -} - -function fixCloneNodeIssues( src, dest ) { - var nodeName, e, data; - - // We do not need to do anything for non-Elements - if ( dest.nodeType !== 1 ) { - return; - } - - nodeName = dest.nodeName.toLowerCase(); - - // IE6-8 copies events bound via attachEvent when using cloneNode. - if ( !support.noCloneEvent && dest[ jQuery.expando ] ) { - data = jQuery._data( dest ); - - for ( e in data.events ) { - jQuery.removeEvent( dest, e, data.handle ); - } - - // Event data gets referenced instead of copied if the expando gets copied too - dest.removeAttribute( jQuery.expando ); - } - - // IE blanks contents when cloning scripts, and tries to evaluate newly-set text - if ( nodeName === "script" && dest.text !== src.text ) { - disableScript( dest ).text = src.text; - restoreScript( dest ); - - // IE6-10 improperly clones children of object elements using classid. - // IE10 throws NoModificationAllowedError if parent is null, #12132. - } else if ( nodeName === "object" ) { - if ( dest.parentNode ) { - dest.outerHTML = src.outerHTML; - } - - // This path appears unavoidable for IE9. When cloning an object - // element in IE9, the outerHTML strategy above is not sufficient. - // If the src has innerHTML and the destination does not, - // copy the src.innerHTML into the dest.innerHTML. #10324 - if ( support.html5Clone && ( src.innerHTML && !jQuery.trim( dest.innerHTML ) ) ) { - dest.innerHTML = src.innerHTML; - } - - } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) { - - // IE6-8 fails to persist the checked state of a cloned checkbox - // or radio button. Worse, IE6-7 fail to give the cloned element - // a checked appearance if the defaultChecked value isn't also set - - dest.defaultChecked = dest.checked = src.checked; - - // IE6-7 get confused and end up setting the value of a cloned - // checkbox/radio button to an empty string instead of "on" - if ( dest.value !== src.value ) { - dest.value = src.value; - } - - // IE6-8 fails to return the selected option to the default selected - // state when cloning options - } else if ( nodeName === "option" ) { - dest.defaultSelected = dest.selected = src.defaultSelected; - - // IE6-8 fails to set the defaultValue to the correct value when - // cloning other types of input fields - } else if ( nodeName === "input" || nodeName === "textarea" ) { - dest.defaultValue = src.defaultValue; - } -} - -function domManip( collection, args, callback, ignored ) { - - // Flatten any nested arrays - args = concat.apply( [], args ); - - var first, node, hasScripts, - scripts, doc, fragment, - i = 0, - l = collection.length, - iNoClone = l - 1, - value = args[ 0 ], - isFunction = jQuery.isFunction( value ); - - // We can't cloneNode fragments that contain checked, in WebKit - if ( isFunction || - ( l > 1 && typeof value === "string" && - !support.checkClone && rchecked.test( value ) ) ) { - return collection.each( function( index ) { - var self = collection.eq( index ); - if ( isFunction ) { - args[ 0 ] = value.call( this, index, self.html() ); - } - domManip( self, args, callback, ignored ); - } ); - } - - if ( l ) { - fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); - first = fragment.firstChild; - - if ( fragment.childNodes.length === 1 ) { - fragment = first; - } - - // Require either new content or an interest in ignored elements to invoke the callback - if ( first || ignored ) { - scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); - hasScripts = scripts.length; - - // Use the original fragment for the last item - // instead of the first because it can end up - // being emptied incorrectly in certain situations (#8070). - for ( ; i < l; i++ ) { - node = fragment; - - if ( i !== iNoClone ) { - node = jQuery.clone( node, true, true ); - - // Keep references to cloned scripts for later restoration - if ( hasScripts ) { - - // Support: Android<4.1, PhantomJS<2 - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge( scripts, getAll( node, "script" ) ); - } - } - - callback.call( collection[ i ], node, i ); - } - - if ( hasScripts ) { - doc = scripts[ scripts.length - 1 ].ownerDocument; - - // Reenable scripts - jQuery.map( scripts, restoreScript ); - - // Evaluate executable scripts on first document insertion - for ( i = 0; i < hasScripts; i++ ) { - node = scripts[ i ]; - if ( rscriptType.test( node.type || "" ) && - !jQuery._data( node, "globalEval" ) && - jQuery.contains( doc, node ) ) { - - if ( node.src ) { - - // Optional AJAX dependency, but won't run scripts if not present - if ( jQuery._evalUrl ) { - jQuery._evalUrl( node.src ); - } - } else { - jQuery.globalEval( - ( node.text || node.textContent || node.innerHTML || "" ) - .replace( rcleanScript, "" ) - ); - } - } - } - } - - // Fix #11809: Avoid leaking memory - fragment = first = null; - } - } - - return collection; -} - -function remove( elem, selector, keepData ) { - var node, - elems = selector ? jQuery.filter( selector, elem ) : elem, - i = 0; - - for ( ; ( node = elems[ i ] ) != null; i++ ) { - - if ( !keepData && node.nodeType === 1 ) { - jQuery.cleanData( getAll( node ) ); - } - - if ( node.parentNode ) { - if ( keepData && jQuery.contains( node.ownerDocument, node ) ) { - setGlobalEval( getAll( node, "script" ) ); - } - node.parentNode.removeChild( node ); - } - } - - return elem; -} - -jQuery.extend( { - htmlPrefilter: function( html ) { - return html.replace( rxhtmlTag, "<$1>" ); - }, - - clone: function( elem, dataAndEvents, deepDataAndEvents ) { - var destElements, node, clone, i, srcElements, - inPage = jQuery.contains( elem.ownerDocument, elem ); - - if ( support.html5Clone || jQuery.isXMLDoc( elem ) || - !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { - - clone = elem.cloneNode( true ); - - // IE<=8 does not properly clone detached, unknown element nodes - } else { - fragmentDiv.innerHTML = elem.outerHTML; - fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); - } - - if ( ( !support.noCloneEvent || !support.noCloneChecked ) && - ( elem.nodeType === 1 || elem.nodeType === 11 ) && !jQuery.isXMLDoc( elem ) ) { - - // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 - destElements = getAll( clone ); - srcElements = getAll( elem ); - - // Fix all IE cloning issues - for ( i = 0; ( node = srcElements[ i ] ) != null; ++i ) { - - // Ensure that the destination node is not null; Fixes #9587 - if ( destElements[ i ] ) { - fixCloneNodeIssues( node, destElements[ i ] ); - } - } - } - - // Copy the events from the original to the clone - if ( dataAndEvents ) { - if ( deepDataAndEvents ) { - srcElements = srcElements || getAll( elem ); - destElements = destElements || getAll( clone ); - - for ( i = 0; ( node = srcElements[ i ] ) != null; i++ ) { - cloneCopyEvent( node, destElements[ i ] ); - } - } else { - cloneCopyEvent( elem, clone ); - } - } - - // Preserve script evaluation history - destElements = getAll( clone, "script" ); - if ( destElements.length > 0 ) { - setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); - } - - destElements = srcElements = node = null; - - // Return the cloned set - return clone; - }, - - cleanData: function( elems, /* internal */ forceAcceptData ) { - var elem, type, id, data, - i = 0, - internalKey = jQuery.expando, - cache = jQuery.cache, - attributes = support.attributes, - special = jQuery.event.special; - - for ( ; ( elem = elems[ i ] ) != null; i++ ) { - if ( forceAcceptData || acceptData( elem ) ) { - - id = elem[ internalKey ]; - data = id && cache[ id ]; - - if ( data ) { - if ( data.events ) { - for ( type in data.events ) { - if ( special[ type ] ) { - jQuery.event.remove( elem, type ); - - // This is a shortcut to avoid jQuery.event.remove's overhead - } else { - jQuery.removeEvent( elem, type, data.handle ); - } - } - } - - // Remove cache only if it was not already removed by jQuery.event.remove - if ( cache[ id ] ) { - - delete cache[ id ]; - - // Support: IE<9 - // IE does not allow us to delete expando properties from nodes - // IE creates expando attributes along with the property - // IE does not have a removeAttribute function on Document nodes - if ( !attributes && typeof elem.removeAttribute !== "undefined" ) { - elem.removeAttribute( internalKey ); - - // Webkit & Blink performance suffers when deleting properties - // from DOM nodes, so set to undefined instead - // https://code.google.com/p/chromium/issues/detail?id=378607 - } else { - elem[ internalKey ] = undefined; - } - - deletedIds.push( id ); - } - } - } - } - } -} ); - -jQuery.fn.extend( { - - // Keep domManip exposed until 3.0 (gh-2225) - domManip: domManip, - - detach: function( selector ) { - return remove( this, selector, true ); - }, - - remove: function( selector ) { - return remove( this, selector ); - }, - - text: function( value ) { - return access( this, function( value ) { - return value === undefined ? - jQuery.text( this ) : - this.empty().append( - ( this[ 0 ] && this[ 0 ].ownerDocument || document ).createTextNode( value ) - ); - }, null, value, arguments.length ); - }, - - append: function() { - return domManip( this, arguments, function( elem ) { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - var target = manipulationTarget( this, elem ); - target.appendChild( elem ); - } - } ); - }, - - prepend: function() { - return domManip( this, arguments, function( elem ) { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - var target = manipulationTarget( this, elem ); - target.insertBefore( elem, target.firstChild ); - } - } ); - }, - - before: function() { - return domManip( this, arguments, function( elem ) { - if ( this.parentNode ) { - this.parentNode.insertBefore( elem, this ); - } - } ); - }, - - after: function() { - return domManip( this, arguments, function( elem ) { - if ( this.parentNode ) { - this.parentNode.insertBefore( elem, this.nextSibling ); - } - } ); - }, - - empty: function() { - var elem, - i = 0; - - for ( ; ( elem = this[ i ] ) != null; i++ ) { - - // Remove element nodes and prevent memory leaks - if ( elem.nodeType === 1 ) { - jQuery.cleanData( getAll( elem, false ) ); - } - - // Remove any remaining nodes - while ( elem.firstChild ) { - elem.removeChild( elem.firstChild ); - } - - // If this is a select, ensure that it displays empty (#12336) - // Support: IE<9 - if ( elem.options && jQuery.nodeName( elem, "select" ) ) { - elem.options.length = 0; - } - } - - return this; - }, - - clone: function( dataAndEvents, deepDataAndEvents ) { - dataAndEvents = dataAndEvents == null ? false : dataAndEvents; - deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; - - return this.map( function() { - return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); - } ); - }, - - html: function( value ) { - return access( this, function( value ) { - var elem = this[ 0 ] || {}, - i = 0, - l = this.length; - - if ( value === undefined ) { - return elem.nodeType === 1 ? - elem.innerHTML.replace( rinlinejQuery, "" ) : - undefined; - } - - // See if we can take a shortcut and just use innerHTML - if ( typeof value === "string" && !rnoInnerhtml.test( value ) && - ( support.htmlSerialize || !rnoshimcache.test( value ) ) && - ( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && - !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { - - value = jQuery.htmlPrefilter( value ); - - try { - for ( ; i < l; i++ ) { - - // Remove element nodes and prevent memory leaks - elem = this[ i ] || {}; - if ( elem.nodeType === 1 ) { - jQuery.cleanData( getAll( elem, false ) ); - elem.innerHTML = value; - } - } - - elem = 0; - - // If using innerHTML throws an exception, use the fallback method - } catch ( e ) {} - } - - if ( elem ) { - this.empty().append( value ); - } - }, null, value, arguments.length ); - }, - - replaceWith: function() { - var ignored = []; - - // Make the changes, replacing each non-ignored context element with the new content - return domManip( this, arguments, function( elem ) { - var parent = this.parentNode; - - if ( jQuery.inArray( this, ignored ) < 0 ) { - jQuery.cleanData( getAll( this ) ); - if ( parent ) { - parent.replaceChild( elem, this ); - } - } - - // Force callback invocation - }, ignored ); - } -} ); - -jQuery.each( { - appendTo: "append", - prependTo: "prepend", - insertBefore: "before", - insertAfter: "after", - replaceAll: "replaceWith" -}, function( name, original ) { - jQuery.fn[ name ] = function( selector ) { - var elems, - i = 0, - ret = [], - insert = jQuery( selector ), - last = insert.length - 1; - - for ( ; i <= last; i++ ) { - elems = i === last ? this : this.clone( true ); - jQuery( insert[ i ] )[ original ]( elems ); - - // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get() - push.apply( ret, elems.get() ); - } - - return this.pushStack( ret ); - }; -} ); - - -var iframe, - elemdisplay = { - - // Support: Firefox - // We have to pre-define these values for FF (#10227) - HTML: "block", - BODY: "block" - }; - -/** - * Retrieve the actual display of a element - * @param {String} name nodeName of the element - * @param {Object} doc Document object - */ - -// Called only from within defaultDisplay -function actualDisplay( name, doc ) { - var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), - - display = jQuery.css( elem[ 0 ], "display" ); - - // We don't have any data stored on the element, - // so use "detach" method as fast way to get rid of the element - elem.detach(); - - return display; -} - -/** - * Try to determine the default display value of an element - * @param {String} nodeName - */ -function defaultDisplay( nodeName ) { - var doc = document, - display = elemdisplay[ nodeName ]; - - if ( !display ) { - display = actualDisplay( nodeName, doc ); - - // If the simple way fails, read from inside an iframe - if ( display === "none" || !display ) { - - // Use the already-created iframe if possible - iframe = ( iframe || jQuery( "