diff --git a/.gitignore b/.gitignore index f66d9ef079..5dbaa70164 100755 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,11 @@ .DS_Store node_modules/ -sandbox/ -tmp/ \ No newline at end of file +sandbox/* +!sandbox/_base.html +!sandbox/_sandbox.css +!sandbox/require.js +!sandbox/sample/ +tmp/ +FIX.js +build/* +!build/README.md diff --git a/.travis.yml b/.travis.yml index b293a23c26..3822763338 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,14 @@ language: node_js -python: +node_js: - '0.10' before_script: -- npm install -g grunt-cli \ No newline at end of file +- npm install -g grunt-cli; chmod u+x scripts/deploy-edge-to-cdn.sh; grunt +script: ./scripts/deploy-edge-to-cdn.sh +env: + global: + - GH_REF: github.com/ractivejs/cdn.ractivejs.org.git + - secure: "dnPSiJmQuKhMh8skVLUjFegc+resP5wZV9scVxrSzkJNOzqLPE9Z8nm4c95gh6MzfHEz6YWz3gKfUfJeyHgpp1zfo+1EfOmit78GxZf+aj7GW1lBpPXFpobpTE1ZVTizu3/M6AojRXB7eIqSGJsUQvZAY8t1dldUDbocwveXqA0=" +branches: + only: + - master + - 0.4.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index 90a5f970d5..5324220505 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,13 +1,43 @@ Changelog --------- +* 0.4.0 + * BREAKING: Filenames are now lowercase. May affect you if you use Browserify etc. + * BREAKING: `set()`, `update()`, `teardown()`, `animate()`, `merge()`, `add()`, `subtract()`, and `toggle()` methods return a Promise that fulfils asynchronously when any resulting transitions have completed + * BREAKING: Elements are detached when *all* transitions are complete for a given instance, not just transitions on descendant nodes + * BREAKING: Default options are placed on `Ractive.defaults` (and `Component.defaults`, where `Component = Ractive.extend(...)`) + * BREAKING: The `adaptors` option is now `adapt`. It can be a string rather than an array if you're only using one adaptor + * Reactive computed properties + * Two-way binding works with 'keypath expressions' such as `{{foo[bar]}}` + * Support for single-file component imports via loader plugins such as http://ractivejs.github.io/ractive-load/ + * A global runloop handles change propagation and other batchable operations, resulting in performance improvements across the board + * Promises are used internally, and exposed as `Ractive.Promise` (Promises/A+ compliant, a la ES6 Promises) + * Components can have encapsulated styles, passed in as the `css` option (disable with `noCssTransform: true`) + * `ractive.reset()` method allows you to replace an instance's `data` object + * Decorators are updated when their arguments change (with specified `update()` method if possible, otherwise by tearing down and reinitialising) + * Inline components inherit surrounding data context, unless defined with `isolated: true` + * Transitions will use JavaScript timers if CSS transitions are unavailable + * A global variable (`window.Ractive`) is always exported, but `Ractive.noConflict()` is provided to prevent clobbering existing `Ractive` variable + * Inline component `init()` methods are only called once the component has entered the DOM + * Any section can be closed with `{{/...}}`, where `...` can be any string other than the closing delimiter + * Evaluators that throw exceptions will print an error to the console in debug mode + * `ractive.observe(callback)` - i.e. with no keypath - observes everything + * `ractive.observe('foo bar baz', callback)` will observe all three keypaths (passed to callback as third argument) + * Better whitespace preservation and indenting when using `ractive.toHTML()` + * Calling `ractive.off()` with no arguments removes all event listeners + * Triples work inside SVG elements + * `` works the same as `` + * More robust data/event propagation between components + * More robust magic mode + * Fixed a host of edge case bugs relating to array mutations + * Many minor fixes and tweaks: #349, #351, #353, #369, #370, #376, #377, #390, #391, #393, #398, #401, #406, #412, #425, #433, #434, #439, #441, #442, #446, #451, #460, #462, #464, #465, #467, #479, #480, #483, #486, #520, #530, #536, #553, #556 * 0.3.9 * `ractive.findComponent()` and `ractive.findAllComponents()` methods, for getting references to components * Expression results are wrapped if necessary (e.g. `{{getJSON(url)}}` wrapped by [@lluchs](https://github.com/lluchs)' [Promise adaptor](lluchs.github.io/Ractive-adaptors-Promise/)) * Mustaches referring to wrapped values render the facade, not the value * Directive arguments are parsed more reliably * Components inherit adaptors from their parents - * Adaptors can be set on subclasses defined with `Ractive.extend()` + * Adapto * Changes to [transitions API](http://docs.ractivejs.org/latest/transitions) * SVG support is detected and exposed as `Ractive.svg` * If subclass has data, it is used as prototype for instance data diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 47912e4128..db61050827 100755 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -19,13 +19,11 @@ Of course, if you've encountered a bug, then the best course of action is to rai Raising issues -------------- -Before submitting an issue, please make sure you're using the [latest released version](https://raw.github.com/RactiveJS/Ractive/master/Ractive.js). +Before submitting an issue, please make sure you're using the latest released version - http://cdn.ractivejs.org/latest/Ractive.js. -If the bug persists, it may have been fixed in the latest development version. New versions are developed in branches, named for the version number (e.g. at the time of writing, the development branch is [0.3.9](https://github.com/RactiveJS/Ractive/tree/0.3.9)). You can get the most recent builds from the `build` folder of this branch. +If the bug persists, it may have been fixed in the latest development version. You can always get the most recent successful build from http://cdn.ractivejs.org/edge/Ractive.js. -See the [branches page](https://github.com/RactiveJS/Ractive/branches) to find the newest development branch. - -The best issues contain a reproducible demonstration of the bug in the form of a [JSFiddle](http://jsfiddle.net/VGaLu/) or similar. A good tip when using these tools is to import Ractive via [rawgithub.com](https://rawgithub.com/), e.g. https://rawgithub.com/RactiveJS/Ractive/master/Ractive.js. +The best issues contain a reproducible demonstration of the bug in the form of a JSFiddle or similar. [This JSFiddle](http://jsfiddle.net/rich_harris/va6jU/) has a basic setup to get started with. Pull requests @@ -34,7 +32,7 @@ Pull requests **Pull requests against the master branch will not be merged!** -All pull requests are welcome. You should create a new branch, based on the newest development branch (see above), and submit the PR against the dev branch. +All pull requests are welcome. You should create a new branch, based on the newest development branch (currently [0.4.0](https://github.com/RactiveJS/Ractive/tree/0.4.0)), and submit the PR against that dev branch. *Caveat for what follows: If in doubt, submit the request - a PR that needs tweaking is infinitely more valuable than a request that wasn't made because you were worrying about meeting these requirements.* diff --git a/Gruntfile.js b/Gruntfile.js index 826130233b..d0174f0075 100755 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,204 +1,35 @@ /*global module:false*/ -module.exports = function(grunt) { +module.exports = function ( grunt ) { - // Project configuration. - grunt.initConfig({ + 'use strict'; - pkg: grunt.file.readJSON( 'package.json' ), - - watch: { - js: { - files: [ 'src/**/*.js', 'wrapper/**/*.js' ], - tasks: [ 'clean:tmp', 'requirejs' ], - options: { - interrupt: true, - force: true - } - } - }, - - nodeunit: { - basic: [ 'test/node/basic.js' ], - parse: [ 'test/node/parse.js' ], - toHTML: [ 'test/node/toHTML.js' ] - }, - - qunit: { - parse: [ 'test/build/parse.html' ], - render: [ 'test/build/render.html' ], - mustache: [ 'test/build/mustache.html' ], - events: [ 'test/build/events.html' ], - misc: [ 'test/build/misc.html' ], - components: [ 'test/build/components.html' ], - merge: [ 'test/build/merge.html' ], - observe: [ 'test/build/observe.html' ], - options: { - timeout: 30000 - } - }, - - requirejs: { - full: { - options: { - baseUrl: 'src/', - name: 'Ractive', - out: 'tmp/Ractive.js', - optimize: 'none', - findNestedDependencies: true, - onBuildWrite: function( name, path, contents ) { - return require( 'amdclean' ).clean( contents ); - }, - - wrap: { - startFile: 'wrapper/intro.js', - endFile: 'wrapper/outro.js' - } - } - }, - runtime: { - options: { - baseUrl: 'src/', - name: 'Ractive', - out: 'tmp/Ractive.runtime.js', - optimize: 'none', - findNestedDependencies: true, - onBuildWrite: function( name, path, contents ) { - return require( 'amdclean' ).clean( contents ); - }, - - paths: { - 'parse/_parse': 'empty:' - }, - - wrap: { - startFile: 'wrapper/intro.js', - endFile: 'wrapper/outro.js' - } - } - } - }, + var config, dependency; - concat: { - options: { - banner: grunt.file.read( 'wrapper/banner.js' ), - process: { - data: { version: '<%= pkg.version %>' } - } - }, - full: { - src: [ 'tmp/Ractive.js' ], - dest: 'build/Ractive.js' - }, - runtime: { - src: [ 'tmp/Ractive.runtime.js' ], - dest: 'build/Ractive.runtime.js' - }, - full_legacy: { - src: [ 'src/legacy.js', 'tmp/Ractive.js' ], - dest: 'build/Ractive-legacy.js' - }, - runtime_legacy: { - src: [ 'src/legacy.js', 'tmp/Ractive.runtime.js' ], - dest: 'build/Ractive-legacy.runtime.js' - } - }, - - clean: { - tmp: [ 'tmp/' ], - build: [ 'build/' ] - }, - - jshint: { - files: [ 'src/**/*.js' ], - options: { - proto: true, - smarttabs: true, - boss: true, - evil: true, - laxbreak: true, - undef: true, - unused: true, - '-W018': true, - '-W041': false, - eqnull: true, - strict: true, - globals: { - define: true, - require: true, - Element: true, - window: true, - setTimeout: true, - setInterval: true, - clearInterval: true, - module: true, - document: true, - loadCircularDependency: true - } - } - }, - - uglify: { - runtime: { - src: ['<%= concat.runtime.dest %>'], - dest: 'build/Ractive.runtime.min.js' - }, - full: { - src: ['<%= concat.full.dest %>'], - dest: 'build/Ractive.min.js' - }, - runtime_legacy: { - src: ['<%= concat.runtime_legacy.dest %>'], - dest: 'build/Ractive-legacy.runtime.min.js' - }, - full_legacy: { - src: ['<%= concat.full_legacy.dest %>'], - dest: 'build/Ractive-legacy.min.js' - } - }, - - copy: { - release: { - files: [{ - expand: true, - cwd: 'build/', - src: [ '**/*' ], - dest: 'release/<%= pkg.version %>/' - }] - }, - link: { - files: { - 'Ractive.js': 'build/Ractive.js' - } - } - } + config = { + pkg: grunt.file.readJSON( 'package.json' ), + intro: grunt.file.read( 'wrapper/intro.js' ), + outro: grunt.file.read( 'wrapper/outro.js' ), + banner: grunt.file.read( 'wrapper/banner.js' ) + }; + + // Read config files from the `grunt/config/` folder + grunt.file.expand( 'grunt/config/*.js' ).forEach( function ( path ) { + var property = /grunt\/config\/(.+)\.js/.exec( path )[1], + module = require( './' + path ); + config[ property ] = typeof module === 'function' ? module( grunt ) : module; }); - grunt.loadNpmTasks( 'grunt-contrib-jshint' ); - grunt.loadNpmTasks( 'grunt-contrib-clean' ); - grunt.loadNpmTasks( 'grunt-contrib-nodeunit' ); - grunt.loadNpmTasks( 'grunt-contrib-qunit' ); - grunt.loadNpmTasks( 'grunt-contrib-concat' ); - grunt.loadNpmTasks( 'grunt-contrib-uglify' ); - grunt.loadNpmTasks( 'grunt-contrib-copy' ); - grunt.loadNpmTasks( 'grunt-contrib-watch' ); - grunt.loadNpmTasks( 'grunt-contrib-requirejs' ); + // Initialise grunt + grunt.initConfig( config ); - grunt.registerTask( 'default', [ - 'test', - 'clean:build', - 'concat', - 'uglify', - 'copy:link' - ]); - - grunt.registerTask( 'test', [ - 'clean:tmp', - 'jshint', - 'requirejs', - 'nodeunit', - 'qunit' - ]); + // Load development dependencies specified in package.json + for ( dependency in config.pkg.devDependencies ) { + if ( /^grunt-/.test( dependency) ) { + grunt.loadNpmTasks( dependency ); + } + } - grunt.registerTask( 'release', [ 'default', 'copy:release', 'copy:link' ] ); + // Load tasks from the `grunt-tasks/` folder + grunt.loadTasks( 'grunt/tasks' ); }; diff --git a/LICENSE.md b/LICENSE.md index beb3fbdbfa..e83ccb5444 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,4 +1,4 @@ -Copyright (c) 2014 Rich Harris and contributors +Copyright (c) 2013-14 Rich Harris and contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation diff --git a/README.md b/README.md index 407698380a..e75c747475 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Ractive.js - Next-generation DOM manipulation *Got questions? Tag Stack Overflow questions with [ractivejs](http://stackoverflow.com/questions/tagged/ractivejs) or contact [@RactiveJS](http://twitter.com/RactiveJS) on Twitter* -*BETANAUTS! Help improve the next version of Ractive by trying out the [pre-release 0.4.0 builds](https://github.com/Rich-Harris/Ractive/tree/0.4.0/build) and [reporting any issues](https://github.com/Rich-Harris/Ractive/issues?state=open)!* +*BETANAUTS! Help improve the next version of Ractive by trying out the [pre-release 0.4.0 builds](https://github.com/ractivejs/ractive/tree/0.4.0/build) and [reporting any issues](https://github.com/ractivejs/ractive/issues?state=open)!* What is Ractive.js? ------------------- @@ -17,13 +17,13 @@ It's a JavaScript library for building reactive user interfaces in a way that do ...among many others. It takes a radically different approach to DOM manipulation - one that saves both you and the browser unnecessary work. -To get a feel for how it will make your life as a web developer easier, visit [ractivejs.org](http://ractivejs.org), follow the [interactive tutorials](http://learn.ractivejs.org), or try the [60 second setup](https://github.com/RactiveJS/Ractive/wiki/60-second-setup). +To get a feel for how it will make your life as a web developer easier, visit [ractivejs.org](http://ractivejs.org), follow the [interactive tutorials](http://learn.ractivejs.org), or try the [60 second setup](https://github.com/ractivejs/ractive/wiki/60-second-setup). Get help -------- -If you don't find what you're looking for in the [docs](https://github.com/rich-harris/Ractive/wiki), ask a question on Stack Overflow with the `ractivejs` tag, or send a tweet to [@RactiveJS](http://twitter.com/RactiveJS) or [@Rich_Harris](http://twitter.com/Rich_Harris). +If you don't find what you're looking for in the [docs](http://docs.ractivejs.org/latest), ask a question on Stack Overflow with the `ractive` tag, or send a tweet to [@RactiveJS](http://twitter.com/RactiveJS). Building @@ -69,7 +69,7 @@ $ grunt release Contributing ------------ -If you have feature suggestions or bug reports, please [raise an issue on GitHub](https://github.com/RactiveJS/Ractive/issues) after checking it's not a duplicate. +If you have feature suggestions or bug reports, please [raise an issue on GitHub](https://github.com/ractivejs/ractive/issues) after checking it's not a duplicate. Pull requests are always welcome! In lieu of a formal styleguide, please try to follow the existing conventions. diff --git a/Ractive.js b/Ractive.js deleted file mode 100644 index 462414585e..0000000000 --- a/Ractive.js +++ /dev/null @@ -1,9134 +0,0 @@ -/* - - Ractive - v0.3.9 - 2013-12-31 - ============================================================== - - Next-generation DOM manipulation - http://ractivejs.org - Follow @RactiveJS for updates - - -------------------------------------------------------------- - - Copyright 2013 2013 Rich Harris and contributors - - 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 ( global ) { - - - -var config_svg = function () { - - if (typeof document === 'undefined') { - return; - } - return document && document.implementation.hasFeature('http://www.w3.org/TR/SVG11/feature#BasicStructure', '1.1'); - }(); -var utils_create = function () { - - var create; - try { - Object.create(null); - create = Object.create; - } catch (err) { - create = function () { - var F = function () { - }; - return function (proto, props) { - var obj; - if (proto === null) { - return {}; - } - F.prototype = proto; - obj = new F(); - if (props) { - Object.defineProperties(obj, props); - } - return obj; - }; - }(); - } - return create; - }(); -var config_namespaces = { - html: 'http://www.w3.org/1999/xhtml', - mathml: 'http://www.w3.org/1998/Math/MathML', - svg: 'http://www.w3.org/2000/svg', - xlink: 'http://www.w3.org/1999/xlink', - xml: 'http://www.w3.org/XML/1998/namespace', - xmlns: 'http://www.w3.org/2000/xmlns/' - }; -var utils_createElement = function (svg, namespaces) { - - if (!svg) { - return function (type, ns) { - if (ns && ns !== namespaces.html) { - throw 'This browser does not support namespaces other than http://www.w3.org/1999/xhtml. The most likely cause of this error is that you\'re trying to render SVG in an older browser. See https://github.com/RactiveJS/Ractive/wiki/SVG-and-older-browsers for more information'; - } - return document.createElement(type); - }; - } else { - return function (type, ns) { - if (!ns) { - return document.createElement(type); - } - return document.createElementNS(ns, type); - }; - } - }(config_svg, config_namespaces); -var config_isClient = function () { - - if (typeof document === 'object') { - return true; - } - return false; - }(); -var utils_defineProperty = function (isClient) { - - try { - Object.defineProperty({}, 'test', { value: 0 }); - if (isClient) { - Object.defineProperty(document.createElement('div'), 'test', { value: 0 }); - } - return Object.defineProperty; - } catch (err) { - return function (obj, prop, desc) { - obj[prop] = desc.value; - }; - } - }(config_isClient); -var utils_defineProperties = function (createElement, defineProperty, isClient) { - - try { - try { - Object.defineProperties({}, { test: { value: 0 } }); - } catch (err) { - throw err; - } - if (isClient) { - Object.defineProperties(createElement('div'), { test: { value: 0 } }); - } - return Object.defineProperties; - } catch (err) { - return function (obj, props) { - var prop; - for (prop in props) { - if (props.hasOwnProperty(prop)) { - defineProperty(obj, prop, props[prop]); - } - } - }; - } - }(utils_createElement, utils_defineProperty, config_isClient); -var utils_normaliseKeypath = function () { - - var regex = /\[\s*(\*|[0-9]|[1-9][0-9]+)\s*\]/g; - return function (keypath) { - return (keypath || '').replace(regex, '.$1'); - }; - }(); -var registries_adaptors = {}; -var config_types = { - TEXT: 1, - INTERPOLATOR: 2, - TRIPLE: 3, - SECTION: 4, - INVERTED: 5, - CLOSING: 6, - ELEMENT: 7, - PARTIAL: 8, - COMMENT: 9, - DELIMCHANGE: 10, - MUSTACHE: 11, - TAG: 12, - ATTRIBUTE: 13, - COMPONENT: 15, - NUMBER_LITERAL: 20, - STRING_LITERAL: 21, - ARRAY_LITERAL: 22, - OBJECT_LITERAL: 23, - BOOLEAN_LITERAL: 24, - GLOBAL: 26, - KEY_VALUE_PAIR: 27, - REFERENCE: 30, - REFINEMENT: 31, - MEMBER: 32, - PREFIX_OPERATOR: 33, - BRACKETED: 34, - CONDITIONAL: 35, - INFIX_OPERATOR: 36, - INVOCATION: 40 - }; -var utils_isArray = function () { - - var toString = Object.prototype.toString; - return function (thing) { - return toString.call(thing) === '[object Array]'; - }; - }(); -var shared_clearCache = function () { - - return function clearCache(ractive, keypath) { - var cacheMap, wrappedProperty; - if (wrappedProperty = ractive._wrapped[keypath]) { - if (wrappedProperty.teardown() !== false) { - ractive._wrapped[keypath] = null; - } - } - ractive._cache[keypath] = undefined; - if (cacheMap = ractive._cacheMap[keypath]) { - while (cacheMap.length) { - clearCache(ractive, cacheMap.pop()); - } - } - }; - }(); -var shared_getValueFromCheckboxes = function () { - - return function (ractive, keypath) { - var value, checkboxes, checkbox, len, i, rootEl; - value = []; - rootEl = ractive.rendered ? ractive.el : ractive.fragment.docFrag; - checkboxes = rootEl.querySelectorAll('input[type="checkbox"][name="{{' + keypath + '}}"]'); - len = checkboxes.length; - for (i = 0; i < len; i += 1) { - checkbox = checkboxes[i]; - if (checkbox.hasAttribute('checked') || checkbox.checked) { - value[value.length] = checkbox._ractive.value; - } - } - return value; - }; - }(); -var shared_preDomUpdate = function (getValueFromCheckboxes) { - - return function (ractive) { - var deferred, evaluator, selectValue, attribute, keypath, radio; - deferred = ractive._deferred; - while (evaluator = deferred.evals.pop()) { - evaluator.update().deferred = false; - } - while (selectValue = deferred.selectValues.pop()) { - selectValue.deferredUpdate(); - } - while (attribute = deferred.attrs.pop()) { - attribute.update().deferred = false; - } - while (keypath = deferred.checkboxes.pop()) { - ractive.set(keypath, getValueFromCheckboxes(ractive, keypath)); - } - while (radio = deferred.radios.pop()) { - radio.update(); - } - }; - }(shared_getValueFromCheckboxes); -var shared_postDomUpdate = function () { - - return function (ractive) { - var deferred, focusable, query, decorator, transition, observer; - deferred = ractive._deferred; - if (focusable = deferred.focusable) { - focusable.focus(); - deferred.focusable = null; - } - while (query = deferred.liveQueries.pop()) { - query._sort(); - } - while (decorator = deferred.decorators.pop()) { - decorator.init(); - } - while (transition = deferred.transitions.pop()) { - transition.init(); - } - while (observer = deferred.observers.pop()) { - observer.update(); - } - }; - }(); -var shared_makeTransitionManager = function () { - - var makeTransitionManager = function (root, callback) { - var transitionManager, elementsToDetach, detachNodes, nodeHasNoTransitioningChildren; - if (root._parent && root._parent._transitionManager) { - return root._parent._transitionManager; - } - elementsToDetach = []; - detachNodes = function () { - var i, element; - i = elementsToDetach.length; - while (i--) { - element = elementsToDetach[i]; - if (nodeHasNoTransitioningChildren(element.node)) { - element.detach(); - elementsToDetach.splice(i, 1); - } - } - }; - nodeHasNoTransitioningChildren = function (node) { - var i, candidate; - i = transitionManager.active.length; - while (i--) { - candidate = transitionManager.active[i]; - if (node.contains(candidate)) { - return false; - } - } - return true; - }; - transitionManager = { - active: [], - push: function (node) { - transitionManager.active[transitionManager.active.length] = node; - }, - pop: function (node) { - var index; - index = transitionManager.active.indexOf(node); - if (index === -1) { - return; - } - transitionManager.active.splice(index, 1); - detachNodes(); - if (!transitionManager.active.length && transitionManager._ready) { - transitionManager.complete(); - } - }, - complete: function () { - if (callback) { - callback.call(root); - } - }, - ready: function () { - detachNodes(); - transitionManager._ready = true; - if (!transitionManager.active.length) { - transitionManager.complete(); - } - }, - detachWhenReady: function (element) { - elementsToDetach[elementsToDetach.length] = element; - } - }; - return transitionManager; - }; - return makeTransitionManager; - }(); -var shared_notifyDependants = function () { - - var notifyDependants, lastKey, starMaps = {}; - lastKey = /[^\.]+$/; - notifyDependants = function (ractive, keypath, onlyDirect) { - var i; - if (ractive._patternObservers.length) { - notifyPatternObservers(ractive, keypath, keypath, onlyDirect, true); - } - for (i = 0; i < ractive._deps.length; i += 1) { - notifyDependantsAtPriority(ractive, keypath, i, onlyDirect); - } - }; - notifyDependants.multiple = function (ractive, keypaths, onlyDirect) { - var i, j, len; - len = keypaths.length; - if (ractive._patternObservers.length) { - i = len; - while (i--) { - notifyPatternObservers(ractive, keypaths[i], keypaths[i], onlyDirect, true); - } - } - for (i = 0; i < ractive._deps.length; i += 1) { - if (ractive._deps[i]) { - j = len; - while (j--) { - notifyDependantsAtPriority(ractive, keypaths[j], i, onlyDirect); - } - } - } - }; - return notifyDependants; - function notifyDependantsAtPriority(ractive, keypath, priority, onlyDirect) { - var depsByKeypath = ractive._deps[priority]; - if (!depsByKeypath) { - return; - } - updateAll(depsByKeypath[keypath]); - if (onlyDirect) { - return; - } - cascade(ractive._depsMap[keypath], ractive, priority); - } - function updateAll(deps) { - var i, len; - if (deps) { - len = deps.length; - for (i = 0; i < len; i += 1) { - deps[i].update(); - } - } - } - function cascade(childDeps, ractive, priority, onlyDirect) { - var i; - if (childDeps) { - i = childDeps.length; - while (i--) { - notifyDependantsAtPriority(ractive, childDeps[i], priority, onlyDirect); - } - } - } - function notifyPatternObservers(ractive, registeredKeypath, actualKeypath, isParentOfChangedKeypath, isTopLevelCall) { - var i, patternObserver, children, child, key, childActualKeypath, potentialWildcardMatches, cascade; - i = ractive._patternObservers.length; - while (i--) { - patternObserver = ractive._patternObservers[i]; - if (patternObserver.regex.test(actualKeypath)) { - patternObserver.update(actualKeypath); - } - } - if (isParentOfChangedKeypath) { - return; - } - cascade = function (keypath) { - if (children = ractive._depsMap[keypath]) { - i = children.length; - while (i--) { - child = children[i]; - key = lastKey.exec(child)[0]; - childActualKeypath = actualKeypath + '.' + key; - notifyPatternObservers(ractive, child, childActualKeypath); - } - } - }; - if (isTopLevelCall) { - potentialWildcardMatches = getPotentialWildcardMatches(actualKeypath); - potentialWildcardMatches.forEach(cascade); - } else { - cascade(registeredKeypath); - } - } - function getPotentialWildcardMatches(keypath) { - var keys, starMap, mapper, i, result, wildcardKeypath; - keys = keypath.split('.'); - starMap = getStarMap(keys.length); - result = []; - mapper = function (star, i) { - return star ? '*' : keys[i]; - }; - i = starMap.length; - while (i--) { - wildcardKeypath = starMap[i].map(mapper).join('.'); - if (!result[wildcardKeypath]) { - result[result.length] = wildcardKeypath; - result[wildcardKeypath] = true; - } - } - return result; - } - function getStarMap(num) { - var ones = '', max, binary, starMap, mapper, i; - if (!starMaps[num]) { - starMap = []; - while (ones.length < num) { - ones += 1; - } - max = parseInt(ones, 2); - mapper = function (digit) { - return digit === '1'; - }; - for (i = 0; i <= max; i += 1) { - binary = i.toString(2); - while (binary.length < num) { - binary = '0' + binary; - } - starMap[i] = Array.prototype.map.call(binary, mapper); - } - starMaps[num] = starMap; - } - return starMaps[num]; - } - }(); -var Ractive_prototype_get_arrayAdaptor = function (types, defineProperty, isArray, clearCache, preDomUpdate, postDomUpdate, makeTransitionManager, notifyDependants) { - - var arrayAdaptor, notifyArrayDependants, ArrayWrapper, patchArrayMethods, unpatchArrayMethods, patchedArrayProto, testObj, mutatorMethods, noop, errorMessage; - arrayAdaptor = { - filter: function (object) { - return isArray(object) && (!object._ractive || !object._ractive.setting); - }, - wrap: function (ractive, array, keypath) { - return new ArrayWrapper(ractive, array, keypath); - } - }; - ArrayWrapper = function (ractive, array, keypath) { - this.root = ractive; - this.value = array; - this.keypath = keypath; - if (!array._ractive) { - defineProperty(array, '_ractive', { - value: { - wrappers: [], - instances: [], - setting: false - }, - configurable: true - }); - patchArrayMethods(array); - } - if (!array._ractive.instances[ractive._guid]) { - array._ractive.instances[ractive._guid] = 0; - array._ractive.instances.push(ractive); - } - array._ractive.instances[ractive._guid] += 1; - array._ractive.wrappers.push(this); - }; - ArrayWrapper.prototype = { - get: function () { - return this.value; - }, - teardown: function () { - var array, storage, wrappers, instances, index; - array = this.value; - storage = array._ractive; - wrappers = storage.wrappers; - instances = storage.instances; - if (storage.setting) { - return false; - } - index = wrappers.indexOf(this); - if (index === -1) { - throw new Error(errorMessage); - } - wrappers.splice(index, 1); - if (!wrappers.length) { - delete array._ractive; - unpatchArrayMethods(this.value); - } else { - instances[this.root._guid] -= 1; - if (!instances[this.root._guid]) { - index = instances.indexOf(this.root); - if (index === -1) { - throw new Error(errorMessage); - } - instances.splice(index, 1); - } - } - } - }; - notifyArrayDependants = function (array, methodName, args) { - var notifyKeypathDependants, queueDependants, wrappers, wrapper, i; - notifyKeypathDependants = function (root, keypath) { - var depsByKeypath, deps, keys, upstreamQueue, smartUpdateQueue, dumbUpdateQueue, i, changed, start, end, childKeypath, lengthUnchanged; - if (methodName === 'sort' || methodName === 'reverse') { - root.set(keypath, array); - return; - } - clearCache(root, keypath); - smartUpdateQueue = []; - dumbUpdateQueue = []; - for (i = 0; i < root._deps.length; i += 1) { - depsByKeypath = root._deps[i]; - if (!depsByKeypath) { - continue; - } - deps = depsByKeypath[keypath]; - if (deps) { - queueDependants(keypath, deps, smartUpdateQueue, dumbUpdateQueue); - preDomUpdate(root); - while (smartUpdateQueue.length) { - smartUpdateQueue.pop().smartUpdate(methodName, args); - } - while (dumbUpdateQueue.length) { - dumbUpdateQueue.pop().update(); - } - } - } - if (methodName === 'splice' && args.length > 2 && args[1]) { - changed = Math.min(args[1], args.length - 2); - start = args[0]; - end = start + changed; - if (args[1] === args.length - 2) { - lengthUnchanged = true; - } - for (i = start; i < end; i += 1) { - childKeypath = keypath + '.' + i; - notifyDependants(root, childKeypath); - } - } - preDomUpdate(root); - upstreamQueue = []; - keys = keypath.split('.'); - while (keys.length) { - keys.pop(); - upstreamQueue[upstreamQueue.length] = keys.join('.'); - } - notifyDependants.multiple(root, upstreamQueue, true); - if (!lengthUnchanged) { - notifyDependants(root, keypath + '.length', true); - } - }; - queueDependants = function (keypath, deps, smartUpdateQueue, dumbUpdateQueue) { - var k, dependant; - k = deps.length; - while (k--) { - dependant = deps[k]; - if (dependant.type === types.REFERENCE) { - dependant.update(); - } else if (dependant.keypath === keypath && dependant.type === types.SECTION && !dependant.inverted && dependant.docFrag) { - smartUpdateQueue[smartUpdateQueue.length] = dependant; - } else { - dumbUpdateQueue[dumbUpdateQueue.length] = dependant; - } - } - }; - wrappers = array._ractive.wrappers; - i = wrappers.length; - while (i--) { - wrapper = wrappers[i]; - notifyKeypathDependants(wrapper.root, wrapper.keypath); - } - }; - patchedArrayProto = []; - mutatorMethods = [ - 'pop', - 'push', - 'reverse', - 'shift', - 'sort', - 'splice', - 'unshift' - ]; - noop = function () { - }; - mutatorMethods.forEach(function (methodName) { - var method = function () { - var result, instances, instance, i, previousTransitionManagers = {}, transitionManagers = {}; - result = Array.prototype[methodName].apply(this, arguments); - instances = this._ractive.instances; - i = instances.length; - while (i--) { - instance = instances[i]; - previousTransitionManagers[instance._guid] = instance._transitionManager; - instance._transitionManager = transitionManagers[instance._guid] = makeTransitionManager(instance, noop); - } - this._ractive.setting = true; - notifyArrayDependants(this, methodName, arguments); - this._ractive.setting = false; - i = instances.length; - while (i--) { - instance = instances[i]; - instance._transitionManager = previousTransitionManagers[instance._guid]; - transitionManagers[instance._guid].ready(); - preDomUpdate(instance); - postDomUpdate(instance); - } - return result; - }; - defineProperty(patchedArrayProto, methodName, { value: method }); - }); - testObj = {}; - if (testObj.__proto__) { - patchArrayMethods = function (array) { - array.__proto__ = patchedArrayProto; - }; - unpatchArrayMethods = function (array) { - array.__proto__ = Array.prototype; - }; - } else { - patchArrayMethods = function (array) { - var i, methodName; - i = mutatorMethods.length; - while (i--) { - methodName = mutatorMethods[i]; - defineProperty(array, methodName, { - value: patchedArrayProto[methodName], - configurable: true - }); - } - }; - unpatchArrayMethods = function (array) { - var i; - i = mutatorMethods.length; - while (i--) { - delete array[mutatorMethods[i]]; - } - }; - } - errorMessage = 'Something went wrong in a rather interesting way'; - return arrayAdaptor; - }(config_types, utils_defineProperty, utils_isArray, shared_clearCache, shared_preDomUpdate, shared_postDomUpdate, shared_makeTransitionManager, shared_notifyDependants); -var Ractive_prototype_get_magicAdaptor = function () { - - var magicAdaptor, MagicWrapper; - try { - Object.defineProperty({}, 'test', { value: 0 }); - } catch (err) { - return false; - } - magicAdaptor = { - filter: function (object, keypath) { - return !!keypath; - }, - wrap: function (ractive, object, keypath) { - return new MagicWrapper(ractive, object, keypath); - } - }; - MagicWrapper = function (ractive, object, keypath) { - var wrapper = this, keys, prop, objKeypath, descriptor, wrappers, oldGet, oldSet, get, set; - this.ractive = ractive; - this.keypath = keypath; - keys = keypath.split('.'); - this.prop = keys.pop(); - objKeypath = keys.join('.'); - this.obj = objKeypath ? ractive.get(objKeypath) : ractive.data; - descriptor = this.originalDescriptor = Object.getOwnPropertyDescriptor(this.obj, this.prop); - if (descriptor && descriptor.set && (wrappers = descriptor.set._ractiveWrappers)) { - if (wrappers.indexOf(this) === -1) { - wrappers.push(this); - } - return; - } - if (descriptor && !descriptor.configurable) { - throw new Error('Cannot use magic mode with property "' + prop + '" - object is not configurable'); - } - if (descriptor) { - this.value = descriptor.value; - oldGet = descriptor.get; - oldSet = descriptor.set; - } - get = oldGet || function () { - return wrapper.value; - }; - set = function (value) { - var wrappers, wrapper, i; - if (oldSet) { - oldSet(value); - } - wrappers = set._ractiveWrappers; - i = wrappers.length; - while (i--) { - wrapper = wrappers[i]; - if (!wrapper.resetting) { - wrapper.ractive.set(wrapper.keypath, value); - } - } - }; - set._ractiveWrappers = [this]; - Object.defineProperty(this.obj, this.prop, { - get: get, - set: set, - enumerable: true, - configurable: true - }); - }; - MagicWrapper.prototype = { - get: function () { - return this.value; - }, - reset: function (value) { - this.resetting = true; - this.value = value; - this.resetting = false; - }, - teardown: function () { - var descriptor, set, value, wrappers; - descriptor = Object.getOwnPropertyDescriptor(this.obj, this.prop); - set = descriptor.set; - wrappers = set._ractiveWrappers; - wrappers.splice(wrappers.indexOf(this), 1); - if (!wrappers.length) { - value = this.obj[this.prop]; - Object.defineProperty(this.obj, this.prop, this.originalDescriptor || { - writable: true, - enumerable: true, - configrable: true - }); - this.obj[this.prop] = value; - } - } - }; - return magicAdaptor; - }(); -var shared_adaptIfNecessary = function (adaptorRegistry, arrayAdaptor, magicAdaptor) { - - var prefixers = {}; - return function (ractive, keypath, value, isExpressionResult) { - var len, i, adaptor, wrapped; - len = ractive.adaptors.length; - for (i = 0; i < len; i += 1) { - adaptor = ractive.adaptors[i]; - if (typeof adaptor === 'string') { - if (!adaptorRegistry[adaptor]) { - throw new Error('Missing adaptor "' + adaptor + '"'); - } - adaptor = ractive.adaptors[i] = adaptorRegistry[adaptor]; - } - if (adaptor.filter(value, keypath, ractive)) { - wrapped = ractive._wrapped[keypath] = adaptor.wrap(ractive, value, keypath, getPrefixer(keypath)); - wrapped.value = value; - return; - } - } - if (!isExpressionResult) { - if (ractive.magic && magicAdaptor.filter(value, keypath, ractive)) { - ractive._wrapped[keypath] = magicAdaptor.wrap(ractive, value, keypath); - } else if (ractive.modifyArrays && arrayAdaptor.filter(value, keypath, ractive)) { - ractive._wrapped[keypath] = arrayAdaptor.wrap(ractive, value, keypath); - } - } - }; - function prefixKeypath(obj, prefix) { - var prefixed = {}, key; - if (!prefix) { - return obj; - } - prefix += '.'; - for (key in obj) { - if (obj.hasOwnProperty(key)) { - prefixed[prefix + key] = obj[key]; - } - } - return prefixed; - } - function getPrefixer(rootKeypath) { - var rootDot; - if (!prefixers[rootKeypath]) { - rootDot = rootKeypath ? rootKeypath + '.' : ''; - prefixers[rootKeypath] = function (relativeKeypath, value) { - var obj; - if (typeof relativeKeypath === 'string') { - obj = {}; - obj[rootDot + relativeKeypath] = value; - return obj; - } - if (typeof relativeKeypath === 'object') { - return rootDot ? prefixKeypath(relativeKeypath, rootKeypath) : relativeKeypath; - } - }; - } - return prefixers[rootKeypath]; - } - }(registries_adaptors, Ractive_prototype_get_arrayAdaptor, Ractive_prototype_get_magicAdaptor); -var Ractive_prototype_get__get = function (normaliseKeypath, adaptorRegistry, adaptIfNecessary) { - - var get, _get, retrieve; - get = function (keypath) { - if (this._captured && !this._captured[keypath]) { - this._captured.push(keypath); - this._captured[keypath] = true; - } - return _get(this, keypath); - }; - _get = function (ractive, keypath) { - var cache, cached, value, wrapped, evaluator; - keypath = normaliseKeypath(keypath); - cache = ractive._cache; - if ((cached = cache[keypath]) !== undefined) { - return cached; - } - if (wrapped = ractive._wrapped[keypath]) { - value = wrapped.value; - } else if (!keypath) { - adaptIfNecessary(ractive, '', ractive.data); - value = ractive.data; - } else if (evaluator = ractive._evaluators[keypath]) { - value = evaluator.value; - } else { - value = retrieve(ractive, keypath); - } - cache[keypath] = value; - return value; - }; - retrieve = function (ractive, keypath) { - var keys, key, parentKeypath, parentValue, cacheMap, value, wrapped; - keys = keypath.split('.'); - key = keys.pop(); - parentKeypath = keys.join('.'); - parentValue = _get(ractive, parentKeypath); - if (wrapped = ractive._wrapped[parentKeypath]) { - parentValue = wrapped.get(); - } - if (parentValue === null || parentValue === undefined) { - return; - } - if (!(cacheMap = ractive._cacheMap[parentKeypath])) { - ractive._cacheMap[parentKeypath] = [keypath]; - } else { - if (cacheMap.indexOf(keypath) === -1) { - cacheMap[cacheMap.length] = keypath; - } - } - value = parentValue[key]; - adaptIfNecessary(ractive, keypath, value); - ractive._cache[keypath] = value; - return value; - }; - return get; - }(utils_normaliseKeypath, registries_adaptors, shared_adaptIfNecessary); -var utils_isObject = function () { - - var toString = Object.prototype.toString; - return function (thing) { - return typeof thing === 'object' && toString.call(thing) === '[object Object]'; - }; - }(); -var utils_isEqual = function () { - - return function (a, b) { - if (a === null && b === null) { - return true; - } - if (typeof a === 'object' || typeof b === 'object') { - return false; - } - return a === b; - }; - }(); -var shared_resolveRef = function () { - - var resolveRef; - resolveRef = function (ractive, ref, contextStack) { - var keypath, keys, lastKey, contextKeys, innerMostContext, postfix, parentKeypath, parentValue, wrapped, context, ancestorErrorMessage; - ancestorErrorMessage = 'Could not resolve reference - too many "../" prefixes'; - if (ref === '.') { - if (!contextStack.length) { - return ''; - } - keypath = contextStack[contextStack.length - 1]; - } else if (ref.charAt(0) === '.') { - context = contextStack[contextStack.length - 1]; - contextKeys = context ? context.split('.') : []; - if (ref.substr(0, 3) === '../') { - while (ref.substr(0, 3) === '../') { - if (!contextKeys.length) { - throw new Error(ancestorErrorMessage); - } - contextKeys.pop(); - ref = ref.substring(3); - } - contextKeys.push(ref); - keypath = contextKeys.join('.'); - } else if (!context) { - keypath = ref.substring(1); - } else { - keypath = context + ref; - } - } else { - keys = ref.split('.'); - lastKey = keys.pop(); - postfix = keys.length ? '.' + keys.join('.') : ''; - contextStack = contextStack.concat(); - while (contextStack.length) { - innerMostContext = contextStack.pop(); - parentKeypath = innerMostContext + postfix; - parentValue = ractive.get(parentKeypath); - if (wrapped = ractive._wrapped[parentKeypath]) { - parentValue = wrapped.get(); - } - if (typeof parentValue === 'object' && parentValue !== null && parentValue.hasOwnProperty(lastKey)) { - keypath = innerMostContext + '.' + ref; - break; - } - } - if (!keypath && ractive.get(ref) !== undefined) { - keypath = ref; - } - } - return keypath ? keypath.replace(/^\./, '') : keypath; - }; - return resolveRef; - }(); -var shared_attemptKeypathResolution = function (resolveRef) { - - var push = Array.prototype.push; - return function (ractive) { - var unresolved, keypath, leftover; - while (unresolved = ractive._pendingResolution.pop()) { - keypath = resolveRef(ractive, unresolved.ref, unresolved.contextStack); - if (keypath !== undefined) { - unresolved.resolve(keypath); - } else { - (leftover || (leftover = [])).push(unresolved); - } - } - if (leftover) { - push.apply(ractive._pendingResolution, leftover); - } - }; - }(shared_resolveRef); -var shared_processDeferredUpdates = function (preDomUpdate, postDomUpdate) { - - return function (ractive) { - preDomUpdate(ractive); - postDomUpdate(ractive); - }; - }(shared_preDomUpdate, shared_postDomUpdate); -var Ractive_prototype_shared_replaceData = function () { - - return function (ractive, keypath, value) { - var keys, accumulated, wrapped, obj, key, currentKeypath, keypathToClear; - keys = keypath.split('.'); - accumulated = []; - if (wrapped = ractive._wrapped['']) { - if (wrapped.set) { - wrapped.set(keys.join('.'), value); - } - obj = wrapped.get(); - } else { - obj = ractive.data; - } - while (keys.length > 1) { - key = accumulated[accumulated.length] = keys.shift(); - currentKeypath = accumulated.join('.'); - if (wrapped = ractive._wrapped[currentKeypath]) { - if (wrapped.set) { - wrapped.set(keys.join('.'), value); - } - obj = wrapped.get(); - } else { - if (!obj.hasOwnProperty(key)) { - if (!keypathToClear) { - keypathToClear = currentKeypath; - } - obj[key] = /^\s*[0-9]+\s*$/.test(keys[0]) ? [] : {}; - } - obj = obj[key]; - } - } - key = keys[0]; - obj[key] = value; - return keypathToClear; - }; - }(); -var Ractive_prototype_set = function (isObject, isEqual, normaliseKeypath, clearCache, notifyDependants, attemptKeypathResolution, makeTransitionManager, processDeferredUpdates, replaceData) { - - var set, updateModel, getUpstreamChanges, resetWrapped; - set = function (keypath, value, complete) { - var map, changes, upstreamChanges, previousTransitionManager, transitionManager, i, changeHash; - changes = []; - if (isObject(keypath)) { - map = keypath; - complete = value; - } - if (map) { - for (keypath in map) { - if (map.hasOwnProperty(keypath)) { - value = map[keypath]; - keypath = normaliseKeypath(keypath); - updateModel(this, keypath, value, changes); - } - } - } else { - keypath = normaliseKeypath(keypath); - updateModel(this, keypath, value, changes); - } - if (!changes.length) { - return; - } - previousTransitionManager = this._transitionManager; - this._transitionManager = transitionManager = makeTransitionManager(this, complete); - upstreamChanges = getUpstreamChanges(changes); - if (upstreamChanges.length) { - notifyDependants.multiple(this, upstreamChanges, true); - } - notifyDependants.multiple(this, changes); - if (this._pendingResolution.length) { - attemptKeypathResolution(this); - } - processDeferredUpdates(this); - this._transitionManager = previousTransitionManager; - transitionManager.ready(); - if (!this.firingChangeEvent) { - this.firingChangeEvent = true; - changeHash = {}; - i = changes.length; - while (i--) { - changeHash[changes[i]] = this.get(changes[i]); - } - this.fire('change', changeHash); - this.firingChangeEvent = false; - } - return this; - }; - updateModel = function (ractive, keypath, value, changes) { - var cached, previous, wrapped, keypathToClear, evaluator; - if ((wrapped = ractive._wrapped[keypath]) && wrapped.reset) { - if (resetWrapped(ractive, keypath, value, wrapped, changes) !== false) { - return; - } - } - if (evaluator = ractive._evaluators[keypath]) { - evaluator.value = value; - } - cached = ractive._cache[keypath]; - previous = ractive.get(keypath); - if (previous !== value && !evaluator) { - keypathToClear = replaceData(ractive, keypath, value); - } else { - if (value === cached && typeof value !== 'object') { - return; - } - } - clearCache(ractive, keypathToClear || keypath); - changes[changes.length] = keypath; - }; - getUpstreamChanges = function (changes) { - var upstreamChanges = [''], i, keypath, keys, upstreamKeypath; - i = changes.length; - while (i--) { - keypath = changes[i]; - keys = keypath.split('.'); - while (keys.length > 1) { - keys.pop(); - upstreamKeypath = keys.join('.'); - if (!upstreamChanges[upstreamKeypath]) { - upstreamChanges[upstreamChanges.length] = upstreamKeypath; - upstreamChanges[upstreamKeypath] = true; - } - } - } - return upstreamChanges; - }; - resetWrapped = function (ractive, keypath, value, wrapped, changes) { - var previous, cached, cacheMap, i; - previous = wrapped.get(); - if (!isEqual(previous, value)) { - if (wrapped.reset(value) === false) { - return false; - } - } - value = wrapped.get(); - cached = ractive._cache[keypath]; - if (!isEqual(cached, value)) { - ractive._cache[keypath] = value; - cacheMap = ractive._cacheMap[keypath]; - if (cacheMap) { - i = cacheMap.length; - while (i--) { - clearCache(ractive, cacheMap[i]); - } - } - changes[changes.length] = keypath; - } - }; - return set; - }(utils_isObject, utils_isEqual, utils_normaliseKeypath, shared_clearCache, shared_notifyDependants, shared_attemptKeypathResolution, shared_makeTransitionManager, shared_processDeferredUpdates, Ractive_prototype_shared_replaceData); -var Ractive_prototype_update = function (makeTransitionManager, attemptKeypathResolution, clearCache, notifyDependants, processDeferredUpdates) { - - return function (keypath, complete) { - var transitionManager, previousTransitionManager; - if (typeof keypath === 'function') { - complete = keypath; - keypath = ''; - } - previousTransitionManager = this._transitionManager; - this._transitionManager = transitionManager = makeTransitionManager(this, complete); - attemptKeypathResolution(this); - clearCache(this, keypath || ''); - notifyDependants(this, keypath || ''); - processDeferredUpdates(this); - this._transitionManager = previousTransitionManager; - transitionManager.ready(); - if (typeof keypath === 'string') { - this.fire('update', keypath); - } else { - this.fire('update'); - } - return this; - }; - }(shared_makeTransitionManager, shared_attemptKeypathResolution, shared_clearCache, shared_notifyDependants, shared_processDeferredUpdates); -var utils_arrayContentsMatch = function (isArray) { - - return function (a, b) { - var i; - if (!isArray(a) || !isArray(b)) { - return false; - } - if (a.length !== b.length) { - return false; - } - i = a.length; - while (i--) { - if (a[i] !== b[i]) { - return false; - } - } - return true; - }; - }(utils_isArray); -var Ractive_prototype_updateModel = function (getValueFromCheckboxes, arrayContentsMatch, isEqual) { - - return function (keypath, cascade) { - var values, deferredCheckboxes, i; - if (typeof keypath !== 'string') { - keypath = ''; - cascade = true; - } - consolidateChangedValues(this, keypath, values = {}, deferredCheckboxes = [], cascade); - if (i = deferredCheckboxes.length) { - while (i--) { - keypath = deferredCheckboxes[i]; - values[keypath] = getValueFromCheckboxes(this, keypath); - } - } - this.set(values); - }; - function consolidateChangedValues(ractive, keypath, values, deferredCheckboxes, cascade) { - var bindings, childDeps, i, binding, oldValue, newValue; - bindings = ractive._twowayBindings[keypath]; - if (bindings) { - i = bindings.length; - while (i--) { - binding = bindings[i]; - if (binding.radioName && !binding.node.checked) { - continue; - } - if (binding.checkboxName) { - if (binding.changed() && !deferredCheckboxes[keypath]) { - deferredCheckboxes[keypath] = true; - deferredCheckboxes[deferredCheckboxes.length] = keypath; - } - continue; - } - oldValue = binding.attr.value; - newValue = binding.value(); - if (arrayContentsMatch(oldValue, newValue)) { - continue; - } - if (!isEqual(oldValue, newValue)) { - values[keypath] = newValue; - } - } - } - if (!cascade) { - return; - } - childDeps = ractive._depsMap[keypath]; - if (childDeps) { - i = childDeps.length; - while (i--) { - consolidateChangedValues(ractive, childDeps[i], values, deferredCheckboxes, cascade); - } - } - } - }(shared_getValueFromCheckboxes, utils_arrayContentsMatch, utils_isEqual); -var Ractive_prototype_animate_requestAnimationFrame = function () { - - if (typeof window === 'undefined') { - return; - } - (function (vendors, lastTime, window) { - var x, setTimeout; - if (window.requestAnimationFrame) { - return; - } - for (x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { - window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame']; - } - if (!window.requestAnimationFrame) { - setTimeout = window.setTimeout; - window.requestAnimationFrame = function (callback) { - var currTime, timeToCall, id; - currTime = Date.now(); - timeToCall = Math.max(0, 16 - (currTime - lastTime)); - id = setTimeout(function () { - callback(currTime + timeToCall); - }, timeToCall); - lastTime = currTime + timeToCall; - return id; - }; - } - }([ - 'ms', - 'moz', - 'webkit', - 'o' - ], 0, window)); - return window.requestAnimationFrame; - }(); -var Ractive_prototype_animate_animations = function (rAF) { - - var queue = []; - var animations = { - tick: function () { - var i, animation; - for (i = 0; i < queue.length; i += 1) { - animation = queue[i]; - if (!animation.tick()) { - queue.splice(i--, 1); - } - } - if (queue.length) { - rAF(animations.tick); - } else { - animations.running = false; - } - }, - add: function (animation) { - queue[queue.length] = animation; - if (!animations.running) { - animations.running = true; - animations.tick(); - } - }, - abort: function (keypath, root) { - var i = queue.length, animation; - while (i--) { - animation = queue[i]; - if (animation.root === root && animation.keypath === keypath) { - animation.stop(); - } - } - } - }; - return animations; - }(Ractive_prototype_animate_requestAnimationFrame); -var utils_warn = function () { - - if (typeof console !== 'undefined' && typeof console.warn === 'function' && typeof console.warn.apply === 'function') { - return function () { - console.warn.apply(console, arguments); - }; - } - return function () { - }; - }(); -var utils_isNumeric = function () { - - return function (thing) { - return !isNaN(parseFloat(thing)) && isFinite(thing); - }; - }(); -var shared_interpolate = function (isArray, isObject, isNumeric) { - - var interpolate = function (from, to) { - if (isNumeric(from) && isNumeric(to)) { - return makeNumberInterpolator(+from, +to); - } - if (isArray(from) && isArray(to)) { - return makeArrayInterpolator(from, to); - } - if (isObject(from) && isObject(to)) { - return makeObjectInterpolator(from, to); - } - return function () { - return to; - }; - }; - return interpolate; - function makeNumberInterpolator(from, to) { - var delta = to - from; - if (!delta) { - return function () { - return from; - }; - } - return function (t) { - return from + t * delta; - }; - } - function makeArrayInterpolator(from, to) { - var intermediate, interpolators, len, i; - intermediate = []; - interpolators = []; - i = len = Math.min(from.length, to.length); - while (i--) { - interpolators[i] = interpolate(from[i], to[i]); - } - for (i = len; i < from.length; i += 1) { - intermediate[i] = from[i]; - } - for (i = len; i < to.length; i += 1) { - intermediate[i] = to[i]; - } - return function (t) { - var i = len; - while (i--) { - intermediate[i] = interpolators[i](t); - } - return intermediate; - }; - } - function makeObjectInterpolator(from, to) { - var properties = [], len, interpolators, intermediate, prop; - intermediate = {}; - interpolators = {}; - for (prop in from) { - if (from.hasOwnProperty(prop)) { - if (to.hasOwnProperty(prop)) { - properties[properties.length] = prop; - interpolators[prop] = interpolate(from[prop], to[prop]); - } else { - intermediate[prop] = from[prop]; - } - } - } - for (prop in to) { - if (to.hasOwnProperty(prop) && !from.hasOwnProperty(prop)) { - intermediate[prop] = to[prop]; - } - } - len = properties.length; - return function (t) { - var i = len, prop; - while (i--) { - prop = properties[i]; - intermediate[prop] = interpolators[prop](t); - } - return intermediate; - }; - } - }(utils_isArray, utils_isObject, utils_isNumeric); -var Ractive_prototype_animate_Animation = function (warn, interpolate) { - - var Animation = function (options) { - var key; - this.startTime = Date.now(); - for (key in options) { - if (options.hasOwnProperty(key)) { - this[key] = options[key]; - } - } - this.interpolator = interpolate(this.from, this.to); - this.running = true; - }; - Animation.prototype = { - tick: function () { - var elapsed, t, value, timeNow, index, keypath; - keypath = this.keypath; - if (this.running) { - timeNow = Date.now(); - elapsed = timeNow - this.startTime; - if (elapsed >= this.duration) { - if (keypath !== null) { - this.root.set(keypath, this.to); - } - if (this.step) { - this.step(1, this.to); - } - if (this.complete) { - this.complete(1, this.to); - } - index = this.root._animations.indexOf(this); - if (index === -1) { - warn('Animation was not found'); - } - this.root._animations.splice(index, 1); - this.running = false; - return false; - } - t = this.easing ? this.easing(elapsed / this.duration) : elapsed / this.duration; - if (keypath !== null) { - value = this.interpolator(t); - this.root.set(keypath, value); - } - if (this.step) { - this.step(t, value); - } - return true; - } - return false; - }, - stop: function () { - var index; - this.running = false; - index = this.root._animations.indexOf(this); - if (index === -1) { - warn('Animation was not found'); - } - this.root._animations.splice(index, 1); - } - }; - return Animation; - }(utils_warn, shared_interpolate); -var registries_easing = function () { - - return { - linear: function (pos) { - return pos; - }, - easeIn: function (pos) { - return Math.pow(pos, 3); - }, - easeOut: function (pos) { - return Math.pow(pos - 1, 3) + 1; - }, - easeInOut: function (pos) { - if ((pos /= 0.5) < 1) { - return 0.5 * Math.pow(pos, 3); - } - return 0.5 * (Math.pow(pos - 2, 3) + 2); - } - }; - }(); -var Ractive_prototype_animate__animate = function (isEqual, animations, Animation, easingRegistry) { - - var noAnimation = { - stop: function () { - } - }; - return function (keypath, to, options) { - var k, animation, animations, easing, duration, step, complete, makeValueCollector, currentValues, collectValue, dummy, dummyOptions; - if (typeof keypath === 'object') { - options = to || {}; - easing = options.easing; - duration = options.duration; - animations = []; - step = options.step; - complete = options.complete; - if (step || complete) { - currentValues = {}; - options.step = null; - options.complete = null; - makeValueCollector = function (keypath) { - return function (t, value) { - currentValues[keypath] = value; - }; - }; - } - for (k in keypath) { - if (keypath.hasOwnProperty(k)) { - if (step || complete) { - collectValue = makeValueCollector(k); - options = { - easing: easing, - duration: duration - }; - if (step) { - options.step = collectValue; - } - if (complete) { - options.complete = collectValue; - } - } - animations[animations.length] = animate(this, k, keypath[k], options); - } - } - if (step || complete) { - dummyOptions = { - easing: easing, - duration: duration - }; - if (step) { - dummyOptions.step = function (t) { - step(t, currentValues); - }; - } - if (complete) { - dummyOptions.complete = function (t) { - complete(t, currentValues); - }; - } - animations[animations.length] = dummy = animate(this, null, null, dummyOptions); - } - return { - stop: function () { - while (animations.length) { - animations.pop().stop(); - } - if (dummy) { - dummy.stop(); - } - } - }; - } - options = options || {}; - animation = animate(this, keypath, to, options); - return { - stop: function () { - animation.stop(); - } - }; - }; - function animate(root, keypath, to, options) { - var easing, duration, animation, from; - if (keypath !== null) { - from = root.get(keypath); - } - animations.abort(keypath, root); - if (isEqual(from, to)) { - if (options.complete) { - options.complete(1, options.to); - } - return noAnimation; - } - if (options.easing) { - if (typeof options.easing === 'function') { - easing = options.easing; - } else { - if (root.easing && root.easing[options.easing]) { - easing = root.easing[options.easing]; - } else { - easing = easingRegistry[options.easing]; - } - } - if (typeof easing !== 'function') { - easing = null; - } - } - duration = options.duration === undefined ? 400 : options.duration; - animation = new Animation({ - keypath: keypath, - from: from, - to: to, - root: root, - duration: duration, - easing: easing, - step: options.step, - complete: options.complete - }); - animations.add(animation); - root._animations[root._animations.length] = animation; - return animation; - } - }(utils_isEqual, Ractive_prototype_animate_animations, Ractive_prototype_animate_Animation, registries_easing); -var Ractive_prototype_on = function () { - - return function (eventName, callback) { - var self = this, listeners, n; - if (typeof eventName === 'object') { - listeners = []; - for (n in eventName) { - if (eventName.hasOwnProperty(n)) { - listeners[listeners.length] = this.on(n, eventName[n]); - } - } - return { - cancel: function () { - while (listeners.length) { - listeners.pop().cancel(); - } - } - }; - } - if (!this._subs[eventName]) { - this._subs[eventName] = [callback]; - } else { - this._subs[eventName].push(callback); - } - return { - cancel: function () { - self.off(eventName, callback); - } - }; - }; - }(); -var Ractive_prototype_off = function () { - - return function (eventName, callback) { - var subscribers, index; - if (!callback) { - if (!eventName) { - for (eventName in this._subs) { - delete this._subs[eventName]; - } - } else { - this._subs[eventName] = []; - } - } - subscribers = this._subs[eventName]; - if (subscribers) { - index = subscribers.indexOf(callback); - if (index !== -1) { - subscribers.splice(index, 1); - } - } - }; - }(); -var shared_registerDependant = function () { - - return function (dependant) { - var depsByKeypath, deps, keys, parentKeypath, map, ractive, keypath, priority; - ractive = dependant.root; - keypath = dependant.keypath; - priority = dependant.priority; - depsByKeypath = ractive._deps[priority] || (ractive._deps[priority] = {}); - deps = depsByKeypath[keypath] || (depsByKeypath[keypath] = []); - deps[deps.length] = dependant; - dependant.registered = true; - if (!keypath) { - return; - } - keys = keypath.split('.'); - while (keys.length) { - keys.pop(); - parentKeypath = keys.join('.'); - map = ractive._depsMap[parentKeypath] || (ractive._depsMap[parentKeypath] = []); - if (map[keypath] === undefined) { - map[keypath] = 0; - map[map.length] = keypath; - } - map[keypath] += 1; - keypath = parentKeypath; - } - }; - }(); -var shared_unregisterDependant = function () { - - return function (dependant) { - var deps, index, keys, parentKeypath, map, ractive, keypath, priority; - ractive = dependant.root; - keypath = dependant.keypath; - priority = dependant.priority; - deps = ractive._deps[priority][keypath]; - index = deps.indexOf(dependant); - if (index === -1 || !dependant.registered) { - throw new Error('Attempted to remove a dependant that was no longer registered! This should not happen. If you are seeing this bug in development please raise an issue at https://github.com/RactiveJS/Ractive/issues - thanks'); - } - deps.splice(index, 1); - dependant.registered = false; - if (!keypath) { - return; - } - keys = keypath.split('.'); - while (keys.length) { - keys.pop(); - parentKeypath = keys.join('.'); - map = ractive._depsMap[parentKeypath]; - map[keypath] -= 1; - if (!map[keypath]) { - map.splice(map.indexOf(keypath), 1); - map[keypath] = undefined; - } - keypath = parentKeypath; - } - }; - }(); -var Ractive_prototype_observe_Observer = function (isEqual) { - - var Observer = function (ractive, keypath, callback, options) { - var self = this; - this.root = ractive; - this.keypath = keypath; - this.callback = callback; - this.defer = options.defer; - this.debug = options.debug; - this.proxy = { - update: function () { - self.reallyUpdate(); - } - }; - this.priority = 0; - this.context = options && options.context ? options.context : ractive; - }; - Observer.prototype = { - init: function (immediate) { - if (immediate !== false) { - this.update(); - } else { - this.value = this.root.get(this.keypath); - } - }, - update: function () { - if (this.defer && this.ready) { - this.root._deferred.observers.push(this.proxy); - return; - } - this.reallyUpdate(); - }, - reallyUpdate: function () { - var oldValue, newValue; - oldValue = this.value; - newValue = this.root.get(this.keypath); - this.value = newValue; - if (this.updating) { - return; - } - this.updating = true; - if (!isEqual(newValue, oldValue) || !this.ready) { - try { - this.callback.call(this.context, newValue, oldValue, this.keypath); - } catch (err) { - if (this.debug || this.root.debug) { - throw err; - } - } - } - this.updating = false; - } - }; - return Observer; - }(utils_isEqual); -var Ractive_prototype_observe_getPattern = function () { - - return function (ractive, pattern) { - var keys, key, values, toGet, newToGet, expand, concatenate; - keys = pattern.split('.'); - toGet = []; - expand = function (keypath) { - var value, key; - value = ractive._wrapped[keypath] ? ractive._wrapped[keypath].get() : ractive.get(keypath); - for (key in value) { - newToGet.push(keypath + '.' + key); - } - }; - concatenate = function (keypath) { - return keypath + '.' + key; - }; - while (key = keys.shift()) { - if (key === '*') { - newToGet = []; - toGet.forEach(expand); - toGet = newToGet; - } else { - if (!toGet[0]) { - toGet[0] = key; - } else { - toGet = toGet.map(concatenate); - } - } - } - values = {}; - toGet.forEach(function (keypath) { - values[keypath] = ractive.get(keypath); - }); - return values; - }; - }(); -var Ractive_prototype_observe_PatternObserver = function (isEqual, getPattern) { - - var PatternObserver, wildcard = /\*/; - PatternObserver = function (ractive, keypath, callback, options) { - this.root = ractive; - this.callback = callback; - this.defer = options.defer; - this.debug = options.debug; - this.keypath = keypath; - this.regex = new RegExp('^' + keypath.replace(/\./g, '\\.').replace(/\*/g, '[^\\.]+') + '$'); - this.values = {}; - if (this.defer) { - this.proxies = []; - } - this.priority = 'pattern'; - this.context = options && options.context ? options.context : ractive; - }; - PatternObserver.prototype = { - init: function (immediate) { - var values, keypath; - values = getPattern(this.root, this.keypath); - if (immediate !== false) { - for (keypath in values) { - if (values.hasOwnProperty(keypath)) { - this.update(keypath); - } - } - } else { - this.values = values; - } - }, - update: function (keypath) { - var values; - if (wildcard.test(keypath)) { - values = getPattern(this.root, keypath); - for (keypath in values) { - if (values.hasOwnProperty(keypath)) { - this.update(keypath); - } - } - return; - } - if (this.defer && this.ready) { - this.root._deferred.observers.push(this.getProxy(keypath)); - return; - } - this.reallyUpdate(keypath); - }, - reallyUpdate: function (keypath) { - var value = this.root.get(keypath); - if (this.updating) { - this.values[keypath] = value; - return; - } - this.updating = true; - if (!isEqual(value, this.values[keypath]) || !this.ready) { - try { - this.callback.call(this.context, value, this.values[keypath], keypath); - } catch (err) { - if (this.debug || this.root.debug) { - throw err; - } - } - this.values[keypath] = value; - } - this.updating = false; - }, - getProxy: function (keypath) { - var self = this; - if (!this.proxies[keypath]) { - this.proxies[keypath] = { - update: function () { - self.reallyUpdate(keypath); - } - }; - } - return this.proxies[keypath]; - } - }; - return PatternObserver; - }(utils_isEqual, Ractive_prototype_observe_getPattern); -var Ractive_prototype_observe_getObserverFacade = function (normaliseKeypath, registerDependant, unregisterDependant, Observer, PatternObserver) { - - var wildcard = /\*/, emptyObject = {}; - return function getObserverFacade(ractive, keypath, callback, options) { - var observer, isPatternObserver; - keypath = normaliseKeypath(keypath); - options = options || emptyObject; - if (wildcard.test(keypath)) { - observer = new PatternObserver(ractive, keypath, callback, options); - ractive._patternObservers.push(observer); - isPatternObserver = true; - } else { - observer = new Observer(ractive, keypath, callback, options); - } - registerDependant(observer); - observer.init(options.init); - observer.ready = true; - return { - cancel: function () { - var index; - if (isPatternObserver) { - index = ractive._patternObservers.indexOf(observer); - if (index !== -1) { - ractive._patternObservers.splice(index, 1); - } - } - unregisterDependant(observer); - } - }; - }; - }(utils_normaliseKeypath, shared_registerDependant, shared_unregisterDependant, Ractive_prototype_observe_Observer, Ractive_prototype_observe_PatternObserver); -var Ractive_prototype_observe__observe = function (isObject, getObserverFacade) { - - return function observe(keypath, callback, options) { - var observers = [], k; - if (isObject(keypath)) { - options = callback; - for (k in keypath) { - if (keypath.hasOwnProperty(k)) { - callback = keypath[k]; - observers[observers.length] = getObserverFacade(this, k, callback, options); - } - } - return { - cancel: function () { - while (observers.length) { - observers.pop().cancel(); - } - } - }; - } - return getObserverFacade(this, keypath, callback, options); - }; - }(utils_isObject, Ractive_prototype_observe_getObserverFacade); -var Ractive_prototype_fire = function () { - - return function (eventName) { - var args, i, len, subscribers = this._subs[eventName]; - if (!subscribers) { - return; - } - args = Array.prototype.slice.call(arguments, 1); - for (i = 0, len = subscribers.length; i < len; i += 1) { - subscribers[i].apply(this, args); - } - }; - }(); -var Ractive_prototype_find = function () { - - return function (selector) { - if (!this.el) { - return null; - } - return this.fragment.find(selector); - }; - }(); -var utils_matches = function (isClient, createElement) { - - var div, methodNames, unprefixed, prefixed, vendors, i, j, makeFunction; - if (!isClient) { - return; - } - div = createElement('div'); - methodNames = [ - 'matches', - 'matchesSelector' - ]; - vendors = [ - 'o', - 'ms', - 'moz', - 'webkit' - ]; - makeFunction = function (methodName) { - return function (node, selector) { - return node[methodName](selector); - }; - }; - i = methodNames.length; - while (i--) { - unprefixed = methodNames[i]; - if (div[unprefixed]) { - return makeFunction(unprefixed); - } - j = vendors.length; - while (j--) { - prefixed = vendors[i] + unprefixed.substr(0, 1).toUpperCase() + unprefixed.substring(1); - if (div[prefixed]) { - return makeFunction(prefixed); - } - } - } - return function (node, selector) { - var nodes, i; - nodes = (node.parentNode || node.document).querySelectorAll(selector); - i = nodes.length; - while (i--) { - if (nodes[i] === node) { - return true; - } - } - return false; - }; - }(config_isClient, utils_createElement); -var Ractive_prototype_shared_makeQuery_test = function (matches) { - - return function (item, noDirty) { - var itemMatches = this._isComponentQuery ? !this.selector || item.name === this.selector : matches(item.node, this.selector); - if (itemMatches) { - this.push(item.node || item.instance); - if (!noDirty) { - this._makeDirty(); - } - return true; - } - }; - }(utils_matches); -var Ractive_prototype_shared_makeQuery_cancel = function () { - - return function () { - var liveQueries, selector, index; - liveQueries = this._root[this._isComponentQuery ? 'liveComponentQueries' : 'liveQueries']; - selector = this.selector; - index = liveQueries.indexOf(selector); - if (index !== -1) { - liveQueries.splice(index, 1); - liveQueries[selector] = null; - } - }; - }(); -var Ractive_prototype_shared_makeQuery_sortByItemPosition = function () { - - return function (a, b) { - var ancestryA, ancestryB, oldestA, oldestB, mutualAncestor, indexA, indexB, fragments, fragmentA, fragmentB; - ancestryA = getAncestry(a.component || a._ractive.proxy); - ancestryB = getAncestry(b.component || b._ractive.proxy); - oldestA = ancestryA[ancestryA.length - 1]; - oldestB = ancestryB[ancestryB.length - 1]; - while (oldestA && oldestA === oldestB) { - ancestryA.pop(); - ancestryB.pop(); - mutualAncestor = oldestA; - oldestA = ancestryA[ancestryA.length - 1]; - oldestB = ancestryB[ancestryB.length - 1]; - } - oldestA = oldestA.component || oldestA; - oldestB = oldestB.component || oldestB; - fragmentA = oldestA.parentFragment; - fragmentB = oldestB.parentFragment; - if (fragmentA === fragmentB) { - indexA = fragmentA.items.indexOf(oldestA); - indexB = fragmentB.items.indexOf(oldestB); - return indexA - indexB || ancestryA.length - ancestryB.length; - } - if (fragments = mutualAncestor.fragments) { - indexA = fragments.indexOf(fragmentA); - indexB = fragments.indexOf(fragmentB); - return indexA - indexB || ancestryA.length - ancestryB.length; - } - throw new Error('An unexpected condition was met while comparing the position of two components. Please file an issue at https://github.com/RactiveJS/Ractive/issues - thanks!'); - }; - function getParent(item) { - var parentFragment; - if (parentFragment = item.parentFragment) { - return parentFragment.owner; - } - if (item.component && (parentFragment = item.component.parentFragment)) { - return parentFragment.owner; - } - } - function getAncestry(item) { - var ancestry, ancestor; - ancestry = [item]; - ancestor = getParent(item); - while (ancestor) { - ancestry.push(ancestor); - ancestor = getParent(ancestor); - } - return ancestry; - } - }(); -var Ractive_prototype_shared_makeQuery_sortByDocumentPosition = function (sortByItemPosition) { - - return function (node, otherNode) { - var bitmask; - if (node.compareDocumentPosition) { - bitmask = node.compareDocumentPosition(otherNode); - return bitmask & 2 ? 1 : -1; - } - return sortByItemPosition(node, otherNode); - }; - }(Ractive_prototype_shared_makeQuery_sortByItemPosition); -var Ractive_prototype_shared_makeQuery_sort = function (sortByDocumentPosition, sortByItemPosition) { - - return function () { - this.sort(this._isComponentQuery ? sortByItemPosition : sortByDocumentPosition); - this._dirty = false; - }; - }(Ractive_prototype_shared_makeQuery_sortByDocumentPosition, Ractive_prototype_shared_makeQuery_sortByItemPosition); -var Ractive_prototype_shared_makeQuery_dirty = function () { - - return function () { - if (!this._dirty) { - this._root._deferred.liveQueries.push(this); - this._dirty = true; - } - }; - }(); -var Ractive_prototype_shared_makeQuery_remove = function () { - - return function (item) { - var index = this.indexOf(this._isComponentQuery ? item.instance : item.node); - if (index !== -1) { - this.splice(index, 1); - } - }; - }(); -var Ractive_prototype_shared_makeQuery__makeQuery = function (defineProperties, test, cancel, sort, dirty, remove) { - - return function (ractive, selector, live, isComponentQuery) { - var query; - query = []; - defineProperties(query, { - selector: { value: selector }, - live: { value: live }, - _isComponentQuery: { value: isComponentQuery }, - _test: { value: test } - }); - if (!live) { - return query; - } - defineProperties(query, { - cancel: { value: cancel }, - _root: { value: ractive }, - _sort: { value: sort }, - _makeDirty: { value: dirty }, - _remove: { value: remove }, - _dirty: { - value: false, - writable: true - } - }); - return query; - }; - }(utils_defineProperties, Ractive_prototype_shared_makeQuery_test, Ractive_prototype_shared_makeQuery_cancel, Ractive_prototype_shared_makeQuery_sort, Ractive_prototype_shared_makeQuery_dirty, Ractive_prototype_shared_makeQuery_remove); -var Ractive_prototype_findAll = function (warn, matches, defineProperties, makeQuery) { - - return function (selector, options) { - var liveQueries, query; - if (!this.el) { - return []; - } - options = options || {}; - liveQueries = this._liveQueries; - if (query = liveQueries[selector]) { - return options && options.live ? query : query.slice(); - } - query = makeQuery(this, selector, !!options.live, false); - if (query.live) { - liveQueries.push(selector); - liveQueries[selector] = query; - } - this.fragment.findAll(selector, query); - return query; - }; - }(utils_warn, utils_matches, utils_defineProperties, Ractive_prototype_shared_makeQuery__makeQuery); -var Ractive_prototype_findComponent = function () { - - return function (selector) { - return this.fragment.findComponent(selector); - }; - }(); -var Ractive_prototype_findAllComponents = function (warn, matches, defineProperties, makeQuery) { - - return function (selector, options) { - var liveQueries, query; - options = options || {}; - liveQueries = this._liveComponentQueries; - if (query = liveQueries[selector]) { - return options && options.live ? query : query.slice(); - } - query = makeQuery(this, selector, !!options.live, true); - if (query.live) { - liveQueries.push(selector); - liveQueries[selector] = query; - } - this.fragment.findAllComponents(selector, query); - return query; - }; - }(utils_warn, utils_matches, utils_defineProperties, Ractive_prototype_shared_makeQuery__makeQuery); -var utils_getElement = function () { - - return function (input) { - var output; - if (typeof window === 'undefined' || !document || !input) { - return null; - } - if (input.nodeType) { - return input; - } - if (typeof input === 'string') { - output = document.getElementById(input); - if (!output && document.querySelector) { - output = document.querySelector(input); - } - if (output && output.nodeType) { - return output; - } - } - if (input[0] && input[0].nodeType) { - return input[0]; - } - return null; - }; - }(); -var render_shared_initFragment = function (types, create) { - - return function (fragment, options) { - var numItems, i, parentFragment, parentRefs, ref; - fragment.owner = options.owner; - parentFragment = fragment.owner.parentFragment; - fragment.root = options.root; - fragment.pNode = options.pNode; - fragment.contextStack = options.contextStack || []; - if (fragment.owner.type === types.SECTION) { - fragment.index = options.index; - } - if (parentFragment) { - parentRefs = parentFragment.indexRefs; - if (parentRefs) { - fragment.indexRefs = create(null); - for (ref in parentRefs) { - fragment.indexRefs[ref] = parentRefs[ref]; - } - } - } - fragment.priority = parentFragment ? parentFragment.priority + 1 : 1; - if (options.indexRef) { - if (!fragment.indexRefs) { - fragment.indexRefs = {}; - } - fragment.indexRefs[options.indexRef] = options.index; - } - fragment.items = []; - numItems = options.descriptor ? options.descriptor.length : 0; - for (i = 0; i < numItems; i += 1) { - fragment.items[fragment.items.length] = fragment.createItem({ - parentFragment: fragment, - descriptor: options.descriptor[i], - index: i - }); - } - }; - }(config_types, utils_create); -var render_DomFragment_shared_insertHtml = function (createElement) { - - var elementCache = {}; - return function (html, tagName, docFrag) { - var container, nodes = []; - if (html) { - container = elementCache[tagName] || (elementCache[tagName] = createElement(tagName)); - container.innerHTML = html; - while (container.firstChild) { - nodes[nodes.length] = container.firstChild; - docFrag.appendChild(container.firstChild); - } - } - return nodes; - }; - }(utils_createElement); -var render_DomFragment_Text = function (types) { - - var DomText, lessThan, greaterThan; - lessThan = //g; - DomText = function (options, docFrag) { - this.type = types.TEXT; - this.descriptor = options.descriptor; - if (docFrag) { - this.node = document.createTextNode(options.descriptor); - docFrag.appendChild(this.node); - } - }; - DomText.prototype = { - detach: function () { - this.node.parentNode.removeChild(this.node); - return this.node; - }, - teardown: function (destroy) { - if (destroy) { - this.detach(); - } - }, - firstNode: function () { - return this.node; - }, - toString: function () { - return ('' + this.descriptor).replace(lessThan, '<').replace(greaterThan, '>'); - } - }; - return DomText; - }(config_types); -var shared_teardown = function (unregisterDependant) { - - return function (thing) { - if (!thing.keypath) { - var index = thing.root._pendingResolution.indexOf(thing); - if (index !== -1) { - thing.root._pendingResolution.splice(index, 1); - } - } else { - unregisterDependant(thing); - } - }; - }(shared_unregisterDependant); -var render_shared_Evaluator_Reference = function (types, isEqual, defineProperty, registerDependant, unregisterDependant) { - - var Reference, thisPattern; - thisPattern = /this/; - Reference = function (root, keypath, evaluator, argNum, priority) { - var value; - this.evaluator = evaluator; - this.keypath = keypath; - this.root = root; - this.argNum = argNum; - this.type = types.REFERENCE; - this.priority = priority; - value = root.get(keypath); - if (typeof value === 'function') { - value = wrapFunction(value, root, evaluator); - } - this.value = evaluator.values[argNum] = value; - registerDependant(this); - }; - Reference.prototype = { - update: function () { - var value = this.root.get(this.keypath); - if (typeof value === 'function' && !value._nowrap) { - value = wrapFunction(value, this.root, this.evaluator); - } - if (!isEqual(value, this.value)) { - this.evaluator.values[this.argNum] = value; - this.evaluator.bubble(); - this.value = value; - } - }, - teardown: function () { - unregisterDependant(this); - } - }; - return Reference; - function wrapFunction(fn, ractive, evaluator) { - var prop, evaluators, index; - if (!thisPattern.test(fn.toString())) { - defineProperty(fn, '_nowrap', { value: true }); - return fn; - } - if (!fn['_' + ractive._guid]) { - defineProperty(fn, '_' + ractive._guid, { - value: function () { - var originalCaptured, result, i, evaluator; - originalCaptured = ractive._captured; - if (!originalCaptured) { - ractive._captured = []; - } - result = fn.apply(ractive, arguments); - if (ractive._captured.length) { - i = evaluators.length; - while (i--) { - evaluator = evaluators[i]; - evaluator.updateSoftDependencies(ractive._captured); - } - } - ractive._captured = originalCaptured; - return result; - }, - writable: true - }); - for (prop in fn) { - if (fn.hasOwnProperty(prop)) { - fn['_' + ractive._guid][prop] = fn[prop]; - } - } - fn['_' + ractive._guid + '_evaluators'] = []; - } - evaluators = fn['_' + ractive._guid + '_evaluators']; - index = evaluators.indexOf(evaluator); - if (index === -1) { - evaluators.push(evaluator); - } - return fn['_' + ractive._guid]; - } - }(config_types, utils_isEqual, utils_defineProperty, shared_registerDependant, shared_unregisterDependant); -var render_shared_Evaluator_SoftReference = function (isEqual, registerDependant, unregisterDependant) { - - var SoftReference = function (root, keypath, evaluator) { - this.root = root; - this.keypath = keypath; - this.priority = evaluator.priority; - this.evaluator = evaluator; - registerDependant(this); - }; - SoftReference.prototype = { - update: function () { - var value = this.root.get(this.keypath); - if (!isEqual(value, this.value)) { - this.evaluator.bubble(); - this.value = value; - } - }, - teardown: function () { - unregisterDependant(this); - } - }; - return SoftReference; - }(utils_isEqual, shared_registerDependant, shared_unregisterDependant); -var render_shared_Evaluator__Evaluator = function (isEqual, defineProperty, clearCache, notifyDependants, registerDependant, unregisterDependant, adaptIfNecessary, Reference, SoftReference) { - - var Evaluator, cache = {}; - Evaluator = function (root, keypath, functionStr, args, priority) { - var i, arg; - this.root = root; - this.keypath = keypath; - this.priority = priority; - this.fn = getFunctionFromString(functionStr, args.length); - this.values = []; - this.refs = []; - i = args.length; - while (i--) { - if (arg = args[i]) { - if (arg[0]) { - this.values[i] = arg[1]; - } else { - this.refs[this.refs.length] = new Reference(root, arg[1], this, i, priority); - } - } else { - this.values[i] = undefined; - } - } - this.selfUpdating = this.refs.length <= 1; - this.update(); - }; - Evaluator.prototype = { - bubble: function () { - if (this.selfUpdating) { - this.update(); - } else if (!this.deferred) { - this.root._deferred.evals.push(this); - this.deferred = true; - } - }, - update: function () { - var value; - if (this.evaluating) { - return this; - } - this.evaluating = true; - try { - value = this.fn.apply(null, this.values); - } catch (err) { - if (this.root.debug) { - throw err; - } else { - value = undefined; - } - } - if (!isEqual(value, this.value)) { - clearCache(this.root, this.keypath); - this.root._cache[this.keypath] = value; - adaptIfNecessary(this.root, this.keypath, value, true); - this.value = value; - notifyDependants(this.root, this.keypath); - } - this.evaluating = false; - return this; - }, - teardown: function () { - while (this.refs.length) { - this.refs.pop().teardown(); - } - clearCache(this.root, this.keypath); - this.root._evaluators[this.keypath] = null; - }, - refresh: function () { - if (!this.selfUpdating) { - this.deferred = true; - } - var i = this.refs.length; - while (i--) { - this.refs[i].update(); - } - if (this.deferred) { - this.update(); - this.deferred = false; - } - }, - updateSoftDependencies: function (softDeps) { - var i, keypath, ref; - if (!this.softRefs) { - this.softRefs = []; - } - i = this.softRefs.length; - while (i--) { - ref = this.softRefs[i]; - if (!softDeps[ref.keypath]) { - this.softRefs.splice(i, 1); - this.softRefs[ref.keypath] = false; - ref.teardown(); - } - } - i = softDeps.length; - while (i--) { - keypath = softDeps[i]; - if (!this.softRefs[keypath]) { - ref = new SoftReference(this.root, keypath, this); - this.softRefs[this.softRefs.length] = ref; - this.softRefs[keypath] = true; - } - } - this.selfUpdating = this.refs.length + this.softRefs.length <= 1; - } - }; - return Evaluator; - function getFunctionFromString(str, i) { - var fn, args; - str = str.replace(/\$\{([0-9]+)\}/g, '_$1'); - if (cache[str]) { - return cache[str]; - } - args = []; - while (i--) { - args[i] = '_' + i; - } - fn = new Function(args.join(','), 'return(' + str + ')'); - cache[str] = fn; - return fn; - } - }(utils_isEqual, utils_defineProperty, shared_clearCache, shared_notifyDependants, shared_registerDependant, shared_unregisterDependant, shared_adaptIfNecessary, render_shared_Evaluator_Reference, render_shared_Evaluator_SoftReference); -var render_shared_ExpressionResolver_ReferenceScout = function (resolveRef, teardown) { - - var ReferenceScout = function (resolver, ref, contextStack, argNum) { - var keypath, root; - root = this.root = resolver.root; - keypath = resolveRef(root, ref, contextStack); - if (keypath !== undefined) { - resolver.resolveRef(argNum, false, keypath); - } else { - this.ref = ref; - this.argNum = argNum; - this.resolver = resolver; - this.contextStack = contextStack; - root._pendingResolution[root._pendingResolution.length] = this; - } - }; - ReferenceScout.prototype = { - resolve: function (keypath) { - this.keypath = keypath; - this.resolver.resolveRef(this.argNum, false, keypath); - }, - teardown: function () { - if (!this.keypath) { - teardown(this); - } - } - }; - return ReferenceScout; - }(shared_resolveRef, shared_teardown); -var render_shared_ExpressionResolver_isRegularKeypath = function () { - - var keyPattern = /^(?:(?:[a-zA-Z$_][a-zA-Z$_0-9]*)|(?:[0-9]|[1-9][0-9]+))$/; - return function (keypath) { - var keys, key, i; - keys = keypath.split('.'); - i = keys.length; - while (i--) { - key = keys[i]; - if (key === 'undefined' || !keyPattern.test(key)) { - return false; - } - } - return true; - }; - }(); -var render_shared_ExpressionResolver_getKeypath = function (normaliseKeypath, isRegularKeypath) { - - return function (str, args) { - var unique, normalised; - unique = str.replace(/\$\{([0-9]+)\}/g, function (match, $1) { - return args[$1] ? args[$1][1] : 'undefined'; - }); - normalised = normaliseKeypath(unique); - if (isRegularKeypath(normalised)) { - return normalised; - } - return '${' + unique.replace(/[\.\[\]]/g, '-') + '}'; - }; - }(utils_normaliseKeypath, render_shared_ExpressionResolver_isRegularKeypath); -var render_shared_ExpressionResolver_reassignDependants = function (registerDependant, unregisterDependant) { - - return function (ractive, oldKeypath, newKeypath) { - var toReassign, i, dependant; - toReassign = []; - gatherDependants(ractive, oldKeypath, toReassign); - i = toReassign.length; - while (i--) { - dependant = toReassign[i]; - unregisterDependant(dependant); - dependant.keypath = dependant.keypath.replace(oldKeypath, newKeypath); - registerDependant(dependant); - dependant.update(); - } - }; - function cascade(ractive, oldKeypath, toReassign) { - var map, i; - map = ractive._depsMap[oldKeypath]; - if (!map) { - return; - } - i = map.length; - while (i--) { - gatherDependants(ractive, map[i], toReassign); - } - } - function gatherDependants(ractive, oldKeypath, toReassign) { - var priority, dependantsByKeypath, dependants, i; - priority = ractive._deps.length; - while (priority--) { - dependantsByKeypath = ractive._deps[priority]; - if (dependantsByKeypath) { - dependants = dependantsByKeypath[oldKeypath]; - if (dependants) { - i = dependants.length; - while (i--) { - toReassign.push(dependants[i]); - } - } - } - } - cascade(ractive, oldKeypath, toReassign); - } - }(shared_registerDependant, shared_unregisterDependant); -var render_shared_ExpressionResolver__ExpressionResolver = function (Evaluator, ReferenceScout, getKeypath, reassignDependants) { - - var ExpressionResolver = function (mustache) { - var expression, i, len, ref, indexRefs; - this.root = mustache.root; - this.mustache = mustache; - this.args = []; - this.scouts = []; - expression = mustache.descriptor.x; - indexRefs = mustache.parentFragment.indexRefs; - this.str = expression.s; - len = this.unresolved = this.args.length = expression.r ? expression.r.length : 0; - if (!len) { - this.resolved = this.ready = true; - this.bubble(); - return; - } - for (i = 0; i < len; i += 1) { - ref = expression.r[i]; - if (indexRefs && indexRefs[ref] !== undefined) { - this.resolveRef(i, true, indexRefs[ref]); - } else { - this.scouts[this.scouts.length] = new ReferenceScout(this, ref, mustache.contextStack, i); - } - } - this.ready = true; - this.bubble(); - }; - ExpressionResolver.prototype = { - bubble: function () { - var oldKeypath; - if (!this.ready) { - return; - } - oldKeypath = this.keypath; - this.keypath = getKeypath(this.str, this.args); - if (this.keypath.substr(0, 2) === '${') { - this.createEvaluator(); - } - if (oldKeypath) { - reassignDependants(this.root, oldKeypath, this.keypath); - } else { - this.mustache.resolve(this.keypath); - } - }, - teardown: function () { - while (this.scouts.length) { - this.scouts.pop().teardown(); - } - }, - resolveRef: function (argNum, isIndexRef, value) { - this.args[argNum] = [ - isIndexRef, - value - ]; - this.bubble(); - this.resolved = !--this.unresolved; - }, - createEvaluator: function () { - if (!this.root._evaluators[this.keypath]) { - this.root._evaluators[this.keypath] = new Evaluator(this.root, this.keypath, this.str, this.args, this.mustache.priority); - } else { - this.root._evaluators[this.keypath].refresh(); - } - } - }; - return ExpressionResolver; - }(render_shared_Evaluator__Evaluator, render_shared_ExpressionResolver_ReferenceScout, render_shared_ExpressionResolver_getKeypath, render_shared_ExpressionResolver_reassignDependants); -var render_shared_initMustache = function (resolveRef, ExpressionResolver) { - - return function (mustache, options) { - var keypath, indexRef, parentFragment; - parentFragment = mustache.parentFragment = options.parentFragment; - mustache.root = parentFragment.root; - mustache.contextStack = parentFragment.contextStack; - mustache.descriptor = options.descriptor; - mustache.index = options.index || 0; - mustache.priority = parentFragment.priority; - mustache.type = options.descriptor.t; - if (options.descriptor.r) { - if (parentFragment.indexRefs && parentFragment.indexRefs[options.descriptor.r] !== undefined) { - indexRef = parentFragment.indexRefs[options.descriptor.r]; - mustache.indexRef = options.descriptor.r; - mustache.value = indexRef; - mustache.render(mustache.value); - } else { - keypath = resolveRef(mustache.root, options.descriptor.r, mustache.contextStack); - if (keypath !== undefined) { - mustache.resolve(keypath); - } else { - mustache.ref = options.descriptor.r; - mustache.root._pendingResolution[mustache.root._pendingResolution.length] = mustache; - } - } - } - if (options.descriptor.x) { - mustache.expressionResolver = new ExpressionResolver(mustache); - } - if (mustache.descriptor.n && !mustache.hasOwnProperty('value')) { - mustache.render(undefined); - } - }; - }(shared_resolveRef, render_shared_ExpressionResolver__ExpressionResolver); -var render_shared_resolveMustache = function (types, registerDependant, unregisterDependant) { - - return function (keypath) { - if (keypath === this.keypath) { - return; - } - if (this.registered) { - unregisterDependant(this); - } - this.keypath = keypath; - registerDependant(this); - this.update(); - if (this.root.twoway && this.parentFragment.owner.type === types.ATTRIBUTE) { - this.parentFragment.owner.element.bind(); - } - if (this.expressionResolver && this.expressionResolver.resolved) { - this.expressionResolver = null; - } - }; - }(config_types, shared_registerDependant, shared_unregisterDependant); -var render_shared_updateMustache = function (isEqual) { - - return function () { - var wrapped, value; - value = this.root.get(this.keypath); - if (wrapped = this.root._wrapped[this.keypath]) { - value = wrapped.get(); - } - if (!isEqual(value, this.value)) { - this.render(value); - this.value = value; - } - }; - }(utils_isEqual); -var render_DomFragment_Interpolator = function (types, teardown, initMustache, resolveMustache, updateMustache) { - - var DomInterpolator, lessThan, greaterThan; - lessThan = //g; - DomInterpolator = function (options, docFrag) { - this.type = types.INTERPOLATOR; - if (docFrag) { - this.node = document.createTextNode(''); - docFrag.appendChild(this.node); - } - initMustache(this, options); - }; - DomInterpolator.prototype = { - update: updateMustache, - resolve: resolveMustache, - detach: function () { - this.node.parentNode.removeChild(this.node); - return this.node; - }, - teardown: function (destroy) { - if (destroy) { - this.detach(); - } - teardown(this); - }, - render: function (value) { - if (this.node) { - this.node.data = value == undefined ? '' : value; - } - }, - firstNode: function () { - return this.node; - }, - toString: function () { - var value = this.value != undefined ? '' + this.value : ''; - return value.replace(lessThan, '<').replace(greaterThan, '>'); - } - }; - return DomInterpolator; - }(config_types, shared_teardown, render_shared_initMustache, render_shared_resolveMustache, render_shared_updateMustache); -var render_shared_updateSection = function (isArray, isObject, create) { - - return function (section, value) { - var fragmentOptions; - fragmentOptions = { - descriptor: section.descriptor.f, - root: section.root, - pNode: section.parentFragment.pNode, - owner: section - }; - if (section.descriptor.n) { - updateConditionalSection(section, value, true, fragmentOptions); - return; - } - if (isArray(value)) { - updateListSection(section, value, fragmentOptions); - } else if (isObject(value)) { - if (section.descriptor.i) { - updateListObjectSection(section, value, fragmentOptions); - } else { - updateContextSection(section, fragmentOptions); - } - } else { - updateConditionalSection(section, value, false, fragmentOptions); - } - }; - function updateListSection(section, value, fragmentOptions) { - var i, length, fragmentsToRemove; - length = value.length; - if (length < section.length) { - fragmentsToRemove = section.fragments.splice(length, section.length - length); - while (fragmentsToRemove.length) { - fragmentsToRemove.pop().teardown(true); - } - } else { - if (length > section.length) { - for (i = section.length; i < length; i += 1) { - fragmentOptions.contextStack = section.contextStack.concat(section.keypath + '.' + i); - fragmentOptions.index = i; - if (section.descriptor.i) { - fragmentOptions.indexRef = section.descriptor.i; - } - section.fragments[i] = section.createFragment(fragmentOptions); - } - } - } - section.length = length; - } - function updateListObjectSection(section, value, fragmentOptions) { - var id, fragmentsById; - fragmentsById = section.fragmentsById || (section.fragmentsById = create(null)); - for (id in fragmentsById) { - if (value[id] === undefined && fragmentsById[id]) { - fragmentsById[id].teardown(true); - fragmentsById[id] = null; - } - } - for (id in value) { - if (value[id] !== undefined && !fragmentsById[id]) { - fragmentOptions.contextStack = section.contextStack.concat(section.keypath + '.' + id); - fragmentOptions.index = id; - if (section.descriptor.i) { - fragmentOptions.indexRef = section.descriptor.i; - } - fragmentsById[id] = section.createFragment(fragmentOptions); - } - } - } - function updateContextSection(section, fragmentOptions) { - if (!section.length) { - fragmentOptions.contextStack = section.contextStack.concat(section.keypath); - fragmentOptions.index = 0; - section.fragments[0] = section.createFragment(fragmentOptions); - section.length = 1; - } - } - function updateConditionalSection(section, value, inverted, fragmentOptions) { - var doRender, emptyArray, fragmentsToRemove, fragment; - emptyArray = isArray(value) && value.length === 0; - if (inverted) { - doRender = emptyArray || !value; - } else { - doRender = value && !emptyArray; - } - if (doRender) { - if (!section.length) { - fragmentOptions.contextStack = section.contextStack; - fragmentOptions.index = 0; - section.fragments[0] = section.createFragment(fragmentOptions); - section.length = 1; - } - if (section.length > 1) { - fragmentsToRemove = section.fragments.splice(1); - while (fragment = fragmentsToRemove.pop()) { - fragment.teardown(true); - } - } - } else if (section.length) { - section.teardownFragments(true); - section.length = 0; - } - } - }(utils_isArray, utils_isObject, utils_create); -var render_DomFragment_Section_reassignFragment = function (types, unregisterDependant, ExpressionResolver) { - - return reassignFragment; - function reassignFragment(fragment, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath) { - var i, item, context, query; - if (fragment.html) { - return; - } - if (fragment.indexRefs && fragment.indexRefs[indexRef] !== undefined) { - fragment.indexRefs[indexRef] = newIndex; - } - i = fragment.contextStack.length; - while (i--) { - context = fragment.contextStack[i]; - if (context.substr(0, oldKeypath.length) === oldKeypath) { - fragment.contextStack[i] = context.replace(oldKeypath, newKeypath); - } - } - i = fragment.items.length; - while (i--) { - item = fragment.items[i]; - switch (item.type) { - case types.ELEMENT: - reassignElement(item, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - break; - case types.PARTIAL: - reassignFragment(item.fragment, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - break; - case types.COMPONENT: - reassignFragment(item.instance.fragment, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - if (query = fragment.root._liveComponentQueries[item.name]) { - query._makeDirty(); - } - break; - case types.SECTION: - case types.INTERPOLATOR: - case types.TRIPLE: - reassignMustache(item, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - break; - } - } - } - function reassignElement(element, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath) { - var i, attribute, storage, masterEventName, proxies, proxy, binding, bindings, liveQueries, ractive; - i = element.attributes.length; - while (i--) { - attribute = element.attributes[i]; - if (attribute.fragment) { - reassignFragment(attribute.fragment, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - if (attribute.twoway) { - attribute.updateBindings(); - } - } - } - if (storage = element.node._ractive) { - if (storage.keypath.substr(0, oldKeypath.length) === oldKeypath) { - storage.keypath = storage.keypath.replace(oldKeypath, newKeypath); - } - if (indexRef !== undefined) { - storage.index[indexRef] = newIndex; - } - for (masterEventName in storage.events) { - proxies = storage.events[masterEventName].proxies; - i = proxies.length; - while (i--) { - proxy = proxies[i]; - if (typeof proxy.n === 'object') { - reassignFragment(proxy.a, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - } - if (proxy.d) { - reassignFragment(proxy.d, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - } - } - } - if (binding = storage.binding) { - if (binding.keypath.substr(0, oldKeypath.length) === oldKeypath) { - bindings = storage.root._twowayBindings[binding.keypath]; - bindings.splice(bindings.indexOf(binding), 1); - binding.keypath = binding.keypath.replace(oldKeypath, newKeypath); - bindings = storage.root._twowayBindings[binding.keypath] || (storage.root._twowayBindings[binding.keypath] = []); - bindings.push(binding); - } - } - } - if (element.fragment) { - reassignFragment(element.fragment, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - } - if (liveQueries = element.liveQueries) { - ractive = element.root; - i = liveQueries.length; - while (i--) { - ractive._liveQueries[liveQueries[i]]._makeDirty(); - } - } - } - function reassignMustache(mustache, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath) { - var i; - if (mustache.descriptor.x) { - if (mustache.expressionResolver) { - mustache.expressionResolver.teardown(); - } - mustache.expressionResolver = new ExpressionResolver(mustache); - } - if (mustache.keypath) { - if (mustache.keypath.substr(0, oldKeypath.length) === oldKeypath) { - mustache.resolve(mustache.keypath.replace(oldKeypath, newKeypath)); - } - } else if (mustache.indexRef === indexRef) { - mustache.value = newIndex; - mustache.render(newIndex); - } - if (mustache.fragments) { - i = mustache.fragments.length; - while (i--) { - reassignFragment(mustache.fragments[i], indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - } - } - } - }(config_types, shared_unregisterDependant, render_shared_ExpressionResolver__ExpressionResolver); -var render_DomFragment_Section_reassignFragments = function (types, reassignFragment, preDomUpdate) { - - return function (root, section, start, end, by) { - var i, fragment, indexRef, oldIndex, newIndex, oldKeypath, newKeypath; - indexRef = section.descriptor.i; - for (i = start; i < end; i += 1) { - fragment = section.fragments[i]; - oldIndex = i - by; - newIndex = i; - oldKeypath = section.keypath + '.' + (i - by); - newKeypath = section.keypath + '.' + i; - fragment.index += by; - reassignFragment(fragment, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - } - preDomUpdate(root); - }; - }(config_types, render_DomFragment_Section_reassignFragment, shared_preDomUpdate); -var render_DomFragment_Section_prototype_merge = function (reassignFragment) { - - return function (newIndices) { - var section = this, parentFragment, firstChange, changed, i, newLength, newFragments, toTeardown, fragmentOptions, fragment, nextNode; - parentFragment = this.parentFragment; - newFragments = []; - newIndices.forEach(function (newIndex, oldIndex) { - var by, oldKeypath, newKeypath; - if (newIndex === oldIndex) { - newFragments[newIndex] = section.fragments[oldIndex]; - return; - } - if (firstChange === undefined) { - firstChange = oldIndex; - } - if (newIndex === -1) { - (toTeardown || (toTeardown = [])).push(section.fragments[oldIndex]); - return; - } - by = newIndex - oldIndex; - oldKeypath = section.keypath + '.' + oldIndex; - newKeypath = section.keypath + '.' + newIndex; - reassignFragment(section.fragments[oldIndex], section.descriptor.i, oldIndex, newIndex, by, oldKeypath, newKeypath); - newFragments[newIndex] = section.fragments[oldIndex]; - changed = true; - }); - if (toTeardown) { - while (fragment = toTeardown.pop()) { - fragment.teardown(true); - } - } - if (firstChange === undefined) { - firstChange = this.length; - } - newLength = this.root.get(this.keypath).length; - if (newLength === firstChange) { - return; - } - fragmentOptions = { - descriptor: this.descriptor.f, - root: this.root, - pNode: parentFragment.pNode, - owner: this - }; - if (this.descriptor.i) { - fragmentOptions.indexRef = this.descriptor.i; - } - for (i = firstChange; i < newLength; i += 1) { - if (fragment = newFragments[i]) { - this.docFrag.appendChild(fragment.detach(false)); - } else { - fragmentOptions.contextStack = this.contextStack.concat(this.keypath + '.' + i); - fragmentOptions.index = i; - fragment = this.createFragment(fragmentOptions); - } - this.fragments[i] = fragment; - } - nextNode = parentFragment.findNextNode(this); - parentFragment.pNode.insertBefore(this.docFrag, nextNode); - this.length = newLength; - }; - }(render_DomFragment_Section_reassignFragment); -var circular = function () { - - return []; - }(); -var render_DomFragment_Section__Section = function (types, isClient, initMustache, updateMustache, resolveMustache, updateSection, reassignFragment, reassignFragments, merge, teardown, circular) { - - var DomSection, DomFragment; - circular.push(function () { - DomFragment = circular.DomFragment; - }); - DomSection = function (options, docFrag) { - this.type = types.SECTION; - this.inverted = !!options.descriptor.n; - this.fragments = []; - this.length = 0; - if (docFrag) { - this.docFrag = document.createDocumentFragment(); - } - this.initialising = true; - initMustache(this, options); - if (docFrag) { - docFrag.appendChild(this.docFrag); - } - this.initialising = false; - }; - DomSection.prototype = { - update: updateMustache, - resolve: resolveMustache, - smartUpdate: function (methodName, args) { - var fragmentOptions; - if (methodName === 'push' || methodName === 'unshift' || methodName === 'splice') { - fragmentOptions = { - descriptor: this.descriptor.f, - root: this.root, - pNode: this.parentFragment.pNode, - owner: this - }; - if (this.descriptor.i) { - fragmentOptions.indexRef = this.descriptor.i; - } - } - if (this[methodName]) { - this.rendering = true; - this[methodName](fragmentOptions, args); - this.rendering = false; - } - }, - pop: function () { - if (this.length) { - this.fragments.pop().teardown(true); - this.length -= 1; - } - }, - push: function (fragmentOptions, args) { - var start, end, i; - start = this.length; - end = start + args.length; - for (i = start; i < end; i += 1) { - fragmentOptions.contextStack = this.contextStack.concat(this.keypath + '.' + i); - fragmentOptions.index = i; - this.fragments[i] = this.createFragment(fragmentOptions); - } - this.length += args.length; - this.parentFragment.pNode.insertBefore(this.docFrag, this.parentFragment.findNextNode(this)); - }, - shift: function () { - this.splice(null, [ - 0, - 1 - ]); - }, - unshift: function (fragmentOptions, args) { - this.splice(fragmentOptions, [ - 0, - 0 - ].concat(new Array(args.length))); - }, - splice: function (fragmentOptions, args) { - var insertionPoint, addedItems, removedItems, balance, i, start, end, spliceArgs, reassignStart; - if (!args.length) { - return; - } - start = +(args[0] < 0 ? this.length + args[0] : args[0]); - addedItems = Math.max(0, args.length - 2); - removedItems = args[1] !== undefined ? args[1] : this.length - start; - removedItems = Math.min(removedItems, this.length - start); - balance = addedItems - removedItems; - if (!balance) { - return; - } - if (balance < 0) { - end = start - balance; - for (i = start; i < end; i += 1) { - this.fragments[i].teardown(true); - } - this.fragments.splice(start, -balance); - } else { - end = start + balance; - insertionPoint = this.fragments[start] ? this.fragments[start].firstNode() : this.parentFragment.findNextNode(this); - spliceArgs = [ - start, - 0 - ].concat(new Array(balance)); - this.fragments.splice.apply(this.fragments, spliceArgs); - for (i = start; i < end; i += 1) { - fragmentOptions.contextStack = this.contextStack.concat(this.keypath + '.' + i); - fragmentOptions.index = i; - this.fragments[i] = this.createFragment(fragmentOptions); - } - this.parentFragment.pNode.insertBefore(this.docFrag, insertionPoint); - } - this.length += balance; - reassignStart = start + addedItems; - reassignFragments(this.root, this, reassignStart, this.length, balance); - }, - merge: merge, - detach: function () { - var i, len; - len = this.fragments.length; - for (i = 0; i < len; i += 1) { - this.docFrag.appendChild(this.fragments[i].detach()); - } - return this.docFrag; - }, - teardown: function (destroy) { - this.teardownFragments(destroy); - teardown(this); - }, - firstNode: function () { - if (this.fragments[0]) { - return this.fragments[0].firstNode(); - } - return this.parentFragment.findNextNode(this); - }, - findNextNode: function (fragment) { - if (this.fragments[fragment.index + 1]) { - return this.fragments[fragment.index + 1].firstNode(); - } - return this.parentFragment.findNextNode(this); - }, - teardownFragments: function (destroy) { - var id, fragment; - while (fragment = this.fragments.shift()) { - fragment.teardown(destroy); - } - if (this.fragmentsById) { - for (id in this.fragmentsById) { - if (this.fragments[id]) { - this.fragmentsById[id].teardown(destroy); - this.fragmentsById[id] = null; - } - } - } - }, - render: function (value) { - var nextNode, wrapped; - if (wrapped = this.root._wrapped[this.keypath]) { - value = wrapped.get(); - } - if (this.rendering) { - return; - } - this.rendering = true; - updateSection(this, value); - this.rendering = false; - if (this.docFrag && !this.docFrag.childNodes.length) { - return; - } - if (!this.initialising && isClient) { - nextNode = this.parentFragment.findNextNode(this); - if (nextNode && nextNode.parentNode === this.parentFragment.pNode) { - this.parentFragment.pNode.insertBefore(this.docFrag, nextNode); - } else { - this.parentFragment.pNode.appendChild(this.docFrag); - } - } - }, - createFragment: function (options) { - var fragment = new DomFragment(options); - if (this.docFrag) { - this.docFrag.appendChild(fragment.docFrag); - } - return fragment; - }, - toString: function () { - var str, i, id, len; - str = ''; - i = 0; - len = this.length; - for (i = 0; i < len; i += 1) { - str += this.fragments[i].toString(); - } - if (this.fragmentsById) { - for (id in this.fragmentsById) { - if (this.fragmentsById[id]) { - str += this.fragmentsById[id].toString(); - } - } - } - return str; - }, - find: function (selector) { - var i, len, queryResult; - len = this.fragments.length; - for (i = 0; i < len; i += 1) { - if (queryResult = this.fragments[i].find(selector)) { - return queryResult; - } - } - return null; - }, - findAll: function (selector, query) { - var i, len; - len = this.fragments.length; - for (i = 0; i < len; i += 1) { - this.fragments[i].findAll(selector, query); - } - }, - findComponent: function (selector) { - var i, len, queryResult; - len = this.fragments.length; - for (i = 0; i < len; i += 1) { - if (queryResult = this.fragments[i].findComponent(selector)) { - return queryResult; - } - } - return null; - }, - findAllComponents: function (selector, query) { - var i, len; - len = this.fragments.length; - for (i = 0; i < len; i += 1) { - this.fragments[i].findAllComponents(selector, query); - } - } - }; - return DomSection; - }(config_types, config_isClient, render_shared_initMustache, render_shared_updateMustache, render_shared_resolveMustache, render_shared_updateSection, render_DomFragment_Section_reassignFragment, render_DomFragment_Section_reassignFragments, render_DomFragment_Section_prototype_merge, shared_teardown, circular); -var render_DomFragment_Triple = function (types, matches, initMustache, updateMustache, resolveMustache, insertHtml, teardown) { - - var DomTriple = function (options, docFrag) { - this.type = types.TRIPLE; - if (docFrag) { - this.nodes = []; - this.docFrag = document.createDocumentFragment(); - } - this.initialising = true; - initMustache(this, options); - if (docFrag) { - docFrag.appendChild(this.docFrag); - } - this.initialising = false; - }; - DomTriple.prototype = { - update: updateMustache, - resolve: resolveMustache, - detach: function () { - var i = this.nodes.length; - while (i--) { - this.docFrag.appendChild(this.nodes[i]); - } - return this.docFrag; - }, - teardown: function (destroy) { - if (destroy) { - this.detach(); - this.docFrag = this.nodes = null; - } - teardown(this); - }, - firstNode: function () { - if (this.nodes[0]) { - return this.nodes[0]; - } - return this.parentFragment.findNextNode(this); - }, - render: function (html) { - var node, pNode; - if (!this.nodes) { - return; - } - while (this.nodes.length) { - node = this.nodes.pop(); - node.parentNode.removeChild(node); - } - if (!html) { - this.nodes = []; - return; - } - pNode = this.parentFragment.pNode; - this.nodes = insertHtml(html, pNode.tagName, this.docFrag); - if (!this.initialising) { - pNode.insertBefore(this.docFrag, this.parentFragment.findNextNode(this)); - } - }, - toString: function () { - return this.value != undefined ? this.value : ''; - }, - find: function (selector) { - var i, len, node, queryResult; - len = this.nodes.length; - for (i = 0; i < len; i += 1) { - node = this.nodes[i]; - if (node.nodeType !== 1) { - continue; - } - if (matches(node, selector)) { - return node; - } - if (queryResult = node.querySelector(selector)) { - return queryResult; - } - } - return null; - }, - findAll: function (selector, queryResult) { - var i, len, node, queryAllResult, numNodes, j; - len = this.nodes.length; - for (i = 0; i < len; i += 1) { - node = this.nodes[i]; - if (node.nodeType !== 1) { - continue; - } - if (matches(node, selector)) { - queryResult.push(node); - } - if (queryAllResult = node.querySelectorAll(selector)) { - numNodes = queryAllResult.length; - for (j = 0; j < numNodes; j += 1) { - queryResult.push(queryAllResult[j]); - } - } - } - } - }; - return DomTriple; - }(config_types, utils_matches, render_shared_initMustache, render_shared_updateMustache, render_shared_resolveMustache, render_DomFragment_shared_insertHtml, shared_teardown); -var render_DomFragment_Element_initialise_getElementNamespace = function (namespaces) { - - return function (descriptor, parentNode) { - if (descriptor.a && descriptor.a.xmlns) { - return descriptor.a.xmlns; - } - return descriptor.e === 'svg' ? namespaces.svg : parentNode.namespaceURI || namespaces.html; - }; - }(config_namespaces); -var render_DomFragment_shared_enforceCase = function () { - - var svgCamelCaseElements, svgCamelCaseAttributes, createMap, map; - svgCamelCaseElements = 'altGlyph altGlyphDef altGlyphItem animateColor animateMotion animateTransform clipPath feBlend feColorMatrix feComponentTransfer feComposite feConvolveMatrix feDiffuseLighting feDisplacementMap feDistantLight feFlood feFuncA feFuncB feFuncG feFuncR feGaussianBlur feImage feMerge feMergeNode feMorphology feOffset fePointLight feSpecularLighting feSpotLight feTile feTurbulence foreignObject glyphRef linearGradient radialGradient textPath vkern'.split(' '); - svgCamelCaseAttributes = 'attributeName attributeType baseFrequency baseProfile calcMode clipPathUnits contentScriptType contentStyleType diffuseConstant edgeMode externalResourcesRequired filterRes filterUnits glyphRef gradientTransform gradientUnits kernelMatrix kernelUnitLength keyPoints keySplines keyTimes lengthAdjust limitingConeAngle markerHeight markerUnits markerWidth maskContentUnits maskUnits numOctaves pathLength patternContentUnits patternTransform patternUnits pointsAtX pointsAtY pointsAtZ preserveAlpha preserveAspectRatio primitiveUnits refX refY repeatCount repeatDur requiredExtensions requiredFeatures specularConstant specularExponent spreadMethod startOffset stdDeviation stitchTiles surfaceScale systemLanguage tableValues targetX targetY textLength viewBox viewTarget xChannelSelector yChannelSelector zoomAndPan'.split(' '); - createMap = function (items) { - var map = {}, i = items.length; - while (i--) { - map[items[i].toLowerCase()] = items[i]; - } - return map; - }; - map = createMap(svgCamelCaseElements.concat(svgCamelCaseAttributes)); - return function (elementName) { - var lowerCaseElementName = elementName.toLowerCase(); - return map[lowerCaseElementName] || lowerCaseElementName; - }; - }(); -var render_DomFragment_Attribute_helpers_determineNameAndNamespace = function (namespaces, enforceCase) { - - return function (attribute, name) { - var colonIndex, namespacePrefix; - colonIndex = name.indexOf(':'); - if (colonIndex !== -1) { - namespacePrefix = name.substr(0, colonIndex); - if (namespacePrefix !== 'xmlns') { - name = name.substring(colonIndex + 1); - attribute.name = enforceCase(name); - attribute.lcName = attribute.name.toLowerCase(); - attribute.namespace = namespaces[namespacePrefix.toLowerCase()]; - if (!attribute.namespace) { - throw 'Unknown namespace ("' + namespacePrefix + '")'; - } - return; - } - } - attribute.name = attribute.element.namespace !== namespaces.html ? enforceCase(name) : name; - attribute.lcName = attribute.name.toLowerCase(); - }; - }(config_namespaces, render_DomFragment_shared_enforceCase); -var render_DomFragment_Attribute_helpers_setStaticAttribute = function (namespaces) { - - return function (attribute, options) { - var node, value = options.value === null ? '' : options.value; - if (node = options.pNode) { - if (attribute.namespace) { - node.setAttributeNS(attribute.namespace, options.name, value); - } else { - if (options.name === 'style' && node.style.setAttribute) { - node.style.setAttribute('cssText', value); - } else if (options.name === 'class' && (!node.namespaceURI || node.namespaceURI === namespaces.html)) { - node.className = value; - } else { - node.setAttribute(options.name, value); - } - } - if (attribute.name === 'id') { - options.root.nodes[options.value] = node; - } - if (attribute.name === 'value') { - node._ractive.value = options.value; - } - } - attribute.value = options.value; - }; - }(config_namespaces); -var render_DomFragment_Attribute_helpers_determinePropertyName = function (namespaces) { - - var propertyNames = { - 'accept-charset': 'acceptCharset', - accesskey: 'accessKey', - bgcolor: 'bgColor', - 'class': 'className', - codebase: 'codeBase', - colspan: 'colSpan', - contenteditable: 'contentEditable', - datetime: 'dateTime', - dirname: 'dirName', - 'for': 'htmlFor', - 'http-equiv': 'httpEquiv', - ismap: 'isMap', - maxlength: 'maxLength', - novalidate: 'noValidate', - pubdate: 'pubDate', - readonly: 'readOnly', - rowspan: 'rowSpan', - tabindex: 'tabIndex', - usemap: 'useMap' - }; - return function (attribute, options) { - var propertyName; - if (attribute.pNode && !attribute.namespace && (!options.pNode.namespaceURI || options.pNode.namespaceURI === namespaces.html)) { - propertyName = propertyNames[attribute.name] || attribute.name; - if (options.pNode[propertyName] !== undefined) { - attribute.propertyName = propertyName; - } - if (typeof options.pNode[propertyName] === 'boolean' || propertyName === 'value') { - attribute.useProperty = true; - } - } - }; - }(config_namespaces); -var render_DomFragment_Attribute_prototype_bind = function (types, warn, arrayContentsMatch, getValueFromCheckboxes) { - - var bindAttribute, getInterpolator, updateModel, update, getBinding, inheritProperties, MultipleSelectBinding, SelectBinding, RadioNameBinding, CheckboxNameBinding, CheckedBinding, FileListBinding, ContentEditableBinding, GenericBinding; - bindAttribute = function () { - var node = this.pNode, interpolator, binding, bindings; - if (!this.fragment) { - return false; - } - interpolator = getInterpolator(this); - if (!interpolator) { - return false; - } - this.interpolator = interpolator; - this.keypath = interpolator.keypath || interpolator.descriptor.r; - binding = getBinding(this); - if (!binding) { - return false; - } - node._ractive.binding = this.element.binding = binding; - this.twoway = true; - bindings = this.root._twowayBindings[this.keypath] || (this.root._twowayBindings[this.keypath] = []); - bindings[bindings.length] = binding; - return true; - }; - updateModel = function () { - this._ractive.binding.update(); - }; - update = function () { - var value = this._ractive.root.get(this._ractive.binding.keypath); - this.value = value == undefined ? '' : value; - }; - getInterpolator = function (attribute) { - var item, errorMessage; - if (attribute.fragment.items.length !== 1) { - return null; - } - item = attribute.fragment.items[0]; - if (item.type !== types.INTERPOLATOR) { - return null; - } - if (!item.keypath && !item.ref) { - return null; - } - if (item.keypath && item.keypath.substr(0, 2) === '${') { - errorMessage = 'You cannot set up two-way binding against an expression ' + item.keypath; - if (attribute.root.debug) { - warn(errorMessage); - } - return null; - } - return item; - }; - getBinding = function (attribute) { - var node = attribute.pNode; - if (node.tagName === 'SELECT') { - return node.multiple ? new MultipleSelectBinding(attribute, node) : new SelectBinding(attribute, node); - } - if (node.type === 'checkbox' || node.type === 'radio') { - if (attribute.propertyName === 'name') { - if (node.type === 'checkbox') { - return new CheckboxNameBinding(attribute, node); - } - if (node.type === 'radio') { - return new RadioNameBinding(attribute, node); - } - } - if (attribute.propertyName === 'checked') { - return new CheckedBinding(attribute, node); - } - return null; - } - if (attribute.lcName !== 'value') { - warn('This is... odd'); - } - if (node.type === 'file') { - return new FileListBinding(attribute, node); - } - if (node.getAttribute('contenteditable')) { - return new ContentEditableBinding(attribute, node); - } - return new GenericBinding(attribute, node); - }; - MultipleSelectBinding = function (attribute, node) { - var valueFromModel; - inheritProperties(this, attribute, node); - node.addEventListener('change', updateModel, false); - valueFromModel = this.root.get(this.keypath); - if (valueFromModel === undefined) { - this.update(); - } - }; - MultipleSelectBinding.prototype = { - value: function () { - var value, options, i, len; - value = []; - options = this.node.options; - len = options.length; - for (i = 0; i < len; i += 1) { - if (options[i].selected) { - value[value.length] = options[i]._ractive.value; - } - } - return value; - }, - update: function () { - var attribute, previousValue, value; - attribute = this.attr; - previousValue = attribute.value; - value = this.value(); - if (previousValue === undefined || !arrayContentsMatch(value, previousValue)) { - attribute.receiving = true; - attribute.value = value; - this.root.set(this.keypath, value); - attribute.receiving = false; - } - return this; - }, - deferUpdate: function () { - if (this.deferred === true) { - return; - } - this.root._deferred.attrs.push(this); - this.deferred = true; - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - } - }; - SelectBinding = function (attribute, node) { - var valueFromModel; - inheritProperties(this, attribute, node); - node.addEventListener('change', updateModel, false); - valueFromModel = this.root.get(this.keypath); - if (valueFromModel === undefined) { - this.update(); - } - }; - SelectBinding.prototype = { - value: function () { - var options, i, len; - options = this.node.options; - len = options.length; - for (i = 0; i < len; i += 1) { - if (options[i].selected) { - return options[i]._ractive.value; - } - } - }, - update: function () { - var value = this.value(); - this.attr.receiving = true; - this.attr.value = value; - this.root.set(this.keypath, value); - this.attr.receiving = false; - return this; - }, - deferUpdate: function () { - if (this.deferred === true) { - return; - } - this.root._deferred.attrs.push(this); - this.deferred = true; - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - } - }; - RadioNameBinding = function (attribute, node) { - var valueFromModel; - this.radioName = true; - inheritProperties(this, attribute, node); - node.name = '{{' + attribute.keypath + '}}'; - node.addEventListener('change', updateModel, false); - if (node.attachEvent) { - node.addEventListener('click', updateModel, false); - } - valueFromModel = this.root.get(this.keypath); - if (valueFromModel !== undefined) { - node.checked = valueFromModel == node._ractive.value; - } else { - this.root._deferred.radios.push(this); - } - }; - RadioNameBinding.prototype = { - value: function () { - return this.node._ractive ? this.node._ractive.value : this.node.value; - }, - update: function () { - var node = this.node; - if (node.checked) { - this.attr.receiving = true; - this.root.set(this.keypath, this.value()); - this.attr.receiving = false; - } - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - this.node.removeEventListener('click', updateModel, false); - } - }; - CheckboxNameBinding = function (attribute, node) { - var valueFromModel, checked; - this.checkboxName = true; - inheritProperties(this, attribute, node); - node.name = '{{' + this.keypath + '}}'; - node.addEventListener('change', updateModel, false); - if (node.attachEvent) { - node.addEventListener('click', updateModel, false); - } - valueFromModel = this.root.get(this.keypath); - if (valueFromModel !== undefined) { - checked = valueFromModel.indexOf(node._ractive.value) !== -1; - node.checked = checked; - } else { - if (this.root._deferred.checkboxes.indexOf(this.keypath) === -1) { - this.root._deferred.checkboxes.push(this.keypath); - } - } - }; - CheckboxNameBinding.prototype = { - changed: function () { - return this.node.checked !== !!this.checked; - }, - update: function () { - this.checked = this.node.checked; - this.attr.receiving = true; - this.root.set(this.keypath, getValueFromCheckboxes(this.root, this.keypath)); - this.attr.receiving = false; - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - this.node.removeEventListener('click', updateModel, false); - } - }; - CheckedBinding = function (attribute, node) { - inheritProperties(this, attribute, node); - node.addEventListener('change', updateModel, false); - if (node.attachEvent) { - node.addEventListener('click', updateModel, false); - } - }; - CheckedBinding.prototype = { - value: function () { - return this.node.checked; - }, - update: function () { - this.attr.receiving = true; - this.root.set(this.keypath, this.value()); - this.attr.receiving = false; - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - this.node.removeEventListener('click', updateModel, false); - } - }; - FileListBinding = function (attribute, node) { - inheritProperties(this, attribute, node); - node.addEventListener('change', updateModel, false); - }; - FileListBinding.prototype = { - value: function () { - return this.attr.pNode.files; - }, - update: function () { - this.attr.root.set(this.attr.keypath, this.value()); - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - } - }; - ContentEditableBinding = function (attribute, node) { - inheritProperties(this, attribute, node); - node.addEventListener('change', updateModel, false); - if (!this.root.lazy) { - node.addEventListener('input', updateModel, false); - if (node.attachEvent) { - node.addEventListener('keyup', updateModel, false); - } - } - }; - ContentEditableBinding.prototype = { - update: function () { - this.attr.receiving = true; - this.root.set(this.keypath, this.node.innerHTML); - this.attr.receiving = false; - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - this.node.removeEventListener('input', updateModel, false); - this.node.removeEventListener('keyup', updateModel, false); - } - }; - GenericBinding = function (attribute, node) { - inheritProperties(this, attribute, node); - node.addEventListener('change', updateModel, false); - if (!this.root.lazy) { - node.addEventListener('input', updateModel, false); - if (node.attachEvent) { - node.addEventListener('keyup', updateModel, false); - } - } - this.node.addEventListener('blur', update, false); - }; - GenericBinding.prototype = { - value: function () { - var value = this.attr.pNode.value; - if (+value + '' === value && value.indexOf('e') === -1) { - value = +value; - } - return value; - }, - update: function () { - var attribute = this.attr, value = this.value(); - attribute.receiving = true; - attribute.root.set(attribute.keypath, value); - attribute.receiving = false; - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - this.node.removeEventListener('input', updateModel, false); - this.node.removeEventListener('keyup', updateModel, false); - this.node.removeEventListener('blur', update, false); - } - }; - inheritProperties = function (binding, attribute, node) { - binding.attr = attribute; - binding.node = node; - binding.root = attribute.root; - binding.keypath = attribute.keypath; - }; - return bindAttribute; - }(config_types, utils_warn, utils_arrayContentsMatch, shared_getValueFromCheckboxes); -var render_DomFragment_Attribute_prototype_update = function (isArray, namespaces) { - - var updateAttribute, updateFileInputValue, deferSelect, initSelect, updateSelect, updateMultipleSelect, updateRadioName, updateCheckboxName, updateIEStyleAttribute, updateClassName, updateContentEditableValue, updateEverythingElse; - updateAttribute = function () { - var node; - if (!this.ready) { - return this; - } - node = this.pNode; - if (node.tagName === 'SELECT' && this.lcName === 'value') { - this.update = deferSelect; - this.deferredUpdate = initSelect; - return this.update(); - } - if (this.isFileInputValue) { - this.update = updateFileInputValue; - return this; - } - if (this.twoway && this.lcName === 'name') { - if (node.type === 'radio') { - this.update = updateRadioName; - return this.update(); - } - if (node.type === 'checkbox') { - this.update = updateCheckboxName; - return this.update(); - } - } - if (this.lcName === 'style' && node.style.setAttribute) { - this.update = updateIEStyleAttribute; - return this.update(); - } - if (this.lcName === 'class' && (!node.namespaceURI || node.namespaceURI === namespaces.html)) { - this.update = updateClassName; - return this.update(); - } - if (node.getAttribute('contenteditable') && this.lcName === 'value') { - this.update = updateContentEditableValue; - return this.update(); - } - this.update = updateEverythingElse; - return this.update(); - }; - updateFileInputValue = function () { - return this; - }; - initSelect = function () { - this.deferredUpdate = this.pNode.multiple ? updateMultipleSelect : updateSelect; - this.deferredUpdate(); - }; - deferSelect = function () { - this.root._deferred.selectValues.push(this); - return this; - }; - updateSelect = function () { - var value = this.fragment.getValue(), options, option, i; - this.value = this.pNode._ractive.value = value; - options = this.pNode.options; - i = options.length; - while (i--) { - option = options[i]; - if (option._ractive.value == value) { - option.selected = true; - return this; - } - } - return this; - }; - updateMultipleSelect = function () { - var value = this.fragment.getValue(), options, i; - if (!isArray(value)) { - value = [value]; - } - options = this.pNode.options; - i = options.length; - while (i--) { - options[i].selected = value.indexOf(options[i]._ractive.value) !== -1; - } - this.value = value; - return this; - }; - updateRadioName = function () { - var node, value; - node = this.pNode; - value = this.fragment.getValue(); - node.checked = value == node._ractive.value; - return this; - }; - updateCheckboxName = function () { - var node, value; - node = this.pNode; - value = this.fragment.getValue(); - if (!isArray(value)) { - node.checked = value == node._ractive.value; - return this; - } - node.checked = value.indexOf(node._ractive.value) !== -1; - return this; - }; - updateIEStyleAttribute = function () { - var node, value; - node = this.pNode; - value = this.fragment.getValue(); - if (value === undefined) { - value = ''; - } - if (value !== this.value) { - node.style.setAttribute('cssText', value); - this.value = value; - } - return this; - }; - updateClassName = function () { - var node, value; - node = this.pNode; - value = this.fragment.getValue(); - if (value === undefined) { - value = ''; - } - if (value !== this.value) { - node.className = value; - this.value = value; - } - return this; - }; - updateContentEditableValue = function () { - var node, value; - node = this.pNode; - value = this.fragment.getValue(); - if (value === undefined) { - value = ''; - } - if (value !== this.value) { - if (!this.receiving) { - node.innerHTML = value; - } - this.value = value; - } - return this; - }; - updateEverythingElse = function () { - var node, value; - node = this.pNode; - value = this.fragment.getValue(); - if (this.isValueAttribute) { - node._ractive.value = value; - } - if (value === undefined) { - value = ''; - } - if (value !== this.value) { - if (this.useProperty) { - if (!this.receiving) { - node[this.propertyName] = value; - } - this.value = value; - return this; - } - if (this.namespace) { - node.setAttributeNS(this.namespace, this.name, value); - this.value = value; - return this; - } - if (this.lcName === 'id') { - if (this.value !== undefined) { - this.root.nodes[this.value] = undefined; - } - this.root.nodes[value] = node; - } - node.setAttribute(this.name, value); - this.value = value; - } - return this; - }; - return updateAttribute; - }(utils_isArray, config_namespaces); -var parse_Tokenizer_utils_getStringMatch = function () { - - return function (string) { - var substr; - substr = this.str.substr(this.pos, string.length); - if (substr === string) { - this.pos += string.length; - return string; - } - return null; - }; - }(); -var parse_Tokenizer_utils_allowWhitespace = function () { - - var leadingWhitespace = /^\s+/; - return function () { - var match = leadingWhitespace.exec(this.remaining()); - if (!match) { - return null; - } - this.pos += match[0].length; - return match[0]; - }; - }(); -var parse_Tokenizer_utils_makeRegexMatcher = function () { - - return function (regex) { - return function (tokenizer) { - var match = regex.exec(tokenizer.str.substring(tokenizer.pos)); - if (!match) { - return null; - } - tokenizer.pos += match[0].length; - return match[1] || match[0]; - }; - }; - }(); -var parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral_getEscapedChars = function () { - - return function (tokenizer) { - var chars = '', character; - character = getEscapedChar(tokenizer); - while (character) { - chars += character; - character = getEscapedChar(tokenizer); - } - return chars || null; - }; - function getEscapedChar(tokenizer) { - var character; - if (!tokenizer.getStringMatch('\\')) { - return null; - } - character = tokenizer.str.charAt(tokenizer.pos); - tokenizer.pos += 1; - return character; - } - }(); -var parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral_getQuotedString = function (makeRegexMatcher, getEscapedChars) { - - var getUnescapedDoubleQuotedChars = makeRegexMatcher(/^[^\\"]+/), getUnescapedSingleQuotedChars = makeRegexMatcher(/^[^\\']+/); - return function getQuotedString(tokenizer, singleQuotes) { - var start, string, escaped, unescaped, next, matcher; - start = tokenizer.pos; - string = ''; - matcher = singleQuotes ? getUnescapedSingleQuotedChars : getUnescapedDoubleQuotedChars; - escaped = getEscapedChars(tokenizer); - if (escaped) { - string += escaped; - } - unescaped = matcher(tokenizer); - if (unescaped) { - string += unescaped; - } - if (!string) { - return ''; - } - next = getQuotedString(tokenizer, singleQuotes); - while (next !== '') { - string += next; - } - return string; - }; - }(parse_Tokenizer_utils_makeRegexMatcher, parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral_getEscapedChars); -var parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral__getStringLiteral = function (types, getQuotedString) { - - return function (tokenizer) { - var start, string; - start = tokenizer.pos; - if (tokenizer.getStringMatch('"')) { - string = getQuotedString(tokenizer, false); - if (!tokenizer.getStringMatch('"')) { - tokenizer.pos = start; - return null; - } - return { - t: types.STRING_LITERAL, - v: string - }; - } - if (tokenizer.getStringMatch('\'')) { - string = getQuotedString(tokenizer, true); - if (!tokenizer.getStringMatch('\'')) { - tokenizer.pos = start; - return null; - } - return { - t: types.STRING_LITERAL, - v: string - }; - } - return null; - }; - }(config_types, parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral_getQuotedString); -var parse_Tokenizer_getExpression_getPrimary_getLiteral_getNumberLiteral = function (types, makeRegexMatcher) { - - var getNumber = makeRegexMatcher(/^(?:[+-]?)(?:(?:(?:0|[1-9]\d*)?\.\d+)|(?:(?:0|[1-9]\d*)\.)|(?:0|[1-9]\d*))(?:[eE][+-]?\d+)?/); - return function (tokenizer) { - var result; - if (result = getNumber(tokenizer)) { - return { - t: types.NUMBER_LITERAL, - v: result - }; - } - return null; - }; - }(config_types, parse_Tokenizer_utils_makeRegexMatcher); -var parse_Tokenizer_getExpression_shared_getName = function (makeRegexMatcher) { - - return makeRegexMatcher(/^[a-zA-Z_$][a-zA-Z_$0-9]*/); - }(parse_Tokenizer_utils_makeRegexMatcher); -var parse_Tokenizer_getExpression_shared_getKey = function (getStringLiteral, getNumberLiteral, getName) { - - var identifier = /^[a-zA-Z_$][a-zA-Z_$0-9]*$/; - return function (tokenizer) { - var token; - if (token = getStringLiteral(tokenizer)) { - return identifier.test(token.v) ? token.v : '"' + token.v.replace(/"/g, '\\"') + '"'; - } - if (token = getNumberLiteral(tokenizer)) { - return token.v; - } - if (token = getName(tokenizer)) { - return token; - } - }; - }(parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral__getStringLiteral, parse_Tokenizer_getExpression_getPrimary_getLiteral_getNumberLiteral, parse_Tokenizer_getExpression_shared_getName); -var utils_parseJSON = function (getStringMatch, allowWhitespace, getStringLiteral, getKey) { - - var Tokenizer, specials, specialsPattern, numberPattern, placeholderPattern, placeholderAtStartPattern; - specials = { - 'true': true, - 'false': false, - 'undefined': undefined, - 'null': null - }; - specialsPattern = new RegExp('^(?:' + Object.keys(specials).join('|') + ')'); - numberPattern = /^(?:[+-]?)(?:(?:(?:0|[1-9]\d*)?\.\d+)|(?:(?:0|[1-9]\d*)\.)|(?:0|[1-9]\d*))(?:[eE][+-]?\d+)?/; - placeholderPattern = /\$\{([^\}]+)\}/g; - placeholderAtStartPattern = /^\$\{([^\}]+)\}/; - Tokenizer = function (str, values) { - this.str = str; - this.values = values; - this.pos = 0; - this.result = this.getToken(); - }; - Tokenizer.prototype = { - remaining: function () { - return this.str.substring(this.pos); - }, - getStringMatch: getStringMatch, - getToken: function () { - this.allowWhitespace(); - return this.getPlaceholder() || this.getSpecial() || this.getNumber() || this.getString() || this.getObject() || this.getArray(); - }, - getPlaceholder: function () { - var match; - if (!this.values) { - return null; - } - if ((match = placeholderAtStartPattern.exec(this.remaining())) && this.values.hasOwnProperty(match[1])) { - this.pos += match[0].length; - return { v: this.values[match[1]] }; - } - }, - getSpecial: function () { - var match; - if (match = specialsPattern.exec(this.remaining())) { - this.pos += match[0].length; - return { v: specials[match[0]] }; - } - }, - getNumber: function () { - var match; - if (match = numberPattern.exec(this.remaining())) { - this.pos += match[0].length; - return { v: +match[0] }; - } - }, - getString: function () { - var stringLiteral = getStringLiteral(this), values; - if (stringLiteral && (values = this.values)) { - return { - v: stringLiteral.v.replace(placeholderPattern, function (match, $1) { - return values[$1] || $1; - }) - }; - } - return stringLiteral; - }, - getObject: function () { - var result, pair; - if (!this.getStringMatch('{')) { - return null; - } - result = {}; - while (pair = getKeyValuePair(this)) { - result[pair.key] = pair.value; - this.allowWhitespace(); - if (this.getStringMatch('}')) { - return { v: result }; - } - if (!this.getStringMatch(',')) { - return null; - } - } - return null; - }, - getArray: function () { - var result, valueToken; - if (!this.getStringMatch('[')) { - return null; - } - result = []; - while (valueToken = this.getToken()) { - result.push(valueToken.v); - if (this.getStringMatch(']')) { - return { v: result }; - } - if (!this.getStringMatch(',')) { - return null; - } - } - return null; - }, - allowWhitespace: allowWhitespace - }; - function getKeyValuePair(tokenizer) { - var key, valueToken, pair; - tokenizer.allowWhitespace(); - key = getKey(tokenizer); - if (!key) { - return null; - } - pair = { key: key }; - tokenizer.allowWhitespace(); - if (!tokenizer.getStringMatch(':')) { - return null; - } - tokenizer.allowWhitespace(); - valueToken = tokenizer.getToken(); - if (!valueToken) { - return null; - } - pair.value = valueToken.v; - return pair; - } - return function (str, values) { - var tokenizer = new Tokenizer(str, values); - if (tokenizer.result) { - return { - value: tokenizer.result.v, - remaining: tokenizer.remaining() - }; - } - return null; - }; - }(parse_Tokenizer_utils_getStringMatch, parse_Tokenizer_utils_allowWhitespace, parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral__getStringLiteral, parse_Tokenizer_getExpression_shared_getKey); -var render_StringFragment_Interpolator = function (types, teardown, initMustache, updateMustache, resolveMustache) { - - var StringInterpolator = function (options) { - this.type = types.INTERPOLATOR; - initMustache(this, options); - }; - StringInterpolator.prototype = { - update: updateMustache, - resolve: resolveMustache, - render: function (value) { - this.value = value; - this.parentFragment.bubble(); - }, - teardown: function () { - teardown(this); - }, - toString: function () { - if (this.value == undefined) { - return ''; - } - return stringify(this.value); - } - }; - return StringInterpolator; - function stringify(value) { - if (typeof value === 'string') { - return value; - } - return JSON.stringify(value); - } - }(config_types, shared_teardown, render_shared_initMustache, render_shared_updateMustache, render_shared_resolveMustache); -var render_StringFragment_Section = function (types, initMustache, updateMustache, resolveMustache, updateSection, teardown, circular) { - - var StringSection, StringFragment; - circular.push(function () { - StringFragment = circular.StringFragment; - }); - StringSection = function (options) { - this.type = types.SECTION; - this.fragments = []; - this.length = 0; - initMustache(this, options); - }; - StringSection.prototype = { - update: updateMustache, - resolve: resolveMustache, - teardown: function () { - this.teardownFragments(); - teardown(this); - }, - teardownFragments: function () { - while (this.fragments.length) { - this.fragments.shift().teardown(); - } - this.length = 0; - }, - bubble: function () { - this.value = this.fragments.join(''); - this.parentFragment.bubble(); - }, - render: function (value) { - var wrapped; - if (wrapped = this.root._wrapped[this.keypath]) { - value = wrapped.get(); - } - updateSection(this, value); - this.parentFragment.bubble(); - }, - createFragment: function (options) { - return new StringFragment(options); - }, - toString: function () { - return this.fragments.join(''); - } - }; - return StringSection; - }(config_types, render_shared_initMustache, render_shared_updateMustache, render_shared_resolveMustache, render_shared_updateSection, shared_teardown, circular); -var render_StringFragment_Text = function (types) { - - var StringText = function (text) { - this.type = types.TEXT; - this.text = text; - }; - StringText.prototype = { - toString: function () { - return this.text; - }, - teardown: function () { - } - }; - return StringText; - }(config_types); -var render_StringFragment_prototype_toArgsList = function (warn, parseJSON) { - - return function () { - var values, counter, jsonesque, guid, errorMessage, parsed, processItems; - if (!this.argsList || this.dirty) { - values = {}; - counter = 0; - guid = this.root._guid; - processItems = function (items) { - return items.map(function (item) { - var placeholderId, wrapped, value; - if (item.text) { - return item.text; - } - if (item.fragments) { - return item.fragments.map(function (fragment) { - return processItems(fragment.items); - }).join(''); - } - placeholderId = guid + '-' + counter++; - if (wrapped = item.root._wrapped[item.keypath]) { - value = wrapped.value; - } else { - value = item.value; - } - values[placeholderId] = value; - return '${' + placeholderId + '}'; - }).join(''); - }; - jsonesque = processItems(this.items); - parsed = parseJSON('[' + jsonesque + ']', values); - if (!parsed) { - errorMessage = 'Could not parse directive arguments (' + this.toString() + '). If you think this is a bug, please file an issue at http://github.com/RactiveJS/Ractive/issues'; - if (this.root.debug) { - throw new Error(errorMessage); - } else { - warn(errorMessage); - this.argsList = [jsonesque]; - } - } else { - this.argsList = parsed.value; - } - this.dirty = false; - } - return this.argsList; - }; - }(utils_warn, utils_parseJSON); -var render_StringFragment__StringFragment = function (types, parseJSON, initFragment, Interpolator, Section, Text, toArgsList, circular) { - - var StringFragment = function (options) { - initFragment(this, options); - }; - StringFragment.prototype = { - createItem: function (options) { - if (typeof options.descriptor === 'string') { - return new Text(options.descriptor); - } - switch (options.descriptor.t) { - case types.INTERPOLATOR: - return new Interpolator(options); - case types.TRIPLE: - return new Interpolator(options); - case types.SECTION: - return new Section(options); - default: - throw 'Something went wrong in a rather interesting way'; - } - }, - bubble: function () { - this.dirty = true; - this.owner.bubble(); - }, - teardown: function () { - var numItems, i; - numItems = this.items.length; - for (i = 0; i < numItems; i += 1) { - this.items[i].teardown(); - } - }, - getValue: function () { - var value; - if (this.items.length === 1 && this.items[0].type === types.INTERPOLATOR) { - value = this.items[0].value; - if (value !== undefined) { - return value; - } - } - return this.toString(); - }, - isSimple: function () { - var i, item, containsInterpolator; - if (this.simple !== undefined) { - return this.simple; - } - i = this.items.length; - while (i--) { - item = this.items[i]; - if (item.type === types.TEXT) { - continue; - } - if (item.type === types.INTERPOLATOR) { - if (containsInterpolator) { - return false; - } else { - containsInterpolator = true; - continue; - } - } - return this.simple = false; - } - return this.simple = true; - }, - toString: function () { - return this.items.join(''); - }, - toJSON: function () { - var value = this.getValue(), parsed; - if (typeof value === 'string') { - parsed = parseJSON(value); - value = parsed ? parsed.value : value; - } - return value; - }, - toArgsList: toArgsList - }; - circular.StringFragment = StringFragment; - return StringFragment; - }(config_types, utils_parseJSON, render_shared_initFragment, render_StringFragment_Interpolator, render_StringFragment_Section, render_StringFragment_Text, render_StringFragment_prototype_toArgsList, circular); -var render_DomFragment_Attribute__Attribute = function (types, determineNameAndNamespace, setStaticAttribute, determinePropertyName, bind, update, StringFragment) { - - var DomAttribute = function (options) { - this.type = types.ATTRIBUTE; - this.element = options.element; - determineNameAndNamespace(this, options.name); - if (options.value === null || typeof options.value === 'string') { - setStaticAttribute(this, options); - return; - } - this.root = options.root; - this.pNode = options.pNode; - this.parentFragment = this.element.parentFragment; - this.fragment = new StringFragment({ - descriptor: options.value, - root: this.root, - owner: this, - contextStack: options.contextStack - }); - if (!this.pNode) { - return; - } - if (this.name === 'value') { - this.isValueAttribute = true; - if (this.pNode.tagName === 'INPUT' && this.pNode.type === 'file') { - this.isFileInputValue = true; - } - } - determinePropertyName(this, options); - this.selfUpdating = this.fragment.isSimple(); - this.ready = true; - }; - DomAttribute.prototype = { - bind: bind, - update: update, - updateBindings: function () { - this.keypath = this.interpolator.keypath || this.interpolator.ref; - if (this.propertyName === 'name') { - this.pNode.name = '{{' + this.keypath + '}}'; - } - }, - teardown: function () { - var i; - if (this.boundEvents) { - i = this.boundEvents.length; - while (i--) { - this.pNode.removeEventListener(this.boundEvents[i], this.updateModel, false); - } - } - if (this.fragment) { - this.fragment.teardown(); - } - }, - bubble: function () { - if (this.selfUpdating) { - this.update(); - } else if (!this.deferred && this.ready) { - this.root._deferred.attrs.push(this); - this.deferred = true; - } - }, - toString: function () { - var str; - if (this.value === null) { - return this.name; - } - if (!this.fragment) { - return this.name + '=' + JSON.stringify(this.value); - } - str = this.fragment.toString(); - return this.name + '=' + JSON.stringify(str); - } - }; - return DomAttribute; - }(config_types, render_DomFragment_Attribute_helpers_determineNameAndNamespace, render_DomFragment_Attribute_helpers_setStaticAttribute, render_DomFragment_Attribute_helpers_determinePropertyName, render_DomFragment_Attribute_prototype_bind, render_DomFragment_Attribute_prototype_update, render_StringFragment__StringFragment); -var render_DomFragment_Element_initialise_createElementAttributes = function (DomAttribute) { - - return function (element, attributes) { - var attrName, attrValue, attr; - element.attributes = []; - for (attrName in attributes) { - if (attributes.hasOwnProperty(attrName)) { - attrValue = attributes[attrName]; - attr = new DomAttribute({ - element: element, - name: attrName, - value: attrValue, - root: element.root, - pNode: element.node, - contextStack: element.parentFragment.contextStack - }); - element.attributes[element.attributes.length] = element.attributes[attrName] = attr; - if (attrName !== 'name') { - attr.update(); - } - } - } - return element.attributes; - }; - }(render_DomFragment_Attribute__Attribute); -var render_DomFragment_Element_initialise_appendElementChildren = function (warn, namespaces, StringFragment, circular) { - - var DomFragment, updateCss, updateScript; - circular.push(function () { - DomFragment = circular.DomFragment; - }); - updateCss = function () { - var node = this.node, content = this.fragment.toString(); - if (node.styleSheet) { - node.styleSheet.cssText = content; - } - node.innerHTML = content; - }; - updateScript = function () { - if (!this.node.type || this.node.type === 'text/javascript') { - warn('Script tag was updated. This does not cause the code to be re-evaluated!'); - } - this.node.innerHTML = this.fragment.toString(); - }; - return function (element, node, descriptor, docFrag) { - var liveQueries, i, selector, queryAllResult, j; - if (element.lcName === 'script' || element.lcName === 'style') { - element.fragment = new StringFragment({ - descriptor: descriptor.f, - root: element.root, - contextStack: element.parentFragment.contextStack, - owner: element - }); - if (docFrag) { - if (element.lcName === 'script') { - element.bubble = updateScript; - element.node.innerHTML = element.fragment.toString(); - } else { - element.bubble = updateCss; - element.bubble(); - } - } - return; - } - if (typeof descriptor.f === 'string' && (!node || (!node.namespaceURI || node.namespaceURI === namespaces.html))) { - element.html = descriptor.f; - if (docFrag) { - node.innerHTML = element.html; - liveQueries = element.root._liveQueries; - i = liveQueries.length; - while (i--) { - selector = liveQueries[i]; - if ((queryAllResult = node.querySelectorAll(selector)) && (j = queryAllResult.length)) { - (element.liveQueries || (element.liveQueries = [])).push(selector); - element.liveQueries[selector] = []; - while (j--) { - element.liveQueries[selector][j] = queryAllResult[j]; - } - } - } - } - } else { - element.fragment = new DomFragment({ - descriptor: descriptor.f, - root: element.root, - pNode: node, - contextStack: element.parentFragment.contextStack, - owner: element - }); - if (docFrag) { - node.appendChild(element.fragment.docFrag); - } - } - }; - }(utils_warn, config_namespaces, render_StringFragment__StringFragment, circular); -var render_DomFragment_Element_initialise_decorate_Decorator = function (warn, StringFragment) { - - var Decorator = function (descriptor, root, owner, contextStack) { - var name, fragment, errorMessage; - this.root = root; - this.node = owner.node; - name = descriptor.n || descriptor; - if (typeof name !== 'string') { - fragment = new StringFragment({ - descriptor: name, - root: this.root, - owner: owner, - contextStack: contextStack - }); - name = fragment.toString(); - fragment.teardown(); - } - if (descriptor.a) { - this.params = descriptor.a; - } else if (descriptor.d) { - fragment = new StringFragment({ - descriptor: descriptor.d, - root: this.root, - owner: owner, - contextStack: contextStack - }); - this.params = fragment.toArgsList(); - fragment.teardown(); - } - this.fn = root.decorators[name]; - if (!this.fn) { - errorMessage = 'Missing "' + name + '" decorator. You may need to download a plugin via https://github.com/RactiveJS/Ractive/wiki/Plugins#decorators'; - if (root.debug) { - throw new Error(errorMessage); - } else { - warn(errorMessage); - } - } - }; - Decorator.prototype = { - init: function () { - var result, args; - if (this.params) { - args = [this.node].concat(this.params); - result = this.fn.apply(this.root, args); - } else { - result = this.fn.call(this.root, this.node); - } - if (!result || !result.teardown) { - throw new Error('Decorator definition must return an object with a teardown method'); - } - this.teardown = result.teardown; - } - }; - return Decorator; - }(utils_warn, render_StringFragment__StringFragment); -var render_DomFragment_Element_initialise_decorate__decorate = function (Decorator) { - - return function (descriptor, root, owner, contextStack) { - owner.decorator = new Decorator(descriptor, root, owner, contextStack); - if (owner.decorator.fn) { - root._deferred.decorators.push(owner.decorator); - } - }; - }(render_DomFragment_Element_initialise_decorate_Decorator); -var render_DomFragment_Element_initialise_addEventProxies_addEventProxy = function (warn, StringFragment) { - - var addEventProxy, MasterEventHandler, ProxyEvent, firePlainEvent, fireEventWithArgs, fireEventWithDynamicArgs, customHandlers, genericHandler, getCustomHandler; - addEventProxy = function (element, triggerEventName, proxyDescriptor, contextStack, indexRefs) { - var events, master; - events = element.node._ractive.events; - master = events[triggerEventName] || (events[triggerEventName] = new MasterEventHandler(element, triggerEventName, contextStack, indexRefs)); - master.add(proxyDescriptor); - }; - MasterEventHandler = function (element, eventName, contextStack) { - var definition; - this.element = element; - this.root = element.root; - this.node = element.node; - this.name = eventName; - this.contextStack = contextStack; - this.proxies = []; - if (definition = this.root.events[eventName]) { - this.custom = definition(this.node, getCustomHandler(eventName)); - } else { - if (!('on' + eventName in this.node)) { - warn('Missing "' + this.name + '" event. You may need to download a plugin via https://github.com/RactiveJS/Ractive/wiki/Plugins#events'); - } - this.node.addEventListener(eventName, genericHandler, false); - } - }; - MasterEventHandler.prototype = { - add: function (proxy) { - this.proxies[this.proxies.length] = new ProxyEvent(this.element, this.root, proxy, this.contextStack); - }, - teardown: function () { - var i; - if (this.custom) { - this.custom.teardown(); - } else { - this.node.removeEventListener(this.name, genericHandler, false); - } - i = this.proxies.length; - while (i--) { - this.proxies[i].teardown(); - } - }, - fire: function (event) { - var i = this.proxies.length; - while (i--) { - this.proxies[i].fire(event); - } - } - }; - ProxyEvent = function (element, ractive, descriptor, contextStack) { - var name; - this.root = ractive; - name = descriptor.n || descriptor; - if (typeof name === 'string') { - this.n = name; - } else { - this.n = new StringFragment({ - descriptor: descriptor.n, - root: this.root, - owner: element, - contextStack: contextStack - }); - } - if (descriptor.a) { - this.a = descriptor.a; - this.fire = fireEventWithArgs; - return; - } - if (descriptor.d) { - this.d = new StringFragment({ - descriptor: descriptor.d, - root: this.root, - owner: element, - contextStack: contextStack - }); - this.fire = fireEventWithDynamicArgs; - return; - } - this.fire = firePlainEvent; - }; - ProxyEvent.prototype = { - teardown: function () { - if (this.n.teardown) { - this.n.teardown(); - } - if (this.d) { - this.d.teardown(); - } - }, - bubble: function () { - } - }; - firePlainEvent = function (event) { - this.root.fire(this.n.toString(), event); - }; - fireEventWithArgs = function (event) { - this.root.fire.apply(this.root, [ - this.n.toString(), - event - ].concat(this.a)); - }; - fireEventWithDynamicArgs = function (event) { - var args = this.d.toArgsList(); - if (typeof args === 'string') { - args = args.substr(1, args.length - 2); - } - this.root.fire.apply(this.root, [ - this.n.toString(), - event - ].concat(args)); - }; - genericHandler = function (event) { - var storage = this._ractive; - storage.events[event.type].fire({ - node: this, - original: event, - index: storage.index, - keypath: storage.keypath, - context: storage.root.get(storage.keypath) - }); - }; - customHandlers = {}; - getCustomHandler = function (eventName) { - if (customHandlers[eventName]) { - return customHandlers[eventName]; - } - return customHandlers[eventName] = function (event) { - var storage = event.node._ractive; - event.index = storage.index; - event.keypath = storage.keypath; - event.context = storage.root.get(storage.keypath); - storage.events[eventName].fire(event); - }; - }; - return addEventProxy; - }(utils_warn, render_StringFragment__StringFragment); -var render_DomFragment_Element_initialise_addEventProxies__addEventProxies = function (addEventProxy) { - - return function (element, proxies) { - var i, eventName, eventNames; - for (eventName in proxies) { - if (proxies.hasOwnProperty(eventName)) { - eventNames = eventName.split('-'); - i = eventNames.length; - while (i--) { - addEventProxy(element, eventNames[i], proxies[eventName], element.parentFragment.contextStack); - } - } - } - }; - }(render_DomFragment_Element_initialise_addEventProxies_addEventProxy); -var render_DomFragment_Element_initialise_updateLiveQueries = function () { - - return function (element) { - var ractive, liveQueries, i, selector, query; - ractive = element.root; - liveQueries = ractive._liveQueries; - i = liveQueries.length; - while (i--) { - selector = liveQueries[i]; - query = liveQueries[selector]; - if (query._test(element)) { - (element.liveQueries || (element.liveQueries = [])).push(selector); - element.liveQueries[selector] = [element.node]; - } - } - }; - }(); -var utils_camelCase = function () { - - return function (hyphenatedStr) { - return hyphenatedStr.replace(/-([a-zA-Z])/g, function (match, $1) { - return $1.toUpperCase(); - }); - }; - }(); -var utils_fillGaps = function () { - - return function (target, source) { - var key; - for (key in source) { - if (source.hasOwnProperty(key) && !target.hasOwnProperty(key)) { - target[key] = source[key]; - } - } - return target; - }; - }(); -var render_DomFragment_Element_shared_executeTransition_Transition = function (isClient, createElement, warn, isNumeric, isArray, camelCase, fillGaps, StringFragment) { - - var Transition, testStyle, vendors, vendorPattern, unprefixPattern, prefixCache, CSS_TRANSITIONS_ENABLED, TRANSITION, TRANSITION_DURATION, TRANSITION_PROPERTY, TRANSITION_TIMING_FUNCTION, TRANSITIONEND; - if (!isClient) { - return; - } - testStyle = createElement('div').style; - (function () { - if (testStyle.transition !== undefined) { - TRANSITION = 'transition'; - TRANSITIONEND = 'transitionend'; - CSS_TRANSITIONS_ENABLED = true; - } else if (testStyle.webkitTransition !== undefined) { - TRANSITION = 'webkitTransition'; - TRANSITIONEND = 'webkitTransitionEnd'; - CSS_TRANSITIONS_ENABLED = true; - } else { - CSS_TRANSITIONS_ENABLED = false; - } - }()); - if (TRANSITION) { - TRANSITION_DURATION = TRANSITION + 'Duration'; - TRANSITION_PROPERTY = TRANSITION + 'Property'; - TRANSITION_TIMING_FUNCTION = TRANSITION + 'TimingFunction'; - } - Transition = function (descriptor, root, owner, contextStack, isIntro) { - var t = this, name, fragment, errorMessage; - this.root = root; - this.node = owner.node; - this.isIntro = isIntro; - this.originalStyle = this.node.getAttribute('style'); - this.complete = function (noReset) { - if (!noReset && t.isIntro) { - t.resetStyle(); - } - t._manager.pop(t.node); - t.node._ractive.transition = null; - }; - name = descriptor.n || descriptor; - if (typeof name !== 'string') { - fragment = new StringFragment({ - descriptor: name, - root: this.root, - owner: owner, - contextStack: contextStack - }); - name = fragment.toString(); - fragment.teardown(); - } - this.name = name; - if (descriptor.a) { - this.params = descriptor.a; - } else if (descriptor.d) { - fragment = new StringFragment({ - descriptor: descriptor.d, - root: this.root, - owner: owner, - contextStack: contextStack - }); - this.params = fragment.toArgsList(); - fragment.teardown(); - } - this._fn = root.transitions[name]; - if (!this._fn) { - errorMessage = 'Missing "' + name + '" transition. You may need to download a plugin via https://github.com/RactiveJS/Ractive/wiki/Plugins#transitions'; - if (root.debug) { - throw new Error(errorMessage); - } else { - warn(errorMessage); - } - return; - } - }; - Transition.prototype = { - init: function () { - if (this._inited) { - throw new Error('Cannot initialize a transition more than once'); - } - this._inited = true; - this._fn.apply(this.root, [this].concat(this.params)); - }, - getStyle: function (props) { - var computedStyle, styles, i, prop, value; - computedStyle = window.getComputedStyle(this.node); - if (typeof props === 'string') { - value = computedStyle[prefix(props)]; - if (value === '0px') { - value = 0; - } - return value; - } - if (!isArray(props)) { - throw new Error('Transition#getStyle must be passed a string, or an array of strings representing CSS properties'); - } - styles = {}; - i = props.length; - while (i--) { - prop = props[i]; - value = computedStyle[prefix(prop)]; - if (value === '0px') { - value = 0; - } - styles[prop] = value; - } - return styles; - }, - setStyle: function (style, value) { - var prop; - if (typeof style === 'string') { - this.node.style[prefix(style)] = value; - } else { - for (prop in style) { - if (style.hasOwnProperty(prop)) { - this.node.style[prefix(prop)] = style[prop]; - } - } - } - return this; - }, - animateStyle: function (style, value, options, complete) { - var t = this, propertyNames, changedProperties, computedStyle, current, to, from, transitionEndHandler, i, prop; - if (typeof style === 'string') { - to = {}; - to[style] = value; - } else { - to = style; - complete = options; - options = value; - } - if (!options) { - warn('The "' + t.name + '" transition does not supply an options object to `t.animateStyle()`. This will break in a future version of Ractive. For more info see https://github.com/RactiveJS/Ractive/issues/340'); - options = t; - complete = t.complete; - } - if (!options.duration) { - t.setStyle(to); - if (complete) { - complete(); - } - } - propertyNames = Object.keys(to); - changedProperties = []; - computedStyle = window.getComputedStyle(t.node); - from = {}; - i = propertyNames.length; - while (i--) { - prop = propertyNames[i]; - current = computedStyle[prefix(prop)]; - if (current === '0px') { - current = 0; - } - if (current != to[prop]) { - changedProperties[changedProperties.length] = prop; - t.node.style[prefix(prop)] = current; - } - } - if (!changedProperties.length) { - if (complete) { - complete(); - } - return; - } - setTimeout(function () { - t.node.style[TRANSITION_PROPERTY] = propertyNames.map(prefix).map(hyphenate).join(','); - t.node.style[TRANSITION_TIMING_FUNCTION] = hyphenate(options.easing || 'linear'); - t.node.style[TRANSITION_DURATION] = options.duration / 1000 + 's'; - transitionEndHandler = function (event) { - var index; - index = changedProperties.indexOf(camelCase(unprefix(event.propertyName))); - if (index !== -1) { - changedProperties.splice(index, 1); - } - if (changedProperties.length) { - return; - } - t.root.fire(t.name + ':end'); - t.node.removeEventListener(TRANSITIONEND, transitionEndHandler, false); - if (complete) { - complete(); - } - }; - t.node.addEventListener(TRANSITIONEND, transitionEndHandler, false); - setTimeout(function () { - var i = changedProperties.length; - while (i--) { - prop = changedProperties[i]; - t.node.style[prefix(prop)] = to[prop]; - } - }, 0); - }, options.delay || 0); - }, - resetStyle: function () { - if (this.originalStyle) { - this.node.setAttribute('style', this.originalStyle); - } else { - this.node.getAttribute('style'); - this.node.removeAttribute('style'); - } - }, - processParams: function (params, defaults) { - if (typeof params === 'number') { - params = { duration: params }; - } else if (typeof params === 'string') { - if (params === 'slow') { - params = { duration: 600 }; - } else if (params === 'fast') { - params = { duration: 200 }; - } else { - params = { duration: 400 }; - } - } else if (!params) { - params = {}; - } - return fillGaps(params, defaults); - } - }; - vendors = [ - 'o', - 'ms', - 'moz', - 'webkit' - ]; - vendorPattern = new RegExp('^(?:' + vendors.join('|') + ')([A-Z])'); - unprefixPattern = new RegExp('^-(?:' + vendors.join('|') + ')-'); - prefixCache = {}; - function prefix(prop) { - var i, vendor, capped; - if (!prefixCache[prop]) { - if (testStyle[prop] !== undefined) { - prefixCache[prop] = prop; - } else { - capped = prop.charAt(0).toUpperCase() + prop.substring(1); - i = vendors.length; - while (i--) { - vendor = vendors[i]; - if (testStyle[vendor + capped] !== undefined) { - prefixCache[prop] = vendor + capped; - break; - } - } - } - } - return prefixCache[prop]; - } - function unprefix(prop) { - return prop.replace(unprefixPattern, ''); - } - function hyphenate(str) { - var hyphenated; - if (vendorPattern.test(str)) { - str = '-' + str; - } - hyphenated = str.replace(/[A-Z]/g, function (match) { - return '-' + match.toLowerCase(); - }); - return hyphenated; - } - return Transition; - }(config_isClient, utils_createElement, utils_warn, utils_isNumeric, utils_isArray, utils_camelCase, utils_fillGaps, render_StringFragment__StringFragment); -var render_DomFragment_Element_shared_executeTransition__executeTransition = function (warn, Transition) { - - return function (descriptor, root, owner, contextStack, isIntro) { - var transition, node, oldTransition; - if (!root.transitionsEnabled || root._parent && !root._parent.transitionsEnabled) { - return; - } - transition = new Transition(descriptor, root, owner, contextStack, isIntro); - if (transition._fn) { - node = transition.node; - transition._manager = root._transitionManager; - if (oldTransition = node._ractive.transition) { - oldTransition.complete(); - } - node._ractive.transition = transition; - transition._manager.push(node); - if (isIntro) { - root._deferred.transitions.push(transition); - } else { - transition.init(); - } - } - }; - }(utils_warn, render_DomFragment_Element_shared_executeTransition_Transition); -var render_DomFragment_Element_initialise__initialise = function (types, namespaces, create, defineProperty, matches, warn, createElement, getElementNamespace, createElementAttributes, appendElementChildren, decorate, addEventProxies, updateLiveQueries, executeTransition, enforceCase) { - - return function (element, options, docFrag) { - var parentFragment, pNode, contextStack, descriptor, namespace, name, attributes, width, height, loadHandler, root, selectBinding, errorMessage; - element.type = types.ELEMENT; - parentFragment = element.parentFragment = options.parentFragment; - pNode = parentFragment.pNode; - contextStack = parentFragment.contextStack; - descriptor = element.descriptor = options.descriptor; - element.root = root = parentFragment.root; - element.index = options.index; - element.lcName = descriptor.e.toLowerCase(); - element.eventListeners = []; - element.customEventListeners = []; - if (pNode) { - namespace = element.namespace = getElementNamespace(descriptor, pNode); - name = namespace !== namespaces.html ? enforceCase(descriptor.e) : descriptor.e; - element.node = createElement(name, namespace); - defineProperty(element.node, '_ractive', { - value: { - proxy: element, - keypath: contextStack.length ? contextStack[contextStack.length - 1] : '', - index: parentFragment.indexRefs, - events: create(null), - root: root - } - }); - } - attributes = createElementAttributes(element, descriptor.a); - if (descriptor.f) { - if (element.node && element.node.getAttribute('contenteditable')) { - if (element.node.innerHTML) { - errorMessage = 'A pre-populated contenteditable element should not have children'; - if (root.debug) { - throw new Error(errorMessage); - } else { - warn(errorMessage); - } - } - } - appendElementChildren(element, element.node, descriptor, docFrag); - } - if (docFrag && descriptor.v) { - addEventProxies(element, descriptor.v); - } - if (docFrag) { - if (root.twoway) { - element.bind(); - if (element.node.getAttribute('contenteditable') && element.node._ractive.binding) { - element.node._ractive.binding.update(); - } - } - if (attributes.name && !attributes.name.twoway) { - attributes.name.update(); - } - if (element.node.tagName === 'IMG' && ((width = element.attributes.width) || (height = element.attributes.height))) { - element.node.addEventListener('load', loadHandler = function () { - if (width) { - element.node.width = width.value; - } - if (height) { - element.node.height = height.value; - } - element.node.removeEventListener('load', loadHandler, false); - }, false); - } - docFrag.appendChild(element.node); - if (descriptor.o) { - decorate(descriptor.o, root, element, contextStack); - } - if (descriptor.t1) { - executeTransition(descriptor.t1, root, element, contextStack, true); - } - if (element.node.tagName === 'OPTION') { - if (pNode.tagName === 'SELECT' && (selectBinding = pNode._ractive.binding)) { - selectBinding.deferUpdate(); - } - if (element.node._ractive.value == pNode._ractive.value) { - element.node.selected = true; - } - } - if (element.node.autofocus) { - root._deferred.focusable = element.node; - } - } - updateLiveQueries(element); - }; - }(config_types, config_namespaces, utils_create, utils_defineProperty, utils_matches, utils_warn, utils_createElement, render_DomFragment_Element_initialise_getElementNamespace, render_DomFragment_Element_initialise_createElementAttributes, render_DomFragment_Element_initialise_appendElementChildren, render_DomFragment_Element_initialise_decorate__decorate, render_DomFragment_Element_initialise_addEventProxies__addEventProxies, render_DomFragment_Element_initialise_updateLiveQueries, render_DomFragment_Element_shared_executeTransition__executeTransition, render_DomFragment_shared_enforceCase); -var render_DomFragment_Element_prototype_teardown = function (executeTransition) { - - return function (destroy) { - var eventName, binding, bindings, i, liveQueries, selector, query, nodesToRemove, j; - if (this.fragment) { - this.fragment.teardown(false); - } - while (this.attributes.length) { - this.attributes.pop().teardown(); - } - if (this.node) { - for (eventName in this.node._ractive.events) { - this.node._ractive.events[eventName].teardown(); - } - if (binding = this.node._ractive.binding) { - binding.teardown(); - bindings = this.root._twowayBindings[binding.attr.keypath]; - bindings.splice(bindings.indexOf(binding), 1); - } - } - if (this.decorator) { - this.decorator.teardown(); - } - if (this.descriptor.t2) { - executeTransition(this.descriptor.t2, this.root, this, this.parentFragment.contextStack, false); - } - if (destroy) { - this.root._transitionManager.detachWhenReady(this); - } - if (liveQueries = this.liveQueries) { - i = liveQueries.length; - while (i--) { - selector = liveQueries[i]; - if (nodesToRemove = this.liveQueries[selector]) { - j = nodesToRemove.length; - query = this.root._liveQueries[selector]; - while (j--) { - query._remove(nodesToRemove[j]); - } - } - } - } - }; - }(render_DomFragment_Element_shared_executeTransition__executeTransition); -var config_voidElementNames = function () { - - return 'area base br col command doctype embed hr img input keygen link meta param source track wbr'.split(' '); - }(); -var render_DomFragment_Element_prototype_toString = function (voidElementNames) { - - return function () { - var str, i, len; - str = '<' + (this.descriptor.y ? '!doctype' : this.descriptor.e); - len = this.attributes.length; - for (i = 0; i < len; i += 1) { - str += ' ' + this.attributes[i].toString(); - } - str += '>'; - if (this.html) { - str += this.html; - } else if (this.fragment) { - str += this.fragment.toString(); - } - if (voidElementNames.indexOf(this.descriptor.e) === -1) { - str += ''; - } - return str; - }; - }(config_voidElementNames); -var render_DomFragment_Element_prototype_find = function (matches) { - - return function (selector) { - var queryResult; - if (matches(this.node, selector)) { - return this.node; - } - if (this.html && (queryResult = this.node.querySelector(selector))) { - return queryResult; - } - if (this.fragment && this.fragment.find) { - return this.fragment.find(selector); - } - }; - }(utils_matches); -var render_DomFragment_Element_prototype_findAll = function () { - - return function (selector, query) { - var queryAllResult, i, numNodes, node, registeredNodes; - if (query._test(this, true) && query.live) { - (this.liveQueries || (this.liveQueries = [])).push(selector); - this.liveQueries[selector] = [this.node]; - } - if (this.html && (queryAllResult = this.node.querySelectorAll(selector)) && (numNodes = queryAllResult.length)) { - if (query.live) { - if (!this.liveQueries[selector]) { - (this.liveQueries || (this.liveQueries = [])).push(selector); - this.liveQueries[selector] = []; - } - registeredNodes = this.liveQueries[selector]; - } - for (i = 0; i < numNodes; i += 1) { - node = queryAllResult[i]; - query.push(node); - if (query.live) { - registeredNodes.push(node); - } - } - } - if (this.fragment) { - this.fragment.findAll(selector, query); - } - }; - }(); -var render_DomFragment_Element_prototype_findComponent = function () { - - return function (selector) { - if (this.fragment) { - return this.fragment.findComponent(selector); - } - }; - }(); -var render_DomFragment_Element_prototype_findAllComponents = function () { - - return function (selector, query) { - if (this.fragment) { - this.fragment.findAllComponents(selector, query); - } - }; - }(); -var render_DomFragment_Element_prototype_bind = function () { - - return function () { - var attributes = this.attributes; - if (!this.node) { - return; - } - if (this.binding) { - this.binding.teardown(); - this.binding = null; - } - if (this.node.getAttribute('contenteditable') && attributes.value && attributes.value.bind()) { - return; - } - switch (this.descriptor.e) { - case 'select': - case 'textarea': - if (attributes.value) { - attributes.value.bind(); - } - return; - case 'input': - if (this.node.type === 'radio' || this.node.type === 'checkbox') { - if (attributes.name && attributes.name.bind()) { - return; - } - if (attributes.checked && attributes.checked.bind()) { - return; - } - } - if (attributes.value && attributes.value.bind()) { - return; - } - } - }; - }(); -var render_DomFragment_Element__Element = function (initialise, teardown, toString, find, findAll, findComponent, findAllComponents, bind) { - - var DomElement = function (options, docFrag) { - initialise(this, options, docFrag); - }; - DomElement.prototype = { - detach: function () { - if (this.node) { - if (this.node.parentNode) { - this.node.parentNode.removeChild(this.node); - } - return this.node; - } - }, - teardown: teardown, - firstNode: function () { - return this.node; - }, - findNextNode: function () { - return null; - }, - bubble: function () { - }, - toString: toString, - find: find, - findAll: findAll, - findComponent: findComponent, - findAllComponents: findAllComponents, - bind: bind - }; - return DomElement; - }(render_DomFragment_Element_initialise__initialise, render_DomFragment_Element_prototype_teardown, render_DomFragment_Element_prototype_toString, render_DomFragment_Element_prototype_find, render_DomFragment_Element_prototype_findAll, render_DomFragment_Element_prototype_findComponent, render_DomFragment_Element_prototype_findAllComponents, render_DomFragment_Element_prototype_bind); -var config_errors = { missingParser: 'Missing Ractive.parse - cannot parse template. Either preparse or use the version that includes the parser' }; -var registries_partials = {}; -var parse_utils_stripHtmlComments = function () { - - return function (html) { - var commentStart, commentEnd, processed; - processed = ''; - while (html.length) { - commentStart = html.indexOf(''); - if (commentStart === -1 && commentEnd === -1) { - processed += html; - break; - } - if (commentStart !== -1 && commentEnd === -1) { - throw 'Illegal HTML - expected closing comment sequence (\'-->\')'; - } - if (commentEnd !== -1 && commentStart === -1 || commentEnd < commentStart) { - throw 'Illegal HTML - unexpected closing comment sequence (\'-->\')'; - } - processed += html.substr(0, commentStart); - html = html.substring(commentEnd + 3); - } - return processed; - }; - }(); -var parse_utils_stripStandalones = function (types) { - - return function (tokens) { - var i, current, backOne, backTwo, leadingLinebreak, trailingLinebreak; - leadingLinebreak = /^\s*\r?\n/; - trailingLinebreak = /\r?\n\s*$/; - for (i = 2; i < tokens.length; i += 1) { - current = tokens[i]; - backOne = tokens[i - 1]; - backTwo = tokens[i - 2]; - if (current.type === types.TEXT && backOne.type === types.MUSTACHE && backTwo.type === types.TEXT) { - if (trailingLinebreak.test(backTwo.value) && leadingLinebreak.test(current.value)) { - if (backOne.mustacheType !== types.INTERPOLATOR && backOne.mustacheType !== types.TRIPLE) { - backTwo.value = backTwo.value.replace(trailingLinebreak, '\n'); - } - current.value = current.value.replace(leadingLinebreak, ''); - if (current.value === '') { - tokens.splice(i--, 1); - } - } - } - } - return tokens; - }; - }(config_types); -var parse_utils_stripCommentTokens = function (types) { - - return function (tokens) { - var i, current, previous, next; - for (i = 0; i < tokens.length; i += 1) { - current = tokens[i]; - previous = tokens[i - 1]; - next = tokens[i + 1]; - if (current.mustacheType === types.COMMENT || current.mustacheType === types.DELIMCHANGE) { - tokens.splice(i, 1); - if (previous && next) { - if (previous.type === types.TEXT && next.type === types.TEXT) { - previous.value += next.value; - tokens.splice(i, 1); - } - } - i -= 1; - } - } - return tokens; - }; - }(config_types); -var parse_Tokenizer_getMustache_getDelimiterChange = function (makeRegexMatcher) { - - var getDelimiter = makeRegexMatcher(/^[^\s=]+/); - return function (tokenizer) { - var start, opening, closing; - if (!tokenizer.getStringMatch('=')) { - return null; - } - start = tokenizer.pos; - tokenizer.allowWhitespace(); - opening = getDelimiter(tokenizer); - if (!opening) { - tokenizer.pos = start; - return null; - } - tokenizer.allowWhitespace(); - closing = getDelimiter(tokenizer); - if (!closing) { - tokenizer.pos = start; - return null; - } - tokenizer.allowWhitespace(); - if (!tokenizer.getStringMatch('=')) { - tokenizer.pos = start; - return null; - } - return [ - opening, - closing - ]; - }; - }(parse_Tokenizer_utils_makeRegexMatcher); -var parse_Tokenizer_getMustache_getMustacheType = function (types) { - - var mustacheTypes = { - '#': types.SECTION, - '^': types.INVERTED, - '/': types.CLOSING, - '>': types.PARTIAL, - '!': types.COMMENT, - '&': types.TRIPLE - }; - return function (tokenizer) { - var type = mustacheTypes[tokenizer.str.charAt(tokenizer.pos)]; - if (!type) { - return null; - } - tokenizer.pos += 1; - return type; - }; - }(config_types); -var parse_Tokenizer_getMustache_getMustacheContent = function (types, makeRegexMatcher, getMustacheType) { - - var getIndexRef = makeRegexMatcher(/^\s*:\s*([a-zA-Z_$][a-zA-Z_$0-9]*)/), arrayMember = /^[0-9][1-9]*$/; - return function (tokenizer, isTriple) { - var start, mustache, type, expr, i, remaining, index; - start = tokenizer.pos; - mustache = { type: isTriple ? types.TRIPLE : types.MUSTACHE }; - if (!isTriple) { - if (expr = tokenizer.getExpression()) { - mustache.mustacheType = types.INTERPOLATOR; - tokenizer.allowWhitespace(); - if (tokenizer.getStringMatch(tokenizer.delimiters[1])) { - tokenizer.pos -= tokenizer.delimiters[1].length; - } else { - tokenizer.pos = start; - expr = null; - } - } - if (!expr) { - type = getMustacheType(tokenizer); - if (type === types.TRIPLE) { - mustache = { type: types.TRIPLE }; - } else { - mustache.mustacheType = type || types.INTERPOLATOR; - } - if (type === types.COMMENT || type === types.CLOSING) { - remaining = tokenizer.remaining(); - index = remaining.indexOf(tokenizer.delimiters[1]); - if (index !== -1) { - mustache.ref = remaining.substr(0, index); - tokenizer.pos += index; - return mustache; - } - } - } - } - if (!expr) { - tokenizer.allowWhitespace(); - expr = tokenizer.getExpression(); - } - while (expr.t === types.BRACKETED && expr.x) { - expr = expr.x; - } - if (expr.t === types.REFERENCE) { - mustache.ref = expr.n; - } else if (expr.t === types.NUMBER_LITERAL && arrayMember.test(expr.v)) { - mustache.ref = expr.v; - } else { - mustache.expression = expr; - } - i = getIndexRef(tokenizer); - if (i !== null) { - mustache.indexRef = i; - } - return mustache; - }; - }(config_types, parse_Tokenizer_utils_makeRegexMatcher, parse_Tokenizer_getMustache_getMustacheType); -var parse_Tokenizer_getMustache__getMustache = function (types, getDelimiterChange, getMustacheContent) { - - return function () { - var seekTripleFirst = this.tripleDelimiters[0].length > this.delimiters[0].length; - return getMustache(this, seekTripleFirst) || getMustache(this, !seekTripleFirst); - }; - function getMustache(tokenizer, seekTriple) { - var start = tokenizer.pos, content, delimiters; - delimiters = seekTriple ? tokenizer.tripleDelimiters : tokenizer.delimiters; - if (!tokenizer.getStringMatch(delimiters[0])) { - return null; - } - content = getDelimiterChange(tokenizer); - if (content) { - if (!tokenizer.getStringMatch(delimiters[1])) { - tokenizer.pos = start; - return null; - } - tokenizer[seekTriple ? 'tripleDelimiters' : 'delimiters'] = content; - return { - type: types.MUSTACHE, - mustacheType: types.DELIMCHANGE - }; - } - tokenizer.allowWhitespace(); - content = getMustacheContent(tokenizer, seekTriple); - if (content === null) { - tokenizer.pos = start; - return null; - } - tokenizer.allowWhitespace(); - if (!tokenizer.getStringMatch(delimiters[1])) { - tokenizer.pos = start; - return null; - } - return content; - } - }(config_types, parse_Tokenizer_getMustache_getDelimiterChange, parse_Tokenizer_getMustache_getMustacheContent); -var parse_Tokenizer_getComment_getComment = function (types) { - - return function () { - var content, remaining, endIndex; - if (!this.getStringMatch(''); - if (endIndex === -1) { - throw new Error('Unexpected end of input (expected "-->" to close comment)'); - } - content = remaining.substr(0, endIndex); - this.pos += endIndex + 3; - return { - type: types.COMMENT, - content: content - }; - }; - }(config_types); -var parse_Tokenizer_utils_getLowestIndex = function () { - - return function (haystack, needles) { - var i, index, lowest; - i = needles.length; - while (i--) { - index = haystack.indexOf(needles[i]); - if (!index) { - return 0; - } - if (index === -1) { - continue; - } - if (!lowest || index < lowest) { - lowest = index; - } - } - return lowest || -1; - }; - }(); -var parse_Tokenizer_getTag__getTag = function (types, makeRegexMatcher, getLowestIndex) { - - var getTag, getOpeningTag, getClosingTag, getTagName, getAttributes, getAttribute, getAttributeName, getAttributeValue, getUnquotedAttributeValue, getUnquotedAttributeValueToken, getUnquotedAttributeValueText, getQuotedStringToken, getQuotedAttributeValue; - getTag = function () { - return getOpeningTag(this) || getClosingTag(this); - }; - getOpeningTag = function (tokenizer) { - var start, tag, attrs, lowerCaseName; - start = tokenizer.pos; - if (tokenizer.inside) { - return null; - } - if (!tokenizer.getStringMatch('<')) { - return null; - } - tag = { type: types.TAG }; - if (tokenizer.getStringMatch('!')) { - tag.doctype = true; - } - tag.name = getTagName(tokenizer); - if (!tag.name) { - tokenizer.pos = start; - return null; - } - attrs = getAttributes(tokenizer); - if (attrs) { - tag.attrs = attrs; - } - tokenizer.allowWhitespace(); - if (tokenizer.getStringMatch('/')) { - tag.selfClosing = true; - } - if (!tokenizer.getStringMatch('>')) { - tokenizer.pos = start; - return null; - } - lowerCaseName = tag.name.toLowerCase(); - if (lowerCaseName === 'script' || lowerCaseName === 'style') { - tokenizer.inside = lowerCaseName; - } - return tag; - }; - getClosingTag = function (tokenizer) { - var start, tag, expected; - start = tokenizer.pos; - expected = function (str) { - throw new Error('Unexpected character ' + tokenizer.remaining().charAt(0) + ' (expected ' + str + ')'); - }; - if (!tokenizer.getStringMatch('<')) { - return null; - } - tag = { - type: types.TAG, - closing: true - }; - if (!tokenizer.getStringMatch('/')) { - expected('"/"'); - } - tag.name = getTagName(tokenizer); - if (!tag.name) { - expected('tag name'); - } - if (!tokenizer.getStringMatch('>')) { - expected('">"'); - } - if (tokenizer.inside) { - if (tag.name.toLowerCase() !== tokenizer.inside) { - tokenizer.pos = start; - return null; - } - tokenizer.inside = null; - } - return tag; - }; - getTagName = makeRegexMatcher(/^[a-zA-Z]{1,}:?[a-zA-Z0-9\-]*/); - getAttributes = function (tokenizer) { - var start, attrs, attr; - start = tokenizer.pos; - tokenizer.allowWhitespace(); - attr = getAttribute(tokenizer); - if (!attr) { - tokenizer.pos = start; - return null; - } - attrs = []; - while (attr !== null) { - attrs[attrs.length] = attr; - tokenizer.allowWhitespace(); - attr = getAttribute(tokenizer); - } - return attrs; - }; - getAttribute = function (tokenizer) { - var attr, name, value; - name = getAttributeName(tokenizer); - if (!name) { - return null; - } - attr = { name: name }; - value = getAttributeValue(tokenizer); - if (value) { - attr.value = value; - } - return attr; - }; - getAttributeName = makeRegexMatcher(/^[^\s"'>\/=]+/); - getAttributeValue = function (tokenizer) { - var start, value; - start = tokenizer.pos; - tokenizer.allowWhitespace(); - if (!tokenizer.getStringMatch('=')) { - tokenizer.pos = start; - return null; - } - tokenizer.allowWhitespace(); - value = getQuotedAttributeValue(tokenizer, '\'') || getQuotedAttributeValue(tokenizer, '"') || getUnquotedAttributeValue(tokenizer); - if (value === null) { - tokenizer.pos = start; - return null; - } - return value; - }; - getUnquotedAttributeValueText = makeRegexMatcher(/^[^\s"'=<>`]+/); - getUnquotedAttributeValueToken = function (tokenizer) { - var start, text, index; - start = tokenizer.pos; - text = getUnquotedAttributeValueText(tokenizer); - if (!text) { - return null; - } - if ((index = text.indexOf(tokenizer.delimiters[0])) !== -1) { - text = text.substr(0, index); - tokenizer.pos = start + text.length; - } - return { - type: types.TEXT, - value: text - }; - }; - getUnquotedAttributeValue = function (tokenizer) { - var tokens, token; - tokens = []; - token = tokenizer.getMustache() || getUnquotedAttributeValueToken(tokenizer); - while (token !== null) { - tokens[tokens.length] = token; - token = tokenizer.getMustache() || getUnquotedAttributeValueToken(tokenizer); - } - if (!tokens.length) { - return null; - } - return tokens; - }; - getQuotedAttributeValue = function (tokenizer, quoteMark) { - var start, tokens, token; - start = tokenizer.pos; - if (!tokenizer.getStringMatch(quoteMark)) { - return null; - } - tokens = []; - token = tokenizer.getMustache() || getQuotedStringToken(tokenizer, quoteMark); - while (token !== null) { - tokens[tokens.length] = token; - token = tokenizer.getMustache() || getQuotedStringToken(tokenizer, quoteMark); - } - if (!tokenizer.getStringMatch(quoteMark)) { - tokenizer.pos = start; - return null; - } - return tokens; - }; - getQuotedStringToken = function (tokenizer, quoteMark) { - var start, index, remaining; - start = tokenizer.pos; - remaining = tokenizer.remaining(); - index = getLowestIndex(remaining, [ - quoteMark, - tokenizer.delimiters[0], - tokenizer.delimiters[1] - ]); - if (index === -1) { - throw new Error('Quoted attribute value must have a closing quote'); - } - if (!index) { - return null; - } - tokenizer.pos += index; - return { - type: types.TEXT, - value: remaining.substr(0, index) - }; - }; - return getTag; - }(config_types, parse_Tokenizer_utils_makeRegexMatcher, parse_Tokenizer_utils_getLowestIndex); -var parse_Tokenizer_getText__getText = function (types, getLowestIndex) { - - return function () { - var index, remaining, barrier; - remaining = this.remaining(); - barrier = this.inside ? '> >>> < <= > >= in instanceof == != === !== & ^ | && ||'.split(' '); - fallthrough = getTypeOf; - for (i = 0, len = infixOperators.length; i < len; i += 1) { - matcher = makeInfixSequenceMatcher(infixOperators[i], fallthrough); - fallthrough = matcher; - } - getLogicalOr = fallthrough; - }()); - return getLogicalOr; - }(config_types, parse_Tokenizer_getExpression_getTypeOf); -var parse_Tokenizer_getExpression_getConditional = function (types, getLogicalOr) { - - return function (tokenizer) { - var start, expression, ifTrue, ifFalse; - expression = getLogicalOr(tokenizer); - if (!expression) { - return null; - } - start = tokenizer.pos; - tokenizer.allowWhitespace(); - if (!tokenizer.getStringMatch('?')) { - tokenizer.pos = start; - return expression; - } - tokenizer.allowWhitespace(); - ifTrue = tokenizer.getExpression(); - if (!ifTrue) { - tokenizer.pos = start; - return expression; - } - tokenizer.allowWhitespace(); - if (!tokenizer.getStringMatch(':')) { - tokenizer.pos = start; - return expression; - } - tokenizer.allowWhitespace(); - ifFalse = tokenizer.getExpression(); - if (!ifFalse) { - tokenizer.pos = start; - return expression; - } - return { - t: types.CONDITIONAL, - o: [ - expression, - ifTrue, - ifFalse - ] - }; - }; - }(config_types, parse_Tokenizer_getExpression_getLogicalOr); -var parse_Tokenizer_getExpression__getExpression = function (getConditional) { - - return function () { - return getConditional(this); - }; - }(parse_Tokenizer_getExpression_getConditional); -var parse_Tokenizer__Tokenizer = function (getMustache, getComment, getTag, getText, getExpression, allowWhitespace, getStringMatch) { - - var Tokenizer; - Tokenizer = function (str, options) { - var token; - this.str = str; - this.pos = 0; - this.delimiters = options.delimiters; - this.tripleDelimiters = options.tripleDelimiters; - this.tokens = []; - while (this.pos < this.str.length) { - token = this.getToken(); - if (token === null && this.remaining()) { - this.fail(); - } - this.tokens.push(token); - } - }; - Tokenizer.prototype = { - getToken: function () { - var token = this.getMustache() || this.getComment() || this.getTag() || this.getText(); - return token; - }, - getMustache: getMustache, - getComment: getComment, - getTag: getTag, - getText: getText, - getExpression: getExpression, - allowWhitespace: allowWhitespace, - getStringMatch: getStringMatch, - remaining: function () { - return this.str.substring(this.pos); - }, - fail: function () { - var last20, next20; - last20 = this.str.substr(0, this.pos).substr(-20); - if (last20.length === 20) { - last20 = '...' + last20; - } - next20 = this.remaining().substr(0, 20); - if (next20.length === 20) { - next20 = next20 + '...'; - } - throw new Error('Could not parse template: ' + (last20 ? last20 + '<- ' : '') + 'failed at character ' + this.pos + ' ->' + next20); - }, - expected: function (thing) { - var remaining = this.remaining().substr(0, 40); - if (remaining.length === 40) { - remaining += '...'; - } - throw new Error('Tokenizer failed: unexpected string "' + remaining + '" (expected ' + thing + ')'); - } - }; - return Tokenizer; - }(parse_Tokenizer_getMustache__getMustache, parse_Tokenizer_getComment_getComment, parse_Tokenizer_getTag__getTag, parse_Tokenizer_getText__getText, parse_Tokenizer_getExpression__getExpression, parse_Tokenizer_utils_allowWhitespace, parse_Tokenizer_utils_getStringMatch); -var parse_tokenize = function (stripHtmlComments, stripStandalones, stripCommentTokens, Tokenizer, circular) { - - var tokenize, Ractive; - circular.push(function () { - Ractive = circular.Ractive; - }); - tokenize = function (template, options) { - var tokenizer, tokens; - options = options || {}; - if (options.stripComments !== false) { - template = stripHtmlComments(template); - } - tokenizer = new Tokenizer(template, { - delimiters: options.delimiters || (Ractive ? Ractive.delimiters : [ - '{{', - '}}' - ]), - tripleDelimiters: options.tripleDelimiters || (Ractive ? Ractive.tripleDelimiters : [ - '{{{', - '}}}' - ]) - }); - tokens = tokenizer.tokens; - stripStandalones(tokens); - stripCommentTokens(tokens); - return tokens; - }; - return tokenize; - }(parse_utils_stripHtmlComments, parse_utils_stripStandalones, parse_utils_stripCommentTokens, parse_Tokenizer__Tokenizer, circular); -var parse_Parser_getText_TextStub__TextStub = function (types) { - - var TextStub, htmlEntities, controlCharacters, namedEntityPattern, hexEntityPattern, decimalEntityPattern, validateCode, decodeCharacterReferences, whitespace; - TextStub = function (token, preserveWhitespace) { - this.text = preserveWhitespace ? token.value : token.value.replace(whitespace, ' '); - }; - TextStub.prototype = { - type: types.TEXT, - toJSON: function () { - return this.decoded || (this.decoded = decodeCharacterReferences(this.text)); - }, - toString: function () { - return this.text; - } - }; - htmlEntities = { - quot: 34, - amp: 38, - apos: 39, - lt: 60, - gt: 62, - nbsp: 160, - iexcl: 161, - cent: 162, - pound: 163, - curren: 164, - yen: 165, - brvbar: 166, - sect: 167, - uml: 168, - copy: 169, - ordf: 170, - laquo: 171, - not: 172, - shy: 173, - reg: 174, - macr: 175, - deg: 176, - plusmn: 177, - sup2: 178, - sup3: 179, - acute: 180, - micro: 181, - para: 182, - middot: 183, - cedil: 184, - sup1: 185, - ordm: 186, - raquo: 187, - frac14: 188, - frac12: 189, - frac34: 190, - iquest: 191, - Agrave: 192, - Aacute: 193, - Acirc: 194, - Atilde: 195, - Auml: 196, - Aring: 197, - AElig: 198, - Ccedil: 199, - Egrave: 200, - Eacute: 201, - Ecirc: 202, - Euml: 203, - Igrave: 204, - Iacute: 205, - Icirc: 206, - Iuml: 207, - ETH: 208, - Ntilde: 209, - Ograve: 210, - Oacute: 211, - Ocirc: 212, - Otilde: 213, - Ouml: 214, - times: 215, - Oslash: 216, - Ugrave: 217, - Uacute: 218, - Ucirc: 219, - Uuml: 220, - Yacute: 221, - THORN: 222, - szlig: 223, - agrave: 224, - aacute: 225, - acirc: 226, - atilde: 227, - auml: 228, - aring: 229, - aelig: 230, - ccedil: 231, - egrave: 232, - eacute: 233, - ecirc: 234, - euml: 235, - igrave: 236, - iacute: 237, - icirc: 238, - iuml: 239, - eth: 240, - ntilde: 241, - ograve: 242, - oacute: 243, - ocirc: 244, - otilde: 245, - ouml: 246, - divide: 247, - oslash: 248, - ugrave: 249, - uacute: 250, - ucirc: 251, - uuml: 252, - yacute: 253, - thorn: 254, - yuml: 255, - OElig: 338, - oelig: 339, - Scaron: 352, - scaron: 353, - Yuml: 376, - fnof: 402, - circ: 710, - tilde: 732, - Alpha: 913, - Beta: 914, - Gamma: 915, - Delta: 916, - Epsilon: 917, - Zeta: 918, - Eta: 919, - Theta: 920, - Iota: 921, - Kappa: 922, - Lambda: 923, - Mu: 924, - Nu: 925, - Xi: 926, - Omicron: 927, - Pi: 928, - Rho: 929, - Sigma: 931, - Tau: 932, - Upsilon: 933, - Phi: 934, - Chi: 935, - Psi: 936, - Omega: 937, - alpha: 945, - beta: 946, - gamma: 947, - delta: 948, - epsilon: 949, - zeta: 950, - eta: 951, - theta: 952, - iota: 953, - kappa: 954, - lambda: 955, - mu: 956, - nu: 957, - xi: 958, - omicron: 959, - pi: 960, - rho: 961, - sigmaf: 962, - sigma: 963, - tau: 964, - upsilon: 965, - phi: 966, - chi: 967, - psi: 968, - omega: 969, - thetasym: 977, - upsih: 978, - piv: 982, - ensp: 8194, - emsp: 8195, - thinsp: 8201, - zwnj: 8204, - zwj: 8205, - lrm: 8206, - rlm: 8207, - ndash: 8211, - mdash: 8212, - lsquo: 8216, - rsquo: 8217, - sbquo: 8218, - ldquo: 8220, - rdquo: 8221, - bdquo: 8222, - dagger: 8224, - Dagger: 8225, - bull: 8226, - hellip: 8230, - permil: 8240, - prime: 8242, - Prime: 8243, - lsaquo: 8249, - rsaquo: 8250, - oline: 8254, - frasl: 8260, - euro: 8364, - image: 8465, - weierp: 8472, - real: 8476, - trade: 8482, - alefsym: 8501, - larr: 8592, - uarr: 8593, - rarr: 8594, - darr: 8595, - harr: 8596, - crarr: 8629, - lArr: 8656, - uArr: 8657, - rArr: 8658, - dArr: 8659, - hArr: 8660, - forall: 8704, - part: 8706, - exist: 8707, - empty: 8709, - nabla: 8711, - isin: 8712, - notin: 8713, - ni: 8715, - prod: 8719, - sum: 8721, - minus: 8722, - lowast: 8727, - radic: 8730, - prop: 8733, - infin: 8734, - ang: 8736, - and: 8743, - or: 8744, - cap: 8745, - cup: 8746, - 'int': 8747, - there4: 8756, - sim: 8764, - cong: 8773, - asymp: 8776, - ne: 8800, - equiv: 8801, - le: 8804, - ge: 8805, - sub: 8834, - sup: 8835, - nsub: 8836, - sube: 8838, - supe: 8839, - oplus: 8853, - otimes: 8855, - perp: 8869, - sdot: 8901, - lceil: 8968, - rceil: 8969, - lfloor: 8970, - rfloor: 8971, - lang: 9001, - rang: 9002, - loz: 9674, - spades: 9824, - clubs: 9827, - hearts: 9829, - diams: 9830 - }; - controlCharacters = [ - 8364, - 129, - 8218, - 402, - 8222, - 8230, - 8224, - 8225, - 710, - 8240, - 352, - 8249, - 338, - 141, - 381, - 143, - 144, - 8216, - 8217, - 8220, - 8221, - 8226, - 8211, - 8212, - 732, - 8482, - 353, - 8250, - 339, - 157, - 382, - 376 - ]; - namedEntityPattern = new RegExp('&(' + Object.keys(htmlEntities).join('|') + ');?', 'g'); - hexEntityPattern = /&#x([0-9]+);?/g; - decimalEntityPattern = /&#([0-9]+);?/g; - validateCode = function (code) { - if (!code) { - return 65533; - } - if (code === 10) { - return 32; - } - if (code < 128) { - return code; - } - if (code <= 159) { - return controlCharacters[code - 128]; - } - if (code < 55296) { - return code; - } - if (code <= 57343) { - return 65533; - } - if (code <= 65535) { - return code; - } - return 65533; - }; - decodeCharacterReferences = function (html) { - var result; - result = html.replace(namedEntityPattern, function (match, name) { - if (htmlEntities[name]) { - return String.fromCharCode(htmlEntities[name]); - } - return match; - }); - result = result.replace(hexEntityPattern, function (match, hex) { - return String.fromCharCode(validateCode(parseInt(hex, 16))); - }); - result = result.replace(decimalEntityPattern, function (match, charCode) { - return String.fromCharCode(validateCode(charCode)); - }); - return result; - }; - whitespace = /\s+/g; - return TextStub; - }(config_types); -var parse_Parser_getText__getText = function (types, TextStub) { - - return function (token) { - if (token.type === types.TEXT) { - this.pos += 1; - return new TextStub(token, this.preserveWhitespace); - } - return null; - }; - }(config_types, parse_Parser_getText_TextStub__TextStub); -var parse_Parser_getComment_CommentStub__CommentStub = function (types) { - - var CommentStub; - CommentStub = function (token) { - this.content = token.content; - }; - CommentStub.prototype = { - toJSON: function () { - return { - t: types.COMMENT, - f: this.content - }; - }, - toString: function () { - return ''; - } - }; - return CommentStub; - }(config_types); -var parse_Parser_getComment__getComment = function (types, CommentStub) { - - return function (token) { - if (token.type === types.COMMENT) { - this.pos += 1; - return new CommentStub(token, this.preserveWhitespace); - } - return null; - }; - }(config_types, parse_Parser_getComment_CommentStub__CommentStub); -var parse_Parser_getMustache_ExpressionStub__ExpressionStub = function (types, isObject) { - - var ExpressionStub, getRefs, stringify; - ExpressionStub = function (token) { - this.refs = []; - getRefs(token, this.refs); - this.str = stringify(token, this.refs); - }; - ExpressionStub.prototype = { - toJSON: function () { - if (this.json) { - return this.json; - } - this.json = { - r: this.refs, - s: this.str - }; - return this.json; - } - }; - getRefs = function (token, refs) { - var i, list; - if (token.t === types.REFERENCE) { - if (refs.indexOf(token.n) === -1) { - refs.unshift(token.n); - } - } - list = token.o || token.m; - if (list) { - if (isObject(list)) { - getRefs(list, refs); - } else { - i = list.length; - while (i--) { - getRefs(list[i], refs); - } - } - } - if (token.x) { - getRefs(token.x, refs); - } - if (token.r) { - getRefs(token.r, refs); - } - if (token.v) { - getRefs(token.v, refs); - } - }; - stringify = function (token, refs) { - var map = function (item) { - return stringify(item, refs); - }; - switch (token.t) { - case types.BOOLEAN_LITERAL: - case types.GLOBAL: - case types.NUMBER_LITERAL: - return token.v; - case types.STRING_LITERAL: - return '\'' + token.v.replace(/'/g, '\\\'') + '\''; - case types.ARRAY_LITERAL: - return '[' + (token.m ? token.m.map(map).join(',') : '') + ']'; - case types.OBJECT_LITERAL: - return '{' + (token.m ? token.m.map(map).join(',') : '') + '}'; - case types.KEY_VALUE_PAIR: - return token.k + ':' + stringify(token.v, refs); - case types.PREFIX_OPERATOR: - return (token.s === 'typeof' ? 'typeof ' : token.s) + stringify(token.o, refs); - case types.INFIX_OPERATOR: - return stringify(token.o[0], refs) + (token.s.substr(0, 2) === 'in' ? ' ' + token.s + ' ' : token.s) + stringify(token.o[1], refs); - case types.INVOCATION: - return stringify(token.x, refs) + '(' + (token.o ? token.o.map(map).join(',') : '') + ')'; - case types.BRACKETED: - return '(' + stringify(token.x, refs) + ')'; - case types.MEMBER: - return stringify(token.x, refs) + stringify(token.r, refs); - case types.REFINEMENT: - return token.n ? '.' + token.n : '[' + stringify(token.x, refs) + ']'; - case types.CONDITIONAL: - return stringify(token.o[0], refs) + '?' + stringify(token.o[1], refs) + ':' + stringify(token.o[2], refs); - case types.REFERENCE: - return '${' + refs.indexOf(token.n) + '}'; - default: - throw new Error('Could not stringify expression token. This error is unexpected'); - } - }; - return ExpressionStub; - }(config_types, utils_isObject); -var parse_Parser_getMustache_MustacheStub__MustacheStub = function (types, ExpressionStub) { - - var MustacheStub = function (token, parser) { - this.type = token.type === types.TRIPLE ? types.TRIPLE : token.mustacheType; - if (token.ref) { - this.ref = token.ref; - } - if (token.expression) { - this.expr = new ExpressionStub(token.expression); - } - parser.pos += 1; - }; - MustacheStub.prototype = { - toJSON: function () { - var json; - if (this.json) { - return this.json; - } - json = { t: this.type }; - if (this.ref) { - json.r = this.ref; - } - if (this.expr) { - json.x = this.expr.toJSON(); - } - this.json = json; - return json; - }, - toString: function () { - return false; - } - }; - return MustacheStub; - }(config_types, parse_Parser_getMustache_ExpressionStub__ExpressionStub); -var parse_Parser_utils_stringifyStubs = function () { - - return function (items) { - var str = '', itemStr, i, len; - if (!items) { - return ''; - } - for (i = 0, len = items.length; i < len; i += 1) { - itemStr = items[i].toString(); - if (itemStr === false) { - return false; - } - str += itemStr; - } - return str; - }; - }(); -var parse_Parser_utils_jsonifyStubs = function (stringifyStubs) { - - return function (items, noStringify) { - var str, json; - if (!noStringify) { - str = stringifyStubs(items); - if (str !== false) { - return str; - } - } - json = items.map(function (item) { - return item.toJSON(noStringify); - }); - return json; - }; - }(parse_Parser_utils_stringifyStubs); -var parse_Parser_getMustache_SectionStub__SectionStub = function (types, jsonifyStubs, ExpressionStub) { - - var SectionStub = function (firstToken, parser) { - var next; - this.ref = firstToken.ref; - this.indexRef = firstToken.indexRef; - this.inverted = firstToken.mustacheType === types.INVERTED; - if (firstToken.expression) { - this.expr = new ExpressionStub(firstToken.expression); - } - parser.pos += 1; - this.items = []; - next = parser.next(); - while (next) { - if (next.mustacheType === types.CLOSING) { - if (next.ref.trim() === this.ref || this.expr) { - parser.pos += 1; - break; - } else { - throw new Error('Could not parse template: Illegal closing section'); - } - } - this.items[this.items.length] = parser.getStub(); - next = parser.next(); - } - }; - SectionStub.prototype = { - toJSON: function (noStringify) { - var json; - if (this.json) { - return this.json; - } - json = { t: types.SECTION }; - if (this.ref) { - json.r = this.ref; - } - if (this.indexRef) { - json.i = this.indexRef; - } - if (this.inverted) { - json.n = true; - } - if (this.expr) { - json.x = this.expr.toJSON(); - } - if (this.items.length) { - json.f = jsonifyStubs(this.items, noStringify); - } - this.json = json; - return json; - }, - toString: function () { - return false; - } - }; - return SectionStub; - }(config_types, parse_Parser_utils_jsonifyStubs, parse_Parser_getMustache_ExpressionStub__ExpressionStub); -var parse_Parser_getMustache__getMustache = function (types, MustacheStub, SectionStub) { - - return function (token) { - if (token.type === types.MUSTACHE || token.type === types.TRIPLE) { - if (token.mustacheType === types.SECTION || token.mustacheType === types.INVERTED) { - return new SectionStub(token, this); - } - return new MustacheStub(token, this); - } - }; - }(config_types, parse_Parser_getMustache_MustacheStub__MustacheStub, parse_Parser_getMustache_SectionStub__SectionStub); -var parse_Parser_getElement_ElementStub_utils_siblingsByTagName = function () { - - return { - li: ['li'], - dt: [ - 'dt', - 'dd' - ], - dd: [ - 'dt', - 'dd' - ], - p: 'address article aside blockquote dir div dl fieldset footer form h1 h2 h3 h4 h5 h6 header hgroup hr menu nav ol p pre section table ul'.split(' '), - rt: [ - 'rt', - 'rp' - ], - rp: [ - 'rp', - 'rt' - ], - optgroup: ['optgroup'], - option: [ - 'option', - 'optgroup' - ], - thead: [ - 'tbody', - 'tfoot' - ], - tbody: [ - 'tbody', - 'tfoot' - ], - tr: ['tr'], - td: [ - 'td', - 'th' - ], - th: [ - 'td', - 'th' - ] - }; - }(); -var parse_Parser_getElement_ElementStub_utils_filterAttributes = function (isArray) { - - return function (items) { - var attrs, proxies, filtered, i, len, item; - filtered = {}; - attrs = []; - proxies = []; - len = items.length; - for (i = 0; i < len; i += 1) { - item = items[i]; - if (item.name === 'intro') { - if (filtered.intro) { - throw new Error('An element can only have one intro transition'); - } - filtered.intro = item; - } else if (item.name === 'outro') { - if (filtered.outro) { - throw new Error('An element can only have one outro transition'); - } - filtered.outro = item; - } else if (item.name === 'intro-outro') { - if (filtered.intro || filtered.outro) { - throw new Error('An element can only have one intro and one outro transition'); - } - filtered.intro = item; - filtered.outro = deepClone(item); - } else if (item.name.substr(0, 6) === 'proxy-') { - item.name = item.name.substring(6); - proxies[proxies.length] = item; - } else if (item.name.substr(0, 3) === 'on-') { - item.name = item.name.substring(3); - proxies[proxies.length] = item; - } else if (item.name === 'decorator') { - filtered.decorator = item; - } else { - attrs[attrs.length] = item; - } - } - filtered.attrs = attrs; - filtered.proxies = proxies; - return filtered; - }; - function deepClone(obj) { - var result, key; - if (typeof obj !== 'object') { - return obj; - } - if (isArray(obj)) { - return obj.map(deepClone); - } - result = {}; - for (key in obj) { - if (obj.hasOwnProperty(key)) { - result[key] = deepClone(obj[key]); - } - } - return result; - } - }(utils_isArray); -var parse_Parser_getElement_ElementStub_utils_processDirective = function (types, parseJSON) { - - return function (directive) { - var processed, tokens, token, colonIndex, throwError, directiveName, directiveArgs, parsed; - throwError = function () { - throw new Error('Illegal directive'); - }; - if (!directive.name || !directive.value) { - throwError(); - } - processed = { directiveType: directive.name }; - tokens = directive.value; - directiveName = []; - directiveArgs = []; - while (tokens.length) { - token = tokens.shift(); - if (token.type === types.TEXT) { - colonIndex = token.value.indexOf(':'); - if (colonIndex === -1) { - directiveName[directiveName.length] = token; - } else { - if (colonIndex) { - directiveName[directiveName.length] = { - type: types.TEXT, - value: token.value.substr(0, colonIndex) - }; - } - if (token.value.length > colonIndex + 1) { - directiveArgs[0] = { - type: types.TEXT, - value: token.value.substring(colonIndex + 1) - }; - } - break; - } - } else { - directiveName[directiveName.length] = token; - } - } - directiveArgs = directiveArgs.concat(tokens); - if (directiveName.length === 1 && directiveName[0].type === types.TEXT) { - processed.name = directiveName[0].value; - } else { - processed.name = directiveName; - } - if (directiveArgs.length) { - if (directiveArgs.length === 1 && directiveArgs[0].type === types.TEXT) { - parsed = parseJSON('[' + directiveArgs[0].value + ']'); - processed.args = parsed ? parsed.value : directiveArgs[0].value; - } else { - processed.dynamicArgs = directiveArgs; - } - } - return processed; - }; - }(config_types, utils_parseJSON); -var parse_Parser_StringStub_StringParser = function (getText, getMustache) { - - var StringParser; - StringParser = function (tokens, options) { - var stub; - this.tokens = tokens || []; - this.pos = 0; - this.options = options; - this.result = []; - while (stub = this.getStub()) { - this.result.push(stub); - } - }; - StringParser.prototype = { - getStub: function () { - var token = this.next(); - if (!token) { - return null; - } - return this.getText(token) || this.getMustache(token); - }, - getText: getText, - getMustache: getMustache, - next: function () { - return this.tokens[this.pos]; - } - }; - return StringParser; - }(parse_Parser_getText__getText, parse_Parser_getMustache__getMustache); -var parse_Parser_StringStub__StringStub = function (StringParser, stringifyStubs, jsonifyStubs) { - - var StringStub; - StringStub = function (tokens) { - var parser = new StringParser(tokens); - this.stubs = parser.result; - }; - StringStub.prototype = { - toJSON: function (noStringify) { - var json; - if (this['json_' + noStringify]) { - return this['json_' + noStringify]; - } - json = this['json_' + noStringify] = jsonifyStubs(this.stubs, noStringify); - return json; - }, - toString: function () { - if (this.str !== undefined) { - return this.str; - } - this.str = stringifyStubs(this.stubs); - return this.str; - } - }; - return StringStub; - }(parse_Parser_StringStub_StringParser, parse_Parser_utils_stringifyStubs, parse_Parser_utils_jsonifyStubs); -var parse_Parser_getElement_ElementStub_utils_jsonifyDirective = function (StringStub) { - - return function (directive) { - var result, name; - if (typeof directive.name === 'string') { - if (!directive.args && !directive.dynamicArgs) { - return directive.name; - } - name = directive.name; - } else { - name = new StringStub(directive.name).toJSON(); - } - result = { n: name }; - if (directive.args) { - result.a = directive.args; - return result; - } - if (directive.dynamicArgs) { - result.d = new StringStub(directive.dynamicArgs).toJSON(); - } - return result; - }; - }(parse_Parser_StringStub__StringStub); -var parse_Parser_getElement_ElementStub_toJSON = function (types, jsonifyStubs, jsonifyDirective) { - - return function (noStringify) { - var json, name, value, proxy, i, len, attribute; - if (this['json_' + noStringify]) { - return this['json_' + noStringify]; - } - if (this.component) { - json = { - t: types.COMPONENT, - e: this.component - }; - } else { - json = { - t: types.ELEMENT, - e: this.tag - }; - } - if (this.doctype) { - json.y = 1; - } - if (this.attributes && this.attributes.length) { - json.a = {}; - len = this.attributes.length; - for (i = 0; i < len; i += 1) { - attribute = this.attributes[i]; - name = attribute.name; - if (json.a[name]) { - throw new Error('You cannot have multiple attributes with the same name'); - } - if (attribute.value === null) { - value = null; - } else { - value = attribute.value.toJSON(noStringify); - } - json.a[name] = value; - } - } - if (this.items && this.items.length) { - json.f = jsonifyStubs(this.items, noStringify); - } - if (this.proxies && this.proxies.length) { - json.v = {}; - len = this.proxies.length; - for (i = 0; i < len; i += 1) { - proxy = this.proxies[i]; - json.v[proxy.directiveType] = jsonifyDirective(proxy); - } - } - if (this.intro) { - json.t1 = jsonifyDirective(this.intro); - } - if (this.outro) { - json.t2 = jsonifyDirective(this.outro); - } - if (this.decorator) { - json.o = jsonifyDirective(this.decorator); - } - this['json_' + noStringify] = json; - return json; - }; - }(config_types, parse_Parser_utils_jsonifyStubs, parse_Parser_getElement_ElementStub_utils_jsonifyDirective); -var parse_Parser_getElement_ElementStub_toString = function (stringifyStubs, voidElementNames) { - - var htmlElements; - htmlElements = 'a abbr acronym address applet area b base basefont bdo big blockquote body br button caption center cite code col colgroup dd del dfn dir div dl dt em fieldset font form frame frameset h1 h2 h3 h4 h5 h6 head hr html i iframe img input ins isindex kbd label legend li link map menu meta noframes noscript object ol p param pre q s samp script select small span strike strong style sub sup textarea title tt u ul var article aside audio bdi canvas command data datagrid datalist details embed eventsource figcaption figure footer header hgroup keygen mark meter nav output progress ruby rp rt section source summary time track video wbr'.split(' '); - return function () { - var str, i, len, attrStr, name, attrValueStr, fragStr, isVoid; - if (this.str !== undefined) { - return this.str; - } - if (this.component) { - return this.str = false; - } - if (htmlElements.indexOf(this.tag.toLowerCase()) === -1) { - return this.str = false; - } - if (this.proxies || this.intro || this.outro || this.decorator) { - return this.str = false; - } - fragStr = stringifyStubs(this.items); - if (fragStr === false) { - return this.str = false; - } - isVoid = voidElementNames.indexOf(this.tag.toLowerCase()) !== -1; - str = '<' + this.tag; - if (this.attributes) { - for (i = 0, len = this.attributes.length; i < len; i += 1) { - name = this.attributes[i].name; - if (name.indexOf(':') !== -1) { - return this.str = false; - } - if (name === 'id' || name === 'intro' || name === 'outro') { - return this.str = false; - } - attrStr = ' ' + name; - if (this.attributes[i].value !== null) { - attrValueStr = this.attributes[i].value.toString(); - if (attrValueStr === false) { - return this.str = false; - } - if (attrValueStr !== '') { - attrStr += '='; - if (/[\s"'=<>`]/.test(attrValueStr)) { - attrStr += '"' + attrValueStr.replace(/"/g, '"') + '"'; - } else { - attrStr += attrValueStr; - } - } - } - str += attrStr; - } - } - if (this.selfClosing && !isVoid) { - str += '/>'; - return this.str = str; - } - str += '>'; - if (isVoid) { - return this.str = str; - } - str += fragStr; - str += ''; - return this.str = str; - }; - }(parse_Parser_utils_stringifyStubs, config_voidElementNames); -var parse_Parser_getElement_ElementStub__ElementStub = function (types, voidElementNames, warn, camelCase, stringifyStubs, siblingsByTagName, filterAttributes, processDirective, toJSON, toString, StringStub) { - - var ElementStub, allElementNames, closedByParentClose, onPattern, sanitize, leadingWhitespace = /^\s+/, trailingWhitespace = /\s+$/; - ElementStub = function (firstToken, parser, preserveWhitespace) { - var next, attrs, filtered, proxies, item, getFrag, lowerCaseTag; - parser.pos += 1; - getFrag = function (attr) { - return { - name: attr.name, - value: attr.value ? new StringStub(attr.value) : null - }; - }; - this.tag = firstToken.name; - lowerCaseTag = firstToken.name.toLowerCase(); - if (lowerCaseTag.substr(0, 3) === 'rv-') { - warn('The "rv-" prefix for components has been deprecated. Support will be removed in a future version'); - this.tag = this.tag.substring(3); - } - preserveWhitespace = preserveWhitespace || lowerCaseTag === 'pre'; - if (firstToken.attrs) { - filtered = filterAttributes(firstToken.attrs); - attrs = filtered.attrs; - proxies = filtered.proxies; - if (parser.options.sanitize && parser.options.sanitize.eventAttributes) { - attrs = attrs.filter(sanitize); - } - if (attrs.length) { - this.attributes = attrs.map(getFrag); - } - if (proxies.length) { - this.proxies = proxies.map(processDirective); - } - if (filtered.intro) { - this.intro = processDirective(filtered.intro); - } - if (filtered.outro) { - this.outro = processDirective(filtered.outro); - } - if (filtered.decorator) { - this.decorator = processDirective(filtered.decorator); - } - } - if (firstToken.doctype) { - this.doctype = true; - } - if (firstToken.selfClosing) { - this.selfClosing = true; - } - if (voidElementNames.indexOf(lowerCaseTag) !== -1) { - this.isVoid = true; - } - if (this.selfClosing || this.isVoid) { - return; - } - this.siblings = siblingsByTagName[lowerCaseTag]; - this.items = []; - next = parser.next(); - while (next) { - if (next.mustacheType === types.CLOSING) { - break; - } - if (next.type === types.TAG) { - if (next.closing) { - if (next.name.toLowerCase() === lowerCaseTag) { - parser.pos += 1; - } - break; - } else if (this.siblings && this.siblings.indexOf(next.name.toLowerCase()) !== -1) { - break; - } - } - this.items[this.items.length] = parser.getStub(); - next = parser.next(); - } - if (!preserveWhitespace) { - item = this.items[0]; - if (item && item.type === types.TEXT) { - item.text = item.text.replace(leadingWhitespace, ''); - if (!item.text) { - this.items.shift(); - } - } - item = this.items[this.items.length - 1]; - if (item && item.type === types.TEXT) { - item.text = item.text.replace(trailingWhitespace, ''); - if (!item.text) { - this.items.pop(); - } - } - } - }; - ElementStub.prototype = { - toJSON: toJSON, - toString: toString - }; - allElementNames = 'a abbr acronym address applet area b base basefont bdo big blockquote body br button caption center cite code col colgroup dd del dfn dir div dl dt em fieldset font form frame frameset h1 h2 h3 h4 h5 h6 head hr html i iframe img input ins isindex kbd label legend li link map menu meta noframes noscript object ol p param pre q s samp script select small span strike strong style sub sup textarea title tt u ul var article aside audio bdi canvas command data datagrid datalist details embed eventsource figcaption figure footer header hgroup keygen mark meter nav output progress ruby rp rt section source summary time track video wbr'.split(' '); - closedByParentClose = 'li dd rt rp optgroup option tbody tfoot tr td th'.split(' '); - onPattern = /^on[a-zA-Z]/; - sanitize = function (attr) { - var valid = !onPattern.test(attr.name); - return valid; - }; - return ElementStub; - }(config_types, config_voidElementNames, utils_warn, utils_camelCase, parse_Parser_utils_stringifyStubs, parse_Parser_getElement_ElementStub_utils_siblingsByTagName, parse_Parser_getElement_ElementStub_utils_filterAttributes, parse_Parser_getElement_ElementStub_utils_processDirective, parse_Parser_getElement_ElementStub_toJSON, parse_Parser_getElement_ElementStub_toString, parse_Parser_StringStub__StringStub); -var parse_Parser_getElement__getElement = function (types, ElementStub) { - - return function (token) { - if (this.options.sanitize && this.options.sanitize.elements) { - if (this.options.sanitize.elements.indexOf(token.name.toLowerCase()) !== -1) { - return null; - } - } - return new ElementStub(token, this); - }; - }(config_types, parse_Parser_getElement_ElementStub__ElementStub); -var parse_Parser__Parser = function (getText, getComment, getMustache, getElement, jsonifyStubs) { - - var Parser; - Parser = function (tokens, options) { - var stub, stubs; - this.tokens = tokens || []; - this.pos = 0; - this.options = options; - this.preserveWhitespace = options.preserveWhitespace; - stubs = []; - while (stub = this.getStub()) { - stubs.push(stub); - } - this.result = jsonifyStubs(stubs); - }; - Parser.prototype = { - getStub: function () { - var token = this.next(); - if (!token) { - return null; - } - return this.getText(token) || this.getComment(token) || this.getMustache(token) || this.getElement(token); - }, - getText: getText, - getComment: getComment, - getMustache: getMustache, - getElement: getElement, - next: function () { - return this.tokens[this.pos]; - } - }; - return Parser; - }(parse_Parser_getText__getText, parse_Parser_getComment__getComment, parse_Parser_getMustache__getMustache, parse_Parser_getElement__getElement, parse_Parser_utils_jsonifyStubs); -var parse__parse = function (tokenize, types, Parser) { - - var parse, onlyWhitespace, inlinePartialStart, inlinePartialEnd, parseCompoundTemplate; - onlyWhitespace = /^\s*$/; - inlinePartialStart = //; - inlinePartialEnd = //; - parse = function (template, options) { - var tokens, json, token; - options = options || {}; - if (inlinePartialStart.test(template)) { - return parseCompoundTemplate(template, options); - } - if (options.sanitize === true) { - options.sanitize = { - elements: 'applet base basefont body frame frameset head html isindex link meta noframes noscript object param script style title'.split(' '), - eventAttributes: true - }; - } - tokens = tokenize(template, options); - if (!options.preserveWhitespace) { - token = tokens[0]; - if (token && token.type === types.TEXT && onlyWhitespace.test(token.value)) { - tokens.shift(); - } - token = tokens[tokens.length - 1]; - if (token && token.type === types.TEXT && onlyWhitespace.test(token.value)) { - tokens.pop(); - } - } - json = new Parser(tokens, options).result; - if (typeof json === 'string') { - return [json]; - } - return json; - }; - parseCompoundTemplate = function (template, options) { - var mainTemplate, remaining, partials, name, startMatch, endMatch; - partials = {}; - mainTemplate = ''; - remaining = template; - while (startMatch = inlinePartialStart.exec(remaining)) { - name = startMatch[1]; - mainTemplate += remaining.substr(0, startMatch.index); - remaining = remaining.substring(startMatch.index + startMatch[0].length); - endMatch = inlinePartialEnd.exec(remaining); - if (!endMatch || endMatch[1] !== name) { - throw new Error('Inline partials must have a closing delimiter, and cannot be nested'); - } - partials[name] = parse(remaining.substr(0, endMatch.index), options); - remaining = remaining.substring(endMatch.index + endMatch[0].length); - } - return { - main: parse(mainTemplate, options), - partials: partials - }; - }; - return parse; - }(parse_tokenize, config_types, parse_Parser__Parser); -var render_DomFragment_Partial_getPartialDescriptor = function (errors, isClient, warn, isObject, partials, parse) { - - var getPartialDescriptor, registerPartial, getPartialFromRegistry, unpack; - getPartialDescriptor = function (root, name) { - var el, partial, errorMessage; - if (partial = getPartialFromRegistry(root, name)) { - return partial; - } - if (isClient) { - el = document.getElementById(name); - if (el && el.tagName === 'SCRIPT') { - if (!parse) { - throw new Error(errors.missingParser); - } - registerPartial(parse(el.innerHTML), name, partials); - } - } - partial = partials[name]; - if (!partial) { - errorMessage = 'Could not find descriptor for partial "' + name + '"'; - if (root.debug) { - throw new Error(errorMessage); - } else { - warn(errorMessage); - } - return []; - } - return unpack(partial); - }; - getPartialFromRegistry = function (registryOwner, name) { - var partial; - if (registryOwner.partials[name]) { - if (typeof registryOwner.partials[name] === 'string') { - if (!parse) { - throw new Error(errors.missingParser); - } - partial = parse(registryOwner.partials[name], registryOwner.parseOptions); - registerPartial(partial, name, registryOwner.partials); - } - return unpack(registryOwner.partials[name]); - } - }; - registerPartial = function (partial, name, registry) { - var key; - if (isObject(partial)) { - registry[name] = partial.main; - for (key in partial.partials) { - if (partial.partials.hasOwnProperty(key)) { - registry[key] = partial.partials[key]; - } - } - } else { - registry[name] = partial; - } - }; - unpack = function (partial) { - if (partial.length === 1 && typeof partial[0] === 'string') { - return partial[0]; - } - return partial; - }; - return getPartialDescriptor; - }(config_errors, config_isClient, utils_warn, utils_isObject, registries_partials, parse__parse); -var render_DomFragment_Partial__Partial = function (types, getPartialDescriptor, circular) { - - var DomPartial, DomFragment; - circular.push(function () { - DomFragment = circular.DomFragment; - }); - DomPartial = function (options, docFrag) { - var parentFragment = this.parentFragment = options.parentFragment, descriptor; - this.type = types.PARTIAL; - this.name = options.descriptor.r; - this.index = options.index; - if (!options.descriptor.r) { - throw new Error('Partials must have a static reference (no expressions). This may change in a future version of Ractive.'); - } - descriptor = getPartialDescriptor(parentFragment.root, options.descriptor.r); - this.fragment = new DomFragment({ - descriptor: descriptor, - root: parentFragment.root, - pNode: parentFragment.pNode, - contextStack: parentFragment.contextStack, - owner: this - }); - if (docFrag) { - docFrag.appendChild(this.fragment.docFrag); - } - }; - DomPartial.prototype = { - firstNode: function () { - return this.fragment.firstNode(); - }, - findNextNode: function () { - return this.parentFragment.findNextNode(this); - }, - detach: function () { - return this.fragment.detach(); - }, - teardown: function (destroy) { - this.fragment.teardown(destroy); - }, - toString: function () { - return this.fragment.toString(); - }, - find: function (selector) { - return this.fragment.find(selector); - }, - findAll: function (selector, query) { - return this.fragment.findAll(selector, query); - }, - findComponent: function (selector) { - return this.fragment.findComponent(selector); - }, - findAllComponents: function (selector, query) { - return this.fragment.findAllComponents(selector, query); - } - }; - return DomPartial; - }(config_types, render_DomFragment_Partial_getPartialDescriptor, circular); -var render_DomFragment_Component_initialise_createModel_ComponentParameter = function (StringFragment) { - - var ComponentParameter = function (component, key, value) { - this.parentFragment = component.parentFragment; - this.component = component; - this.key = key; - this.fragment = new StringFragment({ - descriptor: value, - root: component.root, - owner: this, - contextStack: component.parentFragment.contextStack - }); - this.selfUpdating = this.fragment.isSimple(); - this.value = this.fragment.getValue(); - }; - ComponentParameter.prototype = { - bubble: function () { - if (this.selfUpdating) { - this.update(); - } else if (!this.deferred && this.ready) { - this.root._deferred.attrs.push(this); - this.deferred = true; - } - }, - update: function () { - var value = this.fragment.getValue(); - this.component.instance.set(this.key, value); - this.value = value; - }, - teardown: function () { - this.fragment.teardown(); - } - }; - return ComponentParameter; - }(render_StringFragment__StringFragment); -var render_DomFragment_Component_initialise_createModel__createModel = function (types, parseJSON, resolveRef, ComponentParameter) { - - return function (component, attributes, toBind) { - var data, key, value; - data = {}; - component.complexParameters = []; - for (key in attributes) { - if (attributes.hasOwnProperty(key)) { - value = getValue(component, key, attributes[key], toBind); - if (value !== undefined) { - data[key] = value; - } - } - } - return data; - }; - function getValue(component, key, descriptor, toBind) { - var parameter, parsed, root, parentFragment, keypath; - root = component.root; - parentFragment = component.parentFragment; - if (typeof descriptor === 'string') { - parsed = parseJSON(descriptor); - return parsed ? parsed.value : descriptor; - } - if (descriptor === null) { - return true; - } - if (descriptor.length === 1 && descriptor[0].t === types.INTERPOLATOR && descriptor[0].r) { - if (parentFragment.indexRefs && parentFragment.indexRefs[descriptor[0].r] !== undefined) { - return parentFragment.indexRefs[descriptor[0].r]; - } - keypath = resolveRef(root, descriptor[0].r, parentFragment.contextStack) || descriptor[0].r; - toBind.push({ - childKeypath: key, - parentKeypath: keypath - }); - return root.get(keypath); - } - parameter = new ComponentParameter(component, key, descriptor); - component.complexParameters.push(parameter); - return parameter.value; - } - }(config_types, utils_parseJSON, shared_resolveRef, render_DomFragment_Component_initialise_createModel_ComponentParameter); -var render_DomFragment_Component_initialise_createInstance = function () { - - return function (component, Component, data, docFrag, contentDescriptor) { - var instance, parentFragment, partials, root; - parentFragment = component.parentFragment; - root = component.root; - partials = { content: contentDescriptor || [] }; - instance = new Component({ - el: parentFragment.pNode.cloneNode(false), - data: data, - partials: partials, - _parent: root, - adaptors: root.adaptors - }); - instance.component = component; - component.instance = instance; - instance.insert(docFrag); - instance.fragment.pNode = parentFragment.pNode; - return instance; - }; - }(); -var render_DomFragment_Component_initialise_createObservers = function () { - - var observeOptions = { - init: false, - debug: true - }; - return function (component, toBind) { - var pair, i; - component.observers = []; - i = toBind.length; - while (i--) { - pair = toBind[i]; - bind(component, pair.parentKeypath, pair.childKeypath); - } - }; - function bind(component, parentKeypath, childKeypath) { - var parentInstance, childInstance, settingParent, settingChild, observers, observer, value; - parentInstance = component.root; - childInstance = component.instance; - observers = component.observers; - observer = parentInstance.observe(parentKeypath, function (value) { - if (!settingParent && !parentInstance._wrapped[parentKeypath]) { - settingChild = true; - childInstance.set(childKeypath, value); - settingChild = false; - } - }, observeOptions); - observers.push(observer); - if (childInstance.twoway) { - observer = childInstance.observe(childKeypath, function (value) { - if (!settingChild) { - settingParent = true; - parentInstance.set(parentKeypath, value); - settingParent = false; - } - }, observeOptions); - observers.push(observer); - value = childInstance.get(childKeypath); - if (value !== undefined) { - parentInstance.set(parentKeypath, value); - } - } - } - }(); -var render_DomFragment_Component_initialise_propagateEvents = function (warn) { - - var errorMessage = 'Components currently only support simple events - you cannot include arguments. Sorry!'; - return function (component, eventsDescriptor) { - var eventName; - for (eventName in eventsDescriptor) { - if (eventsDescriptor.hasOwnProperty(eventName)) { - propagateEvent(component.instance, component.root, eventName, eventsDescriptor[eventName]); - } - } - }; - function propagateEvent(childInstance, parentInstance, eventName, proxyEventName) { - if (typeof proxyEventName !== 'string') { - if (parentInstance.debug) { - throw new Error(errorMessage); - } else { - warn(errorMessage); - return; - } - } - childInstance.on(eventName, function () { - var args = Array.prototype.slice.call(arguments); - args.unshift(proxyEventName); - parentInstance.fire.apply(parentInstance, args); - }); - } - }(utils_warn); -var render_DomFragment_Component_initialise_updateLiveQueries = function () { - - return function (component) { - var ancestor, query; - ancestor = component.root; - while (ancestor) { - if (query = ancestor._liveComponentQueries[component.name]) { - query.push(component.instance); - } - ancestor = ancestor._parent; - } - }; - }(); -var render_DomFragment_Component_initialise__initialise = function (types, warn, createModel, createInstance, createObservers, propagateEvents, updateLiveQueries) { - - return function (component, options, docFrag) { - var parentFragment, root, Component, data, toBind; - parentFragment = component.parentFragment = options.parentFragment; - root = parentFragment.root; - component.root = root; - component.type = types.COMPONENT; - component.name = options.descriptor.e; - component.index = options.index; - component.observers = []; - Component = root.components[options.descriptor.e]; - if (!Component) { - throw new Error('Component "' + options.descriptor.e + '" not found'); - } - toBind = []; - data = createModel(component, options.descriptor.a, toBind); - createInstance(component, Component, data, docFrag, options.descriptor.f); - createObservers(component, toBind); - propagateEvents(component, options.descriptor.v); - if (options.descriptor.t1 || options.descriptor.t2 || options.descriptor.o) { - warn('The "intro", "outro" and "decorator" directives have no effect on components'); - } - updateLiveQueries(component); - }; - }(config_types, utils_warn, render_DomFragment_Component_initialise_createModel__createModel, render_DomFragment_Component_initialise_createInstance, render_DomFragment_Component_initialise_createObservers, render_DomFragment_Component_initialise_propagateEvents, render_DomFragment_Component_initialise_updateLiveQueries); -var render_DomFragment_Component__Component = function (initialise) { - - var DomComponent = function (options, docFrag) { - initialise(this, options, docFrag); - }; - DomComponent.prototype = { - firstNode: function () { - return this.instance.fragment.firstNode(); - }, - findNextNode: function () { - return this.parentFragment.findNextNode(this); - }, - detach: function () { - return this.instance.fragment.detach(); - }, - teardown: function () { - var query; - while (this.complexParameters.length) { - this.complexParameters.pop().teardown(); - } - while (this.observers.length) { - this.observers.pop().cancel(); - } - if (query = this.root._liveComponentQueries[this.name]) { - query._remove(this); - } - this.instance.teardown(); - }, - toString: function () { - return this.instance.fragment.toString(); - }, - find: function (selector) { - return this.instance.fragment.find(selector); - }, - findAll: function (selector, query) { - return this.instance.fragment.findAll(selector, query); - }, - findComponent: function (selector) { - if (!selector || selector === this.name) { - return this.instance; - } - return null; - }, - findAllComponents: function (selector, query) { - query._test(this, true); - if (this.instance.fragment) { - this.instance.fragment.findAllComponents(selector, query); - } - } - }; - return DomComponent; - }(render_DomFragment_Component_initialise__initialise); -var render_DomFragment_Comment = function (types) { - - var DomComment = function (options, docFrag) { - this.type = types.COMMENT; - this.descriptor = options.descriptor; - if (docFrag) { - this.node = document.createComment(options.descriptor.f); - docFrag.appendChild(this.node); - } - }; - DomComment.prototype = { - detach: function () { - this.node.parentNode.removeChild(this.node); - return this.node; - }, - teardown: function (destroy) { - if (destroy) { - this.detach(); - } - }, - firstNode: function () { - return this.node; - }, - toString: function () { - return ''; - } - }; - return DomComment; - }(config_types); -var render_DomFragment__DomFragment = function (types, matches, initFragment, insertHtml, Text, Interpolator, Section, Triple, Element, Partial, Component, Comment, circular) { - - var DomFragment = function (options) { - if (options.pNode) { - this.docFrag = document.createDocumentFragment(); - } - if (typeof options.descriptor === 'string') { - this.html = options.descriptor; - if (this.docFrag) { - this.nodes = insertHtml(this.html, options.pNode.tagName, this.docFrag); - } - } else { - initFragment(this, options); - } - }; - DomFragment.prototype = { - detach: function () { - var len, i; - if (this.nodes) { - i = this.nodes.length; - while (i--) { - this.docFrag.appendChild(this.nodes[i]); - } - } else if (this.items) { - len = this.items.length; - for (i = 0; i < len; i += 1) { - this.docFrag.appendChild(this.items[i].detach()); - } - } - return this.docFrag; - }, - createItem: function (options) { - if (typeof options.descriptor === 'string') { - return new Text(options, this.docFrag); - } - switch (options.descriptor.t) { - case types.INTERPOLATOR: - return new Interpolator(options, this.docFrag); - case types.SECTION: - return new Section(options, this.docFrag); - case types.TRIPLE: - return new Triple(options, this.docFrag); - case types.ELEMENT: - if (this.root.components[options.descriptor.e]) { - return new Component(options, this.docFrag); - } - return new Element(options, this.docFrag); - case types.PARTIAL: - return new Partial(options, this.docFrag); - case types.COMMENT: - return new Comment(options, this.docFrag); - default: - throw new Error('Something very strange happened. Please file an issue at https://github.com/RactiveJS/Ractive/issues. Thanks!'); - } - }, - teardown: function (destroy) { - var node; - if (this.nodes && destroy) { - while (node = this.nodes.pop()) { - node.parentNode.removeChild(node); - } - } else if (this.items) { - while (this.items.length) { - this.items.pop().teardown(destroy); - } - } - this.nodes = this.items = this.docFrag = null; - }, - firstNode: function () { - if (this.items && this.items[0]) { - return this.items[0].firstNode(); - } else if (this.nodes) { - return this.nodes[0] || null; - } - return null; - }, - findNextNode: function (item) { - var index = item.index; - if (this.items[index + 1]) { - return this.items[index + 1].firstNode(); - } - if (this.owner === this.root) { - if (!this.owner.component) { - return null; - } - return this.owner.component.findNextNode(); - } - return this.owner.findNextNode(this); - }, - toString: function () { - var html, i, len, item; - if (this.html) { - return this.html; - } - html = ''; - if (!this.items) { - return html; - } - len = this.items.length; - for (i = 0; i < len; i += 1) { - item = this.items[i]; - html += item.toString(); - } - return html; - }, - find: function (selector) { - var i, len, item, node, queryResult; - if (this.nodes) { - len = this.nodes.length; - for (i = 0; i < len; i += 1) { - node = this.nodes[i]; - if (node.nodeType !== 1) { - continue; - } - if (matches(node, selector)) { - return node; - } - if (queryResult = node.querySelector(selector)) { - return queryResult; - } - } - return null; - } - if (this.items) { - len = this.items.length; - for (i = 0; i < len; i += 1) { - item = this.items[i]; - if (item.find && (queryResult = item.find(selector))) { - return queryResult; - } - } - return null; - } - }, - findAll: function (selector, query) { - var i, len, item, node, queryAllResult, numNodes, j; - if (this.nodes) { - len = this.nodes.length; - for (i = 0; i < len; i += 1) { - node = this.nodes[i]; - if (node.nodeType !== 1) { - continue; - } - if (matches(node, selector)) { - query.push(node); - } - if (queryAllResult = node.querySelectorAll(selector)) { - numNodes = queryAllResult.length; - for (j = 0; j < numNodes; j += 1) { - query.push(queryAllResult[j]); - } - } - } - } else if (this.items) { - len = this.items.length; - for (i = 0; i < len; i += 1) { - item = this.items[i]; - if (item.findAll) { - item.findAll(selector, query); - } - } - } - return query; - }, - findComponent: function (selector) { - var len, i, item, queryResult; - if (this.items) { - len = this.items.length; - for (i = 0; i < len; i += 1) { - item = this.items[i]; - if (item.findComponent && (queryResult = item.findComponent(selector))) { - return queryResult; - } - } - return null; - } - }, - findAllComponents: function (selector, query) { - var i, len, item; - if (this.items) { - len = this.items.length; - for (i = 0; i < len; i += 1) { - item = this.items[i]; - if (item.findAllComponents) { - item.findAllComponents(selector, query); - } - } - } - return query; - } - }; - circular.DomFragment = DomFragment; - return DomFragment; - }(config_types, utils_matches, render_shared_initFragment, render_DomFragment_shared_insertHtml, render_DomFragment_Text, render_DomFragment_Interpolator, render_DomFragment_Section__Section, render_DomFragment_Triple, render_DomFragment_Element__Element, render_DomFragment_Partial__Partial, render_DomFragment_Component__Component, render_DomFragment_Comment, circular); -var Ractive_prototype_render = function (getElement, makeTransitionManager, preDomUpdate, postDomUpdate, DomFragment) { - - return function (target, complete) { - var transitionManager; - if (!this._initing) { - throw new Error('You cannot call ractive.render() directly!'); - } - this._transitionManager = transitionManager = makeTransitionManager(this, complete); - this.fragment = new DomFragment({ - descriptor: this.template, - root: this, - owner: this, - pNode: target - }); - preDomUpdate(this); - if (target) { - target.appendChild(this.fragment.docFrag); - } - postDomUpdate(this); - this._transitionManager = null; - transitionManager.ready(); - this.rendered = true; - }; - }(utils_getElement, shared_makeTransitionManager, shared_preDomUpdate, shared_postDomUpdate, render_DomFragment__DomFragment); -var Ractive_prototype_renderHTML = function (warn) { - - return function () { - warn('renderHTML() has been deprecated and will be removed in a future version. Please use toHTML() instead'); - return this.toHTML(); - }; - }(utils_warn); -var Ractive_prototype_toHTML = function () { - - return function () { - return this.fragment.toString(); - }; - }(); -var Ractive_prototype_teardown = function (makeTransitionManager, clearCache) { - - return function (complete) { - var keypath, transitionManager, previousTransitionManager; - this.fire('teardown'); - previousTransitionManager = this._transitionManager; - this._transitionManager = transitionManager = makeTransitionManager(this, complete); - this.fragment.teardown(true); - while (this._animations[0]) { - this._animations[0].stop(); - } - for (keypath in this._cache) { - clearCache(this, keypath); - } - this._transitionManager = previousTransitionManager; - transitionManager.ready(); - }; - }(shared_makeTransitionManager, shared_clearCache); -var Ractive_prototype_shared_add = function (isNumeric) { - - return function (root, keypath, d) { - var value; - if (typeof keypath !== 'string' || !isNumeric(d)) { - if (root.debug) { - throw new Error('Bad arguments'); - } - return; - } - value = root.get(keypath); - if (value === undefined) { - value = 0; - } - if (!isNumeric(value)) { - if (root.debug) { - throw new Error('Cannot add to a non-numeric value'); - } - return; - } - root.set(keypath, value + d); - }; - }(utils_isNumeric); -var Ractive_prototype_add = function (add) { - - return function (keypath, d) { - add(this, keypath, d === undefined ? 1 : d); - }; - }(Ractive_prototype_shared_add); -var Ractive_prototype_subtract = function (add) { - - return function (keypath, d) { - add(this, keypath, d === undefined ? -1 : -d); - }; - }(Ractive_prototype_shared_add); -var Ractive_prototype_toggle = function () { - - return function (keypath) { - var value; - if (typeof keypath !== 'string') { - if (this.debug) { - throw new Error('Bad arguments'); - } - return; - } - value = this.get(keypath); - this.set(keypath, !value); - }; - }(); -var Ractive_prototype_merge_mapOldToNewIndex = function () { - - return function (oldArray, newArray) { - var usedIndices, mapper, firstUnusedIndex, newIndices, changed; - usedIndices = {}; - firstUnusedIndex = 0; - mapper = function (item, i) { - var index, start, len; - start = firstUnusedIndex; - len = newArray.length; - do { - index = newArray.indexOf(item, start); - if (index === -1) { - changed = true; - return -1; - } - start = index + 1; - } while (usedIndices[index] && start < len); - if (index === firstUnusedIndex) { - firstUnusedIndex += 1; - } - if (index !== i) { - changed = true; - } - usedIndices[index] = true; - return index; - }; - newIndices = oldArray.map(mapper); - newIndices.unchanged = !changed; - return newIndices; - }; - }(); -var Ractive_prototype_merge_queueDependants = function (types) { - - return function queueDependants(keypath, deps, mergeQueue, updateQueue) { - var i, dependant; - i = deps.length; - while (i--) { - dependant = deps[i]; - if (dependant.type === types.REFERENCE) { - dependant.update(); - } else if (dependant.keypath === keypath && dependant.type === types.SECTION && !dependant.inverted && dependant.docFrag) { - mergeQueue[mergeQueue.length] = dependant; - } else { - updateQueue[updateQueue.length] = dependant; - } - } - }; - }(config_types); -var Ractive_prototype_merge__merge = function (warn, isArray, clearCache, preDomUpdate, processDeferredUpdates, makeTransitionManager, notifyDependants, replaceData, mapOldToNewIndex, queueDependants) { - - var identifiers = {}; - return function (keypath, array, options) { - var currentArray, oldArray, newArray, identifier, lengthUnchanged, i, newIndices, mergeQueue, updateQueue, depsByKeypath, deps, transitionManager, previousTransitionManager, upstreamQueue, keys; - currentArray = this.get(keypath); - if (!isArray(currentArray) || !isArray(array)) { - return this.set(keypath, array, options && options.complete); - } - lengthUnchanged = currentArray.length === array.length; - if (options && options.compare) { - if (options.compare === true) { - identifier = stringify; - } else if (typeof options.compare === 'string') { - identifier = getIdentifier(options.compare); - } else if (typeof options.compare == 'function') { - identifier = options.compare; - } else { - throw new Error('The `compare` option must be a function, or a string representing an identifying field (or `true` to use JSON.stringify)'); - } - try { - oldArray = currentArray.map(identifier); - newArray = array.map(identifier); - } catch (err) { - if (this.debug) { - throw err; - } else { - warn('Merge operation: comparison failed. Falling back to identity checking'); - } - oldArray = currentArray; - newArray = array; - } - } else { - oldArray = currentArray; - newArray = array; - } - newIndices = mapOldToNewIndex(oldArray, newArray); - clearCache(this, keypath); - replaceData(this, keypath, array); - if (newIndices.unchanged && lengthUnchanged) { - return; - } - previousTransitionManager = this._transitionManager; - this._transitionManager = transitionManager = makeTransitionManager(this, options && options.complete); - mergeQueue = []; - updateQueue = []; - for (i = 0; i < this._deps.length; i += 1) { - depsByKeypath = this._deps[i]; - if (!depsByKeypath) { - continue; - } - deps = depsByKeypath[keypath]; - if (deps) { - queueDependants(keypath, deps, mergeQueue, updateQueue); - preDomUpdate(this); - while (mergeQueue.length) { - mergeQueue.pop().merge(newIndices); - } - while (updateQueue.length) { - updateQueue.pop().update(); - } - } - } - processDeferredUpdates(this); - upstreamQueue = []; - keys = keypath.split('.'); - while (keys.length) { - keys.pop(); - upstreamQueue[upstreamQueue.length] = keys.join('.'); - } - notifyDependants.multiple(this, upstreamQueue, true); - if (oldArray.length !== newArray.length) { - notifyDependants(this, keypath + '.length', true); - } - this._transitionManager = previousTransitionManager; - transitionManager.ready(); - }; - function stringify(item) { - return JSON.stringify(item); - } - function getIdentifier(str) { - if (!identifiers[str]) { - identifiers[str] = function (item) { - return item[str]; - }; - } - return identifiers[str]; - } - }(utils_warn, utils_isArray, shared_clearCache, shared_preDomUpdate, shared_processDeferredUpdates, shared_makeTransitionManager, shared_notifyDependants, Ractive_prototype_shared_replaceData, Ractive_prototype_merge_mapOldToNewIndex, Ractive_prototype_merge_queueDependants); -var Ractive_prototype_detach = function () { - - return function () { - return this.fragment.detach(); - }; - }(); -var Ractive_prototype_insert = function (getElement) { - - return function (target, anchor) { - target = getElement(target); - anchor = getElement(anchor) || null; - if (!target) { - throw new Error('You must specify a valid target to insert into'); - } - target.insertBefore(this.detach(), anchor); - this.fragment.pNode = target; - }; - }(utils_getElement); -var Ractive_prototype__prototype = function (get, set, update, updateModel, animate, on, off, observe, fire, find, findAll, findComponent, findAllComponents, render, renderHTML, toHTML, teardown, add, subtract, toggle, merge, detach, insert) { - - return { - get: get, - set: set, - update: update, - updateModel: updateModel, - animate: animate, - on: on, - off: off, - observe: observe, - fire: fire, - find: find, - findAll: findAll, - findComponent: findComponent, - findAllComponents: findAllComponents, - renderHTML: renderHTML, - toHTML: toHTML, - render: render, - teardown: teardown, - add: add, - subtract: subtract, - toggle: toggle, - merge: merge, - detach: detach, - insert: insert - }; - }(Ractive_prototype_get__get, Ractive_prototype_set, Ractive_prototype_update, Ractive_prototype_updateModel, Ractive_prototype_animate__animate, Ractive_prototype_on, Ractive_prototype_off, Ractive_prototype_observe__observe, Ractive_prototype_fire, Ractive_prototype_find, Ractive_prototype_findAll, Ractive_prototype_findComponent, Ractive_prototype_findAllComponents, Ractive_prototype_render, Ractive_prototype_renderHTML, Ractive_prototype_toHTML, Ractive_prototype_teardown, Ractive_prototype_add, Ractive_prototype_subtract, Ractive_prototype_toggle, Ractive_prototype_merge__merge, Ractive_prototype_detach, Ractive_prototype_insert); -var extend_registries = function () { - - return [ - 'partials', - 'transitions', - 'events', - 'components', - 'decorators', - 'data' - ]; - }(); -var extend_initOptions = function () { - - return [ - 'el', - 'template', - 'complete', - 'modifyArrays', - 'magic', - 'twoway', - 'lazy', - 'append', - 'preserveWhitespace', - 'sanitize', - 'stripComments', - 'noIntro', - 'transitionsEnabled', - 'adaptors' - ]; - }(); -var extend_inheritFromParent = function (registries, initOptions, create) { - - return function (Child, Parent) { - registries.forEach(function (property) { - if (Parent[property]) { - Child[property] = create(Parent[property]); - } - }); - initOptions.forEach(function (property) { - Child[property] = Parent[property]; - }); - }; - }(extend_registries, extend_initOptions, utils_create); -var extend_wrapMethod = function () { - - return function (method, superMethod) { - if (/_super/.test(method)) { - return function () { - var _super = this._super, result; - this._super = superMethod; - result = method.apply(this, arguments); - this._super = _super; - return result; - }; - } else { - return method; - } - }; - }(); -var extend_utils_augment = function () { - - return function (target, source) { - var key; - for (key in source) { - if (source.hasOwnProperty(key)) { - target[key] = source[key]; - } - } - return target; - }; - }(); -var extend_inheritFromChildProps = function (registries, initOptions, wrapMethod, augment) { - - var blacklist, blacklisted; - blacklist = registries.concat(initOptions); - blacklisted = {}; - blacklist.forEach(function (property) { - blacklisted[property] = true; - }); - return function (Child, childProps) { - var key, member; - registries.forEach(function (property) { - var value = childProps[property]; - if (value) { - if (Child[property]) { - augment(Child[property], value); - } else { - Child[property] = value; - } - } - }); - initOptions.forEach(function (property) { - var value = childProps[property]; - if (value !== undefined) { - if (typeof value === 'function' && typeof Child[property] === 'function') { - Child[property] = wrapMethod(value, Child[property]); - } else { - Child[property] = childProps[property]; - } - } - }); - for (key in childProps) { - if (childProps.hasOwnProperty(key) && !blacklisted[key]) { - member = childProps[key]; - if (typeof member === 'function' && typeof Child.prototype[key] === 'function') { - Child.prototype[key] = wrapMethod(member, Child.prototype[key]); - } else { - Child.prototype[key] = member; - } - } - } - }; - }(extend_registries, extend_initOptions, extend_wrapMethod, extend_utils_augment); -var extend_extractInlinePartials = function (isObject, augment) { - - return function (Child, childProps) { - if (isObject(Child.template)) { - if (!Child.partials) { - Child.partials = {}; - } - augment(Child.partials, Child.template.partials); - if (childProps.partials) { - augment(Child.partials, childProps.partials); - } - Child.template = Child.template.main; - } - }; - }(utils_isObject, extend_utils_augment); -var extend_conditionallyParseTemplate = function (errors, isClient, parse) { - - return function (Child) { - var templateEl; - if (typeof Child.template === 'string') { - if (!parse) { - throw new Error(errors.missingParser); - } - if (Child.template.charAt(0) === '#' && isClient) { - templateEl = document.getElementById(Child.template.substring(1)); - if (templateEl && templateEl.tagName === 'SCRIPT') { - Child.template = parse(templateEl.innerHTML, Child); - } else { - throw new Error('Could not find template element (' + Child.template + ')'); - } - } else { - Child.template = parse(Child.template, Child); - } - } - }; - }(config_errors, config_isClient, parse__parse); -var extend_conditionallyParsePartials = function (errors, parse) { - - return function (Child) { - var key; - if (Child.partials) { - for (key in Child.partials) { - if (Child.partials.hasOwnProperty(key) && typeof Child.partials[key] === 'string') { - if (!parse) { - throw new Error(errors.missingParser); - } - Child.partials[key] = parse(Child.partials[key], Child); - } - } - } - }; - }(config_errors, parse__parse); -var extend_utils_clone = function () { - - return function (source) { - var target = {}, key; - for (key in source) { - if (source.hasOwnProperty(key)) { - target[key] = source[key]; - } - } - return target; - }; - }(); -var utils_extend = function () { - - return function (target) { - var prop, source, sources = Array.prototype.slice.call(arguments, 1); - while (source = sources.shift()) { - for (prop in source) { - if (source.hasOwnProperty(prop)) { - target[prop] = source[prop]; - } - } - } - return target; - }; - }(); -var Ractive_initialise = function (isClient, errors, warn, create, extend, defineProperty, defineProperties, getElement, isObject, magicAdaptor, parse) { - - var getObject, getArray, defaultOptions, registries; - getObject = function () { - return {}; - }; - getArray = function () { - return []; - }; - defaultOptions = create(null); - defineProperties(defaultOptions, { - preserveWhitespace: { - enumerable: true, - value: false - }, - append: { - enumerable: true, - value: false - }, - twoway: { - enumerable: true, - value: true - }, - modifyArrays: { - enumerable: true, - value: true - }, - data: { - enumerable: true, - value: getObject - }, - lazy: { - enumerable: true, - value: false - }, - debug: { - enumerable: true, - value: false - }, - transitions: { - enumerable: true, - value: getObject - }, - decorators: { - enumerable: true, - value: getObject - }, - events: { - enumerable: true, - value: getObject - }, - noIntro: { - enumerable: true, - value: false - }, - transitionsEnabled: { - enumerable: true, - value: true - }, - magic: { - enumerable: true, - value: false - }, - adaptors: { - enumerable: true, - value: getArray - } - }); - registries = [ - 'components', - 'decorators', - 'events', - 'partials', - 'transitions', - 'data' - ]; - return function (ractive, options) { - var key, template, templateEl, parsedTemplate; - for (key in defaultOptions) { - if (options[key] === undefined) { - options[key] = typeof defaultOptions[key] === 'function' ? defaultOptions[key]() : defaultOptions[key]; - } - } - defineProperties(ractive, { - _initing: { - value: true, - writable: true - }, - _guid: { - value: 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { - var r, v; - r = Math.random() * 16 | 0; - v = c == 'x' ? r : r & 3 | 8; - return v.toString(16); - }) - }, - _subs: { - value: create(null), - configurable: true - }, - _cache: { value: {} }, - _cacheMap: { value: create(null) }, - _deps: { value: [] }, - _depsMap: { value: create(null) }, - _patternObservers: { value: [] }, - _pendingResolution: { value: [] }, - _deferred: { value: {} }, - _evaluators: { value: create(null) }, - _twowayBindings: { value: {} }, - _transitionManager: { - value: null, - writable: true - }, - _animations: { value: [] }, - nodes: { value: {} }, - _wrapped: { value: create(null) }, - _liveQueries: { value: [] }, - _liveComponentQueries: { value: [] } - }); - defineProperties(ractive._deferred, { - attrs: { value: [] }, - evals: { value: [] }, - selectValues: { value: [] }, - checkboxes: { value: [] }, - radios: { value: [] }, - observers: { value: [] }, - transitions: { value: [] }, - liveQueries: { value: [] }, - decorators: { value: [] }, - focusable: { - value: null, - writable: true - } - }); - ractive.adaptors = options.adaptors; - ractive.modifyArrays = options.modifyArrays; - ractive.magic = options.magic; - ractive.twoway = options.twoway; - ractive.lazy = options.lazy; - ractive.debug = options.debug; - if (ractive.magic && !magicAdaptor) { - throw new Error('Getters and setters (magic mode) are not supported in this browser'); - } - if (options._parent) { - defineProperty(ractive, '_parent', { value: options._parent }); - } - if (options.el) { - ractive.el = getElement(options.el); - if (!ractive.el && ractive.debug) { - throw new Error('Could not find container element'); - } - } - if (options.eventDefinitions) { - warn('ractive.eventDefinitions has been deprecated in favour of ractive.events. Support will be removed in future versions'); - options.events = options.eventDefinitions; - } - registries.forEach(function (registry) { - if (ractive.constructor[registry]) { - ractive[registry] = extend(create(ractive.constructor[registry] || {}), options[registry]); - } else if (options[registry]) { - ractive[registry] = options[registry]; - } - }); - template = options.template; - if (typeof template === 'string') { - if (!parse) { - throw new Error(errors.missingParser); - } - if (template.charAt(0) === '#' && isClient) { - templateEl = document.getElementById(template.substring(1)); - if (templateEl) { - parsedTemplate = parse(templateEl.innerHTML, options); - } else { - throw new Error('Could not find template element (' + template + ')'); - } - } else { - parsedTemplate = parse(template, options); - } - } else { - parsedTemplate = template; - } - if (isObject(parsedTemplate)) { - extend(ractive.partials, parsedTemplate.partials); - parsedTemplate = parsedTemplate.main; - } - if (parsedTemplate && parsedTemplate.length === 1 && typeof parsedTemplate[0] === 'string') { - parsedTemplate = parsedTemplate[0]; - } - ractive.template = parsedTemplate; - extend(ractive.partials, options.partials); - ractive.parseOptions = { - preserveWhitespace: options.preserveWhitespace, - sanitize: options.sanitize, - stripComments: options.stripComments - }; - ractive.transitionsEnabled = options.noIntro ? false : options.transitionsEnabled; - if (isClient && !ractive.el) { - ractive.el = document.createDocumentFragment(); - } - if (ractive.el && !options.append) { - ractive.el.innerHTML = ''; - } - ractive.render(ractive.el, options.complete); - ractive.transitionsEnabled = options.transitionsEnabled; - ractive._initing = false; - }; - }(config_isClient, config_errors, utils_warn, utils_create, utils_extend, utils_defineProperty, utils_defineProperties, utils_getElement, utils_isObject, Ractive_prototype_get_magicAdaptor, parse__parse); -var extend_initChildInstance = function (fillGaps, initOptions, clone, wrapMethod, initialise) { - - return function (child, Child, options) { - initOptions.forEach(function (property) { - var value = options[property], defaultValue = Child[property]; - if (typeof value === 'function' && typeof defaultValue === 'function') { - options[property] = wrapMethod(value, defaultValue); - } else if (value === undefined && defaultValue !== undefined) { - options[property] = defaultValue; - } - }); - if (child.beforeInit) { - child.beforeInit(options); - } - initialise(child, options); - if (child.init) { - child.init(options); - } - }; - }(utils_fillGaps, extend_initOptions, extend_utils_clone, extend_wrapMethod, Ractive_initialise); -var extend__extend = function (create, inheritFromParent, inheritFromChildProps, extractInlinePartials, conditionallyParseTemplate, conditionallyParsePartials, initChildInstance, circular) { - - var Ractive; - circular.push(function () { - Ractive = circular.Ractive; - }); - return function (childProps) { - var Parent = this, Child; - Child = function (options) { - initChildInstance(this, Child, options || {}); - }; - Child.prototype = create(Parent.prototype); - Child.prototype.constructor = Child; - inheritFromParent(Child, Parent); - inheritFromChildProps(Child, childProps); - conditionallyParseTemplate(Child); - extractInlinePartials(Child, childProps); - conditionallyParsePartials(Child); - Child.extend = Parent.extend; - return Child; - }; - }(utils_create, extend_inheritFromParent, extend_inheritFromChildProps, extend_extractInlinePartials, extend_conditionallyParseTemplate, extend_conditionallyParsePartials, extend_initChildInstance, circular); -var Ractive__Ractive = function (svg, create, defineProperties, prototype, partialRegistry, adaptorRegistry, easingRegistry, Ractive_extend, parse, initialise, circular) { - - var Ractive = function (options) { - initialise(this, options); - }; - defineProperties(Ractive, { - prototype: { value: prototype }, - partials: { value: partialRegistry }, - adaptors: { value: adaptorRegistry }, - easing: { value: easingRegistry }, - transitions: { value: {} }, - events: { value: {} }, - components: { value: {} }, - decorators: { value: {} }, - svg: { value: svg }, - VERSION: { value: '0.3.9' } - }); - Ractive.eventDefinitions = Ractive.events; - Ractive.prototype.constructor = Ractive; - Ractive.delimiters = [ - '{{', - '}}' - ]; - Ractive.tripleDelimiters = [ - '{{{', - '}}}' - ]; - Ractive.extend = Ractive_extend; - Ractive.parse = parse; - circular.Ractive = Ractive; - return Ractive; - }(config_svg, utils_create, utils_defineProperties, Ractive_prototype__prototype, registries_partials, registries_adaptors, registries_easing, extend__extend, parse__parse, Ractive_initialise, circular); -var Ractive = function (Ractive, circular) { - - if (typeof window !== 'undefined' && window.Node && !window.Node.prototype.contains && window.HTMLElement && window.HTMLElement.prototype.contains) { - window.Node.prototype.contains = window.HTMLElement.prototype.contains; - } - while (circular.length) { - circular.pop()(); - } - return Ractive; - }(Ractive__Ractive, circular); -// export as Common JS module... -if ( typeof module !== "undefined" && module.exports ) { - module.exports = Ractive; -} - -// ... or as AMD module -else if ( typeof define === "function" && define.amd ) { - define( function () { - return Ractive; - }); -} - -// ... or as browser global -else { - global.Ractive = Ractive; -} - -}( typeof window !== 'undefined' ? window : this )); \ No newline at end of file diff --git a/bower.json b/bower.json index 5a959fad72..a6e4e411ba 100755 --- a/bower.json +++ b/bower.json @@ -1,7 +1,7 @@ { "name": "ractive", - "version": "0.3.9", - "main": "build/Ractive.js", + "version": "0.4.0", + "main": "ractive.js", "ignore": [ "**/.*", "node_modules", diff --git a/build/README.md b/build/README.md new file mode 100644 index 0000000000..d79bc18a96 --- /dev/null +++ b/build/README.md @@ -0,0 +1,22 @@ +Latest builds +============= + +The latest builds are available from http://cdn.ractivejs.org: + + +Compressed +---------- + +* http://cdn.ractivejs.org/edge/ractive.min.js +* http://cdn.ractivejs.org/edge/ractive-legacy.min.js (IE8 compatible version) +* http://cdn.ractivejs.org/edge/ractive.runtime.min.js (excludes `Ractive.parse`) +* http://cdn.ractivejs.org/edge/ractive-legacy.runtime.min.js + + +Uncompressed +------------ + +* http://cdn.ractivejs.org/edge/ractive.js +* http://cdn.ractivejs.org/edge/ractive-legacy.js (IE8 compatible version) +* http://cdn.ractivejs.org/edge/ractive.runtime.js (excludes `Ractive.parse`) +* http://cdn.ractivejs.org/edge/ractive-legacy.runtime.js diff --git a/build/Ractive-legacy.js b/build/Ractive-legacy.js deleted file mode 100644 index 94afc6476c..0000000000 --- a/build/Ractive-legacy.js +++ /dev/null @@ -1,9435 +0,0 @@ -/* - - Ractive - v0.3.9 - 2013-12-31 - ============================================================== - - Next-generation DOM manipulation - http://ractivejs.org - Follow @RactiveJS for updates - - -------------------------------------------------------------- - - Copyright 2013 2013 Rich Harris and contributors - - 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 ( win ) { - - 'use strict'; - - var doc = win.document; - - if ( !doc ) { - return; - } - - // Shims for older browsers - - if ( !Date.now ) { - Date.now = function () { return +new Date(); }; - } - - if ( !String.prototype.trim ) { - String.prototype.trim = function () { - return this.replace(/^\s+/, '').replace(/\s+$/, ''); - }; - } - - - // Polyfill for Object.keys - // https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/keys - if ( !Object.keys ) { - Object.keys = (function () { - var hasOwnProperty = Object.prototype.hasOwnProperty, - hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'), - dontEnums = [ - 'toString', - 'toLocaleString', - 'valueOf', - 'hasOwnProperty', - 'isPrototypeOf', - 'propertyIsEnumerable', - 'constructor' - ], - dontEnumsLength = dontEnums.length; - - return function ( obj ) { - if ( typeof obj !== 'object' && typeof obj !== 'function' || obj === null ) { - throw new TypeError( 'Object.keys called on non-object' ); - } - - var result = []; - - for ( var prop in obj ) { - if ( hasOwnProperty.call( obj, prop ) ){ - result.push( prop ); - } - } - - if ( hasDontEnumBug ) { - for ( var i=0; i < dontEnumsLength; i++ ) { - if ( hasOwnProperty.call( obj, dontEnums[i] ) ){ - result.push( dontEnums[i] ); - } - } - } - return result; - }; - }()); - } - - - // Array extras - if ( !Array.prototype.indexOf ) { - Array.prototype.indexOf = function ( needle, i ) { - var len; - - if ( i === undefined ) { - i = 0; - } - - if ( i < 0 ) { - i+= this.length; - } - - if ( i < 0 ) { - i = 0; - } - - for ( len = this.length; i 2 && args[1]) { - changed = Math.min(args[1], args.length - 2); - start = args[0]; - end = start + changed; - if (args[1] === args.length - 2) { - lengthUnchanged = true; - } - for (i = start; i < end; i += 1) { - childKeypath = keypath + '.' + i; - notifyDependants(root, childKeypath); - } - } - preDomUpdate(root); - upstreamQueue = []; - keys = keypath.split('.'); - while (keys.length) { - keys.pop(); - upstreamQueue[upstreamQueue.length] = keys.join('.'); - } - notifyDependants.multiple(root, upstreamQueue, true); - if (!lengthUnchanged) { - notifyDependants(root, keypath + '.length', true); - } - }; - queueDependants = function (keypath, deps, smartUpdateQueue, dumbUpdateQueue) { - var k, dependant; - k = deps.length; - while (k--) { - dependant = deps[k]; - if (dependant.type === types.REFERENCE) { - dependant.update(); - } else if (dependant.keypath === keypath && dependant.type === types.SECTION && !dependant.inverted && dependant.docFrag) { - smartUpdateQueue[smartUpdateQueue.length] = dependant; - } else { - dumbUpdateQueue[dumbUpdateQueue.length] = dependant; - } - } - }; - wrappers = array._ractive.wrappers; - i = wrappers.length; - while (i--) { - wrapper = wrappers[i]; - notifyKeypathDependants(wrapper.root, wrapper.keypath); - } - }; - patchedArrayProto = []; - mutatorMethods = [ - 'pop', - 'push', - 'reverse', - 'shift', - 'sort', - 'splice', - 'unshift' - ]; - noop = function () { - }; - mutatorMethods.forEach(function (methodName) { - var method = function () { - var result, instances, instance, i, previousTransitionManagers = {}, transitionManagers = {}; - result = Array.prototype[methodName].apply(this, arguments); - instances = this._ractive.instances; - i = instances.length; - while (i--) { - instance = instances[i]; - previousTransitionManagers[instance._guid] = instance._transitionManager; - instance._transitionManager = transitionManagers[instance._guid] = makeTransitionManager(instance, noop); - } - this._ractive.setting = true; - notifyArrayDependants(this, methodName, arguments); - this._ractive.setting = false; - i = instances.length; - while (i--) { - instance = instances[i]; - instance._transitionManager = previousTransitionManagers[instance._guid]; - transitionManagers[instance._guid].ready(); - preDomUpdate(instance); - postDomUpdate(instance); - } - return result; - }; - defineProperty(patchedArrayProto, methodName, { value: method }); - }); - testObj = {}; - if (testObj.__proto__) { - patchArrayMethods = function (array) { - array.__proto__ = patchedArrayProto; - }; - unpatchArrayMethods = function (array) { - array.__proto__ = Array.prototype; - }; - } else { - patchArrayMethods = function (array) { - var i, methodName; - i = mutatorMethods.length; - while (i--) { - methodName = mutatorMethods[i]; - defineProperty(array, methodName, { - value: patchedArrayProto[methodName], - configurable: true - }); - } - }; - unpatchArrayMethods = function (array) { - var i; - i = mutatorMethods.length; - while (i--) { - delete array[mutatorMethods[i]]; - } - }; - } - errorMessage = 'Something went wrong in a rather interesting way'; - return arrayAdaptor; - }(config_types, utils_defineProperty, utils_isArray, shared_clearCache, shared_preDomUpdate, shared_postDomUpdate, shared_makeTransitionManager, shared_notifyDependants); -var Ractive_prototype_get_magicAdaptor = function () { - - var magicAdaptor, MagicWrapper; - try { - Object.defineProperty({}, 'test', { value: 0 }); - } catch (err) { - return false; - } - magicAdaptor = { - filter: function (object, keypath) { - return !!keypath; - }, - wrap: function (ractive, object, keypath) { - return new MagicWrapper(ractive, object, keypath); - } - }; - MagicWrapper = function (ractive, object, keypath) { - var wrapper = this, keys, prop, objKeypath, descriptor, wrappers, oldGet, oldSet, get, set; - this.ractive = ractive; - this.keypath = keypath; - keys = keypath.split('.'); - this.prop = keys.pop(); - objKeypath = keys.join('.'); - this.obj = objKeypath ? ractive.get(objKeypath) : ractive.data; - descriptor = this.originalDescriptor = Object.getOwnPropertyDescriptor(this.obj, this.prop); - if (descriptor && descriptor.set && (wrappers = descriptor.set._ractiveWrappers)) { - if (wrappers.indexOf(this) === -1) { - wrappers.push(this); - } - return; - } - if (descriptor && !descriptor.configurable) { - throw new Error('Cannot use magic mode with property "' + prop + '" - object is not configurable'); - } - if (descriptor) { - this.value = descriptor.value; - oldGet = descriptor.get; - oldSet = descriptor.set; - } - get = oldGet || function () { - return wrapper.value; - }; - set = function (value) { - var wrappers, wrapper, i; - if (oldSet) { - oldSet(value); - } - wrappers = set._ractiveWrappers; - i = wrappers.length; - while (i--) { - wrapper = wrappers[i]; - if (!wrapper.resetting) { - wrapper.ractive.set(wrapper.keypath, value); - } - } - }; - set._ractiveWrappers = [this]; - Object.defineProperty(this.obj, this.prop, { - get: get, - set: set, - enumerable: true, - configurable: true - }); - }; - MagicWrapper.prototype = { - get: function () { - return this.value; - }, - reset: function (value) { - this.resetting = true; - this.value = value; - this.resetting = false; - }, - teardown: function () { - var descriptor, set, value, wrappers; - descriptor = Object.getOwnPropertyDescriptor(this.obj, this.prop); - set = descriptor.set; - wrappers = set._ractiveWrappers; - wrappers.splice(wrappers.indexOf(this), 1); - if (!wrappers.length) { - value = this.obj[this.prop]; - Object.defineProperty(this.obj, this.prop, this.originalDescriptor || { - writable: true, - enumerable: true, - configrable: true - }); - this.obj[this.prop] = value; - } - } - }; - return magicAdaptor; - }(); -var shared_adaptIfNecessary = function (adaptorRegistry, arrayAdaptor, magicAdaptor) { - - var prefixers = {}; - return function (ractive, keypath, value, isExpressionResult) { - var len, i, adaptor, wrapped; - len = ractive.adaptors.length; - for (i = 0; i < len; i += 1) { - adaptor = ractive.adaptors[i]; - if (typeof adaptor === 'string') { - if (!adaptorRegistry[adaptor]) { - throw new Error('Missing adaptor "' + adaptor + '"'); - } - adaptor = ractive.adaptors[i] = adaptorRegistry[adaptor]; - } - if (adaptor.filter(value, keypath, ractive)) { - wrapped = ractive._wrapped[keypath] = adaptor.wrap(ractive, value, keypath, getPrefixer(keypath)); - wrapped.value = value; - return; - } - } - if (!isExpressionResult) { - if (ractive.magic && magicAdaptor.filter(value, keypath, ractive)) { - ractive._wrapped[keypath] = magicAdaptor.wrap(ractive, value, keypath); - } else if (ractive.modifyArrays && arrayAdaptor.filter(value, keypath, ractive)) { - ractive._wrapped[keypath] = arrayAdaptor.wrap(ractive, value, keypath); - } - } - }; - function prefixKeypath(obj, prefix) { - var prefixed = {}, key; - if (!prefix) { - return obj; - } - prefix += '.'; - for (key in obj) { - if (obj.hasOwnProperty(key)) { - prefixed[prefix + key] = obj[key]; - } - } - return prefixed; - } - function getPrefixer(rootKeypath) { - var rootDot; - if (!prefixers[rootKeypath]) { - rootDot = rootKeypath ? rootKeypath + '.' : ''; - prefixers[rootKeypath] = function (relativeKeypath, value) { - var obj; - if (typeof relativeKeypath === 'string') { - obj = {}; - obj[rootDot + relativeKeypath] = value; - return obj; - } - if (typeof relativeKeypath === 'object') { - return rootDot ? prefixKeypath(relativeKeypath, rootKeypath) : relativeKeypath; - } - }; - } - return prefixers[rootKeypath]; - } - }(registries_adaptors, Ractive_prototype_get_arrayAdaptor, Ractive_prototype_get_magicAdaptor); -var Ractive_prototype_get__get = function (normaliseKeypath, adaptorRegistry, adaptIfNecessary) { - - var get, _get, retrieve; - get = function (keypath) { - if (this._captured && !this._captured[keypath]) { - this._captured.push(keypath); - this._captured[keypath] = true; - } - return _get(this, keypath); - }; - _get = function (ractive, keypath) { - var cache, cached, value, wrapped, evaluator; - keypath = normaliseKeypath(keypath); - cache = ractive._cache; - if ((cached = cache[keypath]) !== undefined) { - return cached; - } - if (wrapped = ractive._wrapped[keypath]) { - value = wrapped.value; - } else if (!keypath) { - adaptIfNecessary(ractive, '', ractive.data); - value = ractive.data; - } else if (evaluator = ractive._evaluators[keypath]) { - value = evaluator.value; - } else { - value = retrieve(ractive, keypath); - } - cache[keypath] = value; - return value; - }; - retrieve = function (ractive, keypath) { - var keys, key, parentKeypath, parentValue, cacheMap, value, wrapped; - keys = keypath.split('.'); - key = keys.pop(); - parentKeypath = keys.join('.'); - parentValue = _get(ractive, parentKeypath); - if (wrapped = ractive._wrapped[parentKeypath]) { - parentValue = wrapped.get(); - } - if (parentValue === null || parentValue === undefined) { - return; - } - if (!(cacheMap = ractive._cacheMap[parentKeypath])) { - ractive._cacheMap[parentKeypath] = [keypath]; - } else { - if (cacheMap.indexOf(keypath) === -1) { - cacheMap[cacheMap.length] = keypath; - } - } - value = parentValue[key]; - adaptIfNecessary(ractive, keypath, value); - ractive._cache[keypath] = value; - return value; - }; - return get; - }(utils_normaliseKeypath, registries_adaptors, shared_adaptIfNecessary); -var utils_isObject = function () { - - var toString = Object.prototype.toString; - return function (thing) { - return typeof thing === 'object' && toString.call(thing) === '[object Object]'; - }; - }(); -var utils_isEqual = function () { - - return function (a, b) { - if (a === null && b === null) { - return true; - } - if (typeof a === 'object' || typeof b === 'object') { - return false; - } - return a === b; - }; - }(); -var shared_resolveRef = function () { - - var resolveRef; - resolveRef = function (ractive, ref, contextStack) { - var keypath, keys, lastKey, contextKeys, innerMostContext, postfix, parentKeypath, parentValue, wrapped, context, ancestorErrorMessage; - ancestorErrorMessage = 'Could not resolve reference - too many "../" prefixes'; - if (ref === '.') { - if (!contextStack.length) { - return ''; - } - keypath = contextStack[contextStack.length - 1]; - } else if (ref.charAt(0) === '.') { - context = contextStack[contextStack.length - 1]; - contextKeys = context ? context.split('.') : []; - if (ref.substr(0, 3) === '../') { - while (ref.substr(0, 3) === '../') { - if (!contextKeys.length) { - throw new Error(ancestorErrorMessage); - } - contextKeys.pop(); - ref = ref.substring(3); - } - contextKeys.push(ref); - keypath = contextKeys.join('.'); - } else if (!context) { - keypath = ref.substring(1); - } else { - keypath = context + ref; - } - } else { - keys = ref.split('.'); - lastKey = keys.pop(); - postfix = keys.length ? '.' + keys.join('.') : ''; - contextStack = contextStack.concat(); - while (contextStack.length) { - innerMostContext = contextStack.pop(); - parentKeypath = innerMostContext + postfix; - parentValue = ractive.get(parentKeypath); - if (wrapped = ractive._wrapped[parentKeypath]) { - parentValue = wrapped.get(); - } - if (typeof parentValue === 'object' && parentValue !== null && parentValue.hasOwnProperty(lastKey)) { - keypath = innerMostContext + '.' + ref; - break; - } - } - if (!keypath && ractive.get(ref) !== undefined) { - keypath = ref; - } - } - return keypath ? keypath.replace(/^\./, '') : keypath; - }; - return resolveRef; - }(); -var shared_attemptKeypathResolution = function (resolveRef) { - - var push = Array.prototype.push; - return function (ractive) { - var unresolved, keypath, leftover; - while (unresolved = ractive._pendingResolution.pop()) { - keypath = resolveRef(ractive, unresolved.ref, unresolved.contextStack); - if (keypath !== undefined) { - unresolved.resolve(keypath); - } else { - (leftover || (leftover = [])).push(unresolved); - } - } - if (leftover) { - push.apply(ractive._pendingResolution, leftover); - } - }; - }(shared_resolveRef); -var shared_processDeferredUpdates = function (preDomUpdate, postDomUpdate) { - - return function (ractive) { - preDomUpdate(ractive); - postDomUpdate(ractive); - }; - }(shared_preDomUpdate, shared_postDomUpdate); -var Ractive_prototype_shared_replaceData = function () { - - return function (ractive, keypath, value) { - var keys, accumulated, wrapped, obj, key, currentKeypath, keypathToClear; - keys = keypath.split('.'); - accumulated = []; - if (wrapped = ractive._wrapped['']) { - if (wrapped.set) { - wrapped.set(keys.join('.'), value); - } - obj = wrapped.get(); - } else { - obj = ractive.data; - } - while (keys.length > 1) { - key = accumulated[accumulated.length] = keys.shift(); - currentKeypath = accumulated.join('.'); - if (wrapped = ractive._wrapped[currentKeypath]) { - if (wrapped.set) { - wrapped.set(keys.join('.'), value); - } - obj = wrapped.get(); - } else { - if (!obj.hasOwnProperty(key)) { - if (!keypathToClear) { - keypathToClear = currentKeypath; - } - obj[key] = /^\s*[0-9]+\s*$/.test(keys[0]) ? [] : {}; - } - obj = obj[key]; - } - } - key = keys[0]; - obj[key] = value; - return keypathToClear; - }; - }(); -var Ractive_prototype_set = function (isObject, isEqual, normaliseKeypath, clearCache, notifyDependants, attemptKeypathResolution, makeTransitionManager, processDeferredUpdates, replaceData) { - - var set, updateModel, getUpstreamChanges, resetWrapped; - set = function (keypath, value, complete) { - var map, changes, upstreamChanges, previousTransitionManager, transitionManager, i, changeHash; - changes = []; - if (isObject(keypath)) { - map = keypath; - complete = value; - } - if (map) { - for (keypath in map) { - if (map.hasOwnProperty(keypath)) { - value = map[keypath]; - keypath = normaliseKeypath(keypath); - updateModel(this, keypath, value, changes); - } - } - } else { - keypath = normaliseKeypath(keypath); - updateModel(this, keypath, value, changes); - } - if (!changes.length) { - return; - } - previousTransitionManager = this._transitionManager; - this._transitionManager = transitionManager = makeTransitionManager(this, complete); - upstreamChanges = getUpstreamChanges(changes); - if (upstreamChanges.length) { - notifyDependants.multiple(this, upstreamChanges, true); - } - notifyDependants.multiple(this, changes); - if (this._pendingResolution.length) { - attemptKeypathResolution(this); - } - processDeferredUpdates(this); - this._transitionManager = previousTransitionManager; - transitionManager.ready(); - if (!this.firingChangeEvent) { - this.firingChangeEvent = true; - changeHash = {}; - i = changes.length; - while (i--) { - changeHash[changes[i]] = this.get(changes[i]); - } - this.fire('change', changeHash); - this.firingChangeEvent = false; - } - return this; - }; - updateModel = function (ractive, keypath, value, changes) { - var cached, previous, wrapped, keypathToClear, evaluator; - if ((wrapped = ractive._wrapped[keypath]) && wrapped.reset) { - if (resetWrapped(ractive, keypath, value, wrapped, changes) !== false) { - return; - } - } - if (evaluator = ractive._evaluators[keypath]) { - evaluator.value = value; - } - cached = ractive._cache[keypath]; - previous = ractive.get(keypath); - if (previous !== value && !evaluator) { - keypathToClear = replaceData(ractive, keypath, value); - } else { - if (value === cached && typeof value !== 'object') { - return; - } - } - clearCache(ractive, keypathToClear || keypath); - changes[changes.length] = keypath; - }; - getUpstreamChanges = function (changes) { - var upstreamChanges = [''], i, keypath, keys, upstreamKeypath; - i = changes.length; - while (i--) { - keypath = changes[i]; - keys = keypath.split('.'); - while (keys.length > 1) { - keys.pop(); - upstreamKeypath = keys.join('.'); - if (!upstreamChanges[upstreamKeypath]) { - upstreamChanges[upstreamChanges.length] = upstreamKeypath; - upstreamChanges[upstreamKeypath] = true; - } - } - } - return upstreamChanges; - }; - resetWrapped = function (ractive, keypath, value, wrapped, changes) { - var previous, cached, cacheMap, i; - previous = wrapped.get(); - if (!isEqual(previous, value)) { - if (wrapped.reset(value) === false) { - return false; - } - } - value = wrapped.get(); - cached = ractive._cache[keypath]; - if (!isEqual(cached, value)) { - ractive._cache[keypath] = value; - cacheMap = ractive._cacheMap[keypath]; - if (cacheMap) { - i = cacheMap.length; - while (i--) { - clearCache(ractive, cacheMap[i]); - } - } - changes[changes.length] = keypath; - } - }; - return set; - }(utils_isObject, utils_isEqual, utils_normaliseKeypath, shared_clearCache, shared_notifyDependants, shared_attemptKeypathResolution, shared_makeTransitionManager, shared_processDeferredUpdates, Ractive_prototype_shared_replaceData); -var Ractive_prototype_update = function (makeTransitionManager, attemptKeypathResolution, clearCache, notifyDependants, processDeferredUpdates) { - - return function (keypath, complete) { - var transitionManager, previousTransitionManager; - if (typeof keypath === 'function') { - complete = keypath; - keypath = ''; - } - previousTransitionManager = this._transitionManager; - this._transitionManager = transitionManager = makeTransitionManager(this, complete); - attemptKeypathResolution(this); - clearCache(this, keypath || ''); - notifyDependants(this, keypath || ''); - processDeferredUpdates(this); - this._transitionManager = previousTransitionManager; - transitionManager.ready(); - if (typeof keypath === 'string') { - this.fire('update', keypath); - } else { - this.fire('update'); - } - return this; - }; - }(shared_makeTransitionManager, shared_attemptKeypathResolution, shared_clearCache, shared_notifyDependants, shared_processDeferredUpdates); -var utils_arrayContentsMatch = function (isArray) { - - return function (a, b) { - var i; - if (!isArray(a) || !isArray(b)) { - return false; - } - if (a.length !== b.length) { - return false; - } - i = a.length; - while (i--) { - if (a[i] !== b[i]) { - return false; - } - } - return true; - }; - }(utils_isArray); -var Ractive_prototype_updateModel = function (getValueFromCheckboxes, arrayContentsMatch, isEqual) { - - return function (keypath, cascade) { - var values, deferredCheckboxes, i; - if (typeof keypath !== 'string') { - keypath = ''; - cascade = true; - } - consolidateChangedValues(this, keypath, values = {}, deferredCheckboxes = [], cascade); - if (i = deferredCheckboxes.length) { - while (i--) { - keypath = deferredCheckboxes[i]; - values[keypath] = getValueFromCheckboxes(this, keypath); - } - } - this.set(values); - }; - function consolidateChangedValues(ractive, keypath, values, deferredCheckboxes, cascade) { - var bindings, childDeps, i, binding, oldValue, newValue; - bindings = ractive._twowayBindings[keypath]; - if (bindings) { - i = bindings.length; - while (i--) { - binding = bindings[i]; - if (binding.radioName && !binding.node.checked) { - continue; - } - if (binding.checkboxName) { - if (binding.changed() && !deferredCheckboxes[keypath]) { - deferredCheckboxes[keypath] = true; - deferredCheckboxes[deferredCheckboxes.length] = keypath; - } - continue; - } - oldValue = binding.attr.value; - newValue = binding.value(); - if (arrayContentsMatch(oldValue, newValue)) { - continue; - } - if (!isEqual(oldValue, newValue)) { - values[keypath] = newValue; - } - } - } - if (!cascade) { - return; - } - childDeps = ractive._depsMap[keypath]; - if (childDeps) { - i = childDeps.length; - while (i--) { - consolidateChangedValues(ractive, childDeps[i], values, deferredCheckboxes, cascade); - } - } - } - }(shared_getValueFromCheckboxes, utils_arrayContentsMatch, utils_isEqual); -var Ractive_prototype_animate_requestAnimationFrame = function () { - - if (typeof window === 'undefined') { - return; - } - (function (vendors, lastTime, window) { - var x, setTimeout; - if (window.requestAnimationFrame) { - return; - } - for (x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { - window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame']; - } - if (!window.requestAnimationFrame) { - setTimeout = window.setTimeout; - window.requestAnimationFrame = function (callback) { - var currTime, timeToCall, id; - currTime = Date.now(); - timeToCall = Math.max(0, 16 - (currTime - lastTime)); - id = setTimeout(function () { - callback(currTime + timeToCall); - }, timeToCall); - lastTime = currTime + timeToCall; - return id; - }; - } - }([ - 'ms', - 'moz', - 'webkit', - 'o' - ], 0, window)); - return window.requestAnimationFrame; - }(); -var Ractive_prototype_animate_animations = function (rAF) { - - var queue = []; - var animations = { - tick: function () { - var i, animation; - for (i = 0; i < queue.length; i += 1) { - animation = queue[i]; - if (!animation.tick()) { - queue.splice(i--, 1); - } - } - if (queue.length) { - rAF(animations.tick); - } else { - animations.running = false; - } - }, - add: function (animation) { - queue[queue.length] = animation; - if (!animations.running) { - animations.running = true; - animations.tick(); - } - }, - abort: function (keypath, root) { - var i = queue.length, animation; - while (i--) { - animation = queue[i]; - if (animation.root === root && animation.keypath === keypath) { - animation.stop(); - } - } - } - }; - return animations; - }(Ractive_prototype_animate_requestAnimationFrame); -var utils_warn = function () { - - if (typeof console !== 'undefined' && typeof console.warn === 'function' && typeof console.warn.apply === 'function') { - return function () { - console.warn.apply(console, arguments); - }; - } - return function () { - }; - }(); -var utils_isNumeric = function () { - - return function (thing) { - return !isNaN(parseFloat(thing)) && isFinite(thing); - }; - }(); -var shared_interpolate = function (isArray, isObject, isNumeric) { - - var interpolate = function (from, to) { - if (isNumeric(from) && isNumeric(to)) { - return makeNumberInterpolator(+from, +to); - } - if (isArray(from) && isArray(to)) { - return makeArrayInterpolator(from, to); - } - if (isObject(from) && isObject(to)) { - return makeObjectInterpolator(from, to); - } - return function () { - return to; - }; - }; - return interpolate; - function makeNumberInterpolator(from, to) { - var delta = to - from; - if (!delta) { - return function () { - return from; - }; - } - return function (t) { - return from + t * delta; - }; - } - function makeArrayInterpolator(from, to) { - var intermediate, interpolators, len, i; - intermediate = []; - interpolators = []; - i = len = Math.min(from.length, to.length); - while (i--) { - interpolators[i] = interpolate(from[i], to[i]); - } - for (i = len; i < from.length; i += 1) { - intermediate[i] = from[i]; - } - for (i = len; i < to.length; i += 1) { - intermediate[i] = to[i]; - } - return function (t) { - var i = len; - while (i--) { - intermediate[i] = interpolators[i](t); - } - return intermediate; - }; - } - function makeObjectInterpolator(from, to) { - var properties = [], len, interpolators, intermediate, prop; - intermediate = {}; - interpolators = {}; - for (prop in from) { - if (from.hasOwnProperty(prop)) { - if (to.hasOwnProperty(prop)) { - properties[properties.length] = prop; - interpolators[prop] = interpolate(from[prop], to[prop]); - } else { - intermediate[prop] = from[prop]; - } - } - } - for (prop in to) { - if (to.hasOwnProperty(prop) && !from.hasOwnProperty(prop)) { - intermediate[prop] = to[prop]; - } - } - len = properties.length; - return function (t) { - var i = len, prop; - while (i--) { - prop = properties[i]; - intermediate[prop] = interpolators[prop](t); - } - return intermediate; - }; - } - }(utils_isArray, utils_isObject, utils_isNumeric); -var Ractive_prototype_animate_Animation = function (warn, interpolate) { - - var Animation = function (options) { - var key; - this.startTime = Date.now(); - for (key in options) { - if (options.hasOwnProperty(key)) { - this[key] = options[key]; - } - } - this.interpolator = interpolate(this.from, this.to); - this.running = true; - }; - Animation.prototype = { - tick: function () { - var elapsed, t, value, timeNow, index, keypath; - keypath = this.keypath; - if (this.running) { - timeNow = Date.now(); - elapsed = timeNow - this.startTime; - if (elapsed >= this.duration) { - if (keypath !== null) { - this.root.set(keypath, this.to); - } - if (this.step) { - this.step(1, this.to); - } - if (this.complete) { - this.complete(1, this.to); - } - index = this.root._animations.indexOf(this); - if (index === -1) { - warn('Animation was not found'); - } - this.root._animations.splice(index, 1); - this.running = false; - return false; - } - t = this.easing ? this.easing(elapsed / this.duration) : elapsed / this.duration; - if (keypath !== null) { - value = this.interpolator(t); - this.root.set(keypath, value); - } - if (this.step) { - this.step(t, value); - } - return true; - } - return false; - }, - stop: function () { - var index; - this.running = false; - index = this.root._animations.indexOf(this); - if (index === -1) { - warn('Animation was not found'); - } - this.root._animations.splice(index, 1); - } - }; - return Animation; - }(utils_warn, shared_interpolate); -var registries_easing = function () { - - return { - linear: function (pos) { - return pos; - }, - easeIn: function (pos) { - return Math.pow(pos, 3); - }, - easeOut: function (pos) { - return Math.pow(pos - 1, 3) + 1; - }, - easeInOut: function (pos) { - if ((pos /= 0.5) < 1) { - return 0.5 * Math.pow(pos, 3); - } - return 0.5 * (Math.pow(pos - 2, 3) + 2); - } - }; - }(); -var Ractive_prototype_animate__animate = function (isEqual, animations, Animation, easingRegistry) { - - var noAnimation = { - stop: function () { - } - }; - return function (keypath, to, options) { - var k, animation, animations, easing, duration, step, complete, makeValueCollector, currentValues, collectValue, dummy, dummyOptions; - if (typeof keypath === 'object') { - options = to || {}; - easing = options.easing; - duration = options.duration; - animations = []; - step = options.step; - complete = options.complete; - if (step || complete) { - currentValues = {}; - options.step = null; - options.complete = null; - makeValueCollector = function (keypath) { - return function (t, value) { - currentValues[keypath] = value; - }; - }; - } - for (k in keypath) { - if (keypath.hasOwnProperty(k)) { - if (step || complete) { - collectValue = makeValueCollector(k); - options = { - easing: easing, - duration: duration - }; - if (step) { - options.step = collectValue; - } - if (complete) { - options.complete = collectValue; - } - } - animations[animations.length] = animate(this, k, keypath[k], options); - } - } - if (step || complete) { - dummyOptions = { - easing: easing, - duration: duration - }; - if (step) { - dummyOptions.step = function (t) { - step(t, currentValues); - }; - } - if (complete) { - dummyOptions.complete = function (t) { - complete(t, currentValues); - }; - } - animations[animations.length] = dummy = animate(this, null, null, dummyOptions); - } - return { - stop: function () { - while (animations.length) { - animations.pop().stop(); - } - if (dummy) { - dummy.stop(); - } - } - }; - } - options = options || {}; - animation = animate(this, keypath, to, options); - return { - stop: function () { - animation.stop(); - } - }; - }; - function animate(root, keypath, to, options) { - var easing, duration, animation, from; - if (keypath !== null) { - from = root.get(keypath); - } - animations.abort(keypath, root); - if (isEqual(from, to)) { - if (options.complete) { - options.complete(1, options.to); - } - return noAnimation; - } - if (options.easing) { - if (typeof options.easing === 'function') { - easing = options.easing; - } else { - if (root.easing && root.easing[options.easing]) { - easing = root.easing[options.easing]; - } else { - easing = easingRegistry[options.easing]; - } - } - if (typeof easing !== 'function') { - easing = null; - } - } - duration = options.duration === undefined ? 400 : options.duration; - animation = new Animation({ - keypath: keypath, - from: from, - to: to, - root: root, - duration: duration, - easing: easing, - step: options.step, - complete: options.complete - }); - animations.add(animation); - root._animations[root._animations.length] = animation; - return animation; - } - }(utils_isEqual, Ractive_prototype_animate_animations, Ractive_prototype_animate_Animation, registries_easing); -var Ractive_prototype_on = function () { - - return function (eventName, callback) { - var self = this, listeners, n; - if (typeof eventName === 'object') { - listeners = []; - for (n in eventName) { - if (eventName.hasOwnProperty(n)) { - listeners[listeners.length] = this.on(n, eventName[n]); - } - } - return { - cancel: function () { - while (listeners.length) { - listeners.pop().cancel(); - } - } - }; - } - if (!this._subs[eventName]) { - this._subs[eventName] = [callback]; - } else { - this._subs[eventName].push(callback); - } - return { - cancel: function () { - self.off(eventName, callback); - } - }; - }; - }(); -var Ractive_prototype_off = function () { - - return function (eventName, callback) { - var subscribers, index; - if (!callback) { - if (!eventName) { - for (eventName in this._subs) { - delete this._subs[eventName]; - } - } else { - this._subs[eventName] = []; - } - } - subscribers = this._subs[eventName]; - if (subscribers) { - index = subscribers.indexOf(callback); - if (index !== -1) { - subscribers.splice(index, 1); - } - } - }; - }(); -var shared_registerDependant = function () { - - return function (dependant) { - var depsByKeypath, deps, keys, parentKeypath, map, ractive, keypath, priority; - ractive = dependant.root; - keypath = dependant.keypath; - priority = dependant.priority; - depsByKeypath = ractive._deps[priority] || (ractive._deps[priority] = {}); - deps = depsByKeypath[keypath] || (depsByKeypath[keypath] = []); - deps[deps.length] = dependant; - dependant.registered = true; - if (!keypath) { - return; - } - keys = keypath.split('.'); - while (keys.length) { - keys.pop(); - parentKeypath = keys.join('.'); - map = ractive._depsMap[parentKeypath] || (ractive._depsMap[parentKeypath] = []); - if (map[keypath] === undefined) { - map[keypath] = 0; - map[map.length] = keypath; - } - map[keypath] += 1; - keypath = parentKeypath; - } - }; - }(); -var shared_unregisterDependant = function () { - - return function (dependant) { - var deps, index, keys, parentKeypath, map, ractive, keypath, priority; - ractive = dependant.root; - keypath = dependant.keypath; - priority = dependant.priority; - deps = ractive._deps[priority][keypath]; - index = deps.indexOf(dependant); - if (index === -1 || !dependant.registered) { - throw new Error('Attempted to remove a dependant that was no longer registered! This should not happen. If you are seeing this bug in development please raise an issue at https://github.com/RactiveJS/Ractive/issues - thanks'); - } - deps.splice(index, 1); - dependant.registered = false; - if (!keypath) { - return; - } - keys = keypath.split('.'); - while (keys.length) { - keys.pop(); - parentKeypath = keys.join('.'); - map = ractive._depsMap[parentKeypath]; - map[keypath] -= 1; - if (!map[keypath]) { - map.splice(map.indexOf(keypath), 1); - map[keypath] = undefined; - } - keypath = parentKeypath; - } - }; - }(); -var Ractive_prototype_observe_Observer = function (isEqual) { - - var Observer = function (ractive, keypath, callback, options) { - var self = this; - this.root = ractive; - this.keypath = keypath; - this.callback = callback; - this.defer = options.defer; - this.debug = options.debug; - this.proxy = { - update: function () { - self.reallyUpdate(); - } - }; - this.priority = 0; - this.context = options && options.context ? options.context : ractive; - }; - Observer.prototype = { - init: function (immediate) { - if (immediate !== false) { - this.update(); - } else { - this.value = this.root.get(this.keypath); - } - }, - update: function () { - if (this.defer && this.ready) { - this.root._deferred.observers.push(this.proxy); - return; - } - this.reallyUpdate(); - }, - reallyUpdate: function () { - var oldValue, newValue; - oldValue = this.value; - newValue = this.root.get(this.keypath); - this.value = newValue; - if (this.updating) { - return; - } - this.updating = true; - if (!isEqual(newValue, oldValue) || !this.ready) { - try { - this.callback.call(this.context, newValue, oldValue, this.keypath); - } catch (err) { - if (this.debug || this.root.debug) { - throw err; - } - } - } - this.updating = false; - } - }; - return Observer; - }(utils_isEqual); -var Ractive_prototype_observe_getPattern = function () { - - return function (ractive, pattern) { - var keys, key, values, toGet, newToGet, expand, concatenate; - keys = pattern.split('.'); - toGet = []; - expand = function (keypath) { - var value, key; - value = ractive._wrapped[keypath] ? ractive._wrapped[keypath].get() : ractive.get(keypath); - for (key in value) { - newToGet.push(keypath + '.' + key); - } - }; - concatenate = function (keypath) { - return keypath + '.' + key; - }; - while (key = keys.shift()) { - if (key === '*') { - newToGet = []; - toGet.forEach(expand); - toGet = newToGet; - } else { - if (!toGet[0]) { - toGet[0] = key; - } else { - toGet = toGet.map(concatenate); - } - } - } - values = {}; - toGet.forEach(function (keypath) { - values[keypath] = ractive.get(keypath); - }); - return values; - }; - }(); -var Ractive_prototype_observe_PatternObserver = function (isEqual, getPattern) { - - var PatternObserver, wildcard = /\*/; - PatternObserver = function (ractive, keypath, callback, options) { - this.root = ractive; - this.callback = callback; - this.defer = options.defer; - this.debug = options.debug; - this.keypath = keypath; - this.regex = new RegExp('^' + keypath.replace(/\./g, '\\.').replace(/\*/g, '[^\\.]+') + '$'); - this.values = {}; - if (this.defer) { - this.proxies = []; - } - this.priority = 'pattern'; - this.context = options && options.context ? options.context : ractive; - }; - PatternObserver.prototype = { - init: function (immediate) { - var values, keypath; - values = getPattern(this.root, this.keypath); - if (immediate !== false) { - for (keypath in values) { - if (values.hasOwnProperty(keypath)) { - this.update(keypath); - } - } - } else { - this.values = values; - } - }, - update: function (keypath) { - var values; - if (wildcard.test(keypath)) { - values = getPattern(this.root, keypath); - for (keypath in values) { - if (values.hasOwnProperty(keypath)) { - this.update(keypath); - } - } - return; - } - if (this.defer && this.ready) { - this.root._deferred.observers.push(this.getProxy(keypath)); - return; - } - this.reallyUpdate(keypath); - }, - reallyUpdate: function (keypath) { - var value = this.root.get(keypath); - if (this.updating) { - this.values[keypath] = value; - return; - } - this.updating = true; - if (!isEqual(value, this.values[keypath]) || !this.ready) { - try { - this.callback.call(this.context, value, this.values[keypath], keypath); - } catch (err) { - if (this.debug || this.root.debug) { - throw err; - } - } - this.values[keypath] = value; - } - this.updating = false; - }, - getProxy: function (keypath) { - var self = this; - if (!this.proxies[keypath]) { - this.proxies[keypath] = { - update: function () { - self.reallyUpdate(keypath); - } - }; - } - return this.proxies[keypath]; - } - }; - return PatternObserver; - }(utils_isEqual, Ractive_prototype_observe_getPattern); -var Ractive_prototype_observe_getObserverFacade = function (normaliseKeypath, registerDependant, unregisterDependant, Observer, PatternObserver) { - - var wildcard = /\*/, emptyObject = {}; - return function getObserverFacade(ractive, keypath, callback, options) { - var observer, isPatternObserver; - keypath = normaliseKeypath(keypath); - options = options || emptyObject; - if (wildcard.test(keypath)) { - observer = new PatternObserver(ractive, keypath, callback, options); - ractive._patternObservers.push(observer); - isPatternObserver = true; - } else { - observer = new Observer(ractive, keypath, callback, options); - } - registerDependant(observer); - observer.init(options.init); - observer.ready = true; - return { - cancel: function () { - var index; - if (isPatternObserver) { - index = ractive._patternObservers.indexOf(observer); - if (index !== -1) { - ractive._patternObservers.splice(index, 1); - } - } - unregisterDependant(observer); - } - }; - }; - }(utils_normaliseKeypath, shared_registerDependant, shared_unregisterDependant, Ractive_prototype_observe_Observer, Ractive_prototype_observe_PatternObserver); -var Ractive_prototype_observe__observe = function (isObject, getObserverFacade) { - - return function observe(keypath, callback, options) { - var observers = [], k; - if (isObject(keypath)) { - options = callback; - for (k in keypath) { - if (keypath.hasOwnProperty(k)) { - callback = keypath[k]; - observers[observers.length] = getObserverFacade(this, k, callback, options); - } - } - return { - cancel: function () { - while (observers.length) { - observers.pop().cancel(); - } - } - }; - } - return getObserverFacade(this, keypath, callback, options); - }; - }(utils_isObject, Ractive_prototype_observe_getObserverFacade); -var Ractive_prototype_fire = function () { - - return function (eventName) { - var args, i, len, subscribers = this._subs[eventName]; - if (!subscribers) { - return; - } - args = Array.prototype.slice.call(arguments, 1); - for (i = 0, len = subscribers.length; i < len; i += 1) { - subscribers[i].apply(this, args); - } - }; - }(); -var Ractive_prototype_find = function () { - - return function (selector) { - if (!this.el) { - return null; - } - return this.fragment.find(selector); - }; - }(); -var utils_matches = function (isClient, createElement) { - - var div, methodNames, unprefixed, prefixed, vendors, i, j, makeFunction; - if (!isClient) { - return; - } - div = createElement('div'); - methodNames = [ - 'matches', - 'matchesSelector' - ]; - vendors = [ - 'o', - 'ms', - 'moz', - 'webkit' - ]; - makeFunction = function (methodName) { - return function (node, selector) { - return node[methodName](selector); - }; - }; - i = methodNames.length; - while (i--) { - unprefixed = methodNames[i]; - if (div[unprefixed]) { - return makeFunction(unprefixed); - } - j = vendors.length; - while (j--) { - prefixed = vendors[i] + unprefixed.substr(0, 1).toUpperCase() + unprefixed.substring(1); - if (div[prefixed]) { - return makeFunction(prefixed); - } - } - } - return function (node, selector) { - var nodes, i; - nodes = (node.parentNode || node.document).querySelectorAll(selector); - i = nodes.length; - while (i--) { - if (nodes[i] === node) { - return true; - } - } - return false; - }; - }(config_isClient, utils_createElement); -var Ractive_prototype_shared_makeQuery_test = function (matches) { - - return function (item, noDirty) { - var itemMatches = this._isComponentQuery ? !this.selector || item.name === this.selector : matches(item.node, this.selector); - if (itemMatches) { - this.push(item.node || item.instance); - if (!noDirty) { - this._makeDirty(); - } - return true; - } - }; - }(utils_matches); -var Ractive_prototype_shared_makeQuery_cancel = function () { - - return function () { - var liveQueries, selector, index; - liveQueries = this._root[this._isComponentQuery ? 'liveComponentQueries' : 'liveQueries']; - selector = this.selector; - index = liveQueries.indexOf(selector); - if (index !== -1) { - liveQueries.splice(index, 1); - liveQueries[selector] = null; - } - }; - }(); -var Ractive_prototype_shared_makeQuery_sortByItemPosition = function () { - - return function (a, b) { - var ancestryA, ancestryB, oldestA, oldestB, mutualAncestor, indexA, indexB, fragments, fragmentA, fragmentB; - ancestryA = getAncestry(a.component || a._ractive.proxy); - ancestryB = getAncestry(b.component || b._ractive.proxy); - oldestA = ancestryA[ancestryA.length - 1]; - oldestB = ancestryB[ancestryB.length - 1]; - while (oldestA && oldestA === oldestB) { - ancestryA.pop(); - ancestryB.pop(); - mutualAncestor = oldestA; - oldestA = ancestryA[ancestryA.length - 1]; - oldestB = ancestryB[ancestryB.length - 1]; - } - oldestA = oldestA.component || oldestA; - oldestB = oldestB.component || oldestB; - fragmentA = oldestA.parentFragment; - fragmentB = oldestB.parentFragment; - if (fragmentA === fragmentB) { - indexA = fragmentA.items.indexOf(oldestA); - indexB = fragmentB.items.indexOf(oldestB); - return indexA - indexB || ancestryA.length - ancestryB.length; - } - if (fragments = mutualAncestor.fragments) { - indexA = fragments.indexOf(fragmentA); - indexB = fragments.indexOf(fragmentB); - return indexA - indexB || ancestryA.length - ancestryB.length; - } - throw new Error('An unexpected condition was met while comparing the position of two components. Please file an issue at https://github.com/RactiveJS/Ractive/issues - thanks!'); - }; - function getParent(item) { - var parentFragment; - if (parentFragment = item.parentFragment) { - return parentFragment.owner; - } - if (item.component && (parentFragment = item.component.parentFragment)) { - return parentFragment.owner; - } - } - function getAncestry(item) { - var ancestry, ancestor; - ancestry = [item]; - ancestor = getParent(item); - while (ancestor) { - ancestry.push(ancestor); - ancestor = getParent(ancestor); - } - return ancestry; - } - }(); -var Ractive_prototype_shared_makeQuery_sortByDocumentPosition = function (sortByItemPosition) { - - return function (node, otherNode) { - var bitmask; - if (node.compareDocumentPosition) { - bitmask = node.compareDocumentPosition(otherNode); - return bitmask & 2 ? 1 : -1; - } - return sortByItemPosition(node, otherNode); - }; - }(Ractive_prototype_shared_makeQuery_sortByItemPosition); -var Ractive_prototype_shared_makeQuery_sort = function (sortByDocumentPosition, sortByItemPosition) { - - return function () { - this.sort(this._isComponentQuery ? sortByItemPosition : sortByDocumentPosition); - this._dirty = false; - }; - }(Ractive_prototype_shared_makeQuery_sortByDocumentPosition, Ractive_prototype_shared_makeQuery_sortByItemPosition); -var Ractive_prototype_shared_makeQuery_dirty = function () { - - return function () { - if (!this._dirty) { - this._root._deferred.liveQueries.push(this); - this._dirty = true; - } - }; - }(); -var Ractive_prototype_shared_makeQuery_remove = function () { - - return function (item) { - var index = this.indexOf(this._isComponentQuery ? item.instance : item.node); - if (index !== -1) { - this.splice(index, 1); - } - }; - }(); -var Ractive_prototype_shared_makeQuery__makeQuery = function (defineProperties, test, cancel, sort, dirty, remove) { - - return function (ractive, selector, live, isComponentQuery) { - var query; - query = []; - defineProperties(query, { - selector: { value: selector }, - live: { value: live }, - _isComponentQuery: { value: isComponentQuery }, - _test: { value: test } - }); - if (!live) { - return query; - } - defineProperties(query, { - cancel: { value: cancel }, - _root: { value: ractive }, - _sort: { value: sort }, - _makeDirty: { value: dirty }, - _remove: { value: remove }, - _dirty: { - value: false, - writable: true - } - }); - return query; - }; - }(utils_defineProperties, Ractive_prototype_shared_makeQuery_test, Ractive_prototype_shared_makeQuery_cancel, Ractive_prototype_shared_makeQuery_sort, Ractive_prototype_shared_makeQuery_dirty, Ractive_prototype_shared_makeQuery_remove); -var Ractive_prototype_findAll = function (warn, matches, defineProperties, makeQuery) { - - return function (selector, options) { - var liveQueries, query; - if (!this.el) { - return []; - } - options = options || {}; - liveQueries = this._liveQueries; - if (query = liveQueries[selector]) { - return options && options.live ? query : query.slice(); - } - query = makeQuery(this, selector, !!options.live, false); - if (query.live) { - liveQueries.push(selector); - liveQueries[selector] = query; - } - this.fragment.findAll(selector, query); - return query; - }; - }(utils_warn, utils_matches, utils_defineProperties, Ractive_prototype_shared_makeQuery__makeQuery); -var Ractive_prototype_findComponent = function () { - - return function (selector) { - return this.fragment.findComponent(selector); - }; - }(); -var Ractive_prototype_findAllComponents = function (warn, matches, defineProperties, makeQuery) { - - return function (selector, options) { - var liveQueries, query; - options = options || {}; - liveQueries = this._liveComponentQueries; - if (query = liveQueries[selector]) { - return options && options.live ? query : query.slice(); - } - query = makeQuery(this, selector, !!options.live, true); - if (query.live) { - liveQueries.push(selector); - liveQueries[selector] = query; - } - this.fragment.findAllComponents(selector, query); - return query; - }; - }(utils_warn, utils_matches, utils_defineProperties, Ractive_prototype_shared_makeQuery__makeQuery); -var utils_getElement = function () { - - return function (input) { - var output; - if (typeof window === 'undefined' || !document || !input) { - return null; - } - if (input.nodeType) { - return input; - } - if (typeof input === 'string') { - output = document.getElementById(input); - if (!output && document.querySelector) { - output = document.querySelector(input); - } - if (output && output.nodeType) { - return output; - } - } - if (input[0] && input[0].nodeType) { - return input[0]; - } - return null; - }; - }(); -var render_shared_initFragment = function (types, create) { - - return function (fragment, options) { - var numItems, i, parentFragment, parentRefs, ref; - fragment.owner = options.owner; - parentFragment = fragment.owner.parentFragment; - fragment.root = options.root; - fragment.pNode = options.pNode; - fragment.contextStack = options.contextStack || []; - if (fragment.owner.type === types.SECTION) { - fragment.index = options.index; - } - if (parentFragment) { - parentRefs = parentFragment.indexRefs; - if (parentRefs) { - fragment.indexRefs = create(null); - for (ref in parentRefs) { - fragment.indexRefs[ref] = parentRefs[ref]; - } - } - } - fragment.priority = parentFragment ? parentFragment.priority + 1 : 1; - if (options.indexRef) { - if (!fragment.indexRefs) { - fragment.indexRefs = {}; - } - fragment.indexRefs[options.indexRef] = options.index; - } - fragment.items = []; - numItems = options.descriptor ? options.descriptor.length : 0; - for (i = 0; i < numItems; i += 1) { - fragment.items[fragment.items.length] = fragment.createItem({ - parentFragment: fragment, - descriptor: options.descriptor[i], - index: i - }); - } - }; - }(config_types, utils_create); -var render_DomFragment_shared_insertHtml = function (createElement) { - - var elementCache = {}; - return function (html, tagName, docFrag) { - var container, nodes = []; - if (html) { - container = elementCache[tagName] || (elementCache[tagName] = createElement(tagName)); - container.innerHTML = html; - while (container.firstChild) { - nodes[nodes.length] = container.firstChild; - docFrag.appendChild(container.firstChild); - } - } - return nodes; - }; - }(utils_createElement); -var render_DomFragment_Text = function (types) { - - var DomText, lessThan, greaterThan; - lessThan = //g; - DomText = function (options, docFrag) { - this.type = types.TEXT; - this.descriptor = options.descriptor; - if (docFrag) { - this.node = document.createTextNode(options.descriptor); - docFrag.appendChild(this.node); - } - }; - DomText.prototype = { - detach: function () { - this.node.parentNode.removeChild(this.node); - return this.node; - }, - teardown: function (destroy) { - if (destroy) { - this.detach(); - } - }, - firstNode: function () { - return this.node; - }, - toString: function () { - return ('' + this.descriptor).replace(lessThan, '<').replace(greaterThan, '>'); - } - }; - return DomText; - }(config_types); -var shared_teardown = function (unregisterDependant) { - - return function (thing) { - if (!thing.keypath) { - var index = thing.root._pendingResolution.indexOf(thing); - if (index !== -1) { - thing.root._pendingResolution.splice(index, 1); - } - } else { - unregisterDependant(thing); - } - }; - }(shared_unregisterDependant); -var render_shared_Evaluator_Reference = function (types, isEqual, defineProperty, registerDependant, unregisterDependant) { - - var Reference, thisPattern; - thisPattern = /this/; - Reference = function (root, keypath, evaluator, argNum, priority) { - var value; - this.evaluator = evaluator; - this.keypath = keypath; - this.root = root; - this.argNum = argNum; - this.type = types.REFERENCE; - this.priority = priority; - value = root.get(keypath); - if (typeof value === 'function') { - value = wrapFunction(value, root, evaluator); - } - this.value = evaluator.values[argNum] = value; - registerDependant(this); - }; - Reference.prototype = { - update: function () { - var value = this.root.get(this.keypath); - if (typeof value === 'function' && !value._nowrap) { - value = wrapFunction(value, this.root, this.evaluator); - } - if (!isEqual(value, this.value)) { - this.evaluator.values[this.argNum] = value; - this.evaluator.bubble(); - this.value = value; - } - }, - teardown: function () { - unregisterDependant(this); - } - }; - return Reference; - function wrapFunction(fn, ractive, evaluator) { - var prop, evaluators, index; - if (!thisPattern.test(fn.toString())) { - defineProperty(fn, '_nowrap', { value: true }); - return fn; - } - if (!fn['_' + ractive._guid]) { - defineProperty(fn, '_' + ractive._guid, { - value: function () { - var originalCaptured, result, i, evaluator; - originalCaptured = ractive._captured; - if (!originalCaptured) { - ractive._captured = []; - } - result = fn.apply(ractive, arguments); - if (ractive._captured.length) { - i = evaluators.length; - while (i--) { - evaluator = evaluators[i]; - evaluator.updateSoftDependencies(ractive._captured); - } - } - ractive._captured = originalCaptured; - return result; - }, - writable: true - }); - for (prop in fn) { - if (fn.hasOwnProperty(prop)) { - fn['_' + ractive._guid][prop] = fn[prop]; - } - } - fn['_' + ractive._guid + '_evaluators'] = []; - } - evaluators = fn['_' + ractive._guid + '_evaluators']; - index = evaluators.indexOf(evaluator); - if (index === -1) { - evaluators.push(evaluator); - } - return fn['_' + ractive._guid]; - } - }(config_types, utils_isEqual, utils_defineProperty, shared_registerDependant, shared_unregisterDependant); -var render_shared_Evaluator_SoftReference = function (isEqual, registerDependant, unregisterDependant) { - - var SoftReference = function (root, keypath, evaluator) { - this.root = root; - this.keypath = keypath; - this.priority = evaluator.priority; - this.evaluator = evaluator; - registerDependant(this); - }; - SoftReference.prototype = { - update: function () { - var value = this.root.get(this.keypath); - if (!isEqual(value, this.value)) { - this.evaluator.bubble(); - this.value = value; - } - }, - teardown: function () { - unregisterDependant(this); - } - }; - return SoftReference; - }(utils_isEqual, shared_registerDependant, shared_unregisterDependant); -var render_shared_Evaluator__Evaluator = function (isEqual, defineProperty, clearCache, notifyDependants, registerDependant, unregisterDependant, adaptIfNecessary, Reference, SoftReference) { - - var Evaluator, cache = {}; - Evaluator = function (root, keypath, functionStr, args, priority) { - var i, arg; - this.root = root; - this.keypath = keypath; - this.priority = priority; - this.fn = getFunctionFromString(functionStr, args.length); - this.values = []; - this.refs = []; - i = args.length; - while (i--) { - if (arg = args[i]) { - if (arg[0]) { - this.values[i] = arg[1]; - } else { - this.refs[this.refs.length] = new Reference(root, arg[1], this, i, priority); - } - } else { - this.values[i] = undefined; - } - } - this.selfUpdating = this.refs.length <= 1; - this.update(); - }; - Evaluator.prototype = { - bubble: function () { - if (this.selfUpdating) { - this.update(); - } else if (!this.deferred) { - this.root._deferred.evals.push(this); - this.deferred = true; - } - }, - update: function () { - var value; - if (this.evaluating) { - return this; - } - this.evaluating = true; - try { - value = this.fn.apply(null, this.values); - } catch (err) { - if (this.root.debug) { - throw err; - } else { - value = undefined; - } - } - if (!isEqual(value, this.value)) { - clearCache(this.root, this.keypath); - this.root._cache[this.keypath] = value; - adaptIfNecessary(this.root, this.keypath, value, true); - this.value = value; - notifyDependants(this.root, this.keypath); - } - this.evaluating = false; - return this; - }, - teardown: function () { - while (this.refs.length) { - this.refs.pop().teardown(); - } - clearCache(this.root, this.keypath); - this.root._evaluators[this.keypath] = null; - }, - refresh: function () { - if (!this.selfUpdating) { - this.deferred = true; - } - var i = this.refs.length; - while (i--) { - this.refs[i].update(); - } - if (this.deferred) { - this.update(); - this.deferred = false; - } - }, - updateSoftDependencies: function (softDeps) { - var i, keypath, ref; - if (!this.softRefs) { - this.softRefs = []; - } - i = this.softRefs.length; - while (i--) { - ref = this.softRefs[i]; - if (!softDeps[ref.keypath]) { - this.softRefs.splice(i, 1); - this.softRefs[ref.keypath] = false; - ref.teardown(); - } - } - i = softDeps.length; - while (i--) { - keypath = softDeps[i]; - if (!this.softRefs[keypath]) { - ref = new SoftReference(this.root, keypath, this); - this.softRefs[this.softRefs.length] = ref; - this.softRefs[keypath] = true; - } - } - this.selfUpdating = this.refs.length + this.softRefs.length <= 1; - } - }; - return Evaluator; - function getFunctionFromString(str, i) { - var fn, args; - str = str.replace(/\$\{([0-9]+)\}/g, '_$1'); - if (cache[str]) { - return cache[str]; - } - args = []; - while (i--) { - args[i] = '_' + i; - } - fn = new Function(args.join(','), 'return(' + str + ')'); - cache[str] = fn; - return fn; - } - }(utils_isEqual, utils_defineProperty, shared_clearCache, shared_notifyDependants, shared_registerDependant, shared_unregisterDependant, shared_adaptIfNecessary, render_shared_Evaluator_Reference, render_shared_Evaluator_SoftReference); -var render_shared_ExpressionResolver_ReferenceScout = function (resolveRef, teardown) { - - var ReferenceScout = function (resolver, ref, contextStack, argNum) { - var keypath, root; - root = this.root = resolver.root; - keypath = resolveRef(root, ref, contextStack); - if (keypath !== undefined) { - resolver.resolveRef(argNum, false, keypath); - } else { - this.ref = ref; - this.argNum = argNum; - this.resolver = resolver; - this.contextStack = contextStack; - root._pendingResolution[root._pendingResolution.length] = this; - } - }; - ReferenceScout.prototype = { - resolve: function (keypath) { - this.keypath = keypath; - this.resolver.resolveRef(this.argNum, false, keypath); - }, - teardown: function () { - if (!this.keypath) { - teardown(this); - } - } - }; - return ReferenceScout; - }(shared_resolveRef, shared_teardown); -var render_shared_ExpressionResolver_isRegularKeypath = function () { - - var keyPattern = /^(?:(?:[a-zA-Z$_][a-zA-Z$_0-9]*)|(?:[0-9]|[1-9][0-9]+))$/; - return function (keypath) { - var keys, key, i; - keys = keypath.split('.'); - i = keys.length; - while (i--) { - key = keys[i]; - if (key === 'undefined' || !keyPattern.test(key)) { - return false; - } - } - return true; - }; - }(); -var render_shared_ExpressionResolver_getKeypath = function (normaliseKeypath, isRegularKeypath) { - - return function (str, args) { - var unique, normalised; - unique = str.replace(/\$\{([0-9]+)\}/g, function (match, $1) { - return args[$1] ? args[$1][1] : 'undefined'; - }); - normalised = normaliseKeypath(unique); - if (isRegularKeypath(normalised)) { - return normalised; - } - return '${' + unique.replace(/[\.\[\]]/g, '-') + '}'; - }; - }(utils_normaliseKeypath, render_shared_ExpressionResolver_isRegularKeypath); -var render_shared_ExpressionResolver_reassignDependants = function (registerDependant, unregisterDependant) { - - return function (ractive, oldKeypath, newKeypath) { - var toReassign, i, dependant; - toReassign = []; - gatherDependants(ractive, oldKeypath, toReassign); - i = toReassign.length; - while (i--) { - dependant = toReassign[i]; - unregisterDependant(dependant); - dependant.keypath = dependant.keypath.replace(oldKeypath, newKeypath); - registerDependant(dependant); - dependant.update(); - } - }; - function cascade(ractive, oldKeypath, toReassign) { - var map, i; - map = ractive._depsMap[oldKeypath]; - if (!map) { - return; - } - i = map.length; - while (i--) { - gatherDependants(ractive, map[i], toReassign); - } - } - function gatherDependants(ractive, oldKeypath, toReassign) { - var priority, dependantsByKeypath, dependants, i; - priority = ractive._deps.length; - while (priority--) { - dependantsByKeypath = ractive._deps[priority]; - if (dependantsByKeypath) { - dependants = dependantsByKeypath[oldKeypath]; - if (dependants) { - i = dependants.length; - while (i--) { - toReassign.push(dependants[i]); - } - } - } - } - cascade(ractive, oldKeypath, toReassign); - } - }(shared_registerDependant, shared_unregisterDependant); -var render_shared_ExpressionResolver__ExpressionResolver = function (Evaluator, ReferenceScout, getKeypath, reassignDependants) { - - var ExpressionResolver = function (mustache) { - var expression, i, len, ref, indexRefs; - this.root = mustache.root; - this.mustache = mustache; - this.args = []; - this.scouts = []; - expression = mustache.descriptor.x; - indexRefs = mustache.parentFragment.indexRefs; - this.str = expression.s; - len = this.unresolved = this.args.length = expression.r ? expression.r.length : 0; - if (!len) { - this.resolved = this.ready = true; - this.bubble(); - return; - } - for (i = 0; i < len; i += 1) { - ref = expression.r[i]; - if (indexRefs && indexRefs[ref] !== undefined) { - this.resolveRef(i, true, indexRefs[ref]); - } else { - this.scouts[this.scouts.length] = new ReferenceScout(this, ref, mustache.contextStack, i); - } - } - this.ready = true; - this.bubble(); - }; - ExpressionResolver.prototype = { - bubble: function () { - var oldKeypath; - if (!this.ready) { - return; - } - oldKeypath = this.keypath; - this.keypath = getKeypath(this.str, this.args); - if (this.keypath.substr(0, 2) === '${') { - this.createEvaluator(); - } - if (oldKeypath) { - reassignDependants(this.root, oldKeypath, this.keypath); - } else { - this.mustache.resolve(this.keypath); - } - }, - teardown: function () { - while (this.scouts.length) { - this.scouts.pop().teardown(); - } - }, - resolveRef: function (argNum, isIndexRef, value) { - this.args[argNum] = [ - isIndexRef, - value - ]; - this.bubble(); - this.resolved = !--this.unresolved; - }, - createEvaluator: function () { - if (!this.root._evaluators[this.keypath]) { - this.root._evaluators[this.keypath] = new Evaluator(this.root, this.keypath, this.str, this.args, this.mustache.priority); - } else { - this.root._evaluators[this.keypath].refresh(); - } - } - }; - return ExpressionResolver; - }(render_shared_Evaluator__Evaluator, render_shared_ExpressionResolver_ReferenceScout, render_shared_ExpressionResolver_getKeypath, render_shared_ExpressionResolver_reassignDependants); -var render_shared_initMustache = function (resolveRef, ExpressionResolver) { - - return function (mustache, options) { - var keypath, indexRef, parentFragment; - parentFragment = mustache.parentFragment = options.parentFragment; - mustache.root = parentFragment.root; - mustache.contextStack = parentFragment.contextStack; - mustache.descriptor = options.descriptor; - mustache.index = options.index || 0; - mustache.priority = parentFragment.priority; - mustache.type = options.descriptor.t; - if (options.descriptor.r) { - if (parentFragment.indexRefs && parentFragment.indexRefs[options.descriptor.r] !== undefined) { - indexRef = parentFragment.indexRefs[options.descriptor.r]; - mustache.indexRef = options.descriptor.r; - mustache.value = indexRef; - mustache.render(mustache.value); - } else { - keypath = resolveRef(mustache.root, options.descriptor.r, mustache.contextStack); - if (keypath !== undefined) { - mustache.resolve(keypath); - } else { - mustache.ref = options.descriptor.r; - mustache.root._pendingResolution[mustache.root._pendingResolution.length] = mustache; - } - } - } - if (options.descriptor.x) { - mustache.expressionResolver = new ExpressionResolver(mustache); - } - if (mustache.descriptor.n && !mustache.hasOwnProperty('value')) { - mustache.render(undefined); - } - }; - }(shared_resolveRef, render_shared_ExpressionResolver__ExpressionResolver); -var render_shared_resolveMustache = function (types, registerDependant, unregisterDependant) { - - return function (keypath) { - if (keypath === this.keypath) { - return; - } - if (this.registered) { - unregisterDependant(this); - } - this.keypath = keypath; - registerDependant(this); - this.update(); - if (this.root.twoway && this.parentFragment.owner.type === types.ATTRIBUTE) { - this.parentFragment.owner.element.bind(); - } - if (this.expressionResolver && this.expressionResolver.resolved) { - this.expressionResolver = null; - } - }; - }(config_types, shared_registerDependant, shared_unregisterDependant); -var render_shared_updateMustache = function (isEqual) { - - return function () { - var wrapped, value; - value = this.root.get(this.keypath); - if (wrapped = this.root._wrapped[this.keypath]) { - value = wrapped.get(); - } - if (!isEqual(value, this.value)) { - this.render(value); - this.value = value; - } - }; - }(utils_isEqual); -var render_DomFragment_Interpolator = function (types, teardown, initMustache, resolveMustache, updateMustache) { - - var DomInterpolator, lessThan, greaterThan; - lessThan = //g; - DomInterpolator = function (options, docFrag) { - this.type = types.INTERPOLATOR; - if (docFrag) { - this.node = document.createTextNode(''); - docFrag.appendChild(this.node); - } - initMustache(this, options); - }; - DomInterpolator.prototype = { - update: updateMustache, - resolve: resolveMustache, - detach: function () { - this.node.parentNode.removeChild(this.node); - return this.node; - }, - teardown: function (destroy) { - if (destroy) { - this.detach(); - } - teardown(this); - }, - render: function (value) { - if (this.node) { - this.node.data = value == undefined ? '' : value; - } - }, - firstNode: function () { - return this.node; - }, - toString: function () { - var value = this.value != undefined ? '' + this.value : ''; - return value.replace(lessThan, '<').replace(greaterThan, '>'); - } - }; - return DomInterpolator; - }(config_types, shared_teardown, render_shared_initMustache, render_shared_resolveMustache, render_shared_updateMustache); -var render_shared_updateSection = function (isArray, isObject, create) { - - return function (section, value) { - var fragmentOptions; - fragmentOptions = { - descriptor: section.descriptor.f, - root: section.root, - pNode: section.parentFragment.pNode, - owner: section - }; - if (section.descriptor.n) { - updateConditionalSection(section, value, true, fragmentOptions); - return; - } - if (isArray(value)) { - updateListSection(section, value, fragmentOptions); - } else if (isObject(value)) { - if (section.descriptor.i) { - updateListObjectSection(section, value, fragmentOptions); - } else { - updateContextSection(section, fragmentOptions); - } - } else { - updateConditionalSection(section, value, false, fragmentOptions); - } - }; - function updateListSection(section, value, fragmentOptions) { - var i, length, fragmentsToRemove; - length = value.length; - if (length < section.length) { - fragmentsToRemove = section.fragments.splice(length, section.length - length); - while (fragmentsToRemove.length) { - fragmentsToRemove.pop().teardown(true); - } - } else { - if (length > section.length) { - for (i = section.length; i < length; i += 1) { - fragmentOptions.contextStack = section.contextStack.concat(section.keypath + '.' + i); - fragmentOptions.index = i; - if (section.descriptor.i) { - fragmentOptions.indexRef = section.descriptor.i; - } - section.fragments[i] = section.createFragment(fragmentOptions); - } - } - } - section.length = length; - } - function updateListObjectSection(section, value, fragmentOptions) { - var id, fragmentsById; - fragmentsById = section.fragmentsById || (section.fragmentsById = create(null)); - for (id in fragmentsById) { - if (value[id] === undefined && fragmentsById[id]) { - fragmentsById[id].teardown(true); - fragmentsById[id] = null; - } - } - for (id in value) { - if (value[id] !== undefined && !fragmentsById[id]) { - fragmentOptions.contextStack = section.contextStack.concat(section.keypath + '.' + id); - fragmentOptions.index = id; - if (section.descriptor.i) { - fragmentOptions.indexRef = section.descriptor.i; - } - fragmentsById[id] = section.createFragment(fragmentOptions); - } - } - } - function updateContextSection(section, fragmentOptions) { - if (!section.length) { - fragmentOptions.contextStack = section.contextStack.concat(section.keypath); - fragmentOptions.index = 0; - section.fragments[0] = section.createFragment(fragmentOptions); - section.length = 1; - } - } - function updateConditionalSection(section, value, inverted, fragmentOptions) { - var doRender, emptyArray, fragmentsToRemove, fragment; - emptyArray = isArray(value) && value.length === 0; - if (inverted) { - doRender = emptyArray || !value; - } else { - doRender = value && !emptyArray; - } - if (doRender) { - if (!section.length) { - fragmentOptions.contextStack = section.contextStack; - fragmentOptions.index = 0; - section.fragments[0] = section.createFragment(fragmentOptions); - section.length = 1; - } - if (section.length > 1) { - fragmentsToRemove = section.fragments.splice(1); - while (fragment = fragmentsToRemove.pop()) { - fragment.teardown(true); - } - } - } else if (section.length) { - section.teardownFragments(true); - section.length = 0; - } - } - }(utils_isArray, utils_isObject, utils_create); -var render_DomFragment_Section_reassignFragment = function (types, unregisterDependant, ExpressionResolver) { - - return reassignFragment; - function reassignFragment(fragment, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath) { - var i, item, context, query; - if (fragment.html) { - return; - } - if (fragment.indexRefs && fragment.indexRefs[indexRef] !== undefined) { - fragment.indexRefs[indexRef] = newIndex; - } - i = fragment.contextStack.length; - while (i--) { - context = fragment.contextStack[i]; - if (context.substr(0, oldKeypath.length) === oldKeypath) { - fragment.contextStack[i] = context.replace(oldKeypath, newKeypath); - } - } - i = fragment.items.length; - while (i--) { - item = fragment.items[i]; - switch (item.type) { - case types.ELEMENT: - reassignElement(item, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - break; - case types.PARTIAL: - reassignFragment(item.fragment, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - break; - case types.COMPONENT: - reassignFragment(item.instance.fragment, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - if (query = fragment.root._liveComponentQueries[item.name]) { - query._makeDirty(); - } - break; - case types.SECTION: - case types.INTERPOLATOR: - case types.TRIPLE: - reassignMustache(item, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - break; - } - } - } - function reassignElement(element, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath) { - var i, attribute, storage, masterEventName, proxies, proxy, binding, bindings, liveQueries, ractive; - i = element.attributes.length; - while (i--) { - attribute = element.attributes[i]; - if (attribute.fragment) { - reassignFragment(attribute.fragment, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - if (attribute.twoway) { - attribute.updateBindings(); - } - } - } - if (storage = element.node._ractive) { - if (storage.keypath.substr(0, oldKeypath.length) === oldKeypath) { - storage.keypath = storage.keypath.replace(oldKeypath, newKeypath); - } - if (indexRef !== undefined) { - storage.index[indexRef] = newIndex; - } - for (masterEventName in storage.events) { - proxies = storage.events[masterEventName].proxies; - i = proxies.length; - while (i--) { - proxy = proxies[i]; - if (typeof proxy.n === 'object') { - reassignFragment(proxy.a, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - } - if (proxy.d) { - reassignFragment(proxy.d, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - } - } - } - if (binding = storage.binding) { - if (binding.keypath.substr(0, oldKeypath.length) === oldKeypath) { - bindings = storage.root._twowayBindings[binding.keypath]; - bindings.splice(bindings.indexOf(binding), 1); - binding.keypath = binding.keypath.replace(oldKeypath, newKeypath); - bindings = storage.root._twowayBindings[binding.keypath] || (storage.root._twowayBindings[binding.keypath] = []); - bindings.push(binding); - } - } - } - if (element.fragment) { - reassignFragment(element.fragment, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - } - if (liveQueries = element.liveQueries) { - ractive = element.root; - i = liveQueries.length; - while (i--) { - ractive._liveQueries[liveQueries[i]]._makeDirty(); - } - } - } - function reassignMustache(mustache, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath) { - var i; - if (mustache.descriptor.x) { - if (mustache.expressionResolver) { - mustache.expressionResolver.teardown(); - } - mustache.expressionResolver = new ExpressionResolver(mustache); - } - if (mustache.keypath) { - if (mustache.keypath.substr(0, oldKeypath.length) === oldKeypath) { - mustache.resolve(mustache.keypath.replace(oldKeypath, newKeypath)); - } - } else if (mustache.indexRef === indexRef) { - mustache.value = newIndex; - mustache.render(newIndex); - } - if (mustache.fragments) { - i = mustache.fragments.length; - while (i--) { - reassignFragment(mustache.fragments[i], indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - } - } - } - }(config_types, shared_unregisterDependant, render_shared_ExpressionResolver__ExpressionResolver); -var render_DomFragment_Section_reassignFragments = function (types, reassignFragment, preDomUpdate) { - - return function (root, section, start, end, by) { - var i, fragment, indexRef, oldIndex, newIndex, oldKeypath, newKeypath; - indexRef = section.descriptor.i; - for (i = start; i < end; i += 1) { - fragment = section.fragments[i]; - oldIndex = i - by; - newIndex = i; - oldKeypath = section.keypath + '.' + (i - by); - newKeypath = section.keypath + '.' + i; - fragment.index += by; - reassignFragment(fragment, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - } - preDomUpdate(root); - }; - }(config_types, render_DomFragment_Section_reassignFragment, shared_preDomUpdate); -var render_DomFragment_Section_prototype_merge = function (reassignFragment) { - - return function (newIndices) { - var section = this, parentFragment, firstChange, changed, i, newLength, newFragments, toTeardown, fragmentOptions, fragment, nextNode; - parentFragment = this.parentFragment; - newFragments = []; - newIndices.forEach(function (newIndex, oldIndex) { - var by, oldKeypath, newKeypath; - if (newIndex === oldIndex) { - newFragments[newIndex] = section.fragments[oldIndex]; - return; - } - if (firstChange === undefined) { - firstChange = oldIndex; - } - if (newIndex === -1) { - (toTeardown || (toTeardown = [])).push(section.fragments[oldIndex]); - return; - } - by = newIndex - oldIndex; - oldKeypath = section.keypath + '.' + oldIndex; - newKeypath = section.keypath + '.' + newIndex; - reassignFragment(section.fragments[oldIndex], section.descriptor.i, oldIndex, newIndex, by, oldKeypath, newKeypath); - newFragments[newIndex] = section.fragments[oldIndex]; - changed = true; - }); - if (toTeardown) { - while (fragment = toTeardown.pop()) { - fragment.teardown(true); - } - } - if (firstChange === undefined) { - firstChange = this.length; - } - newLength = this.root.get(this.keypath).length; - if (newLength === firstChange) { - return; - } - fragmentOptions = { - descriptor: this.descriptor.f, - root: this.root, - pNode: parentFragment.pNode, - owner: this - }; - if (this.descriptor.i) { - fragmentOptions.indexRef = this.descriptor.i; - } - for (i = firstChange; i < newLength; i += 1) { - if (fragment = newFragments[i]) { - this.docFrag.appendChild(fragment.detach(false)); - } else { - fragmentOptions.contextStack = this.contextStack.concat(this.keypath + '.' + i); - fragmentOptions.index = i; - fragment = this.createFragment(fragmentOptions); - } - this.fragments[i] = fragment; - } - nextNode = parentFragment.findNextNode(this); - parentFragment.pNode.insertBefore(this.docFrag, nextNode); - this.length = newLength; - }; - }(render_DomFragment_Section_reassignFragment); -var circular = function () { - - return []; - }(); -var render_DomFragment_Section__Section = function (types, isClient, initMustache, updateMustache, resolveMustache, updateSection, reassignFragment, reassignFragments, merge, teardown, circular) { - - var DomSection, DomFragment; - circular.push(function () { - DomFragment = circular.DomFragment; - }); - DomSection = function (options, docFrag) { - this.type = types.SECTION; - this.inverted = !!options.descriptor.n; - this.fragments = []; - this.length = 0; - if (docFrag) { - this.docFrag = document.createDocumentFragment(); - } - this.initialising = true; - initMustache(this, options); - if (docFrag) { - docFrag.appendChild(this.docFrag); - } - this.initialising = false; - }; - DomSection.prototype = { - update: updateMustache, - resolve: resolveMustache, - smartUpdate: function (methodName, args) { - var fragmentOptions; - if (methodName === 'push' || methodName === 'unshift' || methodName === 'splice') { - fragmentOptions = { - descriptor: this.descriptor.f, - root: this.root, - pNode: this.parentFragment.pNode, - owner: this - }; - if (this.descriptor.i) { - fragmentOptions.indexRef = this.descriptor.i; - } - } - if (this[methodName]) { - this.rendering = true; - this[methodName](fragmentOptions, args); - this.rendering = false; - } - }, - pop: function () { - if (this.length) { - this.fragments.pop().teardown(true); - this.length -= 1; - } - }, - push: function (fragmentOptions, args) { - var start, end, i; - start = this.length; - end = start + args.length; - for (i = start; i < end; i += 1) { - fragmentOptions.contextStack = this.contextStack.concat(this.keypath + '.' + i); - fragmentOptions.index = i; - this.fragments[i] = this.createFragment(fragmentOptions); - } - this.length += args.length; - this.parentFragment.pNode.insertBefore(this.docFrag, this.parentFragment.findNextNode(this)); - }, - shift: function () { - this.splice(null, [ - 0, - 1 - ]); - }, - unshift: function (fragmentOptions, args) { - this.splice(fragmentOptions, [ - 0, - 0 - ].concat(new Array(args.length))); - }, - splice: function (fragmentOptions, args) { - var insertionPoint, addedItems, removedItems, balance, i, start, end, spliceArgs, reassignStart; - if (!args.length) { - return; - } - start = +(args[0] < 0 ? this.length + args[0] : args[0]); - addedItems = Math.max(0, args.length - 2); - removedItems = args[1] !== undefined ? args[1] : this.length - start; - removedItems = Math.min(removedItems, this.length - start); - balance = addedItems - removedItems; - if (!balance) { - return; - } - if (balance < 0) { - end = start - balance; - for (i = start; i < end; i += 1) { - this.fragments[i].teardown(true); - } - this.fragments.splice(start, -balance); - } else { - end = start + balance; - insertionPoint = this.fragments[start] ? this.fragments[start].firstNode() : this.parentFragment.findNextNode(this); - spliceArgs = [ - start, - 0 - ].concat(new Array(balance)); - this.fragments.splice.apply(this.fragments, spliceArgs); - for (i = start; i < end; i += 1) { - fragmentOptions.contextStack = this.contextStack.concat(this.keypath + '.' + i); - fragmentOptions.index = i; - this.fragments[i] = this.createFragment(fragmentOptions); - } - this.parentFragment.pNode.insertBefore(this.docFrag, insertionPoint); - } - this.length += balance; - reassignStart = start + addedItems; - reassignFragments(this.root, this, reassignStart, this.length, balance); - }, - merge: merge, - detach: function () { - var i, len; - len = this.fragments.length; - for (i = 0; i < len; i += 1) { - this.docFrag.appendChild(this.fragments[i].detach()); - } - return this.docFrag; - }, - teardown: function (destroy) { - this.teardownFragments(destroy); - teardown(this); - }, - firstNode: function () { - if (this.fragments[0]) { - return this.fragments[0].firstNode(); - } - return this.parentFragment.findNextNode(this); - }, - findNextNode: function (fragment) { - if (this.fragments[fragment.index + 1]) { - return this.fragments[fragment.index + 1].firstNode(); - } - return this.parentFragment.findNextNode(this); - }, - teardownFragments: function (destroy) { - var id, fragment; - while (fragment = this.fragments.shift()) { - fragment.teardown(destroy); - } - if (this.fragmentsById) { - for (id in this.fragmentsById) { - if (this.fragments[id]) { - this.fragmentsById[id].teardown(destroy); - this.fragmentsById[id] = null; - } - } - } - }, - render: function (value) { - var nextNode, wrapped; - if (wrapped = this.root._wrapped[this.keypath]) { - value = wrapped.get(); - } - if (this.rendering) { - return; - } - this.rendering = true; - updateSection(this, value); - this.rendering = false; - if (this.docFrag && !this.docFrag.childNodes.length) { - return; - } - if (!this.initialising && isClient) { - nextNode = this.parentFragment.findNextNode(this); - if (nextNode && nextNode.parentNode === this.parentFragment.pNode) { - this.parentFragment.pNode.insertBefore(this.docFrag, nextNode); - } else { - this.parentFragment.pNode.appendChild(this.docFrag); - } - } - }, - createFragment: function (options) { - var fragment = new DomFragment(options); - if (this.docFrag) { - this.docFrag.appendChild(fragment.docFrag); - } - return fragment; - }, - toString: function () { - var str, i, id, len; - str = ''; - i = 0; - len = this.length; - for (i = 0; i < len; i += 1) { - str += this.fragments[i].toString(); - } - if (this.fragmentsById) { - for (id in this.fragmentsById) { - if (this.fragmentsById[id]) { - str += this.fragmentsById[id].toString(); - } - } - } - return str; - }, - find: function (selector) { - var i, len, queryResult; - len = this.fragments.length; - for (i = 0; i < len; i += 1) { - if (queryResult = this.fragments[i].find(selector)) { - return queryResult; - } - } - return null; - }, - findAll: function (selector, query) { - var i, len; - len = this.fragments.length; - for (i = 0; i < len; i += 1) { - this.fragments[i].findAll(selector, query); - } - }, - findComponent: function (selector) { - var i, len, queryResult; - len = this.fragments.length; - for (i = 0; i < len; i += 1) { - if (queryResult = this.fragments[i].findComponent(selector)) { - return queryResult; - } - } - return null; - }, - findAllComponents: function (selector, query) { - var i, len; - len = this.fragments.length; - for (i = 0; i < len; i += 1) { - this.fragments[i].findAllComponents(selector, query); - } - } - }; - return DomSection; - }(config_types, config_isClient, render_shared_initMustache, render_shared_updateMustache, render_shared_resolveMustache, render_shared_updateSection, render_DomFragment_Section_reassignFragment, render_DomFragment_Section_reassignFragments, render_DomFragment_Section_prototype_merge, shared_teardown, circular); -var render_DomFragment_Triple = function (types, matches, initMustache, updateMustache, resolveMustache, insertHtml, teardown) { - - var DomTriple = function (options, docFrag) { - this.type = types.TRIPLE; - if (docFrag) { - this.nodes = []; - this.docFrag = document.createDocumentFragment(); - } - this.initialising = true; - initMustache(this, options); - if (docFrag) { - docFrag.appendChild(this.docFrag); - } - this.initialising = false; - }; - DomTriple.prototype = { - update: updateMustache, - resolve: resolveMustache, - detach: function () { - var i = this.nodes.length; - while (i--) { - this.docFrag.appendChild(this.nodes[i]); - } - return this.docFrag; - }, - teardown: function (destroy) { - if (destroy) { - this.detach(); - this.docFrag = this.nodes = null; - } - teardown(this); - }, - firstNode: function () { - if (this.nodes[0]) { - return this.nodes[0]; - } - return this.parentFragment.findNextNode(this); - }, - render: function (html) { - var node, pNode; - if (!this.nodes) { - return; - } - while (this.nodes.length) { - node = this.nodes.pop(); - node.parentNode.removeChild(node); - } - if (!html) { - this.nodes = []; - return; - } - pNode = this.parentFragment.pNode; - this.nodes = insertHtml(html, pNode.tagName, this.docFrag); - if (!this.initialising) { - pNode.insertBefore(this.docFrag, this.parentFragment.findNextNode(this)); - } - }, - toString: function () { - return this.value != undefined ? this.value : ''; - }, - find: function (selector) { - var i, len, node, queryResult; - len = this.nodes.length; - for (i = 0; i < len; i += 1) { - node = this.nodes[i]; - if (node.nodeType !== 1) { - continue; - } - if (matches(node, selector)) { - return node; - } - if (queryResult = node.querySelector(selector)) { - return queryResult; - } - } - return null; - }, - findAll: function (selector, queryResult) { - var i, len, node, queryAllResult, numNodes, j; - len = this.nodes.length; - for (i = 0; i < len; i += 1) { - node = this.nodes[i]; - if (node.nodeType !== 1) { - continue; - } - if (matches(node, selector)) { - queryResult.push(node); - } - if (queryAllResult = node.querySelectorAll(selector)) { - numNodes = queryAllResult.length; - for (j = 0; j < numNodes; j += 1) { - queryResult.push(queryAllResult[j]); - } - } - } - } - }; - return DomTriple; - }(config_types, utils_matches, render_shared_initMustache, render_shared_updateMustache, render_shared_resolveMustache, render_DomFragment_shared_insertHtml, shared_teardown); -var render_DomFragment_Element_initialise_getElementNamespace = function (namespaces) { - - return function (descriptor, parentNode) { - if (descriptor.a && descriptor.a.xmlns) { - return descriptor.a.xmlns; - } - return descriptor.e === 'svg' ? namespaces.svg : parentNode.namespaceURI || namespaces.html; - }; - }(config_namespaces); -var render_DomFragment_shared_enforceCase = function () { - - var svgCamelCaseElements, svgCamelCaseAttributes, createMap, map; - svgCamelCaseElements = 'altGlyph altGlyphDef altGlyphItem animateColor animateMotion animateTransform clipPath feBlend feColorMatrix feComponentTransfer feComposite feConvolveMatrix feDiffuseLighting feDisplacementMap feDistantLight feFlood feFuncA feFuncB feFuncG feFuncR feGaussianBlur feImage feMerge feMergeNode feMorphology feOffset fePointLight feSpecularLighting feSpotLight feTile feTurbulence foreignObject glyphRef linearGradient radialGradient textPath vkern'.split(' '); - svgCamelCaseAttributes = 'attributeName attributeType baseFrequency baseProfile calcMode clipPathUnits contentScriptType contentStyleType diffuseConstant edgeMode externalResourcesRequired filterRes filterUnits glyphRef gradientTransform gradientUnits kernelMatrix kernelUnitLength keyPoints keySplines keyTimes lengthAdjust limitingConeAngle markerHeight markerUnits markerWidth maskContentUnits maskUnits numOctaves pathLength patternContentUnits patternTransform patternUnits pointsAtX pointsAtY pointsAtZ preserveAlpha preserveAspectRatio primitiveUnits refX refY repeatCount repeatDur requiredExtensions requiredFeatures specularConstant specularExponent spreadMethod startOffset stdDeviation stitchTiles surfaceScale systemLanguage tableValues targetX targetY textLength viewBox viewTarget xChannelSelector yChannelSelector zoomAndPan'.split(' '); - createMap = function (items) { - var map = {}, i = items.length; - while (i--) { - map[items[i].toLowerCase()] = items[i]; - } - return map; - }; - map = createMap(svgCamelCaseElements.concat(svgCamelCaseAttributes)); - return function (elementName) { - var lowerCaseElementName = elementName.toLowerCase(); - return map[lowerCaseElementName] || lowerCaseElementName; - }; - }(); -var render_DomFragment_Attribute_helpers_determineNameAndNamespace = function (namespaces, enforceCase) { - - return function (attribute, name) { - var colonIndex, namespacePrefix; - colonIndex = name.indexOf(':'); - if (colonIndex !== -1) { - namespacePrefix = name.substr(0, colonIndex); - if (namespacePrefix !== 'xmlns') { - name = name.substring(colonIndex + 1); - attribute.name = enforceCase(name); - attribute.lcName = attribute.name.toLowerCase(); - attribute.namespace = namespaces[namespacePrefix.toLowerCase()]; - if (!attribute.namespace) { - throw 'Unknown namespace ("' + namespacePrefix + '")'; - } - return; - } - } - attribute.name = attribute.element.namespace !== namespaces.html ? enforceCase(name) : name; - attribute.lcName = attribute.name.toLowerCase(); - }; - }(config_namespaces, render_DomFragment_shared_enforceCase); -var render_DomFragment_Attribute_helpers_setStaticAttribute = function (namespaces) { - - return function (attribute, options) { - var node, value = options.value === null ? '' : options.value; - if (node = options.pNode) { - if (attribute.namespace) { - node.setAttributeNS(attribute.namespace, options.name, value); - } else { - if (options.name === 'style' && node.style.setAttribute) { - node.style.setAttribute('cssText', value); - } else if (options.name === 'class' && (!node.namespaceURI || node.namespaceURI === namespaces.html)) { - node.className = value; - } else { - node.setAttribute(options.name, value); - } - } - if (attribute.name === 'id') { - options.root.nodes[options.value] = node; - } - if (attribute.name === 'value') { - node._ractive.value = options.value; - } - } - attribute.value = options.value; - }; - }(config_namespaces); -var render_DomFragment_Attribute_helpers_determinePropertyName = function (namespaces) { - - var propertyNames = { - 'accept-charset': 'acceptCharset', - accesskey: 'accessKey', - bgcolor: 'bgColor', - 'class': 'className', - codebase: 'codeBase', - colspan: 'colSpan', - contenteditable: 'contentEditable', - datetime: 'dateTime', - dirname: 'dirName', - 'for': 'htmlFor', - 'http-equiv': 'httpEquiv', - ismap: 'isMap', - maxlength: 'maxLength', - novalidate: 'noValidate', - pubdate: 'pubDate', - readonly: 'readOnly', - rowspan: 'rowSpan', - tabindex: 'tabIndex', - usemap: 'useMap' - }; - return function (attribute, options) { - var propertyName; - if (attribute.pNode && !attribute.namespace && (!options.pNode.namespaceURI || options.pNode.namespaceURI === namespaces.html)) { - propertyName = propertyNames[attribute.name] || attribute.name; - if (options.pNode[propertyName] !== undefined) { - attribute.propertyName = propertyName; - } - if (typeof options.pNode[propertyName] === 'boolean' || propertyName === 'value') { - attribute.useProperty = true; - } - } - }; - }(config_namespaces); -var render_DomFragment_Attribute_prototype_bind = function (types, warn, arrayContentsMatch, getValueFromCheckboxes) { - - var bindAttribute, getInterpolator, updateModel, update, getBinding, inheritProperties, MultipleSelectBinding, SelectBinding, RadioNameBinding, CheckboxNameBinding, CheckedBinding, FileListBinding, ContentEditableBinding, GenericBinding; - bindAttribute = function () { - var node = this.pNode, interpolator, binding, bindings; - if (!this.fragment) { - return false; - } - interpolator = getInterpolator(this); - if (!interpolator) { - return false; - } - this.interpolator = interpolator; - this.keypath = interpolator.keypath || interpolator.descriptor.r; - binding = getBinding(this); - if (!binding) { - return false; - } - node._ractive.binding = this.element.binding = binding; - this.twoway = true; - bindings = this.root._twowayBindings[this.keypath] || (this.root._twowayBindings[this.keypath] = []); - bindings[bindings.length] = binding; - return true; - }; - updateModel = function () { - this._ractive.binding.update(); - }; - update = function () { - var value = this._ractive.root.get(this._ractive.binding.keypath); - this.value = value == undefined ? '' : value; - }; - getInterpolator = function (attribute) { - var item, errorMessage; - if (attribute.fragment.items.length !== 1) { - return null; - } - item = attribute.fragment.items[0]; - if (item.type !== types.INTERPOLATOR) { - return null; - } - if (!item.keypath && !item.ref) { - return null; - } - if (item.keypath && item.keypath.substr(0, 2) === '${') { - errorMessage = 'You cannot set up two-way binding against an expression ' + item.keypath; - if (attribute.root.debug) { - warn(errorMessage); - } - return null; - } - return item; - }; - getBinding = function (attribute) { - var node = attribute.pNode; - if (node.tagName === 'SELECT') { - return node.multiple ? new MultipleSelectBinding(attribute, node) : new SelectBinding(attribute, node); - } - if (node.type === 'checkbox' || node.type === 'radio') { - if (attribute.propertyName === 'name') { - if (node.type === 'checkbox') { - return new CheckboxNameBinding(attribute, node); - } - if (node.type === 'radio') { - return new RadioNameBinding(attribute, node); - } - } - if (attribute.propertyName === 'checked') { - return new CheckedBinding(attribute, node); - } - return null; - } - if (attribute.lcName !== 'value') { - warn('This is... odd'); - } - if (node.type === 'file') { - return new FileListBinding(attribute, node); - } - if (node.getAttribute('contenteditable')) { - return new ContentEditableBinding(attribute, node); - } - return new GenericBinding(attribute, node); - }; - MultipleSelectBinding = function (attribute, node) { - var valueFromModel; - inheritProperties(this, attribute, node); - node.addEventListener('change', updateModel, false); - valueFromModel = this.root.get(this.keypath); - if (valueFromModel === undefined) { - this.update(); - } - }; - MultipleSelectBinding.prototype = { - value: function () { - var value, options, i, len; - value = []; - options = this.node.options; - len = options.length; - for (i = 0; i < len; i += 1) { - if (options[i].selected) { - value[value.length] = options[i]._ractive.value; - } - } - return value; - }, - update: function () { - var attribute, previousValue, value; - attribute = this.attr; - previousValue = attribute.value; - value = this.value(); - if (previousValue === undefined || !arrayContentsMatch(value, previousValue)) { - attribute.receiving = true; - attribute.value = value; - this.root.set(this.keypath, value); - attribute.receiving = false; - } - return this; - }, - deferUpdate: function () { - if (this.deferred === true) { - return; - } - this.root._deferred.attrs.push(this); - this.deferred = true; - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - } - }; - SelectBinding = function (attribute, node) { - var valueFromModel; - inheritProperties(this, attribute, node); - node.addEventListener('change', updateModel, false); - valueFromModel = this.root.get(this.keypath); - if (valueFromModel === undefined) { - this.update(); - } - }; - SelectBinding.prototype = { - value: function () { - var options, i, len; - options = this.node.options; - len = options.length; - for (i = 0; i < len; i += 1) { - if (options[i].selected) { - return options[i]._ractive.value; - } - } - }, - update: function () { - var value = this.value(); - this.attr.receiving = true; - this.attr.value = value; - this.root.set(this.keypath, value); - this.attr.receiving = false; - return this; - }, - deferUpdate: function () { - if (this.deferred === true) { - return; - } - this.root._deferred.attrs.push(this); - this.deferred = true; - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - } - }; - RadioNameBinding = function (attribute, node) { - var valueFromModel; - this.radioName = true; - inheritProperties(this, attribute, node); - node.name = '{{' + attribute.keypath + '}}'; - node.addEventListener('change', updateModel, false); - if (node.attachEvent) { - node.addEventListener('click', updateModel, false); - } - valueFromModel = this.root.get(this.keypath); - if (valueFromModel !== undefined) { - node.checked = valueFromModel == node._ractive.value; - } else { - this.root._deferred.radios.push(this); - } - }; - RadioNameBinding.prototype = { - value: function () { - return this.node._ractive ? this.node._ractive.value : this.node.value; - }, - update: function () { - var node = this.node; - if (node.checked) { - this.attr.receiving = true; - this.root.set(this.keypath, this.value()); - this.attr.receiving = false; - } - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - this.node.removeEventListener('click', updateModel, false); - } - }; - CheckboxNameBinding = function (attribute, node) { - var valueFromModel, checked; - this.checkboxName = true; - inheritProperties(this, attribute, node); - node.name = '{{' + this.keypath + '}}'; - node.addEventListener('change', updateModel, false); - if (node.attachEvent) { - node.addEventListener('click', updateModel, false); - } - valueFromModel = this.root.get(this.keypath); - if (valueFromModel !== undefined) { - checked = valueFromModel.indexOf(node._ractive.value) !== -1; - node.checked = checked; - } else { - if (this.root._deferred.checkboxes.indexOf(this.keypath) === -1) { - this.root._deferred.checkboxes.push(this.keypath); - } - } - }; - CheckboxNameBinding.prototype = { - changed: function () { - return this.node.checked !== !!this.checked; - }, - update: function () { - this.checked = this.node.checked; - this.attr.receiving = true; - this.root.set(this.keypath, getValueFromCheckboxes(this.root, this.keypath)); - this.attr.receiving = false; - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - this.node.removeEventListener('click', updateModel, false); - } - }; - CheckedBinding = function (attribute, node) { - inheritProperties(this, attribute, node); - node.addEventListener('change', updateModel, false); - if (node.attachEvent) { - node.addEventListener('click', updateModel, false); - } - }; - CheckedBinding.prototype = { - value: function () { - return this.node.checked; - }, - update: function () { - this.attr.receiving = true; - this.root.set(this.keypath, this.value()); - this.attr.receiving = false; - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - this.node.removeEventListener('click', updateModel, false); - } - }; - FileListBinding = function (attribute, node) { - inheritProperties(this, attribute, node); - node.addEventListener('change', updateModel, false); - }; - FileListBinding.prototype = { - value: function () { - return this.attr.pNode.files; - }, - update: function () { - this.attr.root.set(this.attr.keypath, this.value()); - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - } - }; - ContentEditableBinding = function (attribute, node) { - inheritProperties(this, attribute, node); - node.addEventListener('change', updateModel, false); - if (!this.root.lazy) { - node.addEventListener('input', updateModel, false); - if (node.attachEvent) { - node.addEventListener('keyup', updateModel, false); - } - } - }; - ContentEditableBinding.prototype = { - update: function () { - this.attr.receiving = true; - this.root.set(this.keypath, this.node.innerHTML); - this.attr.receiving = false; - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - this.node.removeEventListener('input', updateModel, false); - this.node.removeEventListener('keyup', updateModel, false); - } - }; - GenericBinding = function (attribute, node) { - inheritProperties(this, attribute, node); - node.addEventListener('change', updateModel, false); - if (!this.root.lazy) { - node.addEventListener('input', updateModel, false); - if (node.attachEvent) { - node.addEventListener('keyup', updateModel, false); - } - } - this.node.addEventListener('blur', update, false); - }; - GenericBinding.prototype = { - value: function () { - var value = this.attr.pNode.value; - if (+value + '' === value && value.indexOf('e') === -1) { - value = +value; - } - return value; - }, - update: function () { - var attribute = this.attr, value = this.value(); - attribute.receiving = true; - attribute.root.set(attribute.keypath, value); - attribute.receiving = false; - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - this.node.removeEventListener('input', updateModel, false); - this.node.removeEventListener('keyup', updateModel, false); - this.node.removeEventListener('blur', update, false); - } - }; - inheritProperties = function (binding, attribute, node) { - binding.attr = attribute; - binding.node = node; - binding.root = attribute.root; - binding.keypath = attribute.keypath; - }; - return bindAttribute; - }(config_types, utils_warn, utils_arrayContentsMatch, shared_getValueFromCheckboxes); -var render_DomFragment_Attribute_prototype_update = function (isArray, namespaces) { - - var updateAttribute, updateFileInputValue, deferSelect, initSelect, updateSelect, updateMultipleSelect, updateRadioName, updateCheckboxName, updateIEStyleAttribute, updateClassName, updateContentEditableValue, updateEverythingElse; - updateAttribute = function () { - var node; - if (!this.ready) { - return this; - } - node = this.pNode; - if (node.tagName === 'SELECT' && this.lcName === 'value') { - this.update = deferSelect; - this.deferredUpdate = initSelect; - return this.update(); - } - if (this.isFileInputValue) { - this.update = updateFileInputValue; - return this; - } - if (this.twoway && this.lcName === 'name') { - if (node.type === 'radio') { - this.update = updateRadioName; - return this.update(); - } - if (node.type === 'checkbox') { - this.update = updateCheckboxName; - return this.update(); - } - } - if (this.lcName === 'style' && node.style.setAttribute) { - this.update = updateIEStyleAttribute; - return this.update(); - } - if (this.lcName === 'class' && (!node.namespaceURI || node.namespaceURI === namespaces.html)) { - this.update = updateClassName; - return this.update(); - } - if (node.getAttribute('contenteditable') && this.lcName === 'value') { - this.update = updateContentEditableValue; - return this.update(); - } - this.update = updateEverythingElse; - return this.update(); - }; - updateFileInputValue = function () { - return this; - }; - initSelect = function () { - this.deferredUpdate = this.pNode.multiple ? updateMultipleSelect : updateSelect; - this.deferredUpdate(); - }; - deferSelect = function () { - this.root._deferred.selectValues.push(this); - return this; - }; - updateSelect = function () { - var value = this.fragment.getValue(), options, option, i; - this.value = this.pNode._ractive.value = value; - options = this.pNode.options; - i = options.length; - while (i--) { - option = options[i]; - if (option._ractive.value == value) { - option.selected = true; - return this; - } - } - return this; - }; - updateMultipleSelect = function () { - var value = this.fragment.getValue(), options, i; - if (!isArray(value)) { - value = [value]; - } - options = this.pNode.options; - i = options.length; - while (i--) { - options[i].selected = value.indexOf(options[i]._ractive.value) !== -1; - } - this.value = value; - return this; - }; - updateRadioName = function () { - var node, value; - node = this.pNode; - value = this.fragment.getValue(); - node.checked = value == node._ractive.value; - return this; - }; - updateCheckboxName = function () { - var node, value; - node = this.pNode; - value = this.fragment.getValue(); - if (!isArray(value)) { - node.checked = value == node._ractive.value; - return this; - } - node.checked = value.indexOf(node._ractive.value) !== -1; - return this; - }; - updateIEStyleAttribute = function () { - var node, value; - node = this.pNode; - value = this.fragment.getValue(); - if (value === undefined) { - value = ''; - } - if (value !== this.value) { - node.style.setAttribute('cssText', value); - this.value = value; - } - return this; - }; - updateClassName = function () { - var node, value; - node = this.pNode; - value = this.fragment.getValue(); - if (value === undefined) { - value = ''; - } - if (value !== this.value) { - node.className = value; - this.value = value; - } - return this; - }; - updateContentEditableValue = function () { - var node, value; - node = this.pNode; - value = this.fragment.getValue(); - if (value === undefined) { - value = ''; - } - if (value !== this.value) { - if (!this.receiving) { - node.innerHTML = value; - } - this.value = value; - } - return this; - }; - updateEverythingElse = function () { - var node, value; - node = this.pNode; - value = this.fragment.getValue(); - if (this.isValueAttribute) { - node._ractive.value = value; - } - if (value === undefined) { - value = ''; - } - if (value !== this.value) { - if (this.useProperty) { - if (!this.receiving) { - node[this.propertyName] = value; - } - this.value = value; - return this; - } - if (this.namespace) { - node.setAttributeNS(this.namespace, this.name, value); - this.value = value; - return this; - } - if (this.lcName === 'id') { - if (this.value !== undefined) { - this.root.nodes[this.value] = undefined; - } - this.root.nodes[value] = node; - } - node.setAttribute(this.name, value); - this.value = value; - } - return this; - }; - return updateAttribute; - }(utils_isArray, config_namespaces); -var parse_Tokenizer_utils_getStringMatch = function () { - - return function (string) { - var substr; - substr = this.str.substr(this.pos, string.length); - if (substr === string) { - this.pos += string.length; - return string; - } - return null; - }; - }(); -var parse_Tokenizer_utils_allowWhitespace = function () { - - var leadingWhitespace = /^\s+/; - return function () { - var match = leadingWhitespace.exec(this.remaining()); - if (!match) { - return null; - } - this.pos += match[0].length; - return match[0]; - }; - }(); -var parse_Tokenizer_utils_makeRegexMatcher = function () { - - return function (regex) { - return function (tokenizer) { - var match = regex.exec(tokenizer.str.substring(tokenizer.pos)); - if (!match) { - return null; - } - tokenizer.pos += match[0].length; - return match[1] || match[0]; - }; - }; - }(); -var parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral_getEscapedChars = function () { - - return function (tokenizer) { - var chars = '', character; - character = getEscapedChar(tokenizer); - while (character) { - chars += character; - character = getEscapedChar(tokenizer); - } - return chars || null; - }; - function getEscapedChar(tokenizer) { - var character; - if (!tokenizer.getStringMatch('\\')) { - return null; - } - character = tokenizer.str.charAt(tokenizer.pos); - tokenizer.pos += 1; - return character; - } - }(); -var parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral_getQuotedString = function (makeRegexMatcher, getEscapedChars) { - - var getUnescapedDoubleQuotedChars = makeRegexMatcher(/^[^\\"]+/), getUnescapedSingleQuotedChars = makeRegexMatcher(/^[^\\']+/); - return function getQuotedString(tokenizer, singleQuotes) { - var start, string, escaped, unescaped, next, matcher; - start = tokenizer.pos; - string = ''; - matcher = singleQuotes ? getUnescapedSingleQuotedChars : getUnescapedDoubleQuotedChars; - escaped = getEscapedChars(tokenizer); - if (escaped) { - string += escaped; - } - unescaped = matcher(tokenizer); - if (unescaped) { - string += unescaped; - } - if (!string) { - return ''; - } - next = getQuotedString(tokenizer, singleQuotes); - while (next !== '') { - string += next; - } - return string; - }; - }(parse_Tokenizer_utils_makeRegexMatcher, parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral_getEscapedChars); -var parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral__getStringLiteral = function (types, getQuotedString) { - - return function (tokenizer) { - var start, string; - start = tokenizer.pos; - if (tokenizer.getStringMatch('"')) { - string = getQuotedString(tokenizer, false); - if (!tokenizer.getStringMatch('"')) { - tokenizer.pos = start; - return null; - } - return { - t: types.STRING_LITERAL, - v: string - }; - } - if (tokenizer.getStringMatch('\'')) { - string = getQuotedString(tokenizer, true); - if (!tokenizer.getStringMatch('\'')) { - tokenizer.pos = start; - return null; - } - return { - t: types.STRING_LITERAL, - v: string - }; - } - return null; - }; - }(config_types, parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral_getQuotedString); -var parse_Tokenizer_getExpression_getPrimary_getLiteral_getNumberLiteral = function (types, makeRegexMatcher) { - - var getNumber = makeRegexMatcher(/^(?:[+-]?)(?:(?:(?:0|[1-9]\d*)?\.\d+)|(?:(?:0|[1-9]\d*)\.)|(?:0|[1-9]\d*))(?:[eE][+-]?\d+)?/); - return function (tokenizer) { - var result; - if (result = getNumber(tokenizer)) { - return { - t: types.NUMBER_LITERAL, - v: result - }; - } - return null; - }; - }(config_types, parse_Tokenizer_utils_makeRegexMatcher); -var parse_Tokenizer_getExpression_shared_getName = function (makeRegexMatcher) { - - return makeRegexMatcher(/^[a-zA-Z_$][a-zA-Z_$0-9]*/); - }(parse_Tokenizer_utils_makeRegexMatcher); -var parse_Tokenizer_getExpression_shared_getKey = function (getStringLiteral, getNumberLiteral, getName) { - - var identifier = /^[a-zA-Z_$][a-zA-Z_$0-9]*$/; - return function (tokenizer) { - var token; - if (token = getStringLiteral(tokenizer)) { - return identifier.test(token.v) ? token.v : '"' + token.v.replace(/"/g, '\\"') + '"'; - } - if (token = getNumberLiteral(tokenizer)) { - return token.v; - } - if (token = getName(tokenizer)) { - return token; - } - }; - }(parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral__getStringLiteral, parse_Tokenizer_getExpression_getPrimary_getLiteral_getNumberLiteral, parse_Tokenizer_getExpression_shared_getName); -var utils_parseJSON = function (getStringMatch, allowWhitespace, getStringLiteral, getKey) { - - var Tokenizer, specials, specialsPattern, numberPattern, placeholderPattern, placeholderAtStartPattern; - specials = { - 'true': true, - 'false': false, - 'undefined': undefined, - 'null': null - }; - specialsPattern = new RegExp('^(?:' + Object.keys(specials).join('|') + ')'); - numberPattern = /^(?:[+-]?)(?:(?:(?:0|[1-9]\d*)?\.\d+)|(?:(?:0|[1-9]\d*)\.)|(?:0|[1-9]\d*))(?:[eE][+-]?\d+)?/; - placeholderPattern = /\$\{([^\}]+)\}/g; - placeholderAtStartPattern = /^\$\{([^\}]+)\}/; - Tokenizer = function (str, values) { - this.str = str; - this.values = values; - this.pos = 0; - this.result = this.getToken(); - }; - Tokenizer.prototype = { - remaining: function () { - return this.str.substring(this.pos); - }, - getStringMatch: getStringMatch, - getToken: function () { - this.allowWhitespace(); - return this.getPlaceholder() || this.getSpecial() || this.getNumber() || this.getString() || this.getObject() || this.getArray(); - }, - getPlaceholder: function () { - var match; - if (!this.values) { - return null; - } - if ((match = placeholderAtStartPattern.exec(this.remaining())) && this.values.hasOwnProperty(match[1])) { - this.pos += match[0].length; - return { v: this.values[match[1]] }; - } - }, - getSpecial: function () { - var match; - if (match = specialsPattern.exec(this.remaining())) { - this.pos += match[0].length; - return { v: specials[match[0]] }; - } - }, - getNumber: function () { - var match; - if (match = numberPattern.exec(this.remaining())) { - this.pos += match[0].length; - return { v: +match[0] }; - } - }, - getString: function () { - var stringLiteral = getStringLiteral(this), values; - if (stringLiteral && (values = this.values)) { - return { - v: stringLiteral.v.replace(placeholderPattern, function (match, $1) { - return values[$1] || $1; - }) - }; - } - return stringLiteral; - }, - getObject: function () { - var result, pair; - if (!this.getStringMatch('{')) { - return null; - } - result = {}; - while (pair = getKeyValuePair(this)) { - result[pair.key] = pair.value; - this.allowWhitespace(); - if (this.getStringMatch('}')) { - return { v: result }; - } - if (!this.getStringMatch(',')) { - return null; - } - } - return null; - }, - getArray: function () { - var result, valueToken; - if (!this.getStringMatch('[')) { - return null; - } - result = []; - while (valueToken = this.getToken()) { - result.push(valueToken.v); - if (this.getStringMatch(']')) { - return { v: result }; - } - if (!this.getStringMatch(',')) { - return null; - } - } - return null; - }, - allowWhitespace: allowWhitespace - }; - function getKeyValuePair(tokenizer) { - var key, valueToken, pair; - tokenizer.allowWhitespace(); - key = getKey(tokenizer); - if (!key) { - return null; - } - pair = { key: key }; - tokenizer.allowWhitespace(); - if (!tokenizer.getStringMatch(':')) { - return null; - } - tokenizer.allowWhitespace(); - valueToken = tokenizer.getToken(); - if (!valueToken) { - return null; - } - pair.value = valueToken.v; - return pair; - } - return function (str, values) { - var tokenizer = new Tokenizer(str, values); - if (tokenizer.result) { - return { - value: tokenizer.result.v, - remaining: tokenizer.remaining() - }; - } - return null; - }; - }(parse_Tokenizer_utils_getStringMatch, parse_Tokenizer_utils_allowWhitespace, parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral__getStringLiteral, parse_Tokenizer_getExpression_shared_getKey); -var render_StringFragment_Interpolator = function (types, teardown, initMustache, updateMustache, resolveMustache) { - - var StringInterpolator = function (options) { - this.type = types.INTERPOLATOR; - initMustache(this, options); - }; - StringInterpolator.prototype = { - update: updateMustache, - resolve: resolveMustache, - render: function (value) { - this.value = value; - this.parentFragment.bubble(); - }, - teardown: function () { - teardown(this); - }, - toString: function () { - if (this.value == undefined) { - return ''; - } - return stringify(this.value); - } - }; - return StringInterpolator; - function stringify(value) { - if (typeof value === 'string') { - return value; - } - return JSON.stringify(value); - } - }(config_types, shared_teardown, render_shared_initMustache, render_shared_updateMustache, render_shared_resolveMustache); -var render_StringFragment_Section = function (types, initMustache, updateMustache, resolveMustache, updateSection, teardown, circular) { - - var StringSection, StringFragment; - circular.push(function () { - StringFragment = circular.StringFragment; - }); - StringSection = function (options) { - this.type = types.SECTION; - this.fragments = []; - this.length = 0; - initMustache(this, options); - }; - StringSection.prototype = { - update: updateMustache, - resolve: resolveMustache, - teardown: function () { - this.teardownFragments(); - teardown(this); - }, - teardownFragments: function () { - while (this.fragments.length) { - this.fragments.shift().teardown(); - } - this.length = 0; - }, - bubble: function () { - this.value = this.fragments.join(''); - this.parentFragment.bubble(); - }, - render: function (value) { - var wrapped; - if (wrapped = this.root._wrapped[this.keypath]) { - value = wrapped.get(); - } - updateSection(this, value); - this.parentFragment.bubble(); - }, - createFragment: function (options) { - return new StringFragment(options); - }, - toString: function () { - return this.fragments.join(''); - } - }; - return StringSection; - }(config_types, render_shared_initMustache, render_shared_updateMustache, render_shared_resolveMustache, render_shared_updateSection, shared_teardown, circular); -var render_StringFragment_Text = function (types) { - - var StringText = function (text) { - this.type = types.TEXT; - this.text = text; - }; - StringText.prototype = { - toString: function () { - return this.text; - }, - teardown: function () { - } - }; - return StringText; - }(config_types); -var render_StringFragment_prototype_toArgsList = function (warn, parseJSON) { - - return function () { - var values, counter, jsonesque, guid, errorMessage, parsed, processItems; - if (!this.argsList || this.dirty) { - values = {}; - counter = 0; - guid = this.root._guid; - processItems = function (items) { - return items.map(function (item) { - var placeholderId, wrapped, value; - if (item.text) { - return item.text; - } - if (item.fragments) { - return item.fragments.map(function (fragment) { - return processItems(fragment.items); - }).join(''); - } - placeholderId = guid + '-' + counter++; - if (wrapped = item.root._wrapped[item.keypath]) { - value = wrapped.value; - } else { - value = item.value; - } - values[placeholderId] = value; - return '${' + placeholderId + '}'; - }).join(''); - }; - jsonesque = processItems(this.items); - parsed = parseJSON('[' + jsonesque + ']', values); - if (!parsed) { - errorMessage = 'Could not parse directive arguments (' + this.toString() + '). If you think this is a bug, please file an issue at http://github.com/RactiveJS/Ractive/issues'; - if (this.root.debug) { - throw new Error(errorMessage); - } else { - warn(errorMessage); - this.argsList = [jsonesque]; - } - } else { - this.argsList = parsed.value; - } - this.dirty = false; - } - return this.argsList; - }; - }(utils_warn, utils_parseJSON); -var render_StringFragment__StringFragment = function (types, parseJSON, initFragment, Interpolator, Section, Text, toArgsList, circular) { - - var StringFragment = function (options) { - initFragment(this, options); - }; - StringFragment.prototype = { - createItem: function (options) { - if (typeof options.descriptor === 'string') { - return new Text(options.descriptor); - } - switch (options.descriptor.t) { - case types.INTERPOLATOR: - return new Interpolator(options); - case types.TRIPLE: - return new Interpolator(options); - case types.SECTION: - return new Section(options); - default: - throw 'Something went wrong in a rather interesting way'; - } - }, - bubble: function () { - this.dirty = true; - this.owner.bubble(); - }, - teardown: function () { - var numItems, i; - numItems = this.items.length; - for (i = 0; i < numItems; i += 1) { - this.items[i].teardown(); - } - }, - getValue: function () { - var value; - if (this.items.length === 1 && this.items[0].type === types.INTERPOLATOR) { - value = this.items[0].value; - if (value !== undefined) { - return value; - } - } - return this.toString(); - }, - isSimple: function () { - var i, item, containsInterpolator; - if (this.simple !== undefined) { - return this.simple; - } - i = this.items.length; - while (i--) { - item = this.items[i]; - if (item.type === types.TEXT) { - continue; - } - if (item.type === types.INTERPOLATOR) { - if (containsInterpolator) { - return false; - } else { - containsInterpolator = true; - continue; - } - } - return this.simple = false; - } - return this.simple = true; - }, - toString: function () { - return this.items.join(''); - }, - toJSON: function () { - var value = this.getValue(), parsed; - if (typeof value === 'string') { - parsed = parseJSON(value); - value = parsed ? parsed.value : value; - } - return value; - }, - toArgsList: toArgsList - }; - circular.StringFragment = StringFragment; - return StringFragment; - }(config_types, utils_parseJSON, render_shared_initFragment, render_StringFragment_Interpolator, render_StringFragment_Section, render_StringFragment_Text, render_StringFragment_prototype_toArgsList, circular); -var render_DomFragment_Attribute__Attribute = function (types, determineNameAndNamespace, setStaticAttribute, determinePropertyName, bind, update, StringFragment) { - - var DomAttribute = function (options) { - this.type = types.ATTRIBUTE; - this.element = options.element; - determineNameAndNamespace(this, options.name); - if (options.value === null || typeof options.value === 'string') { - setStaticAttribute(this, options); - return; - } - this.root = options.root; - this.pNode = options.pNode; - this.parentFragment = this.element.parentFragment; - this.fragment = new StringFragment({ - descriptor: options.value, - root: this.root, - owner: this, - contextStack: options.contextStack - }); - if (!this.pNode) { - return; - } - if (this.name === 'value') { - this.isValueAttribute = true; - if (this.pNode.tagName === 'INPUT' && this.pNode.type === 'file') { - this.isFileInputValue = true; - } - } - determinePropertyName(this, options); - this.selfUpdating = this.fragment.isSimple(); - this.ready = true; - }; - DomAttribute.prototype = { - bind: bind, - update: update, - updateBindings: function () { - this.keypath = this.interpolator.keypath || this.interpolator.ref; - if (this.propertyName === 'name') { - this.pNode.name = '{{' + this.keypath + '}}'; - } - }, - teardown: function () { - var i; - if (this.boundEvents) { - i = this.boundEvents.length; - while (i--) { - this.pNode.removeEventListener(this.boundEvents[i], this.updateModel, false); - } - } - if (this.fragment) { - this.fragment.teardown(); - } - }, - bubble: function () { - if (this.selfUpdating) { - this.update(); - } else if (!this.deferred && this.ready) { - this.root._deferred.attrs.push(this); - this.deferred = true; - } - }, - toString: function () { - var str; - if (this.value === null) { - return this.name; - } - if (!this.fragment) { - return this.name + '=' + JSON.stringify(this.value); - } - str = this.fragment.toString(); - return this.name + '=' + JSON.stringify(str); - } - }; - return DomAttribute; - }(config_types, render_DomFragment_Attribute_helpers_determineNameAndNamespace, render_DomFragment_Attribute_helpers_setStaticAttribute, render_DomFragment_Attribute_helpers_determinePropertyName, render_DomFragment_Attribute_prototype_bind, render_DomFragment_Attribute_prototype_update, render_StringFragment__StringFragment); -var render_DomFragment_Element_initialise_createElementAttributes = function (DomAttribute) { - - return function (element, attributes) { - var attrName, attrValue, attr; - element.attributes = []; - for (attrName in attributes) { - if (attributes.hasOwnProperty(attrName)) { - attrValue = attributes[attrName]; - attr = new DomAttribute({ - element: element, - name: attrName, - value: attrValue, - root: element.root, - pNode: element.node, - contextStack: element.parentFragment.contextStack - }); - element.attributes[element.attributes.length] = element.attributes[attrName] = attr; - if (attrName !== 'name') { - attr.update(); - } - } - } - return element.attributes; - }; - }(render_DomFragment_Attribute__Attribute); -var render_DomFragment_Element_initialise_appendElementChildren = function (warn, namespaces, StringFragment, circular) { - - var DomFragment, updateCss, updateScript; - circular.push(function () { - DomFragment = circular.DomFragment; - }); - updateCss = function () { - var node = this.node, content = this.fragment.toString(); - if (node.styleSheet) { - node.styleSheet.cssText = content; - } - node.innerHTML = content; - }; - updateScript = function () { - if (!this.node.type || this.node.type === 'text/javascript') { - warn('Script tag was updated. This does not cause the code to be re-evaluated!'); - } - this.node.innerHTML = this.fragment.toString(); - }; - return function (element, node, descriptor, docFrag) { - var liveQueries, i, selector, queryAllResult, j; - if (element.lcName === 'script' || element.lcName === 'style') { - element.fragment = new StringFragment({ - descriptor: descriptor.f, - root: element.root, - contextStack: element.parentFragment.contextStack, - owner: element - }); - if (docFrag) { - if (element.lcName === 'script') { - element.bubble = updateScript; - element.node.innerHTML = element.fragment.toString(); - } else { - element.bubble = updateCss; - element.bubble(); - } - } - return; - } - if (typeof descriptor.f === 'string' && (!node || (!node.namespaceURI || node.namespaceURI === namespaces.html))) { - element.html = descriptor.f; - if (docFrag) { - node.innerHTML = element.html; - liveQueries = element.root._liveQueries; - i = liveQueries.length; - while (i--) { - selector = liveQueries[i]; - if ((queryAllResult = node.querySelectorAll(selector)) && (j = queryAllResult.length)) { - (element.liveQueries || (element.liveQueries = [])).push(selector); - element.liveQueries[selector] = []; - while (j--) { - element.liveQueries[selector][j] = queryAllResult[j]; - } - } - } - } - } else { - element.fragment = new DomFragment({ - descriptor: descriptor.f, - root: element.root, - pNode: node, - contextStack: element.parentFragment.contextStack, - owner: element - }); - if (docFrag) { - node.appendChild(element.fragment.docFrag); - } - } - }; - }(utils_warn, config_namespaces, render_StringFragment__StringFragment, circular); -var render_DomFragment_Element_initialise_decorate_Decorator = function (warn, StringFragment) { - - var Decorator = function (descriptor, root, owner, contextStack) { - var name, fragment, errorMessage; - this.root = root; - this.node = owner.node; - name = descriptor.n || descriptor; - if (typeof name !== 'string') { - fragment = new StringFragment({ - descriptor: name, - root: this.root, - owner: owner, - contextStack: contextStack - }); - name = fragment.toString(); - fragment.teardown(); - } - if (descriptor.a) { - this.params = descriptor.a; - } else if (descriptor.d) { - fragment = new StringFragment({ - descriptor: descriptor.d, - root: this.root, - owner: owner, - contextStack: contextStack - }); - this.params = fragment.toArgsList(); - fragment.teardown(); - } - this.fn = root.decorators[name]; - if (!this.fn) { - errorMessage = 'Missing "' + name + '" decorator. You may need to download a plugin via https://github.com/RactiveJS/Ractive/wiki/Plugins#decorators'; - if (root.debug) { - throw new Error(errorMessage); - } else { - warn(errorMessage); - } - } - }; - Decorator.prototype = { - init: function () { - var result, args; - if (this.params) { - args = [this.node].concat(this.params); - result = this.fn.apply(this.root, args); - } else { - result = this.fn.call(this.root, this.node); - } - if (!result || !result.teardown) { - throw new Error('Decorator definition must return an object with a teardown method'); - } - this.teardown = result.teardown; - } - }; - return Decorator; - }(utils_warn, render_StringFragment__StringFragment); -var render_DomFragment_Element_initialise_decorate__decorate = function (Decorator) { - - return function (descriptor, root, owner, contextStack) { - owner.decorator = new Decorator(descriptor, root, owner, contextStack); - if (owner.decorator.fn) { - root._deferred.decorators.push(owner.decorator); - } - }; - }(render_DomFragment_Element_initialise_decorate_Decorator); -var render_DomFragment_Element_initialise_addEventProxies_addEventProxy = function (warn, StringFragment) { - - var addEventProxy, MasterEventHandler, ProxyEvent, firePlainEvent, fireEventWithArgs, fireEventWithDynamicArgs, customHandlers, genericHandler, getCustomHandler; - addEventProxy = function (element, triggerEventName, proxyDescriptor, contextStack, indexRefs) { - var events, master; - events = element.node._ractive.events; - master = events[triggerEventName] || (events[triggerEventName] = new MasterEventHandler(element, triggerEventName, contextStack, indexRefs)); - master.add(proxyDescriptor); - }; - MasterEventHandler = function (element, eventName, contextStack) { - var definition; - this.element = element; - this.root = element.root; - this.node = element.node; - this.name = eventName; - this.contextStack = contextStack; - this.proxies = []; - if (definition = this.root.events[eventName]) { - this.custom = definition(this.node, getCustomHandler(eventName)); - } else { - if (!('on' + eventName in this.node)) { - warn('Missing "' + this.name + '" event. You may need to download a plugin via https://github.com/RactiveJS/Ractive/wiki/Plugins#events'); - } - this.node.addEventListener(eventName, genericHandler, false); - } - }; - MasterEventHandler.prototype = { - add: function (proxy) { - this.proxies[this.proxies.length] = new ProxyEvent(this.element, this.root, proxy, this.contextStack); - }, - teardown: function () { - var i; - if (this.custom) { - this.custom.teardown(); - } else { - this.node.removeEventListener(this.name, genericHandler, false); - } - i = this.proxies.length; - while (i--) { - this.proxies[i].teardown(); - } - }, - fire: function (event) { - var i = this.proxies.length; - while (i--) { - this.proxies[i].fire(event); - } - } - }; - ProxyEvent = function (element, ractive, descriptor, contextStack) { - var name; - this.root = ractive; - name = descriptor.n || descriptor; - if (typeof name === 'string') { - this.n = name; - } else { - this.n = new StringFragment({ - descriptor: descriptor.n, - root: this.root, - owner: element, - contextStack: contextStack - }); - } - if (descriptor.a) { - this.a = descriptor.a; - this.fire = fireEventWithArgs; - return; - } - if (descriptor.d) { - this.d = new StringFragment({ - descriptor: descriptor.d, - root: this.root, - owner: element, - contextStack: contextStack - }); - this.fire = fireEventWithDynamicArgs; - return; - } - this.fire = firePlainEvent; - }; - ProxyEvent.prototype = { - teardown: function () { - if (this.n.teardown) { - this.n.teardown(); - } - if (this.d) { - this.d.teardown(); - } - }, - bubble: function () { - } - }; - firePlainEvent = function (event) { - this.root.fire(this.n.toString(), event); - }; - fireEventWithArgs = function (event) { - this.root.fire.apply(this.root, [ - this.n.toString(), - event - ].concat(this.a)); - }; - fireEventWithDynamicArgs = function (event) { - var args = this.d.toArgsList(); - if (typeof args === 'string') { - args = args.substr(1, args.length - 2); - } - this.root.fire.apply(this.root, [ - this.n.toString(), - event - ].concat(args)); - }; - genericHandler = function (event) { - var storage = this._ractive; - storage.events[event.type].fire({ - node: this, - original: event, - index: storage.index, - keypath: storage.keypath, - context: storage.root.get(storage.keypath) - }); - }; - customHandlers = {}; - getCustomHandler = function (eventName) { - if (customHandlers[eventName]) { - return customHandlers[eventName]; - } - return customHandlers[eventName] = function (event) { - var storage = event.node._ractive; - event.index = storage.index; - event.keypath = storage.keypath; - event.context = storage.root.get(storage.keypath); - storage.events[eventName].fire(event); - }; - }; - return addEventProxy; - }(utils_warn, render_StringFragment__StringFragment); -var render_DomFragment_Element_initialise_addEventProxies__addEventProxies = function (addEventProxy) { - - return function (element, proxies) { - var i, eventName, eventNames; - for (eventName in proxies) { - if (proxies.hasOwnProperty(eventName)) { - eventNames = eventName.split('-'); - i = eventNames.length; - while (i--) { - addEventProxy(element, eventNames[i], proxies[eventName], element.parentFragment.contextStack); - } - } - } - }; - }(render_DomFragment_Element_initialise_addEventProxies_addEventProxy); -var render_DomFragment_Element_initialise_updateLiveQueries = function () { - - return function (element) { - var ractive, liveQueries, i, selector, query; - ractive = element.root; - liveQueries = ractive._liveQueries; - i = liveQueries.length; - while (i--) { - selector = liveQueries[i]; - query = liveQueries[selector]; - if (query._test(element)) { - (element.liveQueries || (element.liveQueries = [])).push(selector); - element.liveQueries[selector] = [element.node]; - } - } - }; - }(); -var utils_camelCase = function () { - - return function (hyphenatedStr) { - return hyphenatedStr.replace(/-([a-zA-Z])/g, function (match, $1) { - return $1.toUpperCase(); - }); - }; - }(); -var utils_fillGaps = function () { - - return function (target, source) { - var key; - for (key in source) { - if (source.hasOwnProperty(key) && !target.hasOwnProperty(key)) { - target[key] = source[key]; - } - } - return target; - }; - }(); -var render_DomFragment_Element_shared_executeTransition_Transition = function (isClient, createElement, warn, isNumeric, isArray, camelCase, fillGaps, StringFragment) { - - var Transition, testStyle, vendors, vendorPattern, unprefixPattern, prefixCache, CSS_TRANSITIONS_ENABLED, TRANSITION, TRANSITION_DURATION, TRANSITION_PROPERTY, TRANSITION_TIMING_FUNCTION, TRANSITIONEND; - if (!isClient) { - return; - } - testStyle = createElement('div').style; - (function () { - if (testStyle.transition !== undefined) { - TRANSITION = 'transition'; - TRANSITIONEND = 'transitionend'; - CSS_TRANSITIONS_ENABLED = true; - } else if (testStyle.webkitTransition !== undefined) { - TRANSITION = 'webkitTransition'; - TRANSITIONEND = 'webkitTransitionEnd'; - CSS_TRANSITIONS_ENABLED = true; - } else { - CSS_TRANSITIONS_ENABLED = false; - } - }()); - if (TRANSITION) { - TRANSITION_DURATION = TRANSITION + 'Duration'; - TRANSITION_PROPERTY = TRANSITION + 'Property'; - TRANSITION_TIMING_FUNCTION = TRANSITION + 'TimingFunction'; - } - Transition = function (descriptor, root, owner, contextStack, isIntro) { - var t = this, name, fragment, errorMessage; - this.root = root; - this.node = owner.node; - this.isIntro = isIntro; - this.originalStyle = this.node.getAttribute('style'); - this.complete = function (noReset) { - if (!noReset && t.isIntro) { - t.resetStyle(); - } - t._manager.pop(t.node); - t.node._ractive.transition = null; - }; - name = descriptor.n || descriptor; - if (typeof name !== 'string') { - fragment = new StringFragment({ - descriptor: name, - root: this.root, - owner: owner, - contextStack: contextStack - }); - name = fragment.toString(); - fragment.teardown(); - } - this.name = name; - if (descriptor.a) { - this.params = descriptor.a; - } else if (descriptor.d) { - fragment = new StringFragment({ - descriptor: descriptor.d, - root: this.root, - owner: owner, - contextStack: contextStack - }); - this.params = fragment.toArgsList(); - fragment.teardown(); - } - this._fn = root.transitions[name]; - if (!this._fn) { - errorMessage = 'Missing "' + name + '" transition. You may need to download a plugin via https://github.com/RactiveJS/Ractive/wiki/Plugins#transitions'; - if (root.debug) { - throw new Error(errorMessage); - } else { - warn(errorMessage); - } - return; - } - }; - Transition.prototype = { - init: function () { - if (this._inited) { - throw new Error('Cannot initialize a transition more than once'); - } - this._inited = true; - this._fn.apply(this.root, [this].concat(this.params)); - }, - getStyle: function (props) { - var computedStyle, styles, i, prop, value; - computedStyle = window.getComputedStyle(this.node); - if (typeof props === 'string') { - value = computedStyle[prefix(props)]; - if (value === '0px') { - value = 0; - } - return value; - } - if (!isArray(props)) { - throw new Error('Transition#getStyle must be passed a string, or an array of strings representing CSS properties'); - } - styles = {}; - i = props.length; - while (i--) { - prop = props[i]; - value = computedStyle[prefix(prop)]; - if (value === '0px') { - value = 0; - } - styles[prop] = value; - } - return styles; - }, - setStyle: function (style, value) { - var prop; - if (typeof style === 'string') { - this.node.style[prefix(style)] = value; - } else { - for (prop in style) { - if (style.hasOwnProperty(prop)) { - this.node.style[prefix(prop)] = style[prop]; - } - } - } - return this; - }, - animateStyle: function (style, value, options, complete) { - var t = this, propertyNames, changedProperties, computedStyle, current, to, from, transitionEndHandler, i, prop; - if (typeof style === 'string') { - to = {}; - to[style] = value; - } else { - to = style; - complete = options; - options = value; - } - if (!options) { - warn('The "' + t.name + '" transition does not supply an options object to `t.animateStyle()`. This will break in a future version of Ractive. For more info see https://github.com/RactiveJS/Ractive/issues/340'); - options = t; - complete = t.complete; - } - if (!options.duration) { - t.setStyle(to); - if (complete) { - complete(); - } - } - propertyNames = Object.keys(to); - changedProperties = []; - computedStyle = window.getComputedStyle(t.node); - from = {}; - i = propertyNames.length; - while (i--) { - prop = propertyNames[i]; - current = computedStyle[prefix(prop)]; - if (current === '0px') { - current = 0; - } - if (current != to[prop]) { - changedProperties[changedProperties.length] = prop; - t.node.style[prefix(prop)] = current; - } - } - if (!changedProperties.length) { - if (complete) { - complete(); - } - return; - } - setTimeout(function () { - t.node.style[TRANSITION_PROPERTY] = propertyNames.map(prefix).map(hyphenate).join(','); - t.node.style[TRANSITION_TIMING_FUNCTION] = hyphenate(options.easing || 'linear'); - t.node.style[TRANSITION_DURATION] = options.duration / 1000 + 's'; - transitionEndHandler = function (event) { - var index; - index = changedProperties.indexOf(camelCase(unprefix(event.propertyName))); - if (index !== -1) { - changedProperties.splice(index, 1); - } - if (changedProperties.length) { - return; - } - t.root.fire(t.name + ':end'); - t.node.removeEventListener(TRANSITIONEND, transitionEndHandler, false); - if (complete) { - complete(); - } - }; - t.node.addEventListener(TRANSITIONEND, transitionEndHandler, false); - setTimeout(function () { - var i = changedProperties.length; - while (i--) { - prop = changedProperties[i]; - t.node.style[prefix(prop)] = to[prop]; - } - }, 0); - }, options.delay || 0); - }, - resetStyle: function () { - if (this.originalStyle) { - this.node.setAttribute('style', this.originalStyle); - } else { - this.node.getAttribute('style'); - this.node.removeAttribute('style'); - } - }, - processParams: function (params, defaults) { - if (typeof params === 'number') { - params = { duration: params }; - } else if (typeof params === 'string') { - if (params === 'slow') { - params = { duration: 600 }; - } else if (params === 'fast') { - params = { duration: 200 }; - } else { - params = { duration: 400 }; - } - } else if (!params) { - params = {}; - } - return fillGaps(params, defaults); - } - }; - vendors = [ - 'o', - 'ms', - 'moz', - 'webkit' - ]; - vendorPattern = new RegExp('^(?:' + vendors.join('|') + ')([A-Z])'); - unprefixPattern = new RegExp('^-(?:' + vendors.join('|') + ')-'); - prefixCache = {}; - function prefix(prop) { - var i, vendor, capped; - if (!prefixCache[prop]) { - if (testStyle[prop] !== undefined) { - prefixCache[prop] = prop; - } else { - capped = prop.charAt(0).toUpperCase() + prop.substring(1); - i = vendors.length; - while (i--) { - vendor = vendors[i]; - if (testStyle[vendor + capped] !== undefined) { - prefixCache[prop] = vendor + capped; - break; - } - } - } - } - return prefixCache[prop]; - } - function unprefix(prop) { - return prop.replace(unprefixPattern, ''); - } - function hyphenate(str) { - var hyphenated; - if (vendorPattern.test(str)) { - str = '-' + str; - } - hyphenated = str.replace(/[A-Z]/g, function (match) { - return '-' + match.toLowerCase(); - }); - return hyphenated; - } - return Transition; - }(config_isClient, utils_createElement, utils_warn, utils_isNumeric, utils_isArray, utils_camelCase, utils_fillGaps, render_StringFragment__StringFragment); -var render_DomFragment_Element_shared_executeTransition__executeTransition = function (warn, Transition) { - - return function (descriptor, root, owner, contextStack, isIntro) { - var transition, node, oldTransition; - if (!root.transitionsEnabled || root._parent && !root._parent.transitionsEnabled) { - return; - } - transition = new Transition(descriptor, root, owner, contextStack, isIntro); - if (transition._fn) { - node = transition.node; - transition._manager = root._transitionManager; - if (oldTransition = node._ractive.transition) { - oldTransition.complete(); - } - node._ractive.transition = transition; - transition._manager.push(node); - if (isIntro) { - root._deferred.transitions.push(transition); - } else { - transition.init(); - } - } - }; - }(utils_warn, render_DomFragment_Element_shared_executeTransition_Transition); -var render_DomFragment_Element_initialise__initialise = function (types, namespaces, create, defineProperty, matches, warn, createElement, getElementNamespace, createElementAttributes, appendElementChildren, decorate, addEventProxies, updateLiveQueries, executeTransition, enforceCase) { - - return function (element, options, docFrag) { - var parentFragment, pNode, contextStack, descriptor, namespace, name, attributes, width, height, loadHandler, root, selectBinding, errorMessage; - element.type = types.ELEMENT; - parentFragment = element.parentFragment = options.parentFragment; - pNode = parentFragment.pNode; - contextStack = parentFragment.contextStack; - descriptor = element.descriptor = options.descriptor; - element.root = root = parentFragment.root; - element.index = options.index; - element.lcName = descriptor.e.toLowerCase(); - element.eventListeners = []; - element.customEventListeners = []; - if (pNode) { - namespace = element.namespace = getElementNamespace(descriptor, pNode); - name = namespace !== namespaces.html ? enforceCase(descriptor.e) : descriptor.e; - element.node = createElement(name, namespace); - defineProperty(element.node, '_ractive', { - value: { - proxy: element, - keypath: contextStack.length ? contextStack[contextStack.length - 1] : '', - index: parentFragment.indexRefs, - events: create(null), - root: root - } - }); - } - attributes = createElementAttributes(element, descriptor.a); - if (descriptor.f) { - if (element.node && element.node.getAttribute('contenteditable')) { - if (element.node.innerHTML) { - errorMessage = 'A pre-populated contenteditable element should not have children'; - if (root.debug) { - throw new Error(errorMessage); - } else { - warn(errorMessage); - } - } - } - appendElementChildren(element, element.node, descriptor, docFrag); - } - if (docFrag && descriptor.v) { - addEventProxies(element, descriptor.v); - } - if (docFrag) { - if (root.twoway) { - element.bind(); - if (element.node.getAttribute('contenteditable') && element.node._ractive.binding) { - element.node._ractive.binding.update(); - } - } - if (attributes.name && !attributes.name.twoway) { - attributes.name.update(); - } - if (element.node.tagName === 'IMG' && ((width = element.attributes.width) || (height = element.attributes.height))) { - element.node.addEventListener('load', loadHandler = function () { - if (width) { - element.node.width = width.value; - } - if (height) { - element.node.height = height.value; - } - element.node.removeEventListener('load', loadHandler, false); - }, false); - } - docFrag.appendChild(element.node); - if (descriptor.o) { - decorate(descriptor.o, root, element, contextStack); - } - if (descriptor.t1) { - executeTransition(descriptor.t1, root, element, contextStack, true); - } - if (element.node.tagName === 'OPTION') { - if (pNode.tagName === 'SELECT' && (selectBinding = pNode._ractive.binding)) { - selectBinding.deferUpdate(); - } - if (element.node._ractive.value == pNode._ractive.value) { - element.node.selected = true; - } - } - if (element.node.autofocus) { - root._deferred.focusable = element.node; - } - } - updateLiveQueries(element); - }; - }(config_types, config_namespaces, utils_create, utils_defineProperty, utils_matches, utils_warn, utils_createElement, render_DomFragment_Element_initialise_getElementNamespace, render_DomFragment_Element_initialise_createElementAttributes, render_DomFragment_Element_initialise_appendElementChildren, render_DomFragment_Element_initialise_decorate__decorate, render_DomFragment_Element_initialise_addEventProxies__addEventProxies, render_DomFragment_Element_initialise_updateLiveQueries, render_DomFragment_Element_shared_executeTransition__executeTransition, render_DomFragment_shared_enforceCase); -var render_DomFragment_Element_prototype_teardown = function (executeTransition) { - - return function (destroy) { - var eventName, binding, bindings, i, liveQueries, selector, query, nodesToRemove, j; - if (this.fragment) { - this.fragment.teardown(false); - } - while (this.attributes.length) { - this.attributes.pop().teardown(); - } - if (this.node) { - for (eventName in this.node._ractive.events) { - this.node._ractive.events[eventName].teardown(); - } - if (binding = this.node._ractive.binding) { - binding.teardown(); - bindings = this.root._twowayBindings[binding.attr.keypath]; - bindings.splice(bindings.indexOf(binding), 1); - } - } - if (this.decorator) { - this.decorator.teardown(); - } - if (this.descriptor.t2) { - executeTransition(this.descriptor.t2, this.root, this, this.parentFragment.contextStack, false); - } - if (destroy) { - this.root._transitionManager.detachWhenReady(this); - } - if (liveQueries = this.liveQueries) { - i = liveQueries.length; - while (i--) { - selector = liveQueries[i]; - if (nodesToRemove = this.liveQueries[selector]) { - j = nodesToRemove.length; - query = this.root._liveQueries[selector]; - while (j--) { - query._remove(nodesToRemove[j]); - } - } - } - } - }; - }(render_DomFragment_Element_shared_executeTransition__executeTransition); -var config_voidElementNames = function () { - - return 'area base br col command doctype embed hr img input keygen link meta param source track wbr'.split(' '); - }(); -var render_DomFragment_Element_prototype_toString = function (voidElementNames) { - - return function () { - var str, i, len; - str = '<' + (this.descriptor.y ? '!doctype' : this.descriptor.e); - len = this.attributes.length; - for (i = 0; i < len; i += 1) { - str += ' ' + this.attributes[i].toString(); - } - str += '>'; - if (this.html) { - str += this.html; - } else if (this.fragment) { - str += this.fragment.toString(); - } - if (voidElementNames.indexOf(this.descriptor.e) === -1) { - str += ''; - } - return str; - }; - }(config_voidElementNames); -var render_DomFragment_Element_prototype_find = function (matches) { - - return function (selector) { - var queryResult; - if (matches(this.node, selector)) { - return this.node; - } - if (this.html && (queryResult = this.node.querySelector(selector))) { - return queryResult; - } - if (this.fragment && this.fragment.find) { - return this.fragment.find(selector); - } - }; - }(utils_matches); -var render_DomFragment_Element_prototype_findAll = function () { - - return function (selector, query) { - var queryAllResult, i, numNodes, node, registeredNodes; - if (query._test(this, true) && query.live) { - (this.liveQueries || (this.liveQueries = [])).push(selector); - this.liveQueries[selector] = [this.node]; - } - if (this.html && (queryAllResult = this.node.querySelectorAll(selector)) && (numNodes = queryAllResult.length)) { - if (query.live) { - if (!this.liveQueries[selector]) { - (this.liveQueries || (this.liveQueries = [])).push(selector); - this.liveQueries[selector] = []; - } - registeredNodes = this.liveQueries[selector]; - } - for (i = 0; i < numNodes; i += 1) { - node = queryAllResult[i]; - query.push(node); - if (query.live) { - registeredNodes.push(node); - } - } - } - if (this.fragment) { - this.fragment.findAll(selector, query); - } - }; - }(); -var render_DomFragment_Element_prototype_findComponent = function () { - - return function (selector) { - if (this.fragment) { - return this.fragment.findComponent(selector); - } - }; - }(); -var render_DomFragment_Element_prototype_findAllComponents = function () { - - return function (selector, query) { - if (this.fragment) { - this.fragment.findAllComponents(selector, query); - } - }; - }(); -var render_DomFragment_Element_prototype_bind = function () { - - return function () { - var attributes = this.attributes; - if (!this.node) { - return; - } - if (this.binding) { - this.binding.teardown(); - this.binding = null; - } - if (this.node.getAttribute('contenteditable') && attributes.value && attributes.value.bind()) { - return; - } - switch (this.descriptor.e) { - case 'select': - case 'textarea': - if (attributes.value) { - attributes.value.bind(); - } - return; - case 'input': - if (this.node.type === 'radio' || this.node.type === 'checkbox') { - if (attributes.name && attributes.name.bind()) { - return; - } - if (attributes.checked && attributes.checked.bind()) { - return; - } - } - if (attributes.value && attributes.value.bind()) { - return; - } - } - }; - }(); -var render_DomFragment_Element__Element = function (initialise, teardown, toString, find, findAll, findComponent, findAllComponents, bind) { - - var DomElement = function (options, docFrag) { - initialise(this, options, docFrag); - }; - DomElement.prototype = { - detach: function () { - if (this.node) { - if (this.node.parentNode) { - this.node.parentNode.removeChild(this.node); - } - return this.node; - } - }, - teardown: teardown, - firstNode: function () { - return this.node; - }, - findNextNode: function () { - return null; - }, - bubble: function () { - }, - toString: toString, - find: find, - findAll: findAll, - findComponent: findComponent, - findAllComponents: findAllComponents, - bind: bind - }; - return DomElement; - }(render_DomFragment_Element_initialise__initialise, render_DomFragment_Element_prototype_teardown, render_DomFragment_Element_prototype_toString, render_DomFragment_Element_prototype_find, render_DomFragment_Element_prototype_findAll, render_DomFragment_Element_prototype_findComponent, render_DomFragment_Element_prototype_findAllComponents, render_DomFragment_Element_prototype_bind); -var config_errors = { missingParser: 'Missing Ractive.parse - cannot parse template. Either preparse or use the version that includes the parser' }; -var registries_partials = {}; -var parse_utils_stripHtmlComments = function () { - - return function (html) { - var commentStart, commentEnd, processed; - processed = ''; - while (html.length) { - commentStart = html.indexOf(''); - if (commentStart === -1 && commentEnd === -1) { - processed += html; - break; - } - if (commentStart !== -1 && commentEnd === -1) { - throw 'Illegal HTML - expected closing comment sequence (\'-->\')'; - } - if (commentEnd !== -1 && commentStart === -1 || commentEnd < commentStart) { - throw 'Illegal HTML - unexpected closing comment sequence (\'-->\')'; - } - processed += html.substr(0, commentStart); - html = html.substring(commentEnd + 3); - } - return processed; - }; - }(); -var parse_utils_stripStandalones = function (types) { - - return function (tokens) { - var i, current, backOne, backTwo, leadingLinebreak, trailingLinebreak; - leadingLinebreak = /^\s*\r?\n/; - trailingLinebreak = /\r?\n\s*$/; - for (i = 2; i < tokens.length; i += 1) { - current = tokens[i]; - backOne = tokens[i - 1]; - backTwo = tokens[i - 2]; - if (current.type === types.TEXT && backOne.type === types.MUSTACHE && backTwo.type === types.TEXT) { - if (trailingLinebreak.test(backTwo.value) && leadingLinebreak.test(current.value)) { - if (backOne.mustacheType !== types.INTERPOLATOR && backOne.mustacheType !== types.TRIPLE) { - backTwo.value = backTwo.value.replace(trailingLinebreak, '\n'); - } - current.value = current.value.replace(leadingLinebreak, ''); - if (current.value === '') { - tokens.splice(i--, 1); - } - } - } - } - return tokens; - }; - }(config_types); -var parse_utils_stripCommentTokens = function (types) { - - return function (tokens) { - var i, current, previous, next; - for (i = 0; i < tokens.length; i += 1) { - current = tokens[i]; - previous = tokens[i - 1]; - next = tokens[i + 1]; - if (current.mustacheType === types.COMMENT || current.mustacheType === types.DELIMCHANGE) { - tokens.splice(i, 1); - if (previous && next) { - if (previous.type === types.TEXT && next.type === types.TEXT) { - previous.value += next.value; - tokens.splice(i, 1); - } - } - i -= 1; - } - } - return tokens; - }; - }(config_types); -var parse_Tokenizer_getMustache_getDelimiterChange = function (makeRegexMatcher) { - - var getDelimiter = makeRegexMatcher(/^[^\s=]+/); - return function (tokenizer) { - var start, opening, closing; - if (!tokenizer.getStringMatch('=')) { - return null; - } - start = tokenizer.pos; - tokenizer.allowWhitespace(); - opening = getDelimiter(tokenizer); - if (!opening) { - tokenizer.pos = start; - return null; - } - tokenizer.allowWhitespace(); - closing = getDelimiter(tokenizer); - if (!closing) { - tokenizer.pos = start; - return null; - } - tokenizer.allowWhitespace(); - if (!tokenizer.getStringMatch('=')) { - tokenizer.pos = start; - return null; - } - return [ - opening, - closing - ]; - }; - }(parse_Tokenizer_utils_makeRegexMatcher); -var parse_Tokenizer_getMustache_getMustacheType = function (types) { - - var mustacheTypes = { - '#': types.SECTION, - '^': types.INVERTED, - '/': types.CLOSING, - '>': types.PARTIAL, - '!': types.COMMENT, - '&': types.TRIPLE - }; - return function (tokenizer) { - var type = mustacheTypes[tokenizer.str.charAt(tokenizer.pos)]; - if (!type) { - return null; - } - tokenizer.pos += 1; - return type; - }; - }(config_types); -var parse_Tokenizer_getMustache_getMustacheContent = function (types, makeRegexMatcher, getMustacheType) { - - var getIndexRef = makeRegexMatcher(/^\s*:\s*([a-zA-Z_$][a-zA-Z_$0-9]*)/), arrayMember = /^[0-9][1-9]*$/; - return function (tokenizer, isTriple) { - var start, mustache, type, expr, i, remaining, index; - start = tokenizer.pos; - mustache = { type: isTriple ? types.TRIPLE : types.MUSTACHE }; - if (!isTriple) { - if (expr = tokenizer.getExpression()) { - mustache.mustacheType = types.INTERPOLATOR; - tokenizer.allowWhitespace(); - if (tokenizer.getStringMatch(tokenizer.delimiters[1])) { - tokenizer.pos -= tokenizer.delimiters[1].length; - } else { - tokenizer.pos = start; - expr = null; - } - } - if (!expr) { - type = getMustacheType(tokenizer); - if (type === types.TRIPLE) { - mustache = { type: types.TRIPLE }; - } else { - mustache.mustacheType = type || types.INTERPOLATOR; - } - if (type === types.COMMENT || type === types.CLOSING) { - remaining = tokenizer.remaining(); - index = remaining.indexOf(tokenizer.delimiters[1]); - if (index !== -1) { - mustache.ref = remaining.substr(0, index); - tokenizer.pos += index; - return mustache; - } - } - } - } - if (!expr) { - tokenizer.allowWhitespace(); - expr = tokenizer.getExpression(); - } - while (expr.t === types.BRACKETED && expr.x) { - expr = expr.x; - } - if (expr.t === types.REFERENCE) { - mustache.ref = expr.n; - } else if (expr.t === types.NUMBER_LITERAL && arrayMember.test(expr.v)) { - mustache.ref = expr.v; - } else { - mustache.expression = expr; - } - i = getIndexRef(tokenizer); - if (i !== null) { - mustache.indexRef = i; - } - return mustache; - }; - }(config_types, parse_Tokenizer_utils_makeRegexMatcher, parse_Tokenizer_getMustache_getMustacheType); -var parse_Tokenizer_getMustache__getMustache = function (types, getDelimiterChange, getMustacheContent) { - - return function () { - var seekTripleFirst = this.tripleDelimiters[0].length > this.delimiters[0].length; - return getMustache(this, seekTripleFirst) || getMustache(this, !seekTripleFirst); - }; - function getMustache(tokenizer, seekTriple) { - var start = tokenizer.pos, content, delimiters; - delimiters = seekTriple ? tokenizer.tripleDelimiters : tokenizer.delimiters; - if (!tokenizer.getStringMatch(delimiters[0])) { - return null; - } - content = getDelimiterChange(tokenizer); - if (content) { - if (!tokenizer.getStringMatch(delimiters[1])) { - tokenizer.pos = start; - return null; - } - tokenizer[seekTriple ? 'tripleDelimiters' : 'delimiters'] = content; - return { - type: types.MUSTACHE, - mustacheType: types.DELIMCHANGE - }; - } - tokenizer.allowWhitespace(); - content = getMustacheContent(tokenizer, seekTriple); - if (content === null) { - tokenizer.pos = start; - return null; - } - tokenizer.allowWhitespace(); - if (!tokenizer.getStringMatch(delimiters[1])) { - tokenizer.pos = start; - return null; - } - return content; - } - }(config_types, parse_Tokenizer_getMustache_getDelimiterChange, parse_Tokenizer_getMustache_getMustacheContent); -var parse_Tokenizer_getComment_getComment = function (types) { - - return function () { - var content, remaining, endIndex; - if (!this.getStringMatch(''); - if (endIndex === -1) { - throw new Error('Unexpected end of input (expected "-->" to close comment)'); - } - content = remaining.substr(0, endIndex); - this.pos += endIndex + 3; - return { - type: types.COMMENT, - content: content - }; - }; - }(config_types); -var parse_Tokenizer_utils_getLowestIndex = function () { - - return function (haystack, needles) { - var i, index, lowest; - i = needles.length; - while (i--) { - index = haystack.indexOf(needles[i]); - if (!index) { - return 0; - } - if (index === -1) { - continue; - } - if (!lowest || index < lowest) { - lowest = index; - } - } - return lowest || -1; - }; - }(); -var parse_Tokenizer_getTag__getTag = function (types, makeRegexMatcher, getLowestIndex) { - - var getTag, getOpeningTag, getClosingTag, getTagName, getAttributes, getAttribute, getAttributeName, getAttributeValue, getUnquotedAttributeValue, getUnquotedAttributeValueToken, getUnquotedAttributeValueText, getQuotedStringToken, getQuotedAttributeValue; - getTag = function () { - return getOpeningTag(this) || getClosingTag(this); - }; - getOpeningTag = function (tokenizer) { - var start, tag, attrs, lowerCaseName; - start = tokenizer.pos; - if (tokenizer.inside) { - return null; - } - if (!tokenizer.getStringMatch('<')) { - return null; - } - tag = { type: types.TAG }; - if (tokenizer.getStringMatch('!')) { - tag.doctype = true; - } - tag.name = getTagName(tokenizer); - if (!tag.name) { - tokenizer.pos = start; - return null; - } - attrs = getAttributes(tokenizer); - if (attrs) { - tag.attrs = attrs; - } - tokenizer.allowWhitespace(); - if (tokenizer.getStringMatch('/')) { - tag.selfClosing = true; - } - if (!tokenizer.getStringMatch('>')) { - tokenizer.pos = start; - return null; - } - lowerCaseName = tag.name.toLowerCase(); - if (lowerCaseName === 'script' || lowerCaseName === 'style') { - tokenizer.inside = lowerCaseName; - } - return tag; - }; - getClosingTag = function (tokenizer) { - var start, tag, expected; - start = tokenizer.pos; - expected = function (str) { - throw new Error('Unexpected character ' + tokenizer.remaining().charAt(0) + ' (expected ' + str + ')'); - }; - if (!tokenizer.getStringMatch('<')) { - return null; - } - tag = { - type: types.TAG, - closing: true - }; - if (!tokenizer.getStringMatch('/')) { - expected('"/"'); - } - tag.name = getTagName(tokenizer); - if (!tag.name) { - expected('tag name'); - } - if (!tokenizer.getStringMatch('>')) { - expected('">"'); - } - if (tokenizer.inside) { - if (tag.name.toLowerCase() !== tokenizer.inside) { - tokenizer.pos = start; - return null; - } - tokenizer.inside = null; - } - return tag; - }; - getTagName = makeRegexMatcher(/^[a-zA-Z]{1,}:?[a-zA-Z0-9\-]*/); - getAttributes = function (tokenizer) { - var start, attrs, attr; - start = tokenizer.pos; - tokenizer.allowWhitespace(); - attr = getAttribute(tokenizer); - if (!attr) { - tokenizer.pos = start; - return null; - } - attrs = []; - while (attr !== null) { - attrs[attrs.length] = attr; - tokenizer.allowWhitespace(); - attr = getAttribute(tokenizer); - } - return attrs; - }; - getAttribute = function (tokenizer) { - var attr, name, value; - name = getAttributeName(tokenizer); - if (!name) { - return null; - } - attr = { name: name }; - value = getAttributeValue(tokenizer); - if (value) { - attr.value = value; - } - return attr; - }; - getAttributeName = makeRegexMatcher(/^[^\s"'>\/=]+/); - getAttributeValue = function (tokenizer) { - var start, value; - start = tokenizer.pos; - tokenizer.allowWhitespace(); - if (!tokenizer.getStringMatch('=')) { - tokenizer.pos = start; - return null; - } - tokenizer.allowWhitespace(); - value = getQuotedAttributeValue(tokenizer, '\'') || getQuotedAttributeValue(tokenizer, '"') || getUnquotedAttributeValue(tokenizer); - if (value === null) { - tokenizer.pos = start; - return null; - } - return value; - }; - getUnquotedAttributeValueText = makeRegexMatcher(/^[^\s"'=<>`]+/); - getUnquotedAttributeValueToken = function (tokenizer) { - var start, text, index; - start = tokenizer.pos; - text = getUnquotedAttributeValueText(tokenizer); - if (!text) { - return null; - } - if ((index = text.indexOf(tokenizer.delimiters[0])) !== -1) { - text = text.substr(0, index); - tokenizer.pos = start + text.length; - } - return { - type: types.TEXT, - value: text - }; - }; - getUnquotedAttributeValue = function (tokenizer) { - var tokens, token; - tokens = []; - token = tokenizer.getMustache() || getUnquotedAttributeValueToken(tokenizer); - while (token !== null) { - tokens[tokens.length] = token; - token = tokenizer.getMustache() || getUnquotedAttributeValueToken(tokenizer); - } - if (!tokens.length) { - return null; - } - return tokens; - }; - getQuotedAttributeValue = function (tokenizer, quoteMark) { - var start, tokens, token; - start = tokenizer.pos; - if (!tokenizer.getStringMatch(quoteMark)) { - return null; - } - tokens = []; - token = tokenizer.getMustache() || getQuotedStringToken(tokenizer, quoteMark); - while (token !== null) { - tokens[tokens.length] = token; - token = tokenizer.getMustache() || getQuotedStringToken(tokenizer, quoteMark); - } - if (!tokenizer.getStringMatch(quoteMark)) { - tokenizer.pos = start; - return null; - } - return tokens; - }; - getQuotedStringToken = function (tokenizer, quoteMark) { - var start, index, remaining; - start = tokenizer.pos; - remaining = tokenizer.remaining(); - index = getLowestIndex(remaining, [ - quoteMark, - tokenizer.delimiters[0], - tokenizer.delimiters[1] - ]); - if (index === -1) { - throw new Error('Quoted attribute value must have a closing quote'); - } - if (!index) { - return null; - } - tokenizer.pos += index; - return { - type: types.TEXT, - value: remaining.substr(0, index) - }; - }; - return getTag; - }(config_types, parse_Tokenizer_utils_makeRegexMatcher, parse_Tokenizer_utils_getLowestIndex); -var parse_Tokenizer_getText__getText = function (types, getLowestIndex) { - - return function () { - var index, remaining, barrier; - remaining = this.remaining(); - barrier = this.inside ? '> >>> < <= > >= in instanceof == != === !== & ^ | && ||'.split(' '); - fallthrough = getTypeOf; - for (i = 0, len = infixOperators.length; i < len; i += 1) { - matcher = makeInfixSequenceMatcher(infixOperators[i], fallthrough); - fallthrough = matcher; - } - getLogicalOr = fallthrough; - }()); - return getLogicalOr; - }(config_types, parse_Tokenizer_getExpression_getTypeOf); -var parse_Tokenizer_getExpression_getConditional = function (types, getLogicalOr) { - - return function (tokenizer) { - var start, expression, ifTrue, ifFalse; - expression = getLogicalOr(tokenizer); - if (!expression) { - return null; - } - start = tokenizer.pos; - tokenizer.allowWhitespace(); - if (!tokenizer.getStringMatch('?')) { - tokenizer.pos = start; - return expression; - } - tokenizer.allowWhitespace(); - ifTrue = tokenizer.getExpression(); - if (!ifTrue) { - tokenizer.pos = start; - return expression; - } - tokenizer.allowWhitespace(); - if (!tokenizer.getStringMatch(':')) { - tokenizer.pos = start; - return expression; - } - tokenizer.allowWhitespace(); - ifFalse = tokenizer.getExpression(); - if (!ifFalse) { - tokenizer.pos = start; - return expression; - } - return { - t: types.CONDITIONAL, - o: [ - expression, - ifTrue, - ifFalse - ] - }; - }; - }(config_types, parse_Tokenizer_getExpression_getLogicalOr); -var parse_Tokenizer_getExpression__getExpression = function (getConditional) { - - return function () { - return getConditional(this); - }; - }(parse_Tokenizer_getExpression_getConditional); -var parse_Tokenizer__Tokenizer = function (getMustache, getComment, getTag, getText, getExpression, allowWhitespace, getStringMatch) { - - var Tokenizer; - Tokenizer = function (str, options) { - var token; - this.str = str; - this.pos = 0; - this.delimiters = options.delimiters; - this.tripleDelimiters = options.tripleDelimiters; - this.tokens = []; - while (this.pos < this.str.length) { - token = this.getToken(); - if (token === null && this.remaining()) { - this.fail(); - } - this.tokens.push(token); - } - }; - Tokenizer.prototype = { - getToken: function () { - var token = this.getMustache() || this.getComment() || this.getTag() || this.getText(); - return token; - }, - getMustache: getMustache, - getComment: getComment, - getTag: getTag, - getText: getText, - getExpression: getExpression, - allowWhitespace: allowWhitespace, - getStringMatch: getStringMatch, - remaining: function () { - return this.str.substring(this.pos); - }, - fail: function () { - var last20, next20; - last20 = this.str.substr(0, this.pos).substr(-20); - if (last20.length === 20) { - last20 = '...' + last20; - } - next20 = this.remaining().substr(0, 20); - if (next20.length === 20) { - next20 = next20 + '...'; - } - throw new Error('Could not parse template: ' + (last20 ? last20 + '<- ' : '') + 'failed at character ' + this.pos + ' ->' + next20); - }, - expected: function (thing) { - var remaining = this.remaining().substr(0, 40); - if (remaining.length === 40) { - remaining += '...'; - } - throw new Error('Tokenizer failed: unexpected string "' + remaining + '" (expected ' + thing + ')'); - } - }; - return Tokenizer; - }(parse_Tokenizer_getMustache__getMustache, parse_Tokenizer_getComment_getComment, parse_Tokenizer_getTag__getTag, parse_Tokenizer_getText__getText, parse_Tokenizer_getExpression__getExpression, parse_Tokenizer_utils_allowWhitespace, parse_Tokenizer_utils_getStringMatch); -var parse_tokenize = function (stripHtmlComments, stripStandalones, stripCommentTokens, Tokenizer, circular) { - - var tokenize, Ractive; - circular.push(function () { - Ractive = circular.Ractive; - }); - tokenize = function (template, options) { - var tokenizer, tokens; - options = options || {}; - if (options.stripComments !== false) { - template = stripHtmlComments(template); - } - tokenizer = new Tokenizer(template, { - delimiters: options.delimiters || (Ractive ? Ractive.delimiters : [ - '{{', - '}}' - ]), - tripleDelimiters: options.tripleDelimiters || (Ractive ? Ractive.tripleDelimiters : [ - '{{{', - '}}}' - ]) - }); - tokens = tokenizer.tokens; - stripStandalones(tokens); - stripCommentTokens(tokens); - return tokens; - }; - return tokenize; - }(parse_utils_stripHtmlComments, parse_utils_stripStandalones, parse_utils_stripCommentTokens, parse_Tokenizer__Tokenizer, circular); -var parse_Parser_getText_TextStub__TextStub = function (types) { - - var TextStub, htmlEntities, controlCharacters, namedEntityPattern, hexEntityPattern, decimalEntityPattern, validateCode, decodeCharacterReferences, whitespace; - TextStub = function (token, preserveWhitespace) { - this.text = preserveWhitespace ? token.value : token.value.replace(whitespace, ' '); - }; - TextStub.prototype = { - type: types.TEXT, - toJSON: function () { - return this.decoded || (this.decoded = decodeCharacterReferences(this.text)); - }, - toString: function () { - return this.text; - } - }; - htmlEntities = { - quot: 34, - amp: 38, - apos: 39, - lt: 60, - gt: 62, - nbsp: 160, - iexcl: 161, - cent: 162, - pound: 163, - curren: 164, - yen: 165, - brvbar: 166, - sect: 167, - uml: 168, - copy: 169, - ordf: 170, - laquo: 171, - not: 172, - shy: 173, - reg: 174, - macr: 175, - deg: 176, - plusmn: 177, - sup2: 178, - sup3: 179, - acute: 180, - micro: 181, - para: 182, - middot: 183, - cedil: 184, - sup1: 185, - ordm: 186, - raquo: 187, - frac14: 188, - frac12: 189, - frac34: 190, - iquest: 191, - Agrave: 192, - Aacute: 193, - Acirc: 194, - Atilde: 195, - Auml: 196, - Aring: 197, - AElig: 198, - Ccedil: 199, - Egrave: 200, - Eacute: 201, - Ecirc: 202, - Euml: 203, - Igrave: 204, - Iacute: 205, - Icirc: 206, - Iuml: 207, - ETH: 208, - Ntilde: 209, - Ograve: 210, - Oacute: 211, - Ocirc: 212, - Otilde: 213, - Ouml: 214, - times: 215, - Oslash: 216, - Ugrave: 217, - Uacute: 218, - Ucirc: 219, - Uuml: 220, - Yacute: 221, - THORN: 222, - szlig: 223, - agrave: 224, - aacute: 225, - acirc: 226, - atilde: 227, - auml: 228, - aring: 229, - aelig: 230, - ccedil: 231, - egrave: 232, - eacute: 233, - ecirc: 234, - euml: 235, - igrave: 236, - iacute: 237, - icirc: 238, - iuml: 239, - eth: 240, - ntilde: 241, - ograve: 242, - oacute: 243, - ocirc: 244, - otilde: 245, - ouml: 246, - divide: 247, - oslash: 248, - ugrave: 249, - uacute: 250, - ucirc: 251, - uuml: 252, - yacute: 253, - thorn: 254, - yuml: 255, - OElig: 338, - oelig: 339, - Scaron: 352, - scaron: 353, - Yuml: 376, - fnof: 402, - circ: 710, - tilde: 732, - Alpha: 913, - Beta: 914, - Gamma: 915, - Delta: 916, - Epsilon: 917, - Zeta: 918, - Eta: 919, - Theta: 920, - Iota: 921, - Kappa: 922, - Lambda: 923, - Mu: 924, - Nu: 925, - Xi: 926, - Omicron: 927, - Pi: 928, - Rho: 929, - Sigma: 931, - Tau: 932, - Upsilon: 933, - Phi: 934, - Chi: 935, - Psi: 936, - Omega: 937, - alpha: 945, - beta: 946, - gamma: 947, - delta: 948, - epsilon: 949, - zeta: 950, - eta: 951, - theta: 952, - iota: 953, - kappa: 954, - lambda: 955, - mu: 956, - nu: 957, - xi: 958, - omicron: 959, - pi: 960, - rho: 961, - sigmaf: 962, - sigma: 963, - tau: 964, - upsilon: 965, - phi: 966, - chi: 967, - psi: 968, - omega: 969, - thetasym: 977, - upsih: 978, - piv: 982, - ensp: 8194, - emsp: 8195, - thinsp: 8201, - zwnj: 8204, - zwj: 8205, - lrm: 8206, - rlm: 8207, - ndash: 8211, - mdash: 8212, - lsquo: 8216, - rsquo: 8217, - sbquo: 8218, - ldquo: 8220, - rdquo: 8221, - bdquo: 8222, - dagger: 8224, - Dagger: 8225, - bull: 8226, - hellip: 8230, - permil: 8240, - prime: 8242, - Prime: 8243, - lsaquo: 8249, - rsaquo: 8250, - oline: 8254, - frasl: 8260, - euro: 8364, - image: 8465, - weierp: 8472, - real: 8476, - trade: 8482, - alefsym: 8501, - larr: 8592, - uarr: 8593, - rarr: 8594, - darr: 8595, - harr: 8596, - crarr: 8629, - lArr: 8656, - uArr: 8657, - rArr: 8658, - dArr: 8659, - hArr: 8660, - forall: 8704, - part: 8706, - exist: 8707, - empty: 8709, - nabla: 8711, - isin: 8712, - notin: 8713, - ni: 8715, - prod: 8719, - sum: 8721, - minus: 8722, - lowast: 8727, - radic: 8730, - prop: 8733, - infin: 8734, - ang: 8736, - and: 8743, - or: 8744, - cap: 8745, - cup: 8746, - 'int': 8747, - there4: 8756, - sim: 8764, - cong: 8773, - asymp: 8776, - ne: 8800, - equiv: 8801, - le: 8804, - ge: 8805, - sub: 8834, - sup: 8835, - nsub: 8836, - sube: 8838, - supe: 8839, - oplus: 8853, - otimes: 8855, - perp: 8869, - sdot: 8901, - lceil: 8968, - rceil: 8969, - lfloor: 8970, - rfloor: 8971, - lang: 9001, - rang: 9002, - loz: 9674, - spades: 9824, - clubs: 9827, - hearts: 9829, - diams: 9830 - }; - controlCharacters = [ - 8364, - 129, - 8218, - 402, - 8222, - 8230, - 8224, - 8225, - 710, - 8240, - 352, - 8249, - 338, - 141, - 381, - 143, - 144, - 8216, - 8217, - 8220, - 8221, - 8226, - 8211, - 8212, - 732, - 8482, - 353, - 8250, - 339, - 157, - 382, - 376 - ]; - namedEntityPattern = new RegExp('&(' + Object.keys(htmlEntities).join('|') + ');?', 'g'); - hexEntityPattern = /&#x([0-9]+);?/g; - decimalEntityPattern = /&#([0-9]+);?/g; - validateCode = function (code) { - if (!code) { - return 65533; - } - if (code === 10) { - return 32; - } - if (code < 128) { - return code; - } - if (code <= 159) { - return controlCharacters[code - 128]; - } - if (code < 55296) { - return code; - } - if (code <= 57343) { - return 65533; - } - if (code <= 65535) { - return code; - } - return 65533; - }; - decodeCharacterReferences = function (html) { - var result; - result = html.replace(namedEntityPattern, function (match, name) { - if (htmlEntities[name]) { - return String.fromCharCode(htmlEntities[name]); - } - return match; - }); - result = result.replace(hexEntityPattern, function (match, hex) { - return String.fromCharCode(validateCode(parseInt(hex, 16))); - }); - result = result.replace(decimalEntityPattern, function (match, charCode) { - return String.fromCharCode(validateCode(charCode)); - }); - return result; - }; - whitespace = /\s+/g; - return TextStub; - }(config_types); -var parse_Parser_getText__getText = function (types, TextStub) { - - return function (token) { - if (token.type === types.TEXT) { - this.pos += 1; - return new TextStub(token, this.preserveWhitespace); - } - return null; - }; - }(config_types, parse_Parser_getText_TextStub__TextStub); -var parse_Parser_getComment_CommentStub__CommentStub = function (types) { - - var CommentStub; - CommentStub = function (token) { - this.content = token.content; - }; - CommentStub.prototype = { - toJSON: function () { - return { - t: types.COMMENT, - f: this.content - }; - }, - toString: function () { - return ''; - } - }; - return CommentStub; - }(config_types); -var parse_Parser_getComment__getComment = function (types, CommentStub) { - - return function (token) { - if (token.type === types.COMMENT) { - this.pos += 1; - return new CommentStub(token, this.preserveWhitespace); - } - return null; - }; - }(config_types, parse_Parser_getComment_CommentStub__CommentStub); -var parse_Parser_getMustache_ExpressionStub__ExpressionStub = function (types, isObject) { - - var ExpressionStub, getRefs, stringify; - ExpressionStub = function (token) { - this.refs = []; - getRefs(token, this.refs); - this.str = stringify(token, this.refs); - }; - ExpressionStub.prototype = { - toJSON: function () { - if (this.json) { - return this.json; - } - this.json = { - r: this.refs, - s: this.str - }; - return this.json; - } - }; - getRefs = function (token, refs) { - var i, list; - if (token.t === types.REFERENCE) { - if (refs.indexOf(token.n) === -1) { - refs.unshift(token.n); - } - } - list = token.o || token.m; - if (list) { - if (isObject(list)) { - getRefs(list, refs); - } else { - i = list.length; - while (i--) { - getRefs(list[i], refs); - } - } - } - if (token.x) { - getRefs(token.x, refs); - } - if (token.r) { - getRefs(token.r, refs); - } - if (token.v) { - getRefs(token.v, refs); - } - }; - stringify = function (token, refs) { - var map = function (item) { - return stringify(item, refs); - }; - switch (token.t) { - case types.BOOLEAN_LITERAL: - case types.GLOBAL: - case types.NUMBER_LITERAL: - return token.v; - case types.STRING_LITERAL: - return '\'' + token.v.replace(/'/g, '\\\'') + '\''; - case types.ARRAY_LITERAL: - return '[' + (token.m ? token.m.map(map).join(',') : '') + ']'; - case types.OBJECT_LITERAL: - return '{' + (token.m ? token.m.map(map).join(',') : '') + '}'; - case types.KEY_VALUE_PAIR: - return token.k + ':' + stringify(token.v, refs); - case types.PREFIX_OPERATOR: - return (token.s === 'typeof' ? 'typeof ' : token.s) + stringify(token.o, refs); - case types.INFIX_OPERATOR: - return stringify(token.o[0], refs) + (token.s.substr(0, 2) === 'in' ? ' ' + token.s + ' ' : token.s) + stringify(token.o[1], refs); - case types.INVOCATION: - return stringify(token.x, refs) + '(' + (token.o ? token.o.map(map).join(',') : '') + ')'; - case types.BRACKETED: - return '(' + stringify(token.x, refs) + ')'; - case types.MEMBER: - return stringify(token.x, refs) + stringify(token.r, refs); - case types.REFINEMENT: - return token.n ? '.' + token.n : '[' + stringify(token.x, refs) + ']'; - case types.CONDITIONAL: - return stringify(token.o[0], refs) + '?' + stringify(token.o[1], refs) + ':' + stringify(token.o[2], refs); - case types.REFERENCE: - return '${' + refs.indexOf(token.n) + '}'; - default: - throw new Error('Could not stringify expression token. This error is unexpected'); - } - }; - return ExpressionStub; - }(config_types, utils_isObject); -var parse_Parser_getMustache_MustacheStub__MustacheStub = function (types, ExpressionStub) { - - var MustacheStub = function (token, parser) { - this.type = token.type === types.TRIPLE ? types.TRIPLE : token.mustacheType; - if (token.ref) { - this.ref = token.ref; - } - if (token.expression) { - this.expr = new ExpressionStub(token.expression); - } - parser.pos += 1; - }; - MustacheStub.prototype = { - toJSON: function () { - var json; - if (this.json) { - return this.json; - } - json = { t: this.type }; - if (this.ref) { - json.r = this.ref; - } - if (this.expr) { - json.x = this.expr.toJSON(); - } - this.json = json; - return json; - }, - toString: function () { - return false; - } - }; - return MustacheStub; - }(config_types, parse_Parser_getMustache_ExpressionStub__ExpressionStub); -var parse_Parser_utils_stringifyStubs = function () { - - return function (items) { - var str = '', itemStr, i, len; - if (!items) { - return ''; - } - for (i = 0, len = items.length; i < len; i += 1) { - itemStr = items[i].toString(); - if (itemStr === false) { - return false; - } - str += itemStr; - } - return str; - }; - }(); -var parse_Parser_utils_jsonifyStubs = function (stringifyStubs) { - - return function (items, noStringify) { - var str, json; - if (!noStringify) { - str = stringifyStubs(items); - if (str !== false) { - return str; - } - } - json = items.map(function (item) { - return item.toJSON(noStringify); - }); - return json; - }; - }(parse_Parser_utils_stringifyStubs); -var parse_Parser_getMustache_SectionStub__SectionStub = function (types, jsonifyStubs, ExpressionStub) { - - var SectionStub = function (firstToken, parser) { - var next; - this.ref = firstToken.ref; - this.indexRef = firstToken.indexRef; - this.inverted = firstToken.mustacheType === types.INVERTED; - if (firstToken.expression) { - this.expr = new ExpressionStub(firstToken.expression); - } - parser.pos += 1; - this.items = []; - next = parser.next(); - while (next) { - if (next.mustacheType === types.CLOSING) { - if (next.ref.trim() === this.ref || this.expr) { - parser.pos += 1; - break; - } else { - throw new Error('Could not parse template: Illegal closing section'); - } - } - this.items[this.items.length] = parser.getStub(); - next = parser.next(); - } - }; - SectionStub.prototype = { - toJSON: function (noStringify) { - var json; - if (this.json) { - return this.json; - } - json = { t: types.SECTION }; - if (this.ref) { - json.r = this.ref; - } - if (this.indexRef) { - json.i = this.indexRef; - } - if (this.inverted) { - json.n = true; - } - if (this.expr) { - json.x = this.expr.toJSON(); - } - if (this.items.length) { - json.f = jsonifyStubs(this.items, noStringify); - } - this.json = json; - return json; - }, - toString: function () { - return false; - } - }; - return SectionStub; - }(config_types, parse_Parser_utils_jsonifyStubs, parse_Parser_getMustache_ExpressionStub__ExpressionStub); -var parse_Parser_getMustache__getMustache = function (types, MustacheStub, SectionStub) { - - return function (token) { - if (token.type === types.MUSTACHE || token.type === types.TRIPLE) { - if (token.mustacheType === types.SECTION || token.mustacheType === types.INVERTED) { - return new SectionStub(token, this); - } - return new MustacheStub(token, this); - } - }; - }(config_types, parse_Parser_getMustache_MustacheStub__MustacheStub, parse_Parser_getMustache_SectionStub__SectionStub); -var parse_Parser_getElement_ElementStub_utils_siblingsByTagName = function () { - - return { - li: ['li'], - dt: [ - 'dt', - 'dd' - ], - dd: [ - 'dt', - 'dd' - ], - p: 'address article aside blockquote dir div dl fieldset footer form h1 h2 h3 h4 h5 h6 header hgroup hr menu nav ol p pre section table ul'.split(' '), - rt: [ - 'rt', - 'rp' - ], - rp: [ - 'rp', - 'rt' - ], - optgroup: ['optgroup'], - option: [ - 'option', - 'optgroup' - ], - thead: [ - 'tbody', - 'tfoot' - ], - tbody: [ - 'tbody', - 'tfoot' - ], - tr: ['tr'], - td: [ - 'td', - 'th' - ], - th: [ - 'td', - 'th' - ] - }; - }(); -var parse_Parser_getElement_ElementStub_utils_filterAttributes = function (isArray) { - - return function (items) { - var attrs, proxies, filtered, i, len, item; - filtered = {}; - attrs = []; - proxies = []; - len = items.length; - for (i = 0; i < len; i += 1) { - item = items[i]; - if (item.name === 'intro') { - if (filtered.intro) { - throw new Error('An element can only have one intro transition'); - } - filtered.intro = item; - } else if (item.name === 'outro') { - if (filtered.outro) { - throw new Error('An element can only have one outro transition'); - } - filtered.outro = item; - } else if (item.name === 'intro-outro') { - if (filtered.intro || filtered.outro) { - throw new Error('An element can only have one intro and one outro transition'); - } - filtered.intro = item; - filtered.outro = deepClone(item); - } else if (item.name.substr(0, 6) === 'proxy-') { - item.name = item.name.substring(6); - proxies[proxies.length] = item; - } else if (item.name.substr(0, 3) === 'on-') { - item.name = item.name.substring(3); - proxies[proxies.length] = item; - } else if (item.name === 'decorator') { - filtered.decorator = item; - } else { - attrs[attrs.length] = item; - } - } - filtered.attrs = attrs; - filtered.proxies = proxies; - return filtered; - }; - function deepClone(obj) { - var result, key; - if (typeof obj !== 'object') { - return obj; - } - if (isArray(obj)) { - return obj.map(deepClone); - } - result = {}; - for (key in obj) { - if (obj.hasOwnProperty(key)) { - result[key] = deepClone(obj[key]); - } - } - return result; - } - }(utils_isArray); -var parse_Parser_getElement_ElementStub_utils_processDirective = function (types, parseJSON) { - - return function (directive) { - var processed, tokens, token, colonIndex, throwError, directiveName, directiveArgs, parsed; - throwError = function () { - throw new Error('Illegal directive'); - }; - if (!directive.name || !directive.value) { - throwError(); - } - processed = { directiveType: directive.name }; - tokens = directive.value; - directiveName = []; - directiveArgs = []; - while (tokens.length) { - token = tokens.shift(); - if (token.type === types.TEXT) { - colonIndex = token.value.indexOf(':'); - if (colonIndex === -1) { - directiveName[directiveName.length] = token; - } else { - if (colonIndex) { - directiveName[directiveName.length] = { - type: types.TEXT, - value: token.value.substr(0, colonIndex) - }; - } - if (token.value.length > colonIndex + 1) { - directiveArgs[0] = { - type: types.TEXT, - value: token.value.substring(colonIndex + 1) - }; - } - break; - } - } else { - directiveName[directiveName.length] = token; - } - } - directiveArgs = directiveArgs.concat(tokens); - if (directiveName.length === 1 && directiveName[0].type === types.TEXT) { - processed.name = directiveName[0].value; - } else { - processed.name = directiveName; - } - if (directiveArgs.length) { - if (directiveArgs.length === 1 && directiveArgs[0].type === types.TEXT) { - parsed = parseJSON('[' + directiveArgs[0].value + ']'); - processed.args = parsed ? parsed.value : directiveArgs[0].value; - } else { - processed.dynamicArgs = directiveArgs; - } - } - return processed; - }; - }(config_types, utils_parseJSON); -var parse_Parser_StringStub_StringParser = function (getText, getMustache) { - - var StringParser; - StringParser = function (tokens, options) { - var stub; - this.tokens = tokens || []; - this.pos = 0; - this.options = options; - this.result = []; - while (stub = this.getStub()) { - this.result.push(stub); - } - }; - StringParser.prototype = { - getStub: function () { - var token = this.next(); - if (!token) { - return null; - } - return this.getText(token) || this.getMustache(token); - }, - getText: getText, - getMustache: getMustache, - next: function () { - return this.tokens[this.pos]; - } - }; - return StringParser; - }(parse_Parser_getText__getText, parse_Parser_getMustache__getMustache); -var parse_Parser_StringStub__StringStub = function (StringParser, stringifyStubs, jsonifyStubs) { - - var StringStub; - StringStub = function (tokens) { - var parser = new StringParser(tokens); - this.stubs = parser.result; - }; - StringStub.prototype = { - toJSON: function (noStringify) { - var json; - if (this['json_' + noStringify]) { - return this['json_' + noStringify]; - } - json = this['json_' + noStringify] = jsonifyStubs(this.stubs, noStringify); - return json; - }, - toString: function () { - if (this.str !== undefined) { - return this.str; - } - this.str = stringifyStubs(this.stubs); - return this.str; - } - }; - return StringStub; - }(parse_Parser_StringStub_StringParser, parse_Parser_utils_stringifyStubs, parse_Parser_utils_jsonifyStubs); -var parse_Parser_getElement_ElementStub_utils_jsonifyDirective = function (StringStub) { - - return function (directive) { - var result, name; - if (typeof directive.name === 'string') { - if (!directive.args && !directive.dynamicArgs) { - return directive.name; - } - name = directive.name; - } else { - name = new StringStub(directive.name).toJSON(); - } - result = { n: name }; - if (directive.args) { - result.a = directive.args; - return result; - } - if (directive.dynamicArgs) { - result.d = new StringStub(directive.dynamicArgs).toJSON(); - } - return result; - }; - }(parse_Parser_StringStub__StringStub); -var parse_Parser_getElement_ElementStub_toJSON = function (types, jsonifyStubs, jsonifyDirective) { - - return function (noStringify) { - var json, name, value, proxy, i, len, attribute; - if (this['json_' + noStringify]) { - return this['json_' + noStringify]; - } - if (this.component) { - json = { - t: types.COMPONENT, - e: this.component - }; - } else { - json = { - t: types.ELEMENT, - e: this.tag - }; - } - if (this.doctype) { - json.y = 1; - } - if (this.attributes && this.attributes.length) { - json.a = {}; - len = this.attributes.length; - for (i = 0; i < len; i += 1) { - attribute = this.attributes[i]; - name = attribute.name; - if (json.a[name]) { - throw new Error('You cannot have multiple attributes with the same name'); - } - if (attribute.value === null) { - value = null; - } else { - value = attribute.value.toJSON(noStringify); - } - json.a[name] = value; - } - } - if (this.items && this.items.length) { - json.f = jsonifyStubs(this.items, noStringify); - } - if (this.proxies && this.proxies.length) { - json.v = {}; - len = this.proxies.length; - for (i = 0; i < len; i += 1) { - proxy = this.proxies[i]; - json.v[proxy.directiveType] = jsonifyDirective(proxy); - } - } - if (this.intro) { - json.t1 = jsonifyDirective(this.intro); - } - if (this.outro) { - json.t2 = jsonifyDirective(this.outro); - } - if (this.decorator) { - json.o = jsonifyDirective(this.decorator); - } - this['json_' + noStringify] = json; - return json; - }; - }(config_types, parse_Parser_utils_jsonifyStubs, parse_Parser_getElement_ElementStub_utils_jsonifyDirective); -var parse_Parser_getElement_ElementStub_toString = function (stringifyStubs, voidElementNames) { - - var htmlElements; - htmlElements = 'a abbr acronym address applet area b base basefont bdo big blockquote body br button caption center cite code col colgroup dd del dfn dir div dl dt em fieldset font form frame frameset h1 h2 h3 h4 h5 h6 head hr html i iframe img input ins isindex kbd label legend li link map menu meta noframes noscript object ol p param pre q s samp script select small span strike strong style sub sup textarea title tt u ul var article aside audio bdi canvas command data datagrid datalist details embed eventsource figcaption figure footer header hgroup keygen mark meter nav output progress ruby rp rt section source summary time track video wbr'.split(' '); - return function () { - var str, i, len, attrStr, name, attrValueStr, fragStr, isVoid; - if (this.str !== undefined) { - return this.str; - } - if (this.component) { - return this.str = false; - } - if (htmlElements.indexOf(this.tag.toLowerCase()) === -1) { - return this.str = false; - } - if (this.proxies || this.intro || this.outro || this.decorator) { - return this.str = false; - } - fragStr = stringifyStubs(this.items); - if (fragStr === false) { - return this.str = false; - } - isVoid = voidElementNames.indexOf(this.tag.toLowerCase()) !== -1; - str = '<' + this.tag; - if (this.attributes) { - for (i = 0, len = this.attributes.length; i < len; i += 1) { - name = this.attributes[i].name; - if (name.indexOf(':') !== -1) { - return this.str = false; - } - if (name === 'id' || name === 'intro' || name === 'outro') { - return this.str = false; - } - attrStr = ' ' + name; - if (this.attributes[i].value !== null) { - attrValueStr = this.attributes[i].value.toString(); - if (attrValueStr === false) { - return this.str = false; - } - if (attrValueStr !== '') { - attrStr += '='; - if (/[\s"'=<>`]/.test(attrValueStr)) { - attrStr += '"' + attrValueStr.replace(/"/g, '"') + '"'; - } else { - attrStr += attrValueStr; - } - } - } - str += attrStr; - } - } - if (this.selfClosing && !isVoid) { - str += '/>'; - return this.str = str; - } - str += '>'; - if (isVoid) { - return this.str = str; - } - str += fragStr; - str += ''; - return this.str = str; - }; - }(parse_Parser_utils_stringifyStubs, config_voidElementNames); -var parse_Parser_getElement_ElementStub__ElementStub = function (types, voidElementNames, warn, camelCase, stringifyStubs, siblingsByTagName, filterAttributes, processDirective, toJSON, toString, StringStub) { - - var ElementStub, allElementNames, closedByParentClose, onPattern, sanitize, leadingWhitespace = /^\s+/, trailingWhitespace = /\s+$/; - ElementStub = function (firstToken, parser, preserveWhitespace) { - var next, attrs, filtered, proxies, item, getFrag, lowerCaseTag; - parser.pos += 1; - getFrag = function (attr) { - return { - name: attr.name, - value: attr.value ? new StringStub(attr.value) : null - }; - }; - this.tag = firstToken.name; - lowerCaseTag = firstToken.name.toLowerCase(); - if (lowerCaseTag.substr(0, 3) === 'rv-') { - warn('The "rv-" prefix for components has been deprecated. Support will be removed in a future version'); - this.tag = this.tag.substring(3); - } - preserveWhitespace = preserveWhitespace || lowerCaseTag === 'pre'; - if (firstToken.attrs) { - filtered = filterAttributes(firstToken.attrs); - attrs = filtered.attrs; - proxies = filtered.proxies; - if (parser.options.sanitize && parser.options.sanitize.eventAttributes) { - attrs = attrs.filter(sanitize); - } - if (attrs.length) { - this.attributes = attrs.map(getFrag); - } - if (proxies.length) { - this.proxies = proxies.map(processDirective); - } - if (filtered.intro) { - this.intro = processDirective(filtered.intro); - } - if (filtered.outro) { - this.outro = processDirective(filtered.outro); - } - if (filtered.decorator) { - this.decorator = processDirective(filtered.decorator); - } - } - if (firstToken.doctype) { - this.doctype = true; - } - if (firstToken.selfClosing) { - this.selfClosing = true; - } - if (voidElementNames.indexOf(lowerCaseTag) !== -1) { - this.isVoid = true; - } - if (this.selfClosing || this.isVoid) { - return; - } - this.siblings = siblingsByTagName[lowerCaseTag]; - this.items = []; - next = parser.next(); - while (next) { - if (next.mustacheType === types.CLOSING) { - break; - } - if (next.type === types.TAG) { - if (next.closing) { - if (next.name.toLowerCase() === lowerCaseTag) { - parser.pos += 1; - } - break; - } else if (this.siblings && this.siblings.indexOf(next.name.toLowerCase()) !== -1) { - break; - } - } - this.items[this.items.length] = parser.getStub(); - next = parser.next(); - } - if (!preserveWhitespace) { - item = this.items[0]; - if (item && item.type === types.TEXT) { - item.text = item.text.replace(leadingWhitespace, ''); - if (!item.text) { - this.items.shift(); - } - } - item = this.items[this.items.length - 1]; - if (item && item.type === types.TEXT) { - item.text = item.text.replace(trailingWhitespace, ''); - if (!item.text) { - this.items.pop(); - } - } - } - }; - ElementStub.prototype = { - toJSON: toJSON, - toString: toString - }; - allElementNames = 'a abbr acronym address applet area b base basefont bdo big blockquote body br button caption center cite code col colgroup dd del dfn dir div dl dt em fieldset font form frame frameset h1 h2 h3 h4 h5 h6 head hr html i iframe img input ins isindex kbd label legend li link map menu meta noframes noscript object ol p param pre q s samp script select small span strike strong style sub sup textarea title tt u ul var article aside audio bdi canvas command data datagrid datalist details embed eventsource figcaption figure footer header hgroup keygen mark meter nav output progress ruby rp rt section source summary time track video wbr'.split(' '); - closedByParentClose = 'li dd rt rp optgroup option tbody tfoot tr td th'.split(' '); - onPattern = /^on[a-zA-Z]/; - sanitize = function (attr) { - var valid = !onPattern.test(attr.name); - return valid; - }; - return ElementStub; - }(config_types, config_voidElementNames, utils_warn, utils_camelCase, parse_Parser_utils_stringifyStubs, parse_Parser_getElement_ElementStub_utils_siblingsByTagName, parse_Parser_getElement_ElementStub_utils_filterAttributes, parse_Parser_getElement_ElementStub_utils_processDirective, parse_Parser_getElement_ElementStub_toJSON, parse_Parser_getElement_ElementStub_toString, parse_Parser_StringStub__StringStub); -var parse_Parser_getElement__getElement = function (types, ElementStub) { - - return function (token) { - if (this.options.sanitize && this.options.sanitize.elements) { - if (this.options.sanitize.elements.indexOf(token.name.toLowerCase()) !== -1) { - return null; - } - } - return new ElementStub(token, this); - }; - }(config_types, parse_Parser_getElement_ElementStub__ElementStub); -var parse_Parser__Parser = function (getText, getComment, getMustache, getElement, jsonifyStubs) { - - var Parser; - Parser = function (tokens, options) { - var stub, stubs; - this.tokens = tokens || []; - this.pos = 0; - this.options = options; - this.preserveWhitespace = options.preserveWhitespace; - stubs = []; - while (stub = this.getStub()) { - stubs.push(stub); - } - this.result = jsonifyStubs(stubs); - }; - Parser.prototype = { - getStub: function () { - var token = this.next(); - if (!token) { - return null; - } - return this.getText(token) || this.getComment(token) || this.getMustache(token) || this.getElement(token); - }, - getText: getText, - getComment: getComment, - getMustache: getMustache, - getElement: getElement, - next: function () { - return this.tokens[this.pos]; - } - }; - return Parser; - }(parse_Parser_getText__getText, parse_Parser_getComment__getComment, parse_Parser_getMustache__getMustache, parse_Parser_getElement__getElement, parse_Parser_utils_jsonifyStubs); -var parse__parse = function (tokenize, types, Parser) { - - var parse, onlyWhitespace, inlinePartialStart, inlinePartialEnd, parseCompoundTemplate; - onlyWhitespace = /^\s*$/; - inlinePartialStart = //; - inlinePartialEnd = //; - parse = function (template, options) { - var tokens, json, token; - options = options || {}; - if (inlinePartialStart.test(template)) { - return parseCompoundTemplate(template, options); - } - if (options.sanitize === true) { - options.sanitize = { - elements: 'applet base basefont body frame frameset head html isindex link meta noframes noscript object param script style title'.split(' '), - eventAttributes: true - }; - } - tokens = tokenize(template, options); - if (!options.preserveWhitespace) { - token = tokens[0]; - if (token && token.type === types.TEXT && onlyWhitespace.test(token.value)) { - tokens.shift(); - } - token = tokens[tokens.length - 1]; - if (token && token.type === types.TEXT && onlyWhitespace.test(token.value)) { - tokens.pop(); - } - } - json = new Parser(tokens, options).result; - if (typeof json === 'string') { - return [json]; - } - return json; - }; - parseCompoundTemplate = function (template, options) { - var mainTemplate, remaining, partials, name, startMatch, endMatch; - partials = {}; - mainTemplate = ''; - remaining = template; - while (startMatch = inlinePartialStart.exec(remaining)) { - name = startMatch[1]; - mainTemplate += remaining.substr(0, startMatch.index); - remaining = remaining.substring(startMatch.index + startMatch[0].length); - endMatch = inlinePartialEnd.exec(remaining); - if (!endMatch || endMatch[1] !== name) { - throw new Error('Inline partials must have a closing delimiter, and cannot be nested'); - } - partials[name] = parse(remaining.substr(0, endMatch.index), options); - remaining = remaining.substring(endMatch.index + endMatch[0].length); - } - return { - main: parse(mainTemplate, options), - partials: partials - }; - }; - return parse; - }(parse_tokenize, config_types, parse_Parser__Parser); -var render_DomFragment_Partial_getPartialDescriptor = function (errors, isClient, warn, isObject, partials, parse) { - - var getPartialDescriptor, registerPartial, getPartialFromRegistry, unpack; - getPartialDescriptor = function (root, name) { - var el, partial, errorMessage; - if (partial = getPartialFromRegistry(root, name)) { - return partial; - } - if (isClient) { - el = document.getElementById(name); - if (el && el.tagName === 'SCRIPT') { - if (!parse) { - throw new Error(errors.missingParser); - } - registerPartial(parse(el.innerHTML), name, partials); - } - } - partial = partials[name]; - if (!partial) { - errorMessage = 'Could not find descriptor for partial "' + name + '"'; - if (root.debug) { - throw new Error(errorMessage); - } else { - warn(errorMessage); - } - return []; - } - return unpack(partial); - }; - getPartialFromRegistry = function (registryOwner, name) { - var partial; - if (registryOwner.partials[name]) { - if (typeof registryOwner.partials[name] === 'string') { - if (!parse) { - throw new Error(errors.missingParser); - } - partial = parse(registryOwner.partials[name], registryOwner.parseOptions); - registerPartial(partial, name, registryOwner.partials); - } - return unpack(registryOwner.partials[name]); - } - }; - registerPartial = function (partial, name, registry) { - var key; - if (isObject(partial)) { - registry[name] = partial.main; - for (key in partial.partials) { - if (partial.partials.hasOwnProperty(key)) { - registry[key] = partial.partials[key]; - } - } - } else { - registry[name] = partial; - } - }; - unpack = function (partial) { - if (partial.length === 1 && typeof partial[0] === 'string') { - return partial[0]; - } - return partial; - }; - return getPartialDescriptor; - }(config_errors, config_isClient, utils_warn, utils_isObject, registries_partials, parse__parse); -var render_DomFragment_Partial__Partial = function (types, getPartialDescriptor, circular) { - - var DomPartial, DomFragment; - circular.push(function () { - DomFragment = circular.DomFragment; - }); - DomPartial = function (options, docFrag) { - var parentFragment = this.parentFragment = options.parentFragment, descriptor; - this.type = types.PARTIAL; - this.name = options.descriptor.r; - this.index = options.index; - if (!options.descriptor.r) { - throw new Error('Partials must have a static reference (no expressions). This may change in a future version of Ractive.'); - } - descriptor = getPartialDescriptor(parentFragment.root, options.descriptor.r); - this.fragment = new DomFragment({ - descriptor: descriptor, - root: parentFragment.root, - pNode: parentFragment.pNode, - contextStack: parentFragment.contextStack, - owner: this - }); - if (docFrag) { - docFrag.appendChild(this.fragment.docFrag); - } - }; - DomPartial.prototype = { - firstNode: function () { - return this.fragment.firstNode(); - }, - findNextNode: function () { - return this.parentFragment.findNextNode(this); - }, - detach: function () { - return this.fragment.detach(); - }, - teardown: function (destroy) { - this.fragment.teardown(destroy); - }, - toString: function () { - return this.fragment.toString(); - }, - find: function (selector) { - return this.fragment.find(selector); - }, - findAll: function (selector, query) { - return this.fragment.findAll(selector, query); - }, - findComponent: function (selector) { - return this.fragment.findComponent(selector); - }, - findAllComponents: function (selector, query) { - return this.fragment.findAllComponents(selector, query); - } - }; - return DomPartial; - }(config_types, render_DomFragment_Partial_getPartialDescriptor, circular); -var render_DomFragment_Component_initialise_createModel_ComponentParameter = function (StringFragment) { - - var ComponentParameter = function (component, key, value) { - this.parentFragment = component.parentFragment; - this.component = component; - this.key = key; - this.fragment = new StringFragment({ - descriptor: value, - root: component.root, - owner: this, - contextStack: component.parentFragment.contextStack - }); - this.selfUpdating = this.fragment.isSimple(); - this.value = this.fragment.getValue(); - }; - ComponentParameter.prototype = { - bubble: function () { - if (this.selfUpdating) { - this.update(); - } else if (!this.deferred && this.ready) { - this.root._deferred.attrs.push(this); - this.deferred = true; - } - }, - update: function () { - var value = this.fragment.getValue(); - this.component.instance.set(this.key, value); - this.value = value; - }, - teardown: function () { - this.fragment.teardown(); - } - }; - return ComponentParameter; - }(render_StringFragment__StringFragment); -var render_DomFragment_Component_initialise_createModel__createModel = function (types, parseJSON, resolveRef, ComponentParameter) { - - return function (component, attributes, toBind) { - var data, key, value; - data = {}; - component.complexParameters = []; - for (key in attributes) { - if (attributes.hasOwnProperty(key)) { - value = getValue(component, key, attributes[key], toBind); - if (value !== undefined) { - data[key] = value; - } - } - } - return data; - }; - function getValue(component, key, descriptor, toBind) { - var parameter, parsed, root, parentFragment, keypath; - root = component.root; - parentFragment = component.parentFragment; - if (typeof descriptor === 'string') { - parsed = parseJSON(descriptor); - return parsed ? parsed.value : descriptor; - } - if (descriptor === null) { - return true; - } - if (descriptor.length === 1 && descriptor[0].t === types.INTERPOLATOR && descriptor[0].r) { - if (parentFragment.indexRefs && parentFragment.indexRefs[descriptor[0].r] !== undefined) { - return parentFragment.indexRefs[descriptor[0].r]; - } - keypath = resolveRef(root, descriptor[0].r, parentFragment.contextStack) || descriptor[0].r; - toBind.push({ - childKeypath: key, - parentKeypath: keypath - }); - return root.get(keypath); - } - parameter = new ComponentParameter(component, key, descriptor); - component.complexParameters.push(parameter); - return parameter.value; - } - }(config_types, utils_parseJSON, shared_resolveRef, render_DomFragment_Component_initialise_createModel_ComponentParameter); -var render_DomFragment_Component_initialise_createInstance = function () { - - return function (component, Component, data, docFrag, contentDescriptor) { - var instance, parentFragment, partials, root; - parentFragment = component.parentFragment; - root = component.root; - partials = { content: contentDescriptor || [] }; - instance = new Component({ - el: parentFragment.pNode.cloneNode(false), - data: data, - partials: partials, - _parent: root, - adaptors: root.adaptors - }); - instance.component = component; - component.instance = instance; - instance.insert(docFrag); - instance.fragment.pNode = parentFragment.pNode; - return instance; - }; - }(); -var render_DomFragment_Component_initialise_createObservers = function () { - - var observeOptions = { - init: false, - debug: true - }; - return function (component, toBind) { - var pair, i; - component.observers = []; - i = toBind.length; - while (i--) { - pair = toBind[i]; - bind(component, pair.parentKeypath, pair.childKeypath); - } - }; - function bind(component, parentKeypath, childKeypath) { - var parentInstance, childInstance, settingParent, settingChild, observers, observer, value; - parentInstance = component.root; - childInstance = component.instance; - observers = component.observers; - observer = parentInstance.observe(parentKeypath, function (value) { - if (!settingParent && !parentInstance._wrapped[parentKeypath]) { - settingChild = true; - childInstance.set(childKeypath, value); - settingChild = false; - } - }, observeOptions); - observers.push(observer); - if (childInstance.twoway) { - observer = childInstance.observe(childKeypath, function (value) { - if (!settingChild) { - settingParent = true; - parentInstance.set(parentKeypath, value); - settingParent = false; - } - }, observeOptions); - observers.push(observer); - value = childInstance.get(childKeypath); - if (value !== undefined) { - parentInstance.set(parentKeypath, value); - } - } - } - }(); -var render_DomFragment_Component_initialise_propagateEvents = function (warn) { - - var errorMessage = 'Components currently only support simple events - you cannot include arguments. Sorry!'; - return function (component, eventsDescriptor) { - var eventName; - for (eventName in eventsDescriptor) { - if (eventsDescriptor.hasOwnProperty(eventName)) { - propagateEvent(component.instance, component.root, eventName, eventsDescriptor[eventName]); - } - } - }; - function propagateEvent(childInstance, parentInstance, eventName, proxyEventName) { - if (typeof proxyEventName !== 'string') { - if (parentInstance.debug) { - throw new Error(errorMessage); - } else { - warn(errorMessage); - return; - } - } - childInstance.on(eventName, function () { - var args = Array.prototype.slice.call(arguments); - args.unshift(proxyEventName); - parentInstance.fire.apply(parentInstance, args); - }); - } - }(utils_warn); -var render_DomFragment_Component_initialise_updateLiveQueries = function () { - - return function (component) { - var ancestor, query; - ancestor = component.root; - while (ancestor) { - if (query = ancestor._liveComponentQueries[component.name]) { - query.push(component.instance); - } - ancestor = ancestor._parent; - } - }; - }(); -var render_DomFragment_Component_initialise__initialise = function (types, warn, createModel, createInstance, createObservers, propagateEvents, updateLiveQueries) { - - return function (component, options, docFrag) { - var parentFragment, root, Component, data, toBind; - parentFragment = component.parentFragment = options.parentFragment; - root = parentFragment.root; - component.root = root; - component.type = types.COMPONENT; - component.name = options.descriptor.e; - component.index = options.index; - component.observers = []; - Component = root.components[options.descriptor.e]; - if (!Component) { - throw new Error('Component "' + options.descriptor.e + '" not found'); - } - toBind = []; - data = createModel(component, options.descriptor.a, toBind); - createInstance(component, Component, data, docFrag, options.descriptor.f); - createObservers(component, toBind); - propagateEvents(component, options.descriptor.v); - if (options.descriptor.t1 || options.descriptor.t2 || options.descriptor.o) { - warn('The "intro", "outro" and "decorator" directives have no effect on components'); - } - updateLiveQueries(component); - }; - }(config_types, utils_warn, render_DomFragment_Component_initialise_createModel__createModel, render_DomFragment_Component_initialise_createInstance, render_DomFragment_Component_initialise_createObservers, render_DomFragment_Component_initialise_propagateEvents, render_DomFragment_Component_initialise_updateLiveQueries); -var render_DomFragment_Component__Component = function (initialise) { - - var DomComponent = function (options, docFrag) { - initialise(this, options, docFrag); - }; - DomComponent.prototype = { - firstNode: function () { - return this.instance.fragment.firstNode(); - }, - findNextNode: function () { - return this.parentFragment.findNextNode(this); - }, - detach: function () { - return this.instance.fragment.detach(); - }, - teardown: function () { - var query; - while (this.complexParameters.length) { - this.complexParameters.pop().teardown(); - } - while (this.observers.length) { - this.observers.pop().cancel(); - } - if (query = this.root._liveComponentQueries[this.name]) { - query._remove(this); - } - this.instance.teardown(); - }, - toString: function () { - return this.instance.fragment.toString(); - }, - find: function (selector) { - return this.instance.fragment.find(selector); - }, - findAll: function (selector, query) { - return this.instance.fragment.findAll(selector, query); - }, - findComponent: function (selector) { - if (!selector || selector === this.name) { - return this.instance; - } - return null; - }, - findAllComponents: function (selector, query) { - query._test(this, true); - if (this.instance.fragment) { - this.instance.fragment.findAllComponents(selector, query); - } - } - }; - return DomComponent; - }(render_DomFragment_Component_initialise__initialise); -var render_DomFragment_Comment = function (types) { - - var DomComment = function (options, docFrag) { - this.type = types.COMMENT; - this.descriptor = options.descriptor; - if (docFrag) { - this.node = document.createComment(options.descriptor.f); - docFrag.appendChild(this.node); - } - }; - DomComment.prototype = { - detach: function () { - this.node.parentNode.removeChild(this.node); - return this.node; - }, - teardown: function (destroy) { - if (destroy) { - this.detach(); - } - }, - firstNode: function () { - return this.node; - }, - toString: function () { - return ''; - } - }; - return DomComment; - }(config_types); -var render_DomFragment__DomFragment = function (types, matches, initFragment, insertHtml, Text, Interpolator, Section, Triple, Element, Partial, Component, Comment, circular) { - - var DomFragment = function (options) { - if (options.pNode) { - this.docFrag = document.createDocumentFragment(); - } - if (typeof options.descriptor === 'string') { - this.html = options.descriptor; - if (this.docFrag) { - this.nodes = insertHtml(this.html, options.pNode.tagName, this.docFrag); - } - } else { - initFragment(this, options); - } - }; - DomFragment.prototype = { - detach: function () { - var len, i; - if (this.nodes) { - i = this.nodes.length; - while (i--) { - this.docFrag.appendChild(this.nodes[i]); - } - } else if (this.items) { - len = this.items.length; - for (i = 0; i < len; i += 1) { - this.docFrag.appendChild(this.items[i].detach()); - } - } - return this.docFrag; - }, - createItem: function (options) { - if (typeof options.descriptor === 'string') { - return new Text(options, this.docFrag); - } - switch (options.descriptor.t) { - case types.INTERPOLATOR: - return new Interpolator(options, this.docFrag); - case types.SECTION: - return new Section(options, this.docFrag); - case types.TRIPLE: - return new Triple(options, this.docFrag); - case types.ELEMENT: - if (this.root.components[options.descriptor.e]) { - return new Component(options, this.docFrag); - } - return new Element(options, this.docFrag); - case types.PARTIAL: - return new Partial(options, this.docFrag); - case types.COMMENT: - return new Comment(options, this.docFrag); - default: - throw new Error('Something very strange happened. Please file an issue at https://github.com/RactiveJS/Ractive/issues. Thanks!'); - } - }, - teardown: function (destroy) { - var node; - if (this.nodes && destroy) { - while (node = this.nodes.pop()) { - node.parentNode.removeChild(node); - } - } else if (this.items) { - while (this.items.length) { - this.items.pop().teardown(destroy); - } - } - this.nodes = this.items = this.docFrag = null; - }, - firstNode: function () { - if (this.items && this.items[0]) { - return this.items[0].firstNode(); - } else if (this.nodes) { - return this.nodes[0] || null; - } - return null; - }, - findNextNode: function (item) { - var index = item.index; - if (this.items[index + 1]) { - return this.items[index + 1].firstNode(); - } - if (this.owner === this.root) { - if (!this.owner.component) { - return null; - } - return this.owner.component.findNextNode(); - } - return this.owner.findNextNode(this); - }, - toString: function () { - var html, i, len, item; - if (this.html) { - return this.html; - } - html = ''; - if (!this.items) { - return html; - } - len = this.items.length; - for (i = 0; i < len; i += 1) { - item = this.items[i]; - html += item.toString(); - } - return html; - }, - find: function (selector) { - var i, len, item, node, queryResult; - if (this.nodes) { - len = this.nodes.length; - for (i = 0; i < len; i += 1) { - node = this.nodes[i]; - if (node.nodeType !== 1) { - continue; - } - if (matches(node, selector)) { - return node; - } - if (queryResult = node.querySelector(selector)) { - return queryResult; - } - } - return null; - } - if (this.items) { - len = this.items.length; - for (i = 0; i < len; i += 1) { - item = this.items[i]; - if (item.find && (queryResult = item.find(selector))) { - return queryResult; - } - } - return null; - } - }, - findAll: function (selector, query) { - var i, len, item, node, queryAllResult, numNodes, j; - if (this.nodes) { - len = this.nodes.length; - for (i = 0; i < len; i += 1) { - node = this.nodes[i]; - if (node.nodeType !== 1) { - continue; - } - if (matches(node, selector)) { - query.push(node); - } - if (queryAllResult = node.querySelectorAll(selector)) { - numNodes = queryAllResult.length; - for (j = 0; j < numNodes; j += 1) { - query.push(queryAllResult[j]); - } - } - } - } else if (this.items) { - len = this.items.length; - for (i = 0; i < len; i += 1) { - item = this.items[i]; - if (item.findAll) { - item.findAll(selector, query); - } - } - } - return query; - }, - findComponent: function (selector) { - var len, i, item, queryResult; - if (this.items) { - len = this.items.length; - for (i = 0; i < len; i += 1) { - item = this.items[i]; - if (item.findComponent && (queryResult = item.findComponent(selector))) { - return queryResult; - } - } - return null; - } - }, - findAllComponents: function (selector, query) { - var i, len, item; - if (this.items) { - len = this.items.length; - for (i = 0; i < len; i += 1) { - item = this.items[i]; - if (item.findAllComponents) { - item.findAllComponents(selector, query); - } - } - } - return query; - } - }; - circular.DomFragment = DomFragment; - return DomFragment; - }(config_types, utils_matches, render_shared_initFragment, render_DomFragment_shared_insertHtml, render_DomFragment_Text, render_DomFragment_Interpolator, render_DomFragment_Section__Section, render_DomFragment_Triple, render_DomFragment_Element__Element, render_DomFragment_Partial__Partial, render_DomFragment_Component__Component, render_DomFragment_Comment, circular); -var Ractive_prototype_render = function (getElement, makeTransitionManager, preDomUpdate, postDomUpdate, DomFragment) { - - return function (target, complete) { - var transitionManager; - if (!this._initing) { - throw new Error('You cannot call ractive.render() directly!'); - } - this._transitionManager = transitionManager = makeTransitionManager(this, complete); - this.fragment = new DomFragment({ - descriptor: this.template, - root: this, - owner: this, - pNode: target - }); - preDomUpdate(this); - if (target) { - target.appendChild(this.fragment.docFrag); - } - postDomUpdate(this); - this._transitionManager = null; - transitionManager.ready(); - this.rendered = true; - }; - }(utils_getElement, shared_makeTransitionManager, shared_preDomUpdate, shared_postDomUpdate, render_DomFragment__DomFragment); -var Ractive_prototype_renderHTML = function (warn) { - - return function () { - warn('renderHTML() has been deprecated and will be removed in a future version. Please use toHTML() instead'); - return this.toHTML(); - }; - }(utils_warn); -var Ractive_prototype_toHTML = function () { - - return function () { - return this.fragment.toString(); - }; - }(); -var Ractive_prototype_teardown = function (makeTransitionManager, clearCache) { - - return function (complete) { - var keypath, transitionManager, previousTransitionManager; - this.fire('teardown'); - previousTransitionManager = this._transitionManager; - this._transitionManager = transitionManager = makeTransitionManager(this, complete); - this.fragment.teardown(true); - while (this._animations[0]) { - this._animations[0].stop(); - } - for (keypath in this._cache) { - clearCache(this, keypath); - } - this._transitionManager = previousTransitionManager; - transitionManager.ready(); - }; - }(shared_makeTransitionManager, shared_clearCache); -var Ractive_prototype_shared_add = function (isNumeric) { - - return function (root, keypath, d) { - var value; - if (typeof keypath !== 'string' || !isNumeric(d)) { - if (root.debug) { - throw new Error('Bad arguments'); - } - return; - } - value = root.get(keypath); - if (value === undefined) { - value = 0; - } - if (!isNumeric(value)) { - if (root.debug) { - throw new Error('Cannot add to a non-numeric value'); - } - return; - } - root.set(keypath, value + d); - }; - }(utils_isNumeric); -var Ractive_prototype_add = function (add) { - - return function (keypath, d) { - add(this, keypath, d === undefined ? 1 : d); - }; - }(Ractive_prototype_shared_add); -var Ractive_prototype_subtract = function (add) { - - return function (keypath, d) { - add(this, keypath, d === undefined ? -1 : -d); - }; - }(Ractive_prototype_shared_add); -var Ractive_prototype_toggle = function () { - - return function (keypath) { - var value; - if (typeof keypath !== 'string') { - if (this.debug) { - throw new Error('Bad arguments'); - } - return; - } - value = this.get(keypath); - this.set(keypath, !value); - }; - }(); -var Ractive_prototype_merge_mapOldToNewIndex = function () { - - return function (oldArray, newArray) { - var usedIndices, mapper, firstUnusedIndex, newIndices, changed; - usedIndices = {}; - firstUnusedIndex = 0; - mapper = function (item, i) { - var index, start, len; - start = firstUnusedIndex; - len = newArray.length; - do { - index = newArray.indexOf(item, start); - if (index === -1) { - changed = true; - return -1; - } - start = index + 1; - } while (usedIndices[index] && start < len); - if (index === firstUnusedIndex) { - firstUnusedIndex += 1; - } - if (index !== i) { - changed = true; - } - usedIndices[index] = true; - return index; - }; - newIndices = oldArray.map(mapper); - newIndices.unchanged = !changed; - return newIndices; - }; - }(); -var Ractive_prototype_merge_queueDependants = function (types) { - - return function queueDependants(keypath, deps, mergeQueue, updateQueue) { - var i, dependant; - i = deps.length; - while (i--) { - dependant = deps[i]; - if (dependant.type === types.REFERENCE) { - dependant.update(); - } else if (dependant.keypath === keypath && dependant.type === types.SECTION && !dependant.inverted && dependant.docFrag) { - mergeQueue[mergeQueue.length] = dependant; - } else { - updateQueue[updateQueue.length] = dependant; - } - } - }; - }(config_types); -var Ractive_prototype_merge__merge = function (warn, isArray, clearCache, preDomUpdate, processDeferredUpdates, makeTransitionManager, notifyDependants, replaceData, mapOldToNewIndex, queueDependants) { - - var identifiers = {}; - return function (keypath, array, options) { - var currentArray, oldArray, newArray, identifier, lengthUnchanged, i, newIndices, mergeQueue, updateQueue, depsByKeypath, deps, transitionManager, previousTransitionManager, upstreamQueue, keys; - currentArray = this.get(keypath); - if (!isArray(currentArray) || !isArray(array)) { - return this.set(keypath, array, options && options.complete); - } - lengthUnchanged = currentArray.length === array.length; - if (options && options.compare) { - if (options.compare === true) { - identifier = stringify; - } else if (typeof options.compare === 'string') { - identifier = getIdentifier(options.compare); - } else if (typeof options.compare == 'function') { - identifier = options.compare; - } else { - throw new Error('The `compare` option must be a function, or a string representing an identifying field (or `true` to use JSON.stringify)'); - } - try { - oldArray = currentArray.map(identifier); - newArray = array.map(identifier); - } catch (err) { - if (this.debug) { - throw err; - } else { - warn('Merge operation: comparison failed. Falling back to identity checking'); - } - oldArray = currentArray; - newArray = array; - } - } else { - oldArray = currentArray; - newArray = array; - } - newIndices = mapOldToNewIndex(oldArray, newArray); - clearCache(this, keypath); - replaceData(this, keypath, array); - if (newIndices.unchanged && lengthUnchanged) { - return; - } - previousTransitionManager = this._transitionManager; - this._transitionManager = transitionManager = makeTransitionManager(this, options && options.complete); - mergeQueue = []; - updateQueue = []; - for (i = 0; i < this._deps.length; i += 1) { - depsByKeypath = this._deps[i]; - if (!depsByKeypath) { - continue; - } - deps = depsByKeypath[keypath]; - if (deps) { - queueDependants(keypath, deps, mergeQueue, updateQueue); - preDomUpdate(this); - while (mergeQueue.length) { - mergeQueue.pop().merge(newIndices); - } - while (updateQueue.length) { - updateQueue.pop().update(); - } - } - } - processDeferredUpdates(this); - upstreamQueue = []; - keys = keypath.split('.'); - while (keys.length) { - keys.pop(); - upstreamQueue[upstreamQueue.length] = keys.join('.'); - } - notifyDependants.multiple(this, upstreamQueue, true); - if (oldArray.length !== newArray.length) { - notifyDependants(this, keypath + '.length', true); - } - this._transitionManager = previousTransitionManager; - transitionManager.ready(); - }; - function stringify(item) { - return JSON.stringify(item); - } - function getIdentifier(str) { - if (!identifiers[str]) { - identifiers[str] = function (item) { - return item[str]; - }; - } - return identifiers[str]; - } - }(utils_warn, utils_isArray, shared_clearCache, shared_preDomUpdate, shared_processDeferredUpdates, shared_makeTransitionManager, shared_notifyDependants, Ractive_prototype_shared_replaceData, Ractive_prototype_merge_mapOldToNewIndex, Ractive_prototype_merge_queueDependants); -var Ractive_prototype_detach = function () { - - return function () { - return this.fragment.detach(); - }; - }(); -var Ractive_prototype_insert = function (getElement) { - - return function (target, anchor) { - target = getElement(target); - anchor = getElement(anchor) || null; - if (!target) { - throw new Error('You must specify a valid target to insert into'); - } - target.insertBefore(this.detach(), anchor); - this.fragment.pNode = target; - }; - }(utils_getElement); -var Ractive_prototype__prototype = function (get, set, update, updateModel, animate, on, off, observe, fire, find, findAll, findComponent, findAllComponents, render, renderHTML, toHTML, teardown, add, subtract, toggle, merge, detach, insert) { - - return { - get: get, - set: set, - update: update, - updateModel: updateModel, - animate: animate, - on: on, - off: off, - observe: observe, - fire: fire, - find: find, - findAll: findAll, - findComponent: findComponent, - findAllComponents: findAllComponents, - renderHTML: renderHTML, - toHTML: toHTML, - render: render, - teardown: teardown, - add: add, - subtract: subtract, - toggle: toggle, - merge: merge, - detach: detach, - insert: insert - }; - }(Ractive_prototype_get__get, Ractive_prototype_set, Ractive_prototype_update, Ractive_prototype_updateModel, Ractive_prototype_animate__animate, Ractive_prototype_on, Ractive_prototype_off, Ractive_prototype_observe__observe, Ractive_prototype_fire, Ractive_prototype_find, Ractive_prototype_findAll, Ractive_prototype_findComponent, Ractive_prototype_findAllComponents, Ractive_prototype_render, Ractive_prototype_renderHTML, Ractive_prototype_toHTML, Ractive_prototype_teardown, Ractive_prototype_add, Ractive_prototype_subtract, Ractive_prototype_toggle, Ractive_prototype_merge__merge, Ractive_prototype_detach, Ractive_prototype_insert); -var extend_registries = function () { - - return [ - 'partials', - 'transitions', - 'events', - 'components', - 'decorators', - 'data' - ]; - }(); -var extend_initOptions = function () { - - return [ - 'el', - 'template', - 'complete', - 'modifyArrays', - 'magic', - 'twoway', - 'lazy', - 'append', - 'preserveWhitespace', - 'sanitize', - 'stripComments', - 'noIntro', - 'transitionsEnabled', - 'adaptors' - ]; - }(); -var extend_inheritFromParent = function (registries, initOptions, create) { - - return function (Child, Parent) { - registries.forEach(function (property) { - if (Parent[property]) { - Child[property] = create(Parent[property]); - } - }); - initOptions.forEach(function (property) { - Child[property] = Parent[property]; - }); - }; - }(extend_registries, extend_initOptions, utils_create); -var extend_wrapMethod = function () { - - return function (method, superMethod) { - if (/_super/.test(method)) { - return function () { - var _super = this._super, result; - this._super = superMethod; - result = method.apply(this, arguments); - this._super = _super; - return result; - }; - } else { - return method; - } - }; - }(); -var extend_utils_augment = function () { - - return function (target, source) { - var key; - for (key in source) { - if (source.hasOwnProperty(key)) { - target[key] = source[key]; - } - } - return target; - }; - }(); -var extend_inheritFromChildProps = function (registries, initOptions, wrapMethod, augment) { - - var blacklist, blacklisted; - blacklist = registries.concat(initOptions); - blacklisted = {}; - blacklist.forEach(function (property) { - blacklisted[property] = true; - }); - return function (Child, childProps) { - var key, member; - registries.forEach(function (property) { - var value = childProps[property]; - if (value) { - if (Child[property]) { - augment(Child[property], value); - } else { - Child[property] = value; - } - } - }); - initOptions.forEach(function (property) { - var value = childProps[property]; - if (value !== undefined) { - if (typeof value === 'function' && typeof Child[property] === 'function') { - Child[property] = wrapMethod(value, Child[property]); - } else { - Child[property] = childProps[property]; - } - } - }); - for (key in childProps) { - if (childProps.hasOwnProperty(key) && !blacklisted[key]) { - member = childProps[key]; - if (typeof member === 'function' && typeof Child.prototype[key] === 'function') { - Child.prototype[key] = wrapMethod(member, Child.prototype[key]); - } else { - Child.prototype[key] = member; - } - } - } - }; - }(extend_registries, extend_initOptions, extend_wrapMethod, extend_utils_augment); -var extend_extractInlinePartials = function (isObject, augment) { - - return function (Child, childProps) { - if (isObject(Child.template)) { - if (!Child.partials) { - Child.partials = {}; - } - augment(Child.partials, Child.template.partials); - if (childProps.partials) { - augment(Child.partials, childProps.partials); - } - Child.template = Child.template.main; - } - }; - }(utils_isObject, extend_utils_augment); -var extend_conditionallyParseTemplate = function (errors, isClient, parse) { - - return function (Child) { - var templateEl; - if (typeof Child.template === 'string') { - if (!parse) { - throw new Error(errors.missingParser); - } - if (Child.template.charAt(0) === '#' && isClient) { - templateEl = document.getElementById(Child.template.substring(1)); - if (templateEl && templateEl.tagName === 'SCRIPT') { - Child.template = parse(templateEl.innerHTML, Child); - } else { - throw new Error('Could not find template element (' + Child.template + ')'); - } - } else { - Child.template = parse(Child.template, Child); - } - } - }; - }(config_errors, config_isClient, parse__parse); -var extend_conditionallyParsePartials = function (errors, parse) { - - return function (Child) { - var key; - if (Child.partials) { - for (key in Child.partials) { - if (Child.partials.hasOwnProperty(key) && typeof Child.partials[key] === 'string') { - if (!parse) { - throw new Error(errors.missingParser); - } - Child.partials[key] = parse(Child.partials[key], Child); - } - } - } - }; - }(config_errors, parse__parse); -var extend_utils_clone = function () { - - return function (source) { - var target = {}, key; - for (key in source) { - if (source.hasOwnProperty(key)) { - target[key] = source[key]; - } - } - return target; - }; - }(); -var utils_extend = function () { - - return function (target) { - var prop, source, sources = Array.prototype.slice.call(arguments, 1); - while (source = sources.shift()) { - for (prop in source) { - if (source.hasOwnProperty(prop)) { - target[prop] = source[prop]; - } - } - } - return target; - }; - }(); -var Ractive_initialise = function (isClient, errors, warn, create, extend, defineProperty, defineProperties, getElement, isObject, magicAdaptor, parse) { - - var getObject, getArray, defaultOptions, registries; - getObject = function () { - return {}; - }; - getArray = function () { - return []; - }; - defaultOptions = create(null); - defineProperties(defaultOptions, { - preserveWhitespace: { - enumerable: true, - value: false - }, - append: { - enumerable: true, - value: false - }, - twoway: { - enumerable: true, - value: true - }, - modifyArrays: { - enumerable: true, - value: true - }, - data: { - enumerable: true, - value: getObject - }, - lazy: { - enumerable: true, - value: false - }, - debug: { - enumerable: true, - value: false - }, - transitions: { - enumerable: true, - value: getObject - }, - decorators: { - enumerable: true, - value: getObject - }, - events: { - enumerable: true, - value: getObject - }, - noIntro: { - enumerable: true, - value: false - }, - transitionsEnabled: { - enumerable: true, - value: true - }, - magic: { - enumerable: true, - value: false - }, - adaptors: { - enumerable: true, - value: getArray - } - }); - registries = [ - 'components', - 'decorators', - 'events', - 'partials', - 'transitions', - 'data' - ]; - return function (ractive, options) { - var key, template, templateEl, parsedTemplate; - for (key in defaultOptions) { - if (options[key] === undefined) { - options[key] = typeof defaultOptions[key] === 'function' ? defaultOptions[key]() : defaultOptions[key]; - } - } - defineProperties(ractive, { - _initing: { - value: true, - writable: true - }, - _guid: { - value: 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { - var r, v; - r = Math.random() * 16 | 0; - v = c == 'x' ? r : r & 3 | 8; - return v.toString(16); - }) - }, - _subs: { - value: create(null), - configurable: true - }, - _cache: { value: {} }, - _cacheMap: { value: create(null) }, - _deps: { value: [] }, - _depsMap: { value: create(null) }, - _patternObservers: { value: [] }, - _pendingResolution: { value: [] }, - _deferred: { value: {} }, - _evaluators: { value: create(null) }, - _twowayBindings: { value: {} }, - _transitionManager: { - value: null, - writable: true - }, - _animations: { value: [] }, - nodes: { value: {} }, - _wrapped: { value: create(null) }, - _liveQueries: { value: [] }, - _liveComponentQueries: { value: [] } - }); - defineProperties(ractive._deferred, { - attrs: { value: [] }, - evals: { value: [] }, - selectValues: { value: [] }, - checkboxes: { value: [] }, - radios: { value: [] }, - observers: { value: [] }, - transitions: { value: [] }, - liveQueries: { value: [] }, - decorators: { value: [] }, - focusable: { - value: null, - writable: true - } - }); - ractive.adaptors = options.adaptors; - ractive.modifyArrays = options.modifyArrays; - ractive.magic = options.magic; - ractive.twoway = options.twoway; - ractive.lazy = options.lazy; - ractive.debug = options.debug; - if (ractive.magic && !magicAdaptor) { - throw new Error('Getters and setters (magic mode) are not supported in this browser'); - } - if (options._parent) { - defineProperty(ractive, '_parent', { value: options._parent }); - } - if (options.el) { - ractive.el = getElement(options.el); - if (!ractive.el && ractive.debug) { - throw new Error('Could not find container element'); - } - } - if (options.eventDefinitions) { - warn('ractive.eventDefinitions has been deprecated in favour of ractive.events. Support will be removed in future versions'); - options.events = options.eventDefinitions; - } - registries.forEach(function (registry) { - if (ractive.constructor[registry]) { - ractive[registry] = extend(create(ractive.constructor[registry] || {}), options[registry]); - } else if (options[registry]) { - ractive[registry] = options[registry]; - } - }); - template = options.template; - if (typeof template === 'string') { - if (!parse) { - throw new Error(errors.missingParser); - } - if (template.charAt(0) === '#' && isClient) { - templateEl = document.getElementById(template.substring(1)); - if (templateEl) { - parsedTemplate = parse(templateEl.innerHTML, options); - } else { - throw new Error('Could not find template element (' + template + ')'); - } - } else { - parsedTemplate = parse(template, options); - } - } else { - parsedTemplate = template; - } - if (isObject(parsedTemplate)) { - extend(ractive.partials, parsedTemplate.partials); - parsedTemplate = parsedTemplate.main; - } - if (parsedTemplate && parsedTemplate.length === 1 && typeof parsedTemplate[0] === 'string') { - parsedTemplate = parsedTemplate[0]; - } - ractive.template = parsedTemplate; - extend(ractive.partials, options.partials); - ractive.parseOptions = { - preserveWhitespace: options.preserveWhitespace, - sanitize: options.sanitize, - stripComments: options.stripComments - }; - ractive.transitionsEnabled = options.noIntro ? false : options.transitionsEnabled; - if (isClient && !ractive.el) { - ractive.el = document.createDocumentFragment(); - } - if (ractive.el && !options.append) { - ractive.el.innerHTML = ''; - } - ractive.render(ractive.el, options.complete); - ractive.transitionsEnabled = options.transitionsEnabled; - ractive._initing = false; - }; - }(config_isClient, config_errors, utils_warn, utils_create, utils_extend, utils_defineProperty, utils_defineProperties, utils_getElement, utils_isObject, Ractive_prototype_get_magicAdaptor, parse__parse); -var extend_initChildInstance = function (fillGaps, initOptions, clone, wrapMethod, initialise) { - - return function (child, Child, options) { - initOptions.forEach(function (property) { - var value = options[property], defaultValue = Child[property]; - if (typeof value === 'function' && typeof defaultValue === 'function') { - options[property] = wrapMethod(value, defaultValue); - } else if (value === undefined && defaultValue !== undefined) { - options[property] = defaultValue; - } - }); - if (child.beforeInit) { - child.beforeInit(options); - } - initialise(child, options); - if (child.init) { - child.init(options); - } - }; - }(utils_fillGaps, extend_initOptions, extend_utils_clone, extend_wrapMethod, Ractive_initialise); -var extend__extend = function (create, inheritFromParent, inheritFromChildProps, extractInlinePartials, conditionallyParseTemplate, conditionallyParsePartials, initChildInstance, circular) { - - var Ractive; - circular.push(function () { - Ractive = circular.Ractive; - }); - return function (childProps) { - var Parent = this, Child; - Child = function (options) { - initChildInstance(this, Child, options || {}); - }; - Child.prototype = create(Parent.prototype); - Child.prototype.constructor = Child; - inheritFromParent(Child, Parent); - inheritFromChildProps(Child, childProps); - conditionallyParseTemplate(Child); - extractInlinePartials(Child, childProps); - conditionallyParsePartials(Child); - Child.extend = Parent.extend; - return Child; - }; - }(utils_create, extend_inheritFromParent, extend_inheritFromChildProps, extend_extractInlinePartials, extend_conditionallyParseTemplate, extend_conditionallyParsePartials, extend_initChildInstance, circular); -var Ractive__Ractive = function (svg, create, defineProperties, prototype, partialRegistry, adaptorRegistry, easingRegistry, Ractive_extend, parse, initialise, circular) { - - var Ractive = function (options) { - initialise(this, options); - }; - defineProperties(Ractive, { - prototype: { value: prototype }, - partials: { value: partialRegistry }, - adaptors: { value: adaptorRegistry }, - easing: { value: easingRegistry }, - transitions: { value: {} }, - events: { value: {} }, - components: { value: {} }, - decorators: { value: {} }, - svg: { value: svg }, - VERSION: { value: '0.3.9' } - }); - Ractive.eventDefinitions = Ractive.events; - Ractive.prototype.constructor = Ractive; - Ractive.delimiters = [ - '{{', - '}}' - ]; - Ractive.tripleDelimiters = [ - '{{{', - '}}}' - ]; - Ractive.extend = Ractive_extend; - Ractive.parse = parse; - circular.Ractive = Ractive; - return Ractive; - }(config_svg, utils_create, utils_defineProperties, Ractive_prototype__prototype, registries_partials, registries_adaptors, registries_easing, extend__extend, parse__parse, Ractive_initialise, circular); -var Ractive = function (Ractive, circular) { - - if (typeof window !== 'undefined' && window.Node && !window.Node.prototype.contains && window.HTMLElement && window.HTMLElement.prototype.contains) { - window.Node.prototype.contains = window.HTMLElement.prototype.contains; - } - while (circular.length) { - circular.pop()(); - } - return Ractive; - }(Ractive__Ractive, circular); -// export as Common JS module... -if ( typeof module !== "undefined" && module.exports ) { - module.exports = Ractive; -} - -// ... or as AMD module -else if ( typeof define === "function" && define.amd ) { - define( function () { - return Ractive; - }); -} - -// ... or as browser global -else { - global.Ractive = Ractive; -} - -}( typeof window !== 'undefined' ? window : this )); \ No newline at end of file diff --git a/build/Ractive-legacy.min.js b/build/Ractive-legacy.min.js deleted file mode 100644 index 21bf494537..0000000000 --- a/build/Ractive-legacy.min.js +++ /dev/null @@ -1,4 +0,0 @@ -!function(a){"use strict";var b=a.document;b&&(Date.now||(Date.now=function(){return+new Date}),String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^\s+/,"").replace(/\s+$/,"")}),Object.keys||(Object.keys=function(){var a=Object.prototype.hasOwnProperty,b=!{toString:null}.propertyIsEnumerable("toString"),c=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],d=c.length;return function(e){if("object"!=typeof e&&"function"!=typeof e||null===e)throw new TypeError("Object.keys called on non-object");var f=[];for(var g in e)a.call(e,g)&&f.push(g);if(b)for(var h=0;d>h;h++)a.call(e,c[h])&&f.push(c[h]);return f}}()),Array.prototype.indexOf||(Array.prototype.indexOf=function(a,b){var c;for(void 0===b&&(b=0),0>b&&(b+=this.length),0>b&&(b=0),c=this.length;c>b;b++)if(this.hasOwnProperty(b)&&this[b]===a)return b;return-1}),Array.prototype.forEach||(Array.prototype.forEach=function(a,b){var c,d;for(c=0,d=this.length;d>c;c+=1)this.hasOwnProperty(c)&&a.call(b,this[c],c,this)}),Array.prototype.map||(Array.prototype.map=function(a,b){var c,d,e=[];for(c=0,d=this.length;d>c;c+=1)this.hasOwnProperty(c)&&(e[c]=a.call(b,this[c],c,this));return e}),Array.prototype.filter||(Array.prototype.filter=function(a,b){var c,d,e=[];for(c=0,d=this.length;d>c;c+=1)this.hasOwnProperty(c)&&a.call(b,this[c],c,this)&&(e[e.length]=this[c]);return e}),a.addEventListener||!function(a,b){var c,d,e,f,g,h;c=function(a,b){var c,d=this;for(c in a)d[c]=a[c];d.currentTarget=b,d.target=a.srcElement||b,d.timeStamp=+new Date,d.preventDefault=function(){a.returnValue=!1},d.stopPropagation=function(){a.cancelBubble=!0}},d=function(a,b){var d,e,f=this;d=f.listeners||(f.listeners=[]),e=d.length,d[e]=[b,function(a){b.call(f,new c(a,f))}],f.attachEvent("on"+a,d[e][1])},e=function(a,b){var c,d,e=this;if(e.listeners)for(c=e.listeners,d=c.length;d--;)c[d][0]===b&&e.detachEvent("on"+a,c[d][1])},a.addEventListener=b.addEventListener=d,a.removeEventListener=b.removeEventListener=e,"Element"in a?(Element.prototype.addEventListener=d,Element.prototype.removeEventListener=e):(h=b.createElement,b.createElement=function(a){var b=h(a);return b.addEventListener=d,b.removeEventListener=e,b},f=b.getElementsByTagName("head")[0],g=b.createElement("style"),f.insertBefore(g,f.firstChild))}(a,b),a.getComputedStyle||(a.getComputedStyle=function(){function a(b,c,d,e){var f,g=c[d],h=parseFloat(g),i=g.split(/\d/)[0];return e=null!=e?e:/%|em/.test(i)&&b.parentElement?a(b.parentElement,b.parentElement.currentStyle,"fontSize",null):16,f="fontSize"==d?e:/width/i.test(d)?b.clientWidth:b.clientHeight,"em"==i?h*e:"in"==i?96*h:"pt"==i?96*h/72:"%"==i?h/100*f:h}function b(a,b){var c="border"==b?"Width":"",d=b+"Top"+c,e=b+"Right"+c,f=b+"Bottom"+c,g=b+"Left"+c;a[b]=(a[d]==a[e]==a[f]==a[g]?[a[d]]:a[d]==a[f]&&a[g]==a[e]?[a[d],a[e]]:a[g]==a[e]?[a[d],a[e],a[f]]:[a[d],a[e],a[f],a[g]]).join(" ")}function c(c){var d,e,f,g;d=c.currentStyle,e=this,f=a(c,d,"fontSize",null);for(g in d)/width|height|margin.|padding.|border.+W/.test(g)&&"auto"!==e[g]?e[g]=a(c,d,g,f)+"px":"styleFloat"===g?e.float=d[g]:e[g]=d[g];return b(e,"margin"),b(e,"padding"),b(e,"border"),e.fontSize=f+"px",e}function d(a){return new c(a)}return c.prototype={constructor:c,getPropertyPriority:function(){},getPropertyValue:function(a){return this[a]||""},item:function(){},removeProperty:function(){},setProperty:function(){},getPropertyCSSValue:function(){}},d}()))}("undefined"!=typeof window?window:this),function(a){var b=function(){return"undefined"!=typeof document?document&&document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1"):void 0}(),c=function(){var a;try{Object.create(null),a=Object.create}catch(b){a=function(){var a=function(){};return function(b,c){var d;return null===b?{}:(a.prototype=b,d=new a,c&&Object.defineProperties(d,c),d)}}()}return a}(),d={html:"http://www.w3.org/1999/xhtml",mathml:"http://www.w3.org/1998/Math/MathML",svg:"http://www.w3.org/2000/svg",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"},e=function(a,b){return a?function(a,b){return b?document.createElementNS(b,a):document.createElement(a)}:function(a,c){if(c&&c!==b.html)throw"This browser does not support namespaces other than http://www.w3.org/1999/xhtml. The most likely cause of this error is that you're trying to render SVG in an older browser. See https://github.com/RactiveJS/Ractive/wiki/SVG-and-older-browsers for more information";return document.createElement(a)}}(b,d),f=function(){return"object"==typeof document?!0:!1}(),g=function(a){try{return Object.defineProperty({},"test",{value:0}),a&&Object.defineProperty(document.createElement("div"),"test",{value:0}),Object.defineProperty}catch(b){return function(a,b,c){a[b]=c.value}}}(f),h=function(a,b,c){try{try{Object.defineProperties({},{test:{value:0}})}catch(d){throw d}return c&&Object.defineProperties(a("div"),{test:{value:0}}),Object.defineProperties}catch(d){return function(a,c){var d;for(d in c)c.hasOwnProperty(d)&&b(a,d,c[d])}}}(e,g,f),i=function(){var a=/\[\s*(\*|[0-9]|[1-9][0-9]+)\s*\]/g;return function(b){return(b||"").replace(a,".$1")}}(),j={},k={TEXT:1,INTERPOLATOR:2,TRIPLE:3,SECTION:4,INVERTED:5,CLOSING:6,ELEMENT:7,PARTIAL:8,COMMENT:9,DELIMCHANGE:10,MUSTACHE:11,TAG:12,ATTRIBUTE:13,COMPONENT:15,NUMBER_LITERAL:20,STRING_LITERAL:21,ARRAY_LITERAL:22,OBJECT_LITERAL:23,BOOLEAN_LITERAL:24,GLOBAL:26,KEY_VALUE_PAIR:27,REFERENCE:30,REFINEMENT:31,MEMBER:32,PREFIX_OPERATOR:33,BRACKETED:34,CONDITIONAL:35,INFIX_OPERATOR:36,INVOCATION:40},l=function(){var a=Object.prototype.toString;return function(b){return"[object Array]"===a.call(b)}}(),m=function(){return function a(b,c){var d,e;if((e=b._wrapped[c])&&e.teardown()!==!1&&(b._wrapped[c]=null),b._cache[c]=void 0,d=b._cacheMap[c])for(;d.length;)a(b,d.pop())}}(),n=function(){return function(a,b){var c,d,e,f,g,h;for(c=[],h=a.rendered?a.el:a.fragment.docFrag,d=h.querySelectorAll('input[type="checkbox"][name="{{'+b+'}}"]'),f=d.length,g=0;f>g;g+=1)e=d[g],(e.hasAttribute("checked")||e.checked)&&(c[c.length]=e._ractive.value);return c}}(),o=function(a){return function(b){var c,d,e,f,g,h;for(c=b._deferred;d=c.evals.pop();)d.update().deferred=!1;for(;e=c.selectValues.pop();)e.deferredUpdate();for(;f=c.attrs.pop();)f.update().deferred=!1;for(;g=c.checkboxes.pop();)b.set(g,a(b,g));for(;h=c.radios.pop();)h.update()}}(n),p=function(){return function(a){var b,c,d,e,f,g;for(b=a._deferred,(c=b.focusable)&&(c.focus(),b.focusable=null);d=b.liveQueries.pop();)d._sort();for(;e=b.decorators.pop();)e.init();for(;f=b.transitions.pop();)f.init();for(;g=b.observers.pop();)g.update()}}(),q=function(){var a=function(a,b){var c,d,e,f;return a._parent&&a._parent._transitionManager?a._parent._transitionManager:(d=[],e=function(){var a,b;for(a=d.length;a--;)b=d[a],f(b.node)&&(b.detach(),d.splice(a,1))},f=function(a){var b,d;for(b=c.active.length;b--;)if(d=c.active[b],a.contains(d))return!1;return!0},c={active:[],push:function(a){c.active[c.active.length]=a},pop:function(a){var b;b=c.active.indexOf(a),-1!==b&&(c.active.splice(b,1),e(),!c.active.length&&c._ready&&c.complete())},complete:function(){b&&b.call(a)},ready:function(){e(),c._ready=!0,c.active.length||c.complete()},detachWhenReady:function(a){d[d.length]=a}})};return a}(),r=function(){function a(a,d,e,f){var g=a._deps[e];g&&(b(g[d]),f||c(a._depsMap[d],a,e))}function b(a){var b,c;if(a)for(c=a.length,b=0;c>b;b+=1)a[b].update()}function c(b,c,d,e){var f;if(b)for(f=b.length;f--;)a(c,b[f],d,e)}function d(a,b,c,f,g){var i,j,k,l,m,n,o,p;for(i=a._patternObservers.length;i--;)j=a._patternObservers[i],j.regex.test(c)&&j.update(c);f||(p=function(b){if(k=a._depsMap[b])for(i=k.length;i--;)l=k[i],m=h.exec(l)[0],n=c+"."+m,d(a,l,n)},g?(o=e(c),o.forEach(p)):p(b))}function e(a){var b,c,d,e,g,h;for(b=a.split("."),c=f(b.length),g=[],d=function(a,c){return a?"*":b[c]},e=c.length;e--;)h=c[e].map(d).join("."),g[h]||(g[g.length]=h,g[h]=!0);return g}function f(a){var b,c,d,e,f,g="";if(!i[a]){for(d=[];g.length=f;f+=1){for(c=f.toString(2);c.length2&&f[1])for(q=Math.min(f[1],f.length-2),r=f[0],s=r+q,f[1]===f.length-2&&(u=!0),p=r;s>p;p+=1)t=g+"."+p,h(a,t);for(e(a),m=[],l=g.split(".");l.length;)l.pop(),m[m.length]=l.join(".");h.multiple(a,m,!0),u||h(a,g+".length",!0)},i=function(b,c,d,e){var f,g;for(f=c.length;f--;)g=c[f],g.type===a.REFERENCE?g.update():g.keypath===b&&g.type===a.SECTION&&!g.inverted&&g.docFrag?d[d.length]=g:e[e.length]=g},j=b._ractive.wrappers,l=j.length;l--;)k=j[l],g(k.root,k.keypath)},n=[],p=["pop","push","reverse","shift","sort","splice","unshift"],q=function(){},p.forEach(function(a){var c=function(){var b,c,d,h,i={},k={};for(b=Array.prototype[a].apply(this,arguments),c=this._ractive.instances,h=c.length;h--;)d=c[h],i[d._guid]=d._transitionManager,d._transitionManager=k[d._guid]=g(d,q);for(this._ractive.setting=!0,j(this,a,arguments),this._ractive.setting=!1,h=c.length;h--;)d=c[h],d._transitionManager=i[d._guid],k[d._guid].ready(),e(d),f(d);return b};b(n,a,{value:c})}),o={},o.__proto__?(l=function(a){a.__proto__=n},m=function(a){a.__proto__=Array.prototype}):(l=function(a){var c,d;for(c=p.length;c--;)d=p[c],b(a,d,{value:n[d],configurable:!0})},m=function(a){var b;for(b=p.length;b--;)delete a[p[b]]}),r="Something went wrong in a rather interesting way",i}(k,g,l,m,o,p,q,r),t=function(){var a,b;try{Object.defineProperty({},"test",{value:0})}catch(c){return!1}return a={filter:function(a,b){return!!b},wrap:function(a,c,d){return new b(a,c,d)}},b=function(a,b,c){var d,e,f,g,h,i,j,k,l,m=this;if(this.ractive=a,this.keypath=c,d=c.split("."),this.prop=d.pop(),f=d.join("."),this.obj=f?a.get(f):a.data,g=this.originalDescriptor=Object.getOwnPropertyDescriptor(this.obj,this.prop),g&&g.set&&(h=g.set._ractiveWrappers))return-1===h.indexOf(this)&&h.push(this),void 0;if(g&&!g.configurable)throw new Error('Cannot use magic mode with property "'+e+'" - object is not configurable');g&&(this.value=g.value,i=g.get,j=g.set),k=i||function(){return m.value},l=function(a){var b,c,d;for(j&&j(a),b=l._ractiveWrappers,d=b.length;d--;)c=b[d],c.resetting||c.ractive.set(c.keypath,a)},l._ractiveWrappers=[this],Object.defineProperty(this.obj,this.prop,{get:k,set:l,enumerable:!0,configurable:!0})},b.prototype={get:function(){return this.value},reset:function(a){this.resetting=!0,this.value=a,this.resetting=!1},teardown:function(){var a,b,c,d;a=Object.getOwnPropertyDescriptor(this.obj,this.prop),b=a.set,d=b._ractiveWrappers,d.splice(d.indexOf(this),1),d.length||(c=this.obj[this.prop],Object.defineProperty(this.obj,this.prop,this.originalDescriptor||{writable:!0,enumerable:!0,configrable:!0}),this.obj[this.prop]=c)}},a}(),u=function(a,b,c){function d(a,b){var c,d={};if(!b)return a;b+=".";for(c in a)a.hasOwnProperty(c)&&(d[b+c]=a[c]);return d}function e(a){var b;return f[a]||(b=a?a+".":"",f[a]=function(c,e){var f;return"string"==typeof c?(f={},f[b+c]=e,f):"object"==typeof c?b?d(c,a):c:void 0}),f[a]}var f={};return function(d,f,g,h){var i,j,k,l;for(i=d.adaptors.length,j=0;i>j;j+=1){if(k=d.adaptors[j],"string"==typeof k){if(!a[k])throw new Error('Missing adaptor "'+k+'"');k=d.adaptors[j]=a[k]}if(k.filter(g,f,d))return l=d._wrapped[f]=k.wrap(d,g,f,e(f)),l.value=g,void 0}h||(d.magic&&c.filter(g,f,d)?d._wrapped[f]=c.wrap(d,g,f):d.modifyArrays&&b.filter(g,f,d)&&(d._wrapped[f]=b.wrap(d,g,f)))}}(j,s,t),v=function(a,b,c){var d,e,f;return d=function(a){return this._captured&&!this._captured[a]&&(this._captured.push(a),this._captured[a]=!0),e(this,a)},e=function(b,d){var e,g,h,i,j;return d=a(d),e=b._cache,void 0!==(g=e[d])?g:((i=b._wrapped[d])?h=i.value:d?h=(j=b._evaluators[d])?j.value:f(b,d):(c(b,"",b.data),h=b.data),e[d]=h,h)},f=function(a,b){var d,f,g,h,i,j,k;return d=b.split("."),f=d.pop(),g=d.join("."),h=e(a,g),(k=a._wrapped[g])&&(h=k.get()),null!==h&&void 0!==h?((i=a._cacheMap[g])?-1===i.indexOf(b)&&(i[i.length]=b):a._cacheMap[g]=[b],j=h[f],c(a,b,j),a._cache[b]=j,j):void 0},d}(i,j,u),w=function(){var a=Object.prototype.toString;return function(b){return"object"==typeof b&&"[object Object]"===a.call(b)}}(),x=function(){return function(a,b){return null===a&&null===b?!0:"object"==typeof a||"object"==typeof b?!1:a===b}}(),y=function(){var a;return a=function(a,b,c){var d,e,f,g,h,i,j,k,l,m,n;if(n='Could not resolve reference - too many "../" prefixes',"."===b){if(!c.length)return"";d=c[c.length-1]}else if("."===b.charAt(0))if(m=c[c.length-1],g=m?m.split("."):[],"../"===b.substr(0,3)){for(;"../"===b.substr(0,3);){if(!g.length)throw new Error(n);g.pop(),b=b.substring(3)}g.push(b),d=g.join(".")}else d=m?m+b:b.substring(1);else{for(e=b.split("."),f=e.pop(),i=e.length?"."+e.join("."):"",c=c.concat();c.length;)if(h=c.pop(),j=h+i,k=a.get(j),(l=a._wrapped[j])&&(k=l.get()),"object"==typeof k&&null!==k&&k.hasOwnProperty(f)){d=h+"."+b;break}d||void 0===a.get(b)||(d=b)}return d?d.replace(/^\./,""):d}}(),z=function(a){var b=Array.prototype.push;return function(c){for(var d,e,f;d=c._pendingResolution.pop();)e=a(c,d.ref,d.contextStack),void 0!==e?d.resolve(e):(f||(f=[])).push(d);f&&b.apply(c._pendingResolution,f)}}(y),A=function(a,b){return function(c){a(c),b(c)}}(o,p),B=function(){return function(a,b,c){var d,e,f,g,h,i,j;for(d=b.split("."),e=[],(f=a._wrapped[""])?(f.set&&f.set(d.join("."),c),g=f.get()):g=a.data;d.length>1;)h=e[e.length]=d.shift(),i=e.join("."),(f=a._wrapped[i])?(f.set&&f.set(d.join("."),c),g=f.get()):(g.hasOwnProperty(h)||(j||(j=i),g[h]=/^\s*[0-9]+\s*$/.test(d[0])?[]:{}),g=g[h]);return h=d[0],g[h]=c,j}}(),C=function(a,b,c,d,e,f,g,h,i){var j,k,l,m;return j=function(b,d,i){var j,m,n,o,p,q,r;if(m=[],a(b)&&(j=b,i=d),j)for(b in j)j.hasOwnProperty(b)&&(d=j[b],b=c(b),k(this,b,d,m));else b=c(b),k(this,b,d,m);if(m.length){if(o=this._transitionManager,this._transitionManager=p=g(this,i),n=l(m),n.length&&e.multiple(this,n,!0),e.multiple(this,m),this._pendingResolution.length&&f(this),h(this),this._transitionManager=o,p.ready(),!this.firingChangeEvent){for(this.firingChangeEvent=!0,r={},q=m.length;q--;)r[m[q]]=this.get(m[q]);this.fire("change",r),this.firingChangeEvent=!1}return this}},k=function(a,b,c,e){var f,g,h,j,k;if(!(h=a._wrapped[b])||!h.reset||m(a,b,c,h,e)===!1){if((k=a._evaluators[b])&&(k.value=c),f=a._cache[b],g=a.get(b),g===c||k){if(c===f&&"object"!=typeof c)return}else j=i(a,b,c);d(a,j||b),e[e.length]=b}},l=function(a){var b,c,d,e,f=[""];for(b=a.length;b--;)for(c=a[b],d=c.split(".");d.length>1;)d.pop(),e=d.join("."),f[e]||(f[f.length]=e,f[e]=!0);return f},m=function(a,c,e,f,g){var h,i,j,k;if(h=f.get(),!b(h,e)&&f.reset(e)===!1)return!1;if(e=f.get(),i=a._cache[c],!b(i,e)){if(a._cache[c]=e,j=a._cacheMap[c])for(k=j.length;k--;)d(a,j[k]);g[g.length]=c}},j}(w,x,i,m,r,z,q,A,B),D=function(a,b,c,d,e){return function(f,g){var h,i;return"function"==typeof f&&(g=f,f=""),i=this._transitionManager,this._transitionManager=h=a(this,g),b(this),c(this,f||""),d(this,f||""),e(this),this._transitionManager=i,h.ready(),"string"==typeof f?this.fire("update",f):this.fire("update"),this}}(q,z,m,r,A),E=function(a){return function(b,c){var d;if(!a(b)||!a(c))return!1;if(b.length!==c.length)return!1;for(d=b.length;d--;)if(b[d]!==c[d])return!1;return!0}}(l),F=function(a,b,c){function d(a,e,f,g,h){var i,j,k,l,m,n;if(i=a._twowayBindings[e])for(k=i.length;k--;)l=i[k],(!l.radioName||l.node.checked)&&(l.checkboxName?l.changed()&&!g[e]&&(g[e]=!0,g[g.length]=e):(m=l.attr.value,n=l.value(),b(m,n)||c(m,n)||(f[e]=n)));if(h&&(j=a._depsMap[e]))for(k=j.length;k--;)d(a,j[k],f,g,h)}return function(b,c){var e,f,g;if("string"!=typeof b&&(b="",c=!0),d(this,b,e={},f=[],c),g=f.length)for(;g--;)b=f[g],e[b]=a(this,b);this.set(e)}}(n,E,x),G=function(){return"undefined"!=typeof window?(function(a,b,c){var d,e;if(!c.requestAnimationFrame){for(d=0;d=this.duration?(null!==g&&this.root.set(g,this.to),this.step&&this.step(1,this.to),this.complete&&this.complete(1,this.to),f=this.root._animations.indexOf(this),-1===f&&a("Animation was not found"),this.root._animations.splice(f,1),this.running=!1,!1):(c=this.easing?this.easing(b/this.duration):b/this.duration,null!==g&&(d=this.interpolator(c),this.root.set(g,d)),this.step&&this.step(c,d),!0)):!1},stop:function(){var b;this.running=!1,b=this.root._animations.indexOf(this),-1===b&&a("Animation was not found"),this.root._animations.splice(b,1)}},c}(I,K),M=function(){return{linear:function(a){return a},easeIn:function(a){return Math.pow(a,3)},easeOut:function(a){return Math.pow(a-1,3)+1},easeInOut:function(a){return(a/=.5)<1?.5*Math.pow(a,3):.5*(Math.pow(a-2,3)+2)}}}(),N=function(a,b,c,d){function e(e,g,h,i){var j,k,l,m;return null!==g&&(m=e.get(g)),b.abort(g,e),a(m,h)?(i.complete&&i.complete(1,i.to),f):(i.easing&&(j="function"==typeof i.easing?i.easing:e.easing&&e.easing[i.easing]?e.easing[i.easing]:d[i.easing],"function"!=typeof j&&(j=null)),k=void 0===i.duration?400:i.duration,l=new c({keypath:g,from:m,to:h,root:e,duration:k,easing:j,step:i.step,complete:i.complete}),b.add(l),e._animations[e._animations.length]=l,l)}var f={stop:function(){}};return function(a,b,c){var d,f,g,h,i,j,k,l,m,n,o,p;if("object"==typeof a){c=b||{},h=c.easing,i=c.duration,g=[],j=c.step,k=c.complete,(j||k)&&(m={},c.step=null,c.complete=null,l=function(a){return function(b,c){m[a]=c}});for(d in a)a.hasOwnProperty(d)&&((j||k)&&(n=l(d),c={easing:h,duration:i},j&&(c.step=n),k&&(c.complete=n)),g[g.length]=e(this,d,a[d],c));return(j||k)&&(p={easing:h,duration:i},j&&(p.step=function(a){j(a,m)}),k&&(p.complete=function(a){k(a,m)}),g[g.length]=o=e(this,null,null,p)),{stop:function(){for(;g.length;)g.pop().stop();o&&o.stop()}}}return c=c||{},f=e(this,a,b,c),{stop:function(){f.stop()}}}}(x,H,L,M),O=function(){return function(a,b){var c,d,e=this;if("object"==typeof a){c=[];for(d in a)a.hasOwnProperty(d)&&(c[c.length]=this.on(d,a[d]));return{cancel:function(){for(;c.length;)c.pop().cancel()}}}return this._subs[a]?this._subs[a].push(b):this._subs[a]=[b],{cancel:function(){e.off(a,b)}}}}(),P=function(){return function(a,b){var c,d;if(!b)if(a)this._subs[a]=[];else for(a in this._subs)delete this._subs[a];c=this._subs[a],c&&(d=c.indexOf(b),-1!==d&&c.splice(d,1))}}(),Q=function(){return function(a){var b,c,d,e,f,g,h,i;if(g=a.root,h=a.keypath,i=a.priority,b=g._deps[i]||(g._deps[i]={}),c=b[h]||(b[h]=[]),c[c.length]=a,a.registered=!0,h)for(d=h.split(".");d.length;)d.pop(),e=d.join("."),f=g._depsMap[e]||(g._depsMap[e]=[]),void 0===f[h]&&(f[h]=0,f[f.length]=h),f[h]+=1,h=e}}(),R=function(){return function(a){var b,c,d,e,f,g,h,i;if(g=a.root,h=a.keypath,i=a.priority,b=g._deps[i][h],c=b.indexOf(a),-1===c||!a.registered)throw new Error("Attempted to remove a dependant that was no longer registered! This should not happen. If you are seeing this bug in development please raise an issue at https://github.com/RactiveJS/Ractive/issues - thanks");if(b.splice(c,1),a.registered=!1,h)for(d=h.split(".");d.length;)d.pop(),e=d.join("."),f=g._depsMap[e],f[h]-=1,f[h]||(f.splice(f.indexOf(h),1),f[h]=void 0),h=e}}(),S=function(a){var b=function(a,b,c,d){var e=this;this.root=a,this.keypath=b,this.callback=c,this.defer=d.defer,this.debug=d.debug,this.proxy={update:function(){e.reallyUpdate()}},this.priority=0,this.context=d&&d.context?d.context:a};return b.prototype={init:function(a){a!==!1?this.update():this.value=this.root.get(this.keypath)},update:function(){return this.defer&&this.ready?(this.root._deferred.observers.push(this.proxy),void 0):(this.reallyUpdate(),void 0)},reallyUpdate:function(){var b,c;if(b=this.value,c=this.root.get(this.keypath),this.value=c,!this.updating){if(this.updating=!0,!a(c,b)||!this.ready)try{this.callback.call(this.context,c,b,this.keypath)}catch(d){if(this.debug||this.root.debug)throw d}this.updating=!1}}},b}(x),T=function(){return function(a,b){var c,d,e,f,g,h,i;for(c=b.split("."),f=[],h=function(b){var c,d;c=a._wrapped[b]?a._wrapped[b].get():a.get(b);for(d in c)g.push(b+"."+d)},i=function(a){return a+"."+d};d=c.shift();)"*"===d?(g=[],f.forEach(h),f=g):f[0]?f=f.map(i):f[0]=d;return e={},f.forEach(function(b){e[b]=a.get(b)}),e}}(),U=function(a,b){var c,d=/\*/;return c=function(a,b,c,d){this.root=a,this.callback=c,this.defer=d.defer,this.debug=d.debug,this.keypath=b,this.regex=new RegExp("^"+b.replace(/\./g,"\\.").replace(/\*/g,"[^\\.]+")+"$"),this.values={},this.defer&&(this.proxies=[]),this.priority="pattern",this.context=d&&d.context?d.context:a},c.prototype={init:function(a){var c,d;if(c=b(this.root,this.keypath),a!==!1)for(d in c)c.hasOwnProperty(d)&&this.update(d);else this.values=c},update:function(a){var c;{if(!d.test(a))return this.defer&&this.ready?(this.root._deferred.observers.push(this.getProxy(a)),void 0):(this.reallyUpdate(a),void 0);c=b(this.root,a);for(a in c)c.hasOwnProperty(a)&&this.update(a)}},reallyUpdate:function(b){var c=this.root.get(b);if(this.updating)return this.values[b]=c,void 0;if(this.updating=!0,!a(c,this.values[b])||!this.ready){try{this.callback.call(this.context,c,this.values[b],b)}catch(d){if(this.debug||this.root.debug)throw d}this.values[b]=c}this.updating=!1},getProxy:function(a){var b=this;return this.proxies[a]||(this.proxies[a]={update:function(){b.reallyUpdate(a)}}),this.proxies[a]}},c}(x,T),V=function(a,b,c,d,e){var f=/\*/,g={};return function(h,i,j,k){var l,m;return i=a(i),k=k||g,f.test(i)?(l=new e(h,i,j,k),h._patternObservers.push(l),m=!0):l=new d(h,i,j,k),b(l),l.init(k.init),l.ready=!0,{cancel:function(){var a;m&&(a=h._patternObservers.indexOf(l),-1!==a&&h._patternObservers.splice(a,1)),c(l)}}}}(i,Q,R,S,U),W=function(a,b){return function(c,d,e){var f,g=[];if(a(c)){e=d;for(f in c)c.hasOwnProperty(f)&&(d=c[f],g[g.length]=b(this,f,d,e));return{cancel:function(){for(;g.length;)g.pop().cancel()}}}return b(this,c,d,e)}}(w,V),X=function(){return function(a){var b,c,d,e=this._subs[a];if(e)for(b=Array.prototype.slice.call(arguments,1),c=0,d=e.length;d>c;c+=1)e[c].apply(this,b)}}(),Y=function(){return function(a){return this.el?this.fragment.find(a):null}}(),Z=function(a,b){var c,d,e,f,g,h,i,j;if(a){for(c=b("div"),d=["matches","matchesSelector"],g=["o","ms","moz","webkit"],j=function(a){return function(b,c){return b[a](c)}},h=d.length;h--;){if(e=d[h],c[e])return j(e);for(i=g.length;i--;)if(f=g[h]+e.substr(0,1).toUpperCase()+e.substring(1),c[f])return j(f)}return function(a,b){var c,d;for(c=(a.parentNode||a.document).querySelectorAll(b),d=c.length;d--;)if(c[d]===a)return!0;return!1}}}(f,e),$=function(a){return function(b,c){var d=this._isComponentQuery?!this.selector||b.name===this.selector:a(b.node,this.selector);return d?(this.push(b.node||b.instance),c||this._makeDirty(),!0):void 0}}(Z),_=function(){return function(){var a,b,c;a=this._root[this._isComponentQuery?"liveComponentQueries":"liveQueries"],b=this.selector,c=a.indexOf(b),-1!==c&&(a.splice(c,1),a[b]=null)}}(),ab=function(){function a(a){var b;return(b=a.parentFragment)?b.owner:a.component&&(b=a.component.parentFragment)?b.owner:void 0}function b(b){var c,d;for(c=[b],d=a(b);d;)c.push(d),d=a(d);return c}return function(a,c){var d,e,f,g,h,i,j,k,l,m;for(d=b(a.component||a._ractive.proxy),e=b(c.component||c._ractive.proxy),f=d[d.length-1],g=e[e.length-1];f&&f===g;)d.pop(),e.pop(),h=f,f=d[d.length-1],g=e[e.length-1];if(f=f.component||f,g=g.component||g,l=f.parentFragment,m=g.parentFragment,l===m)return i=l.items.indexOf(f),j=m.items.indexOf(g),i-j||d.length-e.length;if(k=h.fragments)return i=k.indexOf(l),j=k.indexOf(m),i-j||d.length-e.length;throw new Error("An unexpected condition was met while comparing the position of two components. Please file an issue at https://github.com/RactiveJS/Ractive/issues - thanks!")}}(),bb=function(a){return function(b,c){var d;return b.compareDocumentPosition?(d=b.compareDocumentPosition(c),2&d?1:-1):a(b,c)}}(ab),cb=function(a,b){return function(){this.sort(this._isComponentQuery?b:a),this._dirty=!1}}(bb,ab),db=function(){return function(){this._dirty||(this._root._deferred.liveQueries.push(this),this._dirty=!0)}}(),eb=function(){return function(a){var b=this.indexOf(this._isComponentQuery?a.instance:a.node);-1!==b&&this.splice(b,1)}}(),fb=function(a,b,c,d,e,f){return function(g,h,i,j){var k;return k=[],a(k,{selector:{value:h},live:{value:i},_isComponentQuery:{value:j},_test:{value:b}}),i?(a(k,{cancel:{value:c},_root:{value:g},_sort:{value:d},_makeDirty:{value:e},_remove:{value:f},_dirty:{value:!1,writable:!0}}),k):k}}(h,$,_,cb,db,eb),gb=function(a,b,c,d){return function(a,b){var c,e;return this.el?(b=b||{},c=this._liveQueries,(e=c[a])?b&&b.live?e:e.slice():(e=d(this,a,!!b.live,!1),e.live&&(c.push(a),c[a]=e),this.fragment.findAll(a,e),e)):[]}}(I,Z,h,fb),hb=function(){return function(a){return this.fragment.findComponent(a)}}(),ib=function(a,b,c,d){return function(a,b){var c,e;return b=b||{},c=this._liveComponentQueries,(e=c[a])?b&&b.live?e:e.slice():(e=d(this,a,!!b.live,!0),e.live&&(c.push(a),c[a]=e),this.fragment.findAllComponents(a,e),e)}}(I,Z,h,fb),jb=function(){return function(a){var b;return"undefined"!=typeof window&&document&&a?a.nodeType?a:"string"==typeof a&&(b=document.getElementById(a),!b&&document.querySelector&&(b=document.querySelector(a)),b&&b.nodeType)?b:a[0]&&a[0].nodeType?a[0]:null:null}}(),kb=function(a,b){return function(c,d){var e,f,g,h,i;if(c.owner=d.owner,g=c.owner.parentFragment,c.root=d.root,c.pNode=d.pNode,c.contextStack=d.contextStack||[],c.owner.type===a.SECTION&&(c.index=d.index),g&&(h=g.indexRefs)){c.indexRefs=b(null);for(i in h)c.indexRefs[i]=h[i]}for(c.priority=g?g.priority+1:1,d.indexRef&&(c.indexRefs||(c.indexRefs={}),c.indexRefs[d.indexRef]=d.index),c.items=[],e=d.descriptor?d.descriptor.length:0,f=0;e>f;f+=1)c.items[c.items.length]=c.createItem({parentFragment:c,descriptor:d.descriptor[f],index:f})}}(k,c),lb=function(a){var b={};return function(c,d,e){var f,g=[];if(c)for(f=b[d]||(b[d]=a(d)),f.innerHTML=c;f.firstChild;)g[g.length]=f.firstChild,e.appendChild(f.firstChild);return g}}(e),mb=function(a){var b,c,d;return c=//g,b=function(b,c){this.type=a.TEXT,this.descriptor=b.descriptor,c&&(this.node=document.createTextNode(b.descriptor),c.appendChild(this.node))},b.prototype={detach:function(){return this.node.parentNode.removeChild(this.node),this.node},teardown:function(a){a&&this.detach()},firstNode:function(){return this.node},toString:function(){return(""+this.descriptor).replace(c,"<").replace(d,">")}},b}(k),nb=function(a){return function(b){if(b.keypath)a(b);else{var c=b.root._pendingResolution.indexOf(b);-1!==c&&b.root._pendingResolution.splice(c,1)}}}(R),ob=function(a,b,c,d,e){function f(a,b,d){var e,f,g;if(!h.test(a.toString()))return c(a,"_nowrap",{value:!0}),a;if(!a["_"+b._guid]){c(a,"_"+b._guid,{value:function(){var c,d,e,g;if(c=b._captured,c||(b._captured=[]),d=a.apply(b,arguments),b._captured.length)for(e=f.length;e--;)g=f[e],g.updateSoftDependencies(b._captured);return b._captured=c,d},writable:!0});for(e in a)a.hasOwnProperty(e)&&(a["_"+b._guid][e]=a[e]);a["_"+b._guid+"_evaluators"]=[]}return f=a["_"+b._guid+"_evaluators"],g=f.indexOf(d),-1===g&&f.push(d),a["_"+b._guid]}var g,h;return h=/this/,g=function(b,c,e,g,h){var i;this.evaluator=e,this.keypath=c,this.root=b,this.argNum=g,this.type=a.REFERENCE,this.priority=h,i=b.get(c),"function"==typeof i&&(i=f(i,b,e)),this.value=e.values[g]=i,d(this)},g.prototype={update:function(){var a=this.root.get(this.keypath);"function"!=typeof a||a._nowrap||(a=f(a,this.root,this.evaluator)),b(a,this.value)||(this.evaluator.values[this.argNum]=a,this.evaluator.bubble(),this.value=a)},teardown:function(){e(this)}},g}(k,x,g,Q,R),pb=function(a,b,c){var d=function(a,c,d){this.root=a,this.keypath=c,this.priority=d.priority,this.evaluator=d,b(this)};return d.prototype={update:function(){var b=this.root.get(this.keypath);a(b,this.value)||(this.evaluator.bubble(),this.value=b)},teardown:function(){c(this)}},d}(x,Q,R),qb=function(a,b,c,d,e,f,g,h,i){function j(a,b){var c,d;if(a=a.replace(/\$\{([0-9]+)\}/g,"_$1"),l[a])return l[a];for(d=[];b--;)d[b]="_"+b;return c=new Function(d.join(","),"return("+a+")"),l[a]=c,c}var k,l={};return k=function(a,b,c,d,e){var f,g;for(this.root=a,this.keypath=b,this.priority=e,this.fn=j(c,d.length),this.values=[],this.refs=[],f=d.length;f--;)(g=d[f])?g[0]?this.values[f]=g[1]:this.refs[this.refs.length]=new h(a,g[1],this,f,e):this.values[f]=void 0;this.selfUpdating=this.refs.length<=1,this.update()},k.prototype={bubble:function(){this.selfUpdating?this.update():this.deferred||(this.root._deferred.evals.push(this),this.deferred=!0) -},update:function(){var b;if(this.evaluating)return this;this.evaluating=!0;try{b=this.fn.apply(null,this.values)}catch(e){if(this.root.debug)throw e;b=void 0}return a(b,this.value)||(c(this.root,this.keypath),this.root._cache[this.keypath]=b,g(this.root,this.keypath,b,!0),this.value=b,d(this.root,this.keypath)),this.evaluating=!1,this},teardown:function(){for(;this.refs.length;)this.refs.pop().teardown();c(this.root,this.keypath),this.root._evaluators[this.keypath]=null},refresh:function(){this.selfUpdating||(this.deferred=!0);for(var a=this.refs.length;a--;)this.refs[a].update();this.deferred&&(this.update(),this.deferred=!1)},updateSoftDependencies:function(a){var b,c,d;for(this.softRefs||(this.softRefs=[]),b=this.softRefs.length;b--;)d=this.softRefs[b],a[d.keypath]||(this.softRefs.splice(b,1),this.softRefs[d.keypath]=!1,d.teardown());for(b=a.length;b--;)c=a[b],this.softRefs[c]||(d=new i(this.root,c,this),this.softRefs[this.softRefs.length]=d,this.softRefs[c]=!0);this.selfUpdating=this.refs.length+this.softRefs.length<=1}},k}(x,g,m,r,Q,R,u,ob,pb),rb=function(a,b){var c=function(b,c,d,e){var f,g;g=this.root=b.root,f=a(g,c,d),void 0!==f?b.resolveRef(e,!1,f):(this.ref=c,this.argNum=e,this.resolver=b,this.contextStack=d,g._pendingResolution[g._pendingResolution.length]=this)};return c.prototype={resolve:function(a){this.keypath=a,this.resolver.resolveRef(this.argNum,!1,a)},teardown:function(){this.keypath||b(this)}},c}(y,nb),sb=function(){var a=/^(?:(?:[a-zA-Z$_][a-zA-Z$_0-9]*)|(?:[0-9]|[1-9][0-9]+))$/;return function(b){var c,d,e;for(c=b.split("."),e=c.length;e--;)if(d=c[e],"undefined"===d||!a.test(d))return!1;return!0}}(),tb=function(a,b){return function(c,d){var e,f;return e=c.replace(/\$\{([0-9]+)\}/g,function(a,b){return d[b]?d[b][1]:"undefined"}),f=a(e),b(f)?f:"${"+e.replace(/[\.\[\]]/g,"-")+"}"}}(i,sb),ub=function(a,b){function c(a,b,c){var e,f;if(e=a._depsMap[b])for(f=e.length;f--;)d(a,e[f],c)}function d(a,b,d){var e,f,g,h;for(e=a._deps.length;e--;)if(f=a._deps[e],f&&(g=f[b]))for(h=g.length;h--;)d.push(g[h]);c(a,b,d)}return function(c,e,f){var g,h,i;for(g=[],d(c,e,g),h=g.length;h--;)i=g[h],b(i),i.keypath=i.keypath.replace(e,f),a(i),i.update()}}(Q,R),vb=function(a,b,c,d){var e=function(a){var c,d,e,f,g;if(this.root=a.root,this.mustache=a,this.args=[],this.scouts=[],c=a.descriptor.x,g=a.parentFragment.indexRefs,this.str=c.s,e=this.unresolved=this.args.length=c.r?c.r.length:0,!e)return this.resolved=this.ready=!0,this.bubble(),void 0;for(d=0;e>d;d+=1)f=c.r[d],g&&void 0!==g[f]?this.resolveRef(d,!0,g[f]):this.scouts[this.scouts.length]=new b(this,f,a.contextStack,d);this.ready=!0,this.bubble()};return e.prototype={bubble:function(){var a;this.ready&&(a=this.keypath,this.keypath=c(this.str,this.args),"${"===this.keypath.substr(0,2)&&this.createEvaluator(),a?d(this.root,a,this.keypath):this.mustache.resolve(this.keypath))},teardown:function(){for(;this.scouts.length;)this.scouts.pop().teardown()},resolveRef:function(a,b,c){this.args[a]=[b,c],this.bubble(),this.resolved=!--this.unresolved},createEvaluator:function(){this.root._evaluators[this.keypath]?this.root._evaluators[this.keypath].refresh():this.root._evaluators[this.keypath]=new a(this.root,this.keypath,this.str,this.args,this.mustache.priority)}},e}(qb,rb,tb,ub),wb=function(a,b){return function(c,d){var e,f,g;g=c.parentFragment=d.parentFragment,c.root=g.root,c.contextStack=g.contextStack,c.descriptor=d.descriptor,c.index=d.index||0,c.priority=g.priority,c.type=d.descriptor.t,d.descriptor.r&&(g.indexRefs&&void 0!==g.indexRefs[d.descriptor.r]?(f=g.indexRefs[d.descriptor.r],c.indexRef=d.descriptor.r,c.value=f,c.render(c.value)):(e=a(c.root,d.descriptor.r,c.contextStack),void 0!==e?c.resolve(e):(c.ref=d.descriptor.r,c.root._pendingResolution[c.root._pendingResolution.length]=c))),d.descriptor.x&&(c.expressionResolver=new b(c)),c.descriptor.n&&!c.hasOwnProperty("value")&&c.render(void 0)}}(y,vb),xb=function(a,b,c){return function(d){d!==this.keypath&&(this.registered&&c(this),this.keypath=d,b(this),this.update(),this.root.twoway&&this.parentFragment.owner.type===a.ATTRIBUTE&&this.parentFragment.owner.element.bind(),this.expressionResolver&&this.expressionResolver.resolved&&(this.expressionResolver=null))}}(k,Q,R),yb=function(a){return function(){var b,c;c=this.root.get(this.keypath),(b=this.root._wrapped[this.keypath])&&(c=b.get()),a(c,this.value)||(this.render(c),this.value=c)}}(x),zb=function(a,b,c,d,e){var f,g,h;return g=//g,f=function(b,d){this.type=a.INTERPOLATOR,d&&(this.node=document.createTextNode(""),d.appendChild(this.node)),c(this,b)},f.prototype={update:e,resolve:d,detach:function(){return this.node.parentNode.removeChild(this.node),this.node},teardown:function(a){a&&this.detach(),b(this)},render:function(a){this.node&&(this.node.data=void 0==a?"":a)},firstNode:function(){return this.node},toString:function(){var a=void 0!=this.value?""+this.value:"";return a.replace(g,"<").replace(h,">")}},f}(k,nb,wb,xb,yb),Ab=function(a,b,c){function d(a,b,c){var d,e,f;if(e=b.length,ea.length)for(d=a.length;e>d;d+=1)c.contextStack=a.contextStack.concat(a.keypath+"."+d),c.index=d,a.descriptor.i&&(c.indexRef=a.descriptor.i),a.fragments[d]=a.createFragment(c);a.length=e}function e(a,b,d){var e,f;f=a.fragmentsById||(a.fragmentsById=c(null));for(e in f)void 0===b[e]&&f[e]&&(f[e].teardown(!0),f[e]=null);for(e in b)void 0===b[e]||f[e]||(d.contextStack=a.contextStack.concat(a.keypath+"."+e),d.index=e,a.descriptor.i&&(d.indexRef=a.descriptor.i),f[e]=a.createFragment(d))}function f(a,b){a.length||(b.contextStack=a.contextStack.concat(a.keypath),b.index=0,a.fragments[0]=a.createFragment(b),a.length=1)}function g(b,c,d,e){var f,g,h,i;if(g=a(c)&&0===c.length,f=d?g||!c:c&&!g){if(b.length||(e.contextStack=b.contextStack,e.index=0,b.fragments[0]=b.createFragment(e),b.length=1),b.length>1)for(h=b.fragments.splice(1);i=h.pop();)i.teardown(!0)}else b.length&&(b.teardownFragments(!0),b.length=0)}return function(c,h){var i;return i={descriptor:c.descriptor.f,root:c.root,pNode:c.parentFragment.pNode,owner:c},c.descriptor.n?(g(c,h,!0,i),void 0):(a(h)?d(c,h,i):b(h)?c.descriptor.i?e(c,h,i):f(c,i):g(c,h,!1,i),void 0)}}(l,w,c),Bb=function(a,b,c){function d(b,c,g,h,i,j,k){var l,m,n,o;if(!b.html){for(b.indexRefs&&void 0!==b.indexRefs[c]&&(b.indexRefs[c]=h),l=b.contextStack.length;l--;)n=b.contextStack[l],n.substr(0,j.length)===j&&(b.contextStack[l]=n.replace(j,k));for(l=b.items.length;l--;)switch(m=b.items[l],m.type){case a.ELEMENT:e(m,c,g,h,i,j,k);break;case a.PARTIAL:d(m.fragment,c,g,h,i,j,k);break;case a.COMPONENT:d(m.instance.fragment,c,g,h,i,j,k),(o=b.root._liveComponentQueries[m.name])&&o._makeDirty();break;case a.SECTION:case a.INTERPOLATOR:case a.TRIPLE:f(m,c,g,h,i,j,k)}}}function e(a,b,c,e,f,g,h){var i,j,k,l,m,n,o,p,q,r;for(i=a.attributes.length;i--;)j=a.attributes[i],j.fragment&&(d(j.fragment,b,c,e,f,g,h),j.twoway&&j.updateBindings());if(k=a.node._ractive){k.keypath.substr(0,g.length)===g&&(k.keypath=k.keypath.replace(g,h)),void 0!==b&&(k.index[b]=e);for(l in k.events)for(m=k.events[l].proxies,i=m.length;i--;)n=m[i],"object"==typeof n.n&&d(n.a,b,c,e,f,g,h),n.d&&d(n.d,b,c,e,f,g,h);(o=k.binding)&&o.keypath.substr(0,g.length)===g&&(p=k.root._twowayBindings[o.keypath],p.splice(p.indexOf(o),1),o.keypath=o.keypath.replace(g,h),p=k.root._twowayBindings[o.keypath]||(k.root._twowayBindings[o.keypath]=[]),p.push(o))}if(a.fragment&&d(a.fragment,b,c,e,f,g,h),q=a.liveQueries)for(r=a.root,i=q.length;i--;)r._liveQueries[q[i]]._makeDirty()}function f(a,b,e,f,g,h,i){var j;if(a.descriptor.x&&(a.expressionResolver&&a.expressionResolver.teardown(),a.expressionResolver=new c(a)),a.keypath?a.keypath.substr(0,h.length)===h&&a.resolve(a.keypath.replace(h,i)):a.indexRef===b&&(a.value=f,a.render(f)),a.fragments)for(j=a.fragments.length;j--;)d(a.fragments[j],b,e,f,g,h,i)}return d}(k,R,vb),Cb=function(a,b,c){return function(a,d,e,f,g){var h,i,j,k,l,m,n;for(j=d.descriptor.i,h=e;f>h;h+=1)i=d.fragments[h],k=h-g,l=h,m=d.keypath+"."+(h-g),n=d.keypath+"."+h,i.index+=g,b(i,j,k,l,g,m,n);c(a)}}(k,Bb,o),Db=function(a){return function(b){var c,d,e,f,g,h,i,j,k,l,m=this;if(c=this.parentFragment,h=[],b.forEach(function(b,c){var f,g,j;return b===c?(h[b]=m.fragments[c],void 0):(void 0===d&&(d=c),-1===b?((i||(i=[])).push(m.fragments[c]),void 0):(f=b-c,g=m.keypath+"."+c,j=m.keypath+"."+b,a(m.fragments[c],m.descriptor.i,c,b,f,g,j),h[b]=m.fragments[c],e=!0,void 0))}),i)for(;k=i.pop();)k.teardown(!0);if(void 0===d&&(d=this.length),g=this.root.get(this.keypath).length,g!==d){for(j={descriptor:this.descriptor.f,root:this.root,pNode:c.pNode,owner:this},this.descriptor.i&&(j.indexRef=this.descriptor.i),f=d;g>f;f+=1)(k=h[f])?this.docFrag.appendChild(k.detach(!1)):(j.contextStack=this.contextStack.concat(this.keypath+"."+f),j.index=f,k=this.createFragment(j)),this.fragments[f]=k;l=c.findNextNode(this),c.pNode.insertBefore(this.docFrag,l),this.length=g}}}(Bb),Eb=function(){return[]}(),Fb=function(a,b,c,d,e,f,g,h,i,j,k){var l,m;return k.push(function(){m=k.DomFragment}),l=function(b,d){this.type=a.SECTION,this.inverted=!!b.descriptor.n,this.fragments=[],this.length=0,d&&(this.docFrag=document.createDocumentFragment()),this.initialising=!0,c(this,b),d&&d.appendChild(this.docFrag),this.initialising=!1},l.prototype={update:d,resolve:e,smartUpdate:function(a,b){var c;("push"===a||"unshift"===a||"splice"===a)&&(c={descriptor:this.descriptor.f,root:this.root,pNode:this.parentFragment.pNode,owner:this},this.descriptor.i&&(c.indexRef=this.descriptor.i)),this[a]&&(this.rendering=!0,this[a](c,b),this.rendering=!1)},pop:function(){this.length&&(this.fragments.pop().teardown(!0),this.length-=1)},push:function(a,b){var c,d,e;for(c=this.length,d=c+b.length,e=c;d>e;e+=1)a.contextStack=this.contextStack.concat(this.keypath+"."+e),a.index=e,this.fragments[e]=this.createFragment(a);this.length+=b.length,this.parentFragment.pNode.insertBefore(this.docFrag,this.parentFragment.findNextNode(this))},shift:function(){this.splice(null,[0,1])},unshift:function(a,b){this.splice(a,[0,0].concat(new Array(b.length)))},splice:function(a,b){var c,d,e,f,g,i,j,k,l;if(b.length&&(i=+(b[0]<0?this.length+b[0]:b[0]),d=Math.max(0,b.length-2),e=void 0!==b[1]?b[1]:this.length-i,e=Math.min(e,this.length-i),f=d-e)){if(0>f){for(j=i-f,g=i;j>g;g+=1)this.fragments[g].teardown(!0);this.fragments.splice(i,-f)}else{for(j=i+f,c=this.fragments[i]?this.fragments[i].firstNode():this.parentFragment.findNextNode(this),k=[i,0].concat(new Array(f)),this.fragments.splice.apply(this.fragments,k),g=i;j>g;g+=1)a.contextStack=this.contextStack.concat(this.keypath+"."+g),a.index=g,this.fragments[g]=this.createFragment(a);this.parentFragment.pNode.insertBefore(this.docFrag,c)}this.length+=f,l=i+d,h(this.root,this,l,this.length,f)}},merge:i,detach:function(){var a,b;for(b=this.fragments.length,a=0;b>a;a+=1)this.docFrag.appendChild(this.fragments[a].detach());return this.docFrag},teardown:function(a){this.teardownFragments(a),j(this)},firstNode:function(){return this.fragments[0]?this.fragments[0].firstNode():this.parentFragment.findNextNode(this)},findNextNode:function(a){return this.fragments[a.index+1]?this.fragments[a.index+1].firstNode():this.parentFragment.findNextNode(this)},teardownFragments:function(a){for(var b,c;c=this.fragments.shift();)c.teardown(a);if(this.fragmentsById)for(b in this.fragmentsById)this.fragments[b]&&(this.fragmentsById[b].teardown(a),this.fragmentsById[b]=null)},render:function(a){var c,d;(d=this.root._wrapped[this.keypath])&&(a=d.get()),this.rendering||(this.rendering=!0,f(this,a),this.rendering=!1,(!this.docFrag||this.docFrag.childNodes.length)&&!this.initialising&&b&&(c=this.parentFragment.findNextNode(this),c&&c.parentNode===this.parentFragment.pNode?this.parentFragment.pNode.insertBefore(this.docFrag,c):this.parentFragment.pNode.appendChild(this.docFrag)))},createFragment:function(a){var b=new m(a);return this.docFrag&&this.docFrag.appendChild(b.docFrag),b},toString:function(){var a,b,c,d;for(a="",b=0,d=this.length,b=0;d>b;b+=1)a+=this.fragments[b].toString();if(this.fragmentsById)for(c in this.fragmentsById)this.fragmentsById[c]&&(a+=this.fragmentsById[c].toString());return a},find:function(a){var b,c,d;for(c=this.fragments.length,b=0;c>b;b+=1)if(d=this.fragments[b].find(a))return d;return null},findAll:function(a,b){var c,d;for(d=this.fragments.length,c=0;d>c;c+=1)this.fragments[c].findAll(a,b)},findComponent:function(a){var b,c,d;for(c=this.fragments.length,b=0;c>b;b+=1)if(d=this.fragments[b].findComponent(a))return d;return null},findAllComponents:function(a,b){var c,d;for(d=this.fragments.length,c=0;d>c;c+=1)this.fragments[c].findAllComponents(a,b)}},l}(k,f,wb,yb,xb,Ab,Bb,Cb,Db,nb,Eb),Gb=function(a,b,c,d,e,f,g){var h=function(b,d){this.type=a.TRIPLE,d&&(this.nodes=[],this.docFrag=document.createDocumentFragment()),this.initialising=!0,c(this,b),d&&d.appendChild(this.docFrag),this.initialising=!1};return h.prototype={update:d,resolve:e,detach:function(){for(var a=this.nodes.length;a--;)this.docFrag.appendChild(this.nodes[a]);return this.docFrag},teardown:function(a){a&&(this.detach(),this.docFrag=this.nodes=null),g(this)},firstNode:function(){return this.nodes[0]?this.nodes[0]:this.parentFragment.findNextNode(this)},render:function(a){var b,c;if(this.nodes){for(;this.nodes.length;)b=this.nodes.pop(),b.parentNode.removeChild(b);if(!a)return this.nodes=[],void 0;c=this.parentFragment.pNode,this.nodes=f(a,c.tagName,this.docFrag),this.initialising||c.insertBefore(this.docFrag,this.parentFragment.findNextNode(this))}},toString:function(){return void 0!=this.value?this.value:""},find:function(a){var c,d,e,f;for(d=this.nodes.length,c=0;d>c;c+=1)if(e=this.nodes[c],1===e.nodeType){if(b(e,a))return e;if(f=e.querySelector(a))return f}return null},findAll:function(a,c){var d,e,f,g,h,i;for(e=this.nodes.length,d=0;e>d;d+=1)if(f=this.nodes[d],1===f.nodeType&&(b(f,a)&&c.push(f),g=f.querySelectorAll(a)))for(h=g.length,i=0;h>i;i+=1)c.push(g[i])}},h}(k,Z,wb,yb,xb,lb,nb),Hb=function(a){return function(b,c){return b.a&&b.a.xmlns?b.a.xmlns:"svg"===b.e?a.svg:c.namespaceURI||a.html}}(d),Ib=function(){var a,b,c,d;return a="altGlyph altGlyphDef altGlyphItem animateColor animateMotion animateTransform clipPath feBlend feColorMatrix feComponentTransfer feComposite feConvolveMatrix feDiffuseLighting feDisplacementMap feDistantLight feFlood feFuncA feFuncB feFuncG feFuncR feGaussianBlur feImage feMerge feMergeNode feMorphology feOffset fePointLight feSpecularLighting feSpotLight feTile feTurbulence foreignObject glyphRef linearGradient radialGradient textPath vkern".split(" "),b="attributeName attributeType baseFrequency baseProfile calcMode clipPathUnits contentScriptType contentStyleType diffuseConstant edgeMode externalResourcesRequired filterRes filterUnits glyphRef gradientTransform gradientUnits kernelMatrix kernelUnitLength keyPoints keySplines keyTimes lengthAdjust limitingConeAngle markerHeight markerUnits markerWidth maskContentUnits maskUnits numOctaves pathLength patternContentUnits patternTransform patternUnits pointsAtX pointsAtY pointsAtZ preserveAlpha preserveAspectRatio primitiveUnits refX refY repeatCount repeatDur requiredExtensions requiredFeatures specularConstant specularExponent spreadMethod startOffset stdDeviation stitchTiles surfaceScale systemLanguage tableValues targetX targetY textLength viewBox viewTarget xChannelSelector yChannelSelector zoomAndPan".split(" "),c=function(a){for(var b={},c=a.length;c--;)b[a[c].toLowerCase()]=a[c];return b},d=c(a.concat(b)),function(a){var b=a.toLowerCase();return d[b]||b}}(),Jb=function(a,b){return function(c,d){var e,f;if(e=d.indexOf(":"),-1===e||(f=d.substr(0,e),"xmlns"===f))c.name=c.element.namespace!==a.html?b(d):d,c.lcName=c.name.toLowerCase();else if(d=d.substring(e+1),c.name=b(d),c.lcName=c.name.toLowerCase(),c.namespace=a[f.toLowerCase()],!c.namespace)throw'Unknown namespace ("'+f+'")'}}(d,Ib),Kb=function(a){return function(b,c){var d,e=null===c.value?"":c.value;(d=c.pNode)&&(b.namespace?d.setAttributeNS(b.namespace,c.name,e):"style"===c.name&&d.style.setAttribute?d.style.setAttribute("cssText",e):"class"!==c.name||d.namespaceURI&&d.namespaceURI!==a.html?d.setAttribute(c.name,e):d.className=e,"id"===b.name&&(c.root.nodes[c.value]=d),"value"===b.name&&(d._ractive.value=c.value)),b.value=c.value}}(d),Lb=function(a){var b={"accept-charset":"acceptCharset",accesskey:"accessKey",bgcolor:"bgColor","class":"className",codebase:"codeBase",colspan:"colSpan",contenteditable:"contentEditable",datetime:"dateTime",dirname:"dirName","for":"htmlFor","http-equiv":"httpEquiv",ismap:"isMap",maxlength:"maxLength",novalidate:"noValidate",pubdate:"pubDate",readonly:"readOnly",rowspan:"rowSpan",tabindex:"tabIndex",usemap:"useMap"};return function(c,d){var e;!c.pNode||c.namespace||d.pNode.namespaceURI&&d.pNode.namespaceURI!==a.html||(e=b[c.name]||c.name,void 0!==d.pNode[e]&&(c.propertyName=e),("boolean"==typeof d.pNode[e]||"value"===e)&&(c.useProperty=!0))}}(d),Mb=function(a,b,c,d){var e,f,g,h,i,j,k,l,m,n,o,p,q,r;return e=function(){var a,b,c,d=this.pNode;return this.fragment?(a=f(this))?(this.interpolator=a,this.keypath=a.keypath||a.descriptor.r,(b=i(this))?(d._ractive.binding=this.element.binding=b,this.twoway=!0,c=this.root._twowayBindings[this.keypath]||(this.root._twowayBindings[this.keypath]=[]),c[c.length]=b,!0):!1):!1:!1},g=function(){this._ractive.binding.update()},h=function(){var a=this._ractive.root.get(this._ractive.binding.keypath);this.value=void 0==a?"":a},f=function(c){var d,e;return 1!==c.fragment.items.length?null:(d=c.fragment.items[0],d.type!==a.INTERPOLATOR?null:d.keypath||d.ref?d.keypath&&"${"===d.keypath.substr(0,2)?(e="You cannot set up two-way binding against an expression "+d.keypath,c.root.debug&&b(e),null):d:null)},i=function(a){var c=a.pNode;if("SELECT"===c.tagName)return c.multiple?new k(a,c):new l(a,c);if("checkbox"===c.type||"radio"===c.type){if("name"===a.propertyName){if("checkbox"===c.type)return new n(a,c);if("radio"===c.type)return new m(a,c)}return"checked"===a.propertyName?new o(a,c):null}return"value"!==a.lcName&&b("This is... odd"),"file"===c.type?new p(a,c):c.getAttribute("contenteditable")?new q(a,c):new r(a,c)},k=function(a,b){var c;j(this,a,b),b.addEventListener("change",g,!1),c=this.root.get(this.keypath),void 0===c&&this.update()},k.prototype={value:function(){var a,b,c,d;for(a=[],b=this.node.options,d=b.length,c=0;d>c;c+=1)b[c].selected&&(a[a.length]=b[c]._ractive.value);return a},update:function(){var a,b,d;return a=this.attr,b=a.value,d=this.value(),void 0!==b&&c(d,b)||(a.receiving=!0,a.value=d,this.root.set(this.keypath,d),a.receiving=!1),this},deferUpdate:function(){this.deferred!==!0&&(this.root._deferred.attrs.push(this),this.deferred=!0)},teardown:function(){this.node.removeEventListener("change",g,!1)}},l=function(a,b){var c;j(this,a,b),b.addEventListener("change",g,!1),c=this.root.get(this.keypath),void 0===c&&this.update()},l.prototype={value:function(){var a,b,c;for(a=this.node.options,c=a.length,b=0;c>b;b+=1)if(a[b].selected)return a[b]._ractive.value},update:function(){var a=this.value();return this.attr.receiving=!0,this.attr.value=a,this.root.set(this.keypath,a),this.attr.receiving=!1,this},deferUpdate:function(){this.deferred!==!0&&(this.root._deferred.attrs.push(this),this.deferred=!0)},teardown:function(){this.node.removeEventListener("change",g,!1)}},m=function(a,b){var c;this.radioName=!0,j(this,a,b),b.name="{{"+a.keypath+"}}",b.addEventListener("change",g,!1),b.attachEvent&&b.addEventListener("click",g,!1),c=this.root.get(this.keypath),void 0!==c?b.checked=c==b._ractive.value:this.root._deferred.radios.push(this)},m.prototype={value:function(){return this.node._ractive?this.node._ractive.value:this.node.value},update:function(){var a=this.node;a.checked&&(this.attr.receiving=!0,this.root.set(this.keypath,this.value()),this.attr.receiving=!1)},teardown:function(){this.node.removeEventListener("change",g,!1),this.node.removeEventListener("click",g,!1)}},n=function(a,b){var c,d;this.checkboxName=!0,j(this,a,b),b.name="{{"+this.keypath+"}}",b.addEventListener("change",g,!1),b.attachEvent&&b.addEventListener("click",g,!1),c=this.root.get(this.keypath),void 0!==c?(d=-1!==c.indexOf(b._ractive.value),b.checked=d):-1===this.root._deferred.checkboxes.indexOf(this.keypath)&&this.root._deferred.checkboxes.push(this.keypath)},n.prototype={changed:function(){return this.node.checked!==!!this.checked},update:function(){this.checked=this.node.checked,this.attr.receiving=!0,this.root.set(this.keypath,d(this.root,this.keypath)),this.attr.receiving=!1},teardown:function(){this.node.removeEventListener("change",g,!1),this.node.removeEventListener("click",g,!1)}},o=function(a,b){j(this,a,b),b.addEventListener("change",g,!1),b.attachEvent&&b.addEventListener("click",g,!1)},o.prototype={value:function(){return this.node.checked},update:function(){this.attr.receiving=!0,this.root.set(this.keypath,this.value()),this.attr.receiving=!1},teardown:function(){this.node.removeEventListener("change",g,!1),this.node.removeEventListener("click",g,!1)}},p=function(a,b){j(this,a,b),b.addEventListener("change",g,!1)},p.prototype={value:function(){return this.attr.pNode.files},update:function(){this.attr.root.set(this.attr.keypath,this.value())},teardown:function(){this.node.removeEventListener("change",g,!1)}},q=function(a,b){j(this,a,b),b.addEventListener("change",g,!1),this.root.lazy||(b.addEventListener("input",g,!1),b.attachEvent&&b.addEventListener("keyup",g,!1))},q.prototype={update:function(){this.attr.receiving=!0,this.root.set(this.keypath,this.node.innerHTML),this.attr.receiving=!1},teardown:function(){this.node.removeEventListener("change",g,!1),this.node.removeEventListener("input",g,!1),this.node.removeEventListener("keyup",g,!1)}},r=function(a,b){j(this,a,b),b.addEventListener("change",g,!1),this.root.lazy||(b.addEventListener("input",g,!1),b.attachEvent&&b.addEventListener("keyup",g,!1)),this.node.addEventListener("blur",h,!1)},r.prototype={value:function(){var a=this.attr.pNode.value;return+a+""===a&&-1===a.indexOf("e")&&(a=+a),a},update:function(){var a=this.attr,b=this.value();a.receiving=!0,a.root.set(a.keypath,b),a.receiving=!1},teardown:function(){this.node.removeEventListener("change",g,!1),this.node.removeEventListener("input",g,!1),this.node.removeEventListener("keyup",g,!1),this.node.removeEventListener("blur",h,!1)}},j=function(a,b,c){a.attr=b,a.node=c,a.root=b.root,a.keypath=b.keypath},e}(k,I,E,n),Nb=function(a,b){var c,d,e,f,g,h,i,j,k,l,m,n;return c=function(){var a;if(!this.ready)return this;if(a=this.pNode,"SELECT"===a.tagName&&"value"===this.lcName)return this.update=e,this.deferredUpdate=f,this.update();if(this.isFileInputValue)return this.update=d,this;if(this.twoway&&"name"===this.lcName){if("radio"===a.type)return this.update=i,this.update();if("checkbox"===a.type)return this.update=j,this.update()}return"style"===this.lcName&&a.style.setAttribute?(this.update=k,this.update()):"class"!==this.lcName||a.namespaceURI&&a.namespaceURI!==b.html?a.getAttribute("contenteditable")&&"value"===this.lcName?(this.update=m,this.update()):(this.update=n,this.update()):(this.update=l,this.update())},d=function(){return this},f=function(){this.deferredUpdate=this.pNode.multiple?h:g,this.deferredUpdate()},e=function(){return this.root._deferred.selectValues.push(this),this},g=function(){var a,b,c,d=this.fragment.getValue();for(this.value=this.pNode._ractive.value=d,a=this.pNode.options,c=a.length;c--;)if(b=a[c],b._ractive.value==d)return b.selected=!0,this;return this},h=function(){var b,c,d=this.fragment.getValue();for(a(d)||(d=[d]),b=this.pNode.options,c=b.length;c--;)b[c].selected=-1!==d.indexOf(b[c]._ractive.value);return this.value=d,this},i=function(){var a,b;return a=this.pNode,b=this.fragment.getValue(),a.checked=b==a._ractive.value,this},j=function(){var b,c;return b=this.pNode,c=this.fragment.getValue(),a(c)?(b.checked=-1!==c.indexOf(b._ractive.value),this):(b.checked=c==b._ractive.value,this)},k=function(){var a,b;return a=this.pNode,b=this.fragment.getValue(),void 0===b&&(b=""),b!==this.value&&(a.style.setAttribute("cssText",b),this.value=b),this},l=function(){var a,b;return a=this.pNode,b=this.fragment.getValue(),void 0===b&&(b=""),b!==this.value&&(a.className=b,this.value=b),this},m=function(){var a,b;return a=this.pNode,b=this.fragment.getValue(),void 0===b&&(b=""),b!==this.value&&(this.receiving||(a.innerHTML=b),this.value=b),this},n=function(){var a,b;if(a=this.pNode,b=this.fragment.getValue(),this.isValueAttribute&&(a._ractive.value=b),void 0===b&&(b=""),b!==this.value){if(this.useProperty)return this.receiving||(a[this.propertyName]=b),this.value=b,this;if(this.namespace)return a.setAttributeNS(this.namespace,this.name,b),this.value=b,this;"id"===this.lcName&&(void 0!==this.value&&(this.root.nodes[this.value]=void 0),this.root.nodes[b]=a),a.setAttribute(this.name,b),this.value=b}return this},c}(l,d),Ob=function(){return function(a){var b;return b=this.str.substr(this.pos,a.length),b===a?(this.pos+=a.length,a):null}}(),Pb=function(){var a=/^\s+/;return function(){var b=a.exec(this.remaining());return b?(this.pos+=b[0].length,b[0]):null}}(),Qb=function(){return function(a){return function(b){var c=a.exec(b.str.substring(b.pos));return c?(b.pos+=c[0].length,c[1]||c[0]):null}}}(),Rb=function(){function a(a){var b;return a.getStringMatch("\\")?(b=a.str.charAt(a.pos),a.pos+=1,b):null}return function(b){var c,d="";for(c=a(b);c;)d+=c,c=a(b);return d||null}}(),Sb=function(a,b){var c=a(/^[^\\"]+/),d=a(/^[^\\']+/);return function e(a,f){var g,h,i,j,k,l;if(g=a.pos,h="",l=f?d:c,i=b(a),i&&(h+=i),j=l(a),j&&(h+=j),!h)return"";for(k=e(a,f);""!==k;)h+=k;return h}}(Qb,Rb),Tb=function(a,b){return function(c){var d,e;return d=c.pos,c.getStringMatch('"')?(e=b(c,!1),c.getStringMatch('"')?{t:a.STRING_LITERAL,v:e}:(c.pos=d,null)):c.getStringMatch("'")?(e=b(c,!0),c.getStringMatch("'")?{t:a.STRING_LITERAL,v:e}:(c.pos=d,null)):null}}(k,Sb),Ub=function(a,b){var c=b(/^(?:[+-]?)(?:(?:(?:0|[1-9]\d*)?\.\d+)|(?:(?:0|[1-9]\d*)\.)|(?:0|[1-9]\d*))(?:[eE][+-]?\d+)?/);return function(b){var d;return(d=c(b))?{t:a.NUMBER_LITERAL,v:d}:null}}(k,Qb),Vb=function(a){return a(/^[a-zA-Z_$][a-zA-Z_$0-9]*/)}(Qb),Wb=function(a,b,c){var d=/^[a-zA-Z_$][a-zA-Z_$0-9]*$/;return function(e){var f;return(f=a(e))?d.test(f.v)?f.v:'"'+f.v.replace(/"/g,'\\"')+'"':(f=b(e))?f.v:(f=c(e))?f:void 0}}(Tb,Ub,Vb),Xb=function(a,b,c,d){function e(a){var b,c,e;return a.allowWhitespace(),(b=d(a))?(e={key:b},a.allowWhitespace(),a.getStringMatch(":")?(a.allowWhitespace(),(c=a.getToken())?(e.value=c.v,e):null):null):null}var f,g,h,i,j,k;return g={"true":!0,"false":!1,undefined:void 0,"null":null},h=new RegExp("^(?:"+Object.keys(g).join("|")+")"),i=/^(?:[+-]?)(?:(?:(?:0|[1-9]\d*)?\.\d+)|(?:(?:0|[1-9]\d*)\.)|(?:0|[1-9]\d*))(?:[eE][+-]?\d+)?/,j=/\$\{([^\}]+)\}/g,k=/^\$\{([^\}]+)\}/,f=function(a,b){this.str=a,this.values=b,this.pos=0,this.result=this.getToken()},f.prototype={remaining:function(){return this.str.substring(this.pos)},getStringMatch:a,getToken:function(){return this.allowWhitespace(),this.getPlaceholder()||this.getSpecial()||this.getNumber()||this.getString()||this.getObject()||this.getArray()},getPlaceholder:function(){var a;return this.values?(a=k.exec(this.remaining()))&&this.values.hasOwnProperty(a[1])?(this.pos+=a[0].length,{v:this.values[a[1]]}):void 0:null},getSpecial:function(){var a;return(a=h.exec(this.remaining()))?(this.pos+=a[0].length,{v:g[a[0]]}):void 0},getNumber:function(){var a;return(a=i.exec(this.remaining()))?(this.pos+=a[0].length,{v:+a[0]}):void 0},getString:function(){var a,b=c(this);return b&&(a=this.values)?{v:b.v.replace(j,function(b,c){return a[c]||c})}:b},getObject:function(){var a,b;if(!this.getStringMatch("{"))return null;for(a={};b=e(this);){if(a[b.key]=b.value,this.allowWhitespace(),this.getStringMatch("}"))return{v:a};if(!this.getStringMatch(","))return null}return null},getArray:function(){var a,b;if(!this.getStringMatch("["))return null;for(a=[];b=this.getToken();){if(a.push(b.v),this.getStringMatch("]"))return{v:a};if(!this.getStringMatch(","))return null}return null},allowWhitespace:b},function(a,b){var c=new f(a,b);return c.result?{value:c.result.v,remaining:c.remaining()}:null}}(Ob,Pb,Tb,Wb),Yb=function(a,b,c,d,e){function f(a){return"string"==typeof a?a:JSON.stringify(a)}var g=function(b){this.type=a.INTERPOLATOR,c(this,b)};return g.prototype={update:d,resolve:e,render:function(a){this.value=a,this.parentFragment.bubble()},teardown:function(){b(this)},toString:function(){return void 0==this.value?"":f(this.value)}},g}(k,nb,wb,yb,xb),Zb=function(a,b,c,d,e,f,g){var h,i;return g.push(function(){i=g.StringFragment}),h=function(c){this.type=a.SECTION,this.fragments=[],this.length=0,b(this,c)},h.prototype={update:c,resolve:d,teardown:function(){this.teardownFragments(),f(this)},teardownFragments:function(){for(;this.fragments.length;)this.fragments.shift().teardown();this.length=0},bubble:function(){this.value=this.fragments.join(""),this.parentFragment.bubble()},render:function(a){var b;(b=this.root._wrapped[this.keypath])&&(a=b.get()),e(this,a),this.parentFragment.bubble()},createFragment:function(a){return new i(a)},toString:function(){return this.fragments.join("")}},h}(k,wb,yb,xb,Ab,nb,Eb),$b=function(a){var b=function(b){this.type=a.TEXT,this.text=b};return b.prototype={toString:function(){return this.text},teardown:function(){}},b}(k),_b=function(a,b){return function(){var c,d,e,f,g,h,i;if(!this.argsList||this.dirty){if(c={},d=0,f=this.root._guid,i=function(a){return a.map(function(a){var b,e,g;return a.text?a.text:a.fragments?a.fragments.map(function(a){return i(a.items)}).join(""):(b=f+"-"+d++,g=(e=a.root._wrapped[a.keypath])?e.value:a.value,c[b]=g,"${"+b+"}")}).join("")},e=i(this.items),h=b("["+e+"]",c))this.argsList=h.value;else{if(g="Could not parse directive arguments ("+this.toString()+"). If you think this is a bug, please file an issue at http://github.com/RactiveJS/Ractive/issues",this.root.debug)throw new Error(g);a(g),this.argsList=[e]}this.dirty=!1}return this.argsList}}(I,Xb),ac=function(a,b,c,d,e,f,g,h){var i=function(a){c(this,a)};return i.prototype={createItem:function(b){if("string"==typeof b.descriptor)return new f(b.descriptor);switch(b.descriptor.t){case a.INTERPOLATOR:return new d(b);case a.TRIPLE:return new d(b);case a.SECTION:return new e(b);default:throw"Something went wrong in a rather interesting way"}},bubble:function(){this.dirty=!0,this.owner.bubble()},teardown:function(){var a,b;for(a=this.items.length,b=0;a>b;b+=1)this.items[b].teardown()},getValue:function(){var b;return 1===this.items.length&&this.items[0].type===a.INTERPOLATOR&&(b=this.items[0].value,void 0!==b)?b:this.toString()},isSimple:function(){var b,c,d;if(void 0!==this.simple)return this.simple;for(b=this.items.length;b--;)if(c=this.items[b],c.type!==a.TEXT){if(c.type!==a.INTERPOLATOR)return this.simple=!1;if(d)return!1;d=!0}return this.simple=!0},toString:function(){return this.items.join("")},toJSON:function(){var a,c=this.getValue();return"string"==typeof c&&(a=b(c),c=a?a.value:c),c},toArgsList:g},h.StringFragment=i,i}(k,Xb,kb,Yb,Zb,$b,_b,Eb),bc=function(a,b,c,d,e,f,g){var h=function(e){return this.type=a.ATTRIBUTE,this.element=e.element,b(this,e.name),null===e.value||"string"==typeof e.value?(c(this,e),void 0):(this.root=e.root,this.pNode=e.pNode,this.parentFragment=this.element.parentFragment,this.fragment=new g({descriptor:e.value,root:this.root,owner:this,contextStack:e.contextStack}),this.pNode&&("value"===this.name&&(this.isValueAttribute=!0,"INPUT"===this.pNode.tagName&&"file"===this.pNode.type&&(this.isFileInputValue=!0)),d(this,e),this.selfUpdating=this.fragment.isSimple(),this.ready=!0),void 0)};return h.prototype={bind:e,update:f,updateBindings:function(){this.keypath=this.interpolator.keypath||this.interpolator.ref,"name"===this.propertyName&&(this.pNode.name="{{"+this.keypath+"}}") -},teardown:function(){var a;if(this.boundEvents)for(a=this.boundEvents.length;a--;)this.pNode.removeEventListener(this.boundEvents[a],this.updateModel,!1);this.fragment&&this.fragment.teardown()},bubble:function(){this.selfUpdating?this.update():!this.deferred&&this.ready&&(this.root._deferred.attrs.push(this),this.deferred=!0)},toString:function(){var a;return null===this.value?this.name:this.fragment?(a=this.fragment.toString(),this.name+"="+JSON.stringify(a)):this.name+"="+JSON.stringify(this.value)}},h}(k,Jb,Kb,Lb,Mb,Nb,ac),cc=function(a){return function(b,c){var d,e,f;b.attributes=[];for(d in c)c.hasOwnProperty(d)&&(e=c[d],f=new a({element:b,name:d,value:e,root:b.root,pNode:b.node,contextStack:b.parentFragment.contextStack}),b.attributes[b.attributes.length]=b.attributes[d]=f,"name"!==d&&f.update());return b.attributes}}(bc),dc=function(a,b,c,d){var e,f,g;return d.push(function(){e=d.DomFragment}),f=function(){var a=this.node,b=this.fragment.toString();a.styleSheet&&(a.styleSheet.cssText=b),a.innerHTML=b},g=function(){this.node.type&&"text/javascript"!==this.node.type||a("Script tag was updated. This does not cause the code to be re-evaluated!"),this.node.innerHTML=this.fragment.toString()},function(a,d,h,i){var j,k,l,m,n;if("script"===a.lcName||"style"===a.lcName)return a.fragment=new c({descriptor:h.f,root:a.root,contextStack:a.parentFragment.contextStack,owner:a}),i&&("script"===a.lcName?(a.bubble=g,a.node.innerHTML=a.fragment.toString()):(a.bubble=f,a.bubble())),void 0;if("string"!=typeof h.f||d&&d.namespaceURI&&d.namespaceURI!==b.html)a.fragment=new e({descriptor:h.f,root:a.root,pNode:d,contextStack:a.parentFragment.contextStack,owner:a}),i&&d.appendChild(a.fragment.docFrag);else if(a.html=h.f,i)for(d.innerHTML=a.html,j=a.root._liveQueries,k=j.length;k--;)if(l=j[k],(m=d.querySelectorAll(l))&&(n=m.length))for((a.liveQueries||(a.liveQueries=[])).push(l),a.liveQueries[l]=[];n--;)a.liveQueries[l][n]=m[n]}}(I,d,ac,Eb),ec=function(a,b){var c=function(c,d,e,f){var g,h,i;if(this.root=d,this.node=e.node,g=c.n||c,"string"!=typeof g&&(h=new b({descriptor:g,root:this.root,owner:e,contextStack:f}),g=h.toString(),h.teardown()),c.a?this.params=c.a:c.d&&(h=new b({descriptor:c.d,root:this.root,owner:e,contextStack:f}),this.params=h.toArgsList(),h.teardown()),this.fn=d.decorators[g],!this.fn){if(i='Missing "'+g+'" decorator. You may need to download a plugin via https://github.com/RactiveJS/Ractive/wiki/Plugins#decorators',d.debug)throw new Error(i);a(i)}};return c.prototype={init:function(){var a,b;if(this.params?(b=[this.node].concat(this.params),a=this.fn.apply(this.root,b)):a=this.fn.call(this.root,this.node),!a||!a.teardown)throw new Error("Decorator definition must return an object with a teardown method");this.teardown=a.teardown}},c}(I,ac),fc=function(a){return function(b,c,d,e){d.decorator=new a(b,c,d,e),d.decorator.fn&&c._deferred.decorators.push(d.decorator)}}(ec),gc=function(a,b){var c,d,e,f,g,h,i,j,k;return c=function(a,b,c,e,f){var g,h;g=a.node._ractive.events,h=g[b]||(g[b]=new d(a,b,e,f)),h.add(c)},d=function(b,c,d){var e;this.element=b,this.root=b.root,this.node=b.node,this.name=c,this.contextStack=d,this.proxies=[],(e=this.root.events[c])?this.custom=e(this.node,k(c)):("on"+c in this.node||a('Missing "'+this.name+'" event. You may need to download a plugin via https://github.com/RactiveJS/Ractive/wiki/Plugins#events'),this.node.addEventListener(c,j,!1))},d.prototype={add:function(a){this.proxies[this.proxies.length]=new e(this.element,this.root,a,this.contextStack)},teardown:function(){var a;for(this.custom?this.custom.teardown():this.node.removeEventListener(this.name,j,!1),a=this.proxies.length;a--;)this.proxies[a].teardown()},fire:function(a){for(var b=this.proxies.length;b--;)this.proxies[b].fire(a)}},e=function(a,c,d,e){var i;return this.root=c,i=d.n||d,this.n="string"==typeof i?i:new b({descriptor:d.n,root:this.root,owner:a,contextStack:e}),d.a?(this.a=d.a,this.fire=g,void 0):d.d?(this.d=new b({descriptor:d.d,root:this.root,owner:a,contextStack:e}),this.fire=h,void 0):(this.fire=f,void 0)},e.prototype={teardown:function(){this.n.teardown&&this.n.teardown(),this.d&&this.d.teardown()},bubble:function(){}},f=function(a){this.root.fire(this.n.toString(),a)},g=function(a){this.root.fire.apply(this.root,[this.n.toString(),a].concat(this.a))},h=function(a){var b=this.d.toArgsList();"string"==typeof b&&(b=b.substr(1,b.length-2)),this.root.fire.apply(this.root,[this.n.toString(),a].concat(b))},j=function(a){var b=this._ractive;b.events[a.type].fire({node:this,original:a,index:b.index,keypath:b.keypath,context:b.root.get(b.keypath)})},i={},k=function(a){return i[a]?i[a]:i[a]=function(b){var c=b.node._ractive;b.index=c.index,b.keypath=c.keypath,b.context=c.root.get(c.keypath),c.events[a].fire(b)}},c}(I,ac),hc=function(a){return function(b,c){var d,e,f;for(e in c)if(c.hasOwnProperty(e))for(f=e.split("-"),d=f.length;d--;)a(b,f[d],c[e],b.parentFragment.contextStack)}}(gc),ic=function(){return function(a){var b,c,d,e,f;for(b=a.root,c=b._liveQueries,d=c.length;d--;)e=c[d],f=c[e],f._test(a)&&((a.liveQueries||(a.liveQueries=[])).push(e),a.liveQueries[e]=[a.node])}}(),jc=function(){return function(a){return a.replace(/-([a-zA-Z])/g,function(a,b){return b.toUpperCase()})}}(),kc=function(){return function(a,b){var c;for(c in b)b.hasOwnProperty(c)&&!a.hasOwnProperty(c)&&(a[c]=b[c]);return a}}(),lc=function(a,b,c,d,e,f,g,h){function i(a){var b,c,d;if(!q[a])if(void 0!==m[a])q[a]=a;else for(d=a.charAt(0).toUpperCase()+a.substring(1),b=n.length;b--;)if(c=n[b],void 0!==m[c+d]){q[a]=c+d;break}return q[a]}function j(a){return a.replace(p,"")}function k(a){var b;return o.test(a)&&(a="-"+a),b=a.replace(/[A-Z]/g,function(a){return"-"+a.toLowerCase()})}var l,m,n,o,p,q,r,s,t,u,v,w;if(a)return m=b("div").style,function(){void 0!==m.transition?(s="transition",w="transitionend",r=!0):void 0!==m.webkitTransition?(s="webkitTransition",w="webkitTransitionEnd",r=!0):r=!1}(),s&&(t=s+"Duration",u=s+"Property",v=s+"TimingFunction"),l=function(a,b,d,e,f){var g,i,j,k=this;if(this.root=b,this.node=d.node,this.isIntro=f,this.originalStyle=this.node.getAttribute("style"),this.complete=function(a){!a&&k.isIntro&&k.resetStyle(),k._manager.pop(k.node),k.node._ractive.transition=null},g=a.n||a,"string"!=typeof g&&(i=new h({descriptor:g,root:this.root,owner:d,contextStack:e}),g=i.toString(),i.teardown()),this.name=g,a.a?this.params=a.a:a.d&&(i=new h({descriptor:a.d,root:this.root,owner:d,contextStack:e}),this.params=i.toArgsList(),i.teardown()),this._fn=b.transitions[g],!this._fn){if(j='Missing "'+g+'" transition. You may need to download a plugin via https://github.com/RactiveJS/Ractive/wiki/Plugins#transitions',b.debug)throw new Error(j);return c(j),void 0}},l.prototype={init:function(){if(this._inited)throw new Error("Cannot initialize a transition more than once");this._inited=!0,this._fn.apply(this.root,[this].concat(this.params))},getStyle:function(a){var b,c,d,f,g;if(b=window.getComputedStyle(this.node),"string"==typeof a)return g=b[i(a)],"0px"===g&&(g=0),g;if(!e(a))throw new Error("Transition#getStyle must be passed a string, or an array of strings representing CSS properties");for(c={},d=a.length;d--;)f=a[d],g=b[i(f)],"0px"===g&&(g=0),c[f]=g;return c},setStyle:function(a,b){var c;if("string"==typeof a)this.node.style[i(a)]=b;else for(c in a)a.hasOwnProperty(c)&&(this.node.style[i(c)]=a[c]);return this},animateStyle:function(a,b,d,e){var g,h,l,m,n,o,p,q,r,s=this;for("string"==typeof a?(n={},n[a]=b):(n=a,e=d,d=b),d||(c('The "'+s.name+'" transition does not supply an options object to `t.animateStyle()`. This will break in a future version of Ractive. For more info see https://github.com/RactiveJS/Ractive/issues/340'),d=s,e=s.complete),d.duration||(s.setStyle(n),e&&e()),g=Object.keys(n),h=[],l=window.getComputedStyle(s.node),o={},q=g.length;q--;)r=g[q],m=l[i(r)],"0px"===m&&(m=0),m!=n[r]&&(h[h.length]=r,s.node.style[i(r)]=m);return h.length?(setTimeout(function(){s.node.style[u]=g.map(i).map(k).join(","),s.node.style[v]=k(d.easing||"linear"),s.node.style[t]=d.duration/1e3+"s",p=function(a){var b;b=h.indexOf(f(j(a.propertyName))),-1!==b&&h.splice(b,1),h.length||(s.root.fire(s.name+":end"),s.node.removeEventListener(w,p,!1),e&&e())},s.node.addEventListener(w,p,!1),setTimeout(function(){for(var a=h.length;a--;)r=h[a],s.node.style[i(r)]=n[r]},0)},d.delay||0),void 0):(e&&e(),void 0)},resetStyle:function(){this.originalStyle?this.node.setAttribute("style",this.originalStyle):(this.node.getAttribute("style"),this.node.removeAttribute("style"))},processParams:function(a,b){return"number"==typeof a?a={duration:a}:"string"==typeof a?a="slow"===a?{duration:600}:"fast"===a?{duration:200}:{duration:400}:a||(a={}),g(a,b)}},n=["o","ms","moz","webkit"],o=new RegExp("^(?:"+n.join("|")+")([A-Z])"),p=new RegExp("^-(?:"+n.join("|")+")-"),q={},l}(f,e,I,J,l,jc,kc,ac),mc=function(a,b){return function(a,c,d,e,f){var g,h,i;!c.transitionsEnabled||c._parent&&!c._parent.transitionsEnabled||(g=new b(a,c,d,e,f),g._fn&&(h=g.node,g._manager=c._transitionManager,(i=h._ractive.transition)&&i.complete(),h._ractive.transition=g,g._manager.push(h),f?c._deferred.transitions.push(g):g.init()))}}(I,lc),nc=function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){return function(e,p,q){var r,s,t,u,v,w,x,y,z,A,B,C,D;if(e.type=a.ELEMENT,r=e.parentFragment=p.parentFragment,s=r.pNode,t=r.contextStack,u=e.descriptor=p.descriptor,e.root=B=r.root,e.index=p.index,e.lcName=u.e.toLowerCase(),e.eventListeners=[],e.customEventListeners=[],s&&(v=e.namespace=h(u,s),w=v!==b.html?o(u.e):u.e,e.node=g(w,v),d(e.node,"_ractive",{value:{proxy:e,keypath:t.length?t[t.length-1]:"",index:r.indexRefs,events:c(null),root:B}})),x=i(e,u.a),u.f){if(e.node&&e.node.getAttribute("contenteditable")&&e.node.innerHTML){if(D="A pre-populated contenteditable element should not have children",B.debug)throw new Error(D);f(D)}j(e,e.node,u,q)}q&&u.v&&l(e,u.v),q&&(B.twoway&&(e.bind(),e.node.getAttribute("contenteditable")&&e.node._ractive.binding&&e.node._ractive.binding.update()),x.name&&!x.name.twoway&&x.name.update(),"IMG"===e.node.tagName&&((y=e.attributes.width)||(z=e.attributes.height))&&e.node.addEventListener("load",A=function(){y&&(e.node.width=y.value),z&&(e.node.height=z.value),e.node.removeEventListener("load",A,!1)},!1),q.appendChild(e.node),u.o&&k(u.o,B,e,t),u.t1&&n(u.t1,B,e,t,!0),"OPTION"===e.node.tagName&&("SELECT"===s.tagName&&(C=s._ractive.binding)&&C.deferUpdate(),e.node._ractive.value==s._ractive.value&&(e.node.selected=!0)),e.node.autofocus&&(B._deferred.focusable=e.node)),m(e)}}(k,d,c,g,Z,I,e,Hb,cc,dc,fc,hc,ic,mc,Ib),oc=function(a){return function(b){var c,d,e,f,g,h,i,j,k;for(this.fragment&&this.fragment.teardown(!1);this.attributes.length;)this.attributes.pop().teardown();if(this.node){for(c in this.node._ractive.events)this.node._ractive.events[c].teardown();(d=this.node._ractive.binding)&&(d.teardown(),e=this.root._twowayBindings[d.attr.keypath],e.splice(e.indexOf(d),1))}if(this.decorator&&this.decorator.teardown(),this.descriptor.t2&&a(this.descriptor.t2,this.root,this,this.parentFragment.contextStack,!1),b&&this.root._transitionManager.detachWhenReady(this),g=this.liveQueries)for(f=g.length;f--;)if(h=g[f],j=this.liveQueries[h])for(k=j.length,i=this.root._liveQueries[h];k--;)i._remove(j[k])}}(mc),pc=function(){return"area base br col command doctype embed hr img input keygen link meta param source track wbr".split(" ")}(),qc=function(a){return function(){var b,c,d;for(b="<"+(this.descriptor.y?"!doctype":this.descriptor.e),d=this.attributes.length,c=0;d>c;c+=1)b+=" "+this.attributes[c].toString();return b+=">",this.html?b+=this.html:this.fragment&&(b+=this.fragment.toString()),-1===a.indexOf(this.descriptor.e)&&(b+=""),b}}(pc),rc=function(a){return function(b){var c;return a(this.node,b)?this.node:this.html&&(c=this.node.querySelector(b))?c:this.fragment&&this.fragment.find?this.fragment.find(b):void 0}}(Z),sc=function(){return function(a,b){var c,d,e,f,g;if(b._test(this,!0)&&b.live&&((this.liveQueries||(this.liveQueries=[])).push(a),this.liveQueries[a]=[this.node]),this.html&&(c=this.node.querySelectorAll(a))&&(e=c.length))for(b.live&&(this.liveQueries[a]||((this.liveQueries||(this.liveQueries=[])).push(a),this.liveQueries[a]=[]),g=this.liveQueries[a]),d=0;e>d;d+=1)f=c[d],b.push(f),b.live&&g.push(f);this.fragment&&this.fragment.findAll(a,b)}}(),tc=function(){return function(a){return this.fragment?this.fragment.findComponent(a):void 0}}(),uc=function(){return function(a,b){this.fragment&&this.fragment.findAllComponents(a,b)}}(),vc=function(){return function(){var a=this.attributes;if(this.node&&(this.binding&&(this.binding.teardown(),this.binding=null),!(this.node.getAttribute("contenteditable")&&a.value&&a.value.bind())))switch(this.descriptor.e){case"select":case"textarea":return a.value&&a.value.bind(),void 0;case"input":if("radio"===this.node.type||"checkbox"===this.node.type){if(a.name&&a.name.bind())return;if(a.checked&&a.checked.bind())return}if(a.value&&a.value.bind())return}}}(),wc=function(a,b,c,d,e,f,g,h){var i=function(b,c){a(this,b,c)};return i.prototype={detach:function(){return this.node?(this.node.parentNode&&this.node.parentNode.removeChild(this.node),this.node):void 0},teardown:b,firstNode:function(){return this.node},findNextNode:function(){return null},bubble:function(){},toString:c,find:d,findAll:e,findComponent:f,findAllComponents:g,bind:h},i}(nc,oc,qc,rc,sc,tc,uc,vc),xc={missingParser:"Missing Ractive.parse - cannot parse template. Either preparse or use the version that includes the parser"},yc={},zc=function(){return function(a){var b,c,d;for(d="";a.length;){if(b=a.indexOf(""),-1===b&&-1===c){d+=a;break}if(-1!==b&&-1===c)throw"Illegal HTML - expected closing comment sequence ('-->')";if(-1!==c&&-1===b||b>c)throw"Illegal HTML - unexpected closing comment sequence ('-->')";d+=a.substr(0,b),a=a.substring(c+3)}return d}}(),Ac=function(a){return function(b){var c,d,e,f,g,h;for(g=/^\s*\r?\n/,h=/\r?\n\s*$/,c=2;c":a.PARTIAL,"!":a.COMMENT,"&":a.TRIPLE};return function(a){var c=b[a.str.charAt(a.pos)];return c?(a.pos+=1,c):null}}(k),Ec=function(a,b,c){var d=b(/^\s*:\s*([a-zA-Z_$][a-zA-Z_$0-9]*)/),e=/^[0-9][1-9]*$/;return function(b,f){var g,h,i,j,k,l,m;if(g=b.pos,h={type:f?a.TRIPLE:a.MUSTACHE},!(f||((j=b.getExpression())&&(h.mustacheType=a.INTERPOLATOR,b.allowWhitespace(),b.getStringMatch(b.delimiters[1])?b.pos-=b.delimiters[1].length:(b.pos=g,j=null)),j||(i=c(b),i===a.TRIPLE?h={type:a.TRIPLE}:h.mustacheType=i||a.INTERPOLATOR,i!==a.COMMENT&&i!==a.CLOSING||(l=b.remaining(),m=l.indexOf(b.delimiters[1]),-1===m)))))return h.ref=l.substr(0,m),b.pos+=m,h;for(j||(b.allowWhitespace(),j=b.getExpression());j.t===a.BRACKETED&&j.x;)j=j.x;return j.t===a.REFERENCE?h.ref=j.n:j.t===a.NUMBER_LITERAL&&e.test(j.v)?h.ref=j.v:h.expression=j,k=d(b),null!==k&&(h.indexRef=k),h}}(k,Qb,Dc),Fc=function(a,b,c){function d(d,e){var f,g,h=d.pos;return g=e?d.tripleDelimiters:d.delimiters,d.getStringMatch(g[0])?(f=b(d))?d.getStringMatch(g[1])?(d[e?"tripleDelimiters":"delimiters"]=f,{type:a.MUSTACHE,mustacheType:a.DELIMCHANGE}):(d.pos=h,null):(d.allowWhitespace(),f=c(d,e),null===f?(d.pos=h,null):(d.allowWhitespace(),d.getStringMatch(g[1])?f:(d.pos=h,null))):null}return function(){var a=this.tripleDelimiters[0].length>this.delimiters[0].length;return d(this,a)||d(this,!a)}}(k,Cc,Ec),Gc=function(a){return function(){var b,c,d;if(!this.getStringMatch(""),-1===d)throw new Error('Unexpected end of input (expected "-->" to close comment)');return b=c.substr(0,d),this.pos+=d+3,{type:a.COMMENT,content:b}}}(k),Hc=function(){return function(a,b){var c,d,e;for(c=b.length;c--;){if(d=a.indexOf(b[c]),!d)return 0;-1!==d&&(!e||e>d)&&(e=d)}return e||-1}}(),Ic=function(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p;return d=function(){return e(this)||f(this)},e=function(b){var c,d,e,f;return c=b.pos,b.inside?null:b.getStringMatch("<")?(d={type:a.TAG},b.getStringMatch("!")&&(d.doctype=!0),d.name=g(b),d.name?(e=h(b),e&&(d.attrs=e),b.allowWhitespace(),b.getStringMatch("/")&&(d.selfClosing=!0),b.getStringMatch(">")?(f=d.name.toLowerCase(),("script"===f||"style"===f)&&(b.inside=f),d):(b.pos=c,null)):(b.pos=c,null)):null},f=function(b){var c,d,e;if(c=b.pos,e=function(a){throw new Error("Unexpected character "+b.remaining().charAt(0)+" (expected "+a+")")},!b.getStringMatch("<"))return null;if(d={type:a.TAG,closing:!0},b.getStringMatch("/")||e('"/"'),d.name=g(b),d.name||e("tag name"),b.getStringMatch(">")||e('">"'),b.inside){if(d.name.toLowerCase()!==b.inside)return b.pos=c,null;b.inside=null}return d},g=b(/^[a-zA-Z]{1,}:?[a-zA-Z0-9\-]*/),h=function(a){var b,c,d;if(b=a.pos,a.allowWhitespace(),d=i(a),!d)return a.pos=b,null;for(c=[];null!==d;)c[c.length]=d,a.allowWhitespace(),d=i(a);return c},i=function(a){var b,c,d;return(c=j(a))?(b={name:c},d=k(a),d&&(b.value=d),b):null},j=b(/^[^\s"'>\/=]+/),k=function(a){var b,c;return b=a.pos,a.allowWhitespace(),a.getStringMatch("=")?(a.allowWhitespace(),c=p(a,"'")||p(a,'"')||l(a),null===c?(a.pos=b,null):c):(a.pos=b,null)},n=b(/^[^\s"'=<>`]+/),m=function(b){var c,d,e;return c=b.pos,(d=n(b))?(-1!==(e=d.indexOf(b.delimiters[0]))&&(d=d.substr(0,e),b.pos=c+d.length),{type:a.TEXT,value:d}):null},l=function(a){var b,c;for(b=[],c=a.getMustache()||m(a);null!==c;)b[b.length]=c,c=a.getMustache()||m(a);return b.length?b:null},p=function(a,b){var c,d,e;if(c=a.pos,!a.getStringMatch(b))return null;for(d=[],e=a.getMustache()||o(a,b);null!==e;)d[d.length]=e,e=a.getMustache()||o(a,b);return a.getStringMatch(b)?d:(a.pos=c,null)},o=function(b,d){var e,f,g;if(e=b.pos,g=b.remaining(),f=c(g,[d,b.delimiters[0],b.delimiters[1]]),-1===f)throw new Error("Quoted attribute value must have a closing quote");return f?(b.pos+=f,{type:a.TEXT,value:g.substr(0,f)}):null},d}(k,Qb,Hc),Jc=function(a,b){return function(){var c,d,e;return d=this.remaining(),e=this.inside?"a;a+=1)f=d(g[a],h),h=f;c=h}(),c}(k,Vc),Xc=function(a,b){var c,d;return d=function(b,c){return function(d){var e,f,g;return(f=c(d))?(e=d.pos,d.allowWhitespace(),d.getStringMatch(b)?"in"===b&&/[a-zA-Z_$0-9]/.test(d.remaining().charAt(0))?(d.pos=e,f):(d.allowWhitespace(),g=d.getExpression(),g?{t:a.INFIX_OPERATOR,s:b,o:[f,g]}:(d.pos=e,f)):(d.pos=e,f)):null}},function(){var a,e,f,g,h;for(g="* / % + - << >> >>> < <= > >= in instanceof == != === !== & ^ | && ||".split(" "),h=b,a=0,e=g.length;e>a;a+=1)f=d(g[a],h),h=f;c=h}(),c}(k,Wc),Yc=function(a,b){return function(c){var d,e,f,g;return(e=b(c))?(d=c.pos,c.allowWhitespace(),c.getStringMatch("?")?(c.allowWhitespace(),(f=c.getExpression())?(c.allowWhitespace(),c.getStringMatch(":")?(c.allowWhitespace(),g=c.getExpression(),g?{t:a.CONDITIONAL,o:[e,f,g]}:(c.pos=d,e)):(c.pos=d,e)):(c.pos=d,e)):(c.pos=d,e)):null}}(k,Xc),Zc=function(a){return function(){return a(this)}}(Yc),$c=function(a,b,c,d,e,f,g){var h;return h=function(a,b){var c;for(this.str=a,this.pos=0,this.delimiters=b.delimiters,this.tripleDelimiters=b.tripleDelimiters,this.tokens=[];this.pos"+b)},expected:function(a){var b=this.remaining().substr(0,40);throw 40===b.length&&(b+="..."),new Error('Tokenizer failed: unexpected string "'+b+'" (expected '+a+")")}},h}(Fc,Gc,Ic,Jc,Zc,Pb,Ob),_c=function(a,b,c,d,e){var f,g;return e.push(function(){g=e.Ractive}),f=function(e,f){var h,i;return f=f||{},f.stripComments!==!1&&(e=a(e)),h=new d(e,{delimiters:f.delimiters||(g?g.delimiters:["{{","}}"]),tripleDelimiters:f.tripleDelimiters||(g?g.tripleDelimiters:["{{{","}}}"])}),i=h.tokens,b(i),c(i),i}}(zc,Ac,Bc,$c,Eb),ad=function(a){var b,c,d,e,f,g,h,i,j;return b=function(a,b){this.text=b?a.value:a.value.replace(j," ")},b.prototype={type:a.TEXT,toJSON:function(){return this.decoded||(this.decoded=i(this.text))},toString:function(){return this.text}},c={quot:34,amp:38,apos:39,lt:60,gt:62,nbsp:160,iexcl:161,cent:162,pound:163,curren:164,yen:165,brvbar:166,sect:167,uml:168,copy:169,ordf:170,laquo:171,not:172,shy:173,reg:174,macr:175,deg:176,plusmn:177,sup2:178,sup3:179,acute:180,micro:181,para:182,middot:183,cedil:184,sup1:185,ordm:186,raquo:187,frac14:188,frac12:189,frac34:190,iquest:191,Agrave:192,Aacute:193,Acirc:194,Atilde:195,Auml:196,Aring:197,AElig:198,Ccedil:199,Egrave:200,Eacute:201,Ecirc:202,Euml:203,Igrave:204,Iacute:205,Icirc:206,Iuml:207,ETH:208,Ntilde:209,Ograve:210,Oacute:211,Ocirc:212,Otilde:213,Ouml:214,times:215,Oslash:216,Ugrave:217,Uacute:218,Ucirc:219,Uuml:220,Yacute:221,THORN:222,szlig:223,agrave:224,aacute:225,acirc:226,atilde:227,auml:228,aring:229,aelig:230,ccedil:231,egrave:232,eacute:233,ecirc:234,euml:235,igrave:236,iacute:237,icirc:238,iuml:239,eth:240,ntilde:241,ograve:242,oacute:243,ocirc:244,otilde:245,ouml:246,divide:247,oslash:248,ugrave:249,uacute:250,ucirc:251,uuml:252,yacute:253,thorn:254,yuml:255,OElig:338,oelig:339,Scaron:352,scaron:353,Yuml:376,fnof:402,circ:710,tilde:732,Alpha:913,Beta:914,Gamma:915,Delta:916,Epsilon:917,Zeta:918,Eta:919,Theta:920,Iota:921,Kappa:922,Lambda:923,Mu:924,Nu:925,Xi:926,Omicron:927,Pi:928,Rho:929,Sigma:931,Tau:932,Upsilon:933,Phi:934,Chi:935,Psi:936,Omega:937,alpha:945,beta:946,gamma:947,delta:948,epsilon:949,zeta:950,eta:951,theta:952,iota:953,kappa:954,lambda:955,mu:956,nu:957,xi:958,omicron:959,pi:960,rho:961,sigmaf:962,sigma:963,tau:964,upsilon:965,phi:966,chi:967,psi:968,omega:969,thetasym:977,upsih:978,piv:982,ensp:8194,emsp:8195,thinsp:8201,zwnj:8204,zwj:8205,lrm:8206,rlm:8207,ndash:8211,mdash:8212,lsquo:8216,rsquo:8217,sbquo:8218,ldquo:8220,rdquo:8221,bdquo:8222,dagger:8224,Dagger:8225,bull:8226,hellip:8230,permil:8240,prime:8242,Prime:8243,lsaquo:8249,rsaquo:8250,oline:8254,frasl:8260,euro:8364,image:8465,weierp:8472,real:8476,trade:8482,alefsym:8501,larr:8592,uarr:8593,rarr:8594,darr:8595,harr:8596,crarr:8629,lArr:8656,uArr:8657,rArr:8658,dArr:8659,hArr:8660,forall:8704,part:8706,exist:8707,empty:8709,nabla:8711,isin:8712,notin:8713,ni:8715,prod:8719,sum:8721,minus:8722,lowast:8727,radic:8730,prop:8733,infin:8734,ang:8736,and:8743,or:8744,cap:8745,cup:8746,"int":8747,there4:8756,sim:8764,cong:8773,asymp:8776,ne:8800,equiv:8801,le:8804,ge:8805,sub:8834,sup:8835,nsub:8836,sube:8838,supe:8839,oplus:8853,otimes:8855,perp:8869,sdot:8901,lceil:8968,rceil:8969,lfloor:8970,rfloor:8971,lang:9001,rang:9002,loz:9674,spades:9824,clubs:9827,hearts:9829,diams:9830},d=[8364,129,8218,402,8222,8230,8224,8225,710,8240,352,8249,338,141,381,143,144,8216,8217,8220,8221,8226,8211,8212,732,8482,353,8250,339,157,382,376],e=new RegExp("&("+Object.keys(c).join("|")+");?","g"),f=/&#x([0-9]+);?/g,g=/&#([0-9]+);?/g,h=function(a){return a?10===a?32:128>a?a:159>=a?d[a-128]:55296>a?a:57343>=a?65533:65535>=a?a:65533:65533},i=function(a){var b;return b=a.replace(e,function(a,b){return c[b]?String.fromCharCode(c[b]):a}),b=b.replace(f,function(a,b){return String.fromCharCode(h(parseInt(b,16)))}),b=b.replace(g,function(a,b){return String.fromCharCode(h(b))})},j=/\s+/g,b}(k),bd=function(a,b){return function(c){return c.type===a.TEXT?(this.pos+=1,new b(c,this.preserveWhitespace)):null}}(k,ad),cd=function(a){var b;return b=function(a){this.content=a.content},b.prototype={toJSON:function(){return{t:a.COMMENT,f:this.content}},toString:function(){return""}},b}(k),dd=function(a,b){return function(c){return c.type===a.COMMENT?(this.pos+=1,new b(c,this.preserveWhitespace)):null}}(k,cd),ed=function(a,b){var c,d,e;return c=function(a){this.refs=[],d(a,this.refs),this.str=e(a,this.refs)},c.prototype={toJSON:function(){return this.json?this.json:(this.json={r:this.refs,s:this.str},this.json)}},d=function(c,e){var f,g;if(c.t===a.REFERENCE&&-1===e.indexOf(c.n)&&e.unshift(c.n),g=c.o||c.m)if(b(g))d(g,e);else for(f=g.length;f--;)d(g[f],e);c.x&&d(c.x,e),c.r&&d(c.r,e),c.v&&d(c.v,e)},e=function(b,c){var d=function(a){return e(a,c)};switch(b.t){case a.BOOLEAN_LITERAL:case a.GLOBAL:case a.NUMBER_LITERAL:return b.v;case a.STRING_LITERAL:return"'"+b.v.replace(/'/g,"\\'")+"'";case a.ARRAY_LITERAL:return"["+(b.m?b.m.map(d).join(","):"")+"]";case a.OBJECT_LITERAL:return"{"+(b.m?b.m.map(d).join(","):"")+"}";case a.KEY_VALUE_PAIR:return b.k+":"+e(b.v,c);case a.PREFIX_OPERATOR:return("typeof"===b.s?"typeof ":b.s)+e(b.o,c);case a.INFIX_OPERATOR:return e(b.o[0],c)+("in"===b.s.substr(0,2)?" "+b.s+" ":b.s)+e(b.o[1],c);case a.INVOCATION:return e(b.x,c)+"("+(b.o?b.o.map(d).join(","):"")+")";case a.BRACKETED:return"("+e(b.x,c)+")";case a.MEMBER:return e(b.x,c)+e(b.r,c);case a.REFINEMENT:return b.n?"."+b.n:"["+e(b.x,c)+"]";case a.CONDITIONAL:return e(b.o[0],c)+"?"+e(b.o[1],c)+":"+e(b.o[2],c);case a.REFERENCE:return"${"+c.indexOf(b.n)+"}";default:throw new Error("Could not stringify expression token. This error is unexpected")}},c}(k,w),fd=function(a,b){var c=function(c,d){this.type=c.type===a.TRIPLE?a.TRIPLE:c.mustacheType,c.ref&&(this.ref=c.ref),c.expression&&(this.expr=new b(c.expression)),d.pos+=1};return c.prototype={toJSON:function(){var a;return this.json?this.json:(a={t:this.type},this.ref&&(a.r=this.ref),this.expr&&(a.x=this.expr.toJSON()),this.json=a,a)},toString:function(){return!1}},c}(k,ed),gd=function(){return function(a){var b,c,d,e="";if(!a)return"";for(c=0,d=a.length;d>c;c+=1){if(b=a[c].toString(),b===!1)return!1;e+=b}return e}}(),hd=function(a){return function(b,c){var d,e;return c||(d=a(b),d===!1)?e=b.map(function(a){return a.toJSON(c)}):d}}(gd),id=function(a,b,c){var d=function(b,d){var e;for(this.ref=b.ref,this.indexRef=b.indexRef,this.inverted=b.mustacheType===a.INVERTED,b.expression&&(this.expr=new c(b.expression)),d.pos+=1,this.items=[],e=d.next();e;){if(e.mustacheType===a.CLOSING){if(e.ref.trim()===this.ref||this.expr){d.pos+=1;break}throw new Error("Could not parse template: Illegal closing section")}this.items[this.items.length]=d.getStub(),e=d.next()}};return d.prototype={toJSON:function(c){var d;return this.json?this.json:(d={t:a.SECTION},this.ref&&(d.r=this.ref),this.indexRef&&(d.i=this.indexRef),this.inverted&&(d.n=!0),this.expr&&(d.x=this.expr.toJSON()),this.items.length&&(d.f=b(this.items,c)),this.json=d,d)},toString:function(){return!1}},d}(k,hd,ed),jd=function(a,b,c){return function(d){return d.type===a.MUSTACHE||d.type===a.TRIPLE?d.mustacheType===a.SECTION||d.mustacheType===a.INVERTED?new c(d,this):new b(d,this):void 0}}(k,fd,id),kd=function(){return{li:["li"],dt:["dt","dd"],dd:["dt","dd"],p:"address article aside blockquote dir div dl fieldset footer form h1 h2 h3 h4 h5 h6 header hgroup hr menu nav ol p pre section table ul".split(" "),rt:["rt","rp"],rp:["rp","rt"],optgroup:["optgroup"],option:["option","optgroup"],thead:["tbody","tfoot"],tbody:["tbody","tfoot"],tr:["tr"],td:["td","th"],th:["td","th"]}}(),ld=function(a){function b(c){var d,e;if("object"!=typeof c)return c;if(a(c))return c.map(b);d={};for(e in c)c.hasOwnProperty(e)&&(d[e]=b(c[e]));return d}return function(a){var c,d,e,f,g,h;for(e={},c=[],d=[],g=a.length,f=0;g>f;f+=1)if(h=a[f],"intro"===h.name){if(e.intro)throw new Error("An element can only have one intro transition"); -e.intro=h}else if("outro"===h.name){if(e.outro)throw new Error("An element can only have one outro transition");e.outro=h}else if("intro-outro"===h.name){if(e.intro||e.outro)throw new Error("An element can only have one intro and one outro transition");e.intro=h,e.outro=b(h)}else"proxy-"===h.name.substr(0,6)?(h.name=h.name.substring(6),d[d.length]=h):"on-"===h.name.substr(0,3)?(h.name=h.name.substring(3),d[d.length]=h):"decorator"===h.name?e.decorator=h:c[c.length]=h;return e.attrs=c,e.proxies=d,e}}(l),md=function(a,b){return function(c){var d,e,f,g,h,i,j,k;for(h=function(){throw new Error("Illegal directive")},c.name&&c.value||h(),d={directiveType:c.name},e=c.value,i=[],j=[];e.length;)if(f=e.shift(),f.type===a.TEXT){if(g=f.value.indexOf(":"),-1!==g){g&&(i[i.length]={type:a.TEXT,value:f.value.substr(0,g)}),f.value.length>g+1&&(j[0]={type:a.TEXT,value:f.value.substring(g+1)});break}i[i.length]=f}else i[i.length]=f;return j=j.concat(e),d.name=1===i.length&&i[0].type===a.TEXT?i[0].value:i,j.length&&(1===j.length&&j[0].type===a.TEXT?(k=b("["+j[0].value+"]"),d.args=k?k.value:j[0].value):d.dynamicArgs=j),d}}(k,Xb),nd=function(a,b){var c;return c=function(a,b){var c;for(this.tokens=a||[],this.pos=0,this.options=b,this.result=[];c=this.getStub();)this.result.push(c)},c.prototype={getStub:function(){var a=this.next();return a?this.getText(a)||this.getMustache(a):null},getText:a,getMustache:b,next:function(){return this.tokens[this.pos]}},c}(bd,jd),od=function(a,b,c){var d;return d=function(b){var c=new a(b);this.stubs=c.result},d.prototype={toJSON:function(a){var b;return this["json_"+a]?this["json_"+a]:b=this["json_"+a]=c(this.stubs,a)},toString:function(){return void 0!==this.str?this.str:(this.str=b(this.stubs),this.str)}},d}(nd,gd,hd),pd=function(a){return function(b){var c,d;if("string"==typeof b.name){if(!b.args&&!b.dynamicArgs)return b.name;d=b.name}else d=new a(b.name).toJSON();return c={n:d},b.args?(c.a=b.args,c):(b.dynamicArgs&&(c.d=new a(b.dynamicArgs).toJSON()),c)}}(od),qd=function(a,b,c){return function(d){var e,f,g,h,i,j,k;if(this["json_"+d])return this["json_"+d];if(e=this.component?{t:a.COMPONENT,e:this.component}:{t:a.ELEMENT,e:this.tag},this.doctype&&(e.y=1),this.attributes&&this.attributes.length)for(e.a={},j=this.attributes.length,i=0;j>i;i+=1){if(k=this.attributes[i],f=k.name,e.a[f])throw new Error("You cannot have multiple attributes with the same name");g=null===k.value?null:k.value.toJSON(d),e.a[f]=g}if(this.items&&this.items.length&&(e.f=b(this.items,d)),this.proxies&&this.proxies.length)for(e.v={},j=this.proxies.length,i=0;j>i;i+=1)h=this.proxies[i],e.v[h.directiveType]=c(h);return this.intro&&(e.t1=c(this.intro)),this.outro&&(e.t2=c(this.outro)),this.decorator&&(e.o=c(this.decorator)),this["json_"+d]=e,e}}(k,hd,pd),rd=function(a,b){var c;return c="a abbr acronym address applet area b base basefont bdo big blockquote body br button caption center cite code col colgroup dd del dfn dir div dl dt em fieldset font form frame frameset h1 h2 h3 h4 h5 h6 head hr html i iframe img input ins isindex kbd label legend li link map menu meta noframes noscript object ol p param pre q s samp script select small span strike strong style sub sup textarea title tt u ul var article aside audio bdi canvas command data datagrid datalist details embed eventsource figcaption figure footer header hgroup keygen mark meter nav output progress ruby rp rt section source summary time track video wbr".split(" "),function(){var d,e,f,g,h,i,j,k;if(void 0!==this.str)return this.str;if(this.component)return this.str=!1;if(-1===c.indexOf(this.tag.toLowerCase()))return this.str=!1;if(this.proxies||this.intro||this.outro||this.decorator)return this.str=!1;if(j=a(this.items),j===!1)return this.str=!1;if(k=-1!==b.indexOf(this.tag.toLowerCase()),d="<"+this.tag,this.attributes)for(e=0,f=this.attributes.length;f>e;e+=1){if(h=this.attributes[e].name,-1!==h.indexOf(":"))return this.str=!1;if("id"===h||"intro"===h||"outro"===h)return this.str=!1;if(g=" "+h,null!==this.attributes[e].value){if(i=this.attributes[e].value.toString(),i===!1)return this.str=!1;""!==i&&(g+="=",g+=/[\s"'=<>`]/.test(i)?'"'+i.replace(/"/g,""")+'"':i)}d+=g}return this.selfClosing&&!k?(d+="/>",this.str=d):(d+=">",k?this.str=d:(d+=j,d+="",this.str=d))}}(gd,pc),sd=function(a,b,c,d,e,f,g,h,i,j,k){var l,m,n,o,p,q=/^\s+/,r=/\s+$/;return l=function(d,e,i){var j,l,m,n,o,s,t;if(e.pos+=1,s=function(a){return{name:a.name,value:a.value?new k(a.value):null}},this.tag=d.name,t=d.name.toLowerCase(),"rv-"===t.substr(0,3)&&(c('The "rv-" prefix for components has been deprecated. Support will be removed in a future version'),this.tag=this.tag.substring(3)),i=i||"pre"===t,d.attrs&&(m=g(d.attrs),l=m.attrs,n=m.proxies,e.options.sanitize&&e.options.sanitize.eventAttributes&&(l=l.filter(p)),l.length&&(this.attributes=l.map(s)),n.length&&(this.proxies=n.map(h)),m.intro&&(this.intro=h(m.intro)),m.outro&&(this.outro=h(m.outro)),m.decorator&&(this.decorator=h(m.decorator))),d.doctype&&(this.doctype=!0),d.selfClosing&&(this.selfClosing=!0),-1!==b.indexOf(t)&&(this.isVoid=!0),!this.selfClosing&&!this.isVoid){for(this.siblings=f[t],this.items=[],j=e.next();j&&j.mustacheType!==a.CLOSING;){if(j.type===a.TAG){if(j.closing){j.name.toLowerCase()===t&&(e.pos+=1);break}if(this.siblings&&-1!==this.siblings.indexOf(j.name.toLowerCase()))break}this.items[this.items.length]=e.getStub(),j=e.next()}i||(o=this.items[0],o&&o.type===a.TEXT&&(o.text=o.text.replace(q,""),o.text||this.items.shift()),o=this.items[this.items.length-1],o&&o.type===a.TEXT&&(o.text=o.text.replace(r,""),o.text||this.items.pop()))}},l.prototype={toJSON:i,toString:j},m="a abbr acronym address applet area b base basefont bdo big blockquote body br button caption center cite code col colgroup dd del dfn dir div dl dt em fieldset font form frame frameset h1 h2 h3 h4 h5 h6 head hr html i iframe img input ins isindex kbd label legend li link map menu meta noframes noscript object ol p param pre q s samp script select small span strike strong style sub sup textarea title tt u ul var article aside audio bdi canvas command data datagrid datalist details embed eventsource figcaption figure footer header hgroup keygen mark meter nav output progress ruby rp rt section source summary time track video wbr".split(" "),n="li dd rt rp optgroup option tbody tfoot tr td th".split(" "),o=/^on[a-zA-Z]/,p=function(a){var b=!o.test(a.name);return b},l}(k,pc,I,jc,gd,kd,ld,md,qd,rd,od),td=function(a,b){return function(a){return this.options.sanitize&&this.options.sanitize.elements&&-1!==this.options.sanitize.elements.indexOf(a.name.toLowerCase())?null:new b(a,this)}}(k,sd),ud=function(a,b,c,d,e){var f;return f=function(a,b){var c,d;for(this.tokens=a||[],this.pos=0,this.options=b,this.preserveWhitespace=b.preserveWhitespace,d=[];c=this.getStub();)d.push(c);this.result=e(d)},f.prototype={getStub:function(){var a=this.next();return a?this.getText(a)||this.getComment(a)||this.getMustache(a)||this.getElement(a):null},getText:a,getComment:b,getMustache:c,getElement:d,next:function(){return this.tokens[this.pos]}},f}(bd,dd,jd,td,hd),vd=function(a,b,c){var d,e,f,g,h;return e=/^\s*$/,f=//,g=//,d=function(d,g){var i,j,k;return g=g||{},f.test(d)?h(d,g):(g.sanitize===!0&&(g.sanitize={elements:"applet base basefont body frame frameset head html isindex link meta noframes noscript object param script style title".split(" "),eventAttributes:!0}),i=a(d,g),g.preserveWhitespace||(k=i[0],k&&k.type===b.TEXT&&e.test(k.value)&&i.shift(),k=i[i.length-1],k&&k.type===b.TEXT&&e.test(k.value)&&i.pop()),j=new c(i,g).result,"string"==typeof j?[j]:j)},h=function(a,b){var c,e,h,i,j,k;for(h={},c="",e=a;j=f.exec(e);){if(i=j[1],c+=e.substr(0,j.index),e=e.substring(j.index+j[0].length),k=g.exec(e),!k||k[1]!==i)throw new Error("Inline partials must have a closing delimiter, and cannot be nested");h[i]=d(e.substr(0,k.index),b),e=e.substring(k.index+k[0].length)}return{main:d(c,b),partials:h}},d}(_c,k,ud),wd=function(a,b,c,d,e,f){var g,h,i,j;return g=function(d,g){var k,l,m;if(l=i(d,g))return l;if(b&&(k=document.getElementById(g),k&&"SCRIPT"===k.tagName)){if(!f)throw new Error(a.missingParser);h(f(k.innerHTML),g,e)}if(l=e[g],!l){if(m='Could not find descriptor for partial "'+g+'"',d.debug)throw new Error(m);return c(m),[]}return j(l)},i=function(b,c){var d;if(b.partials[c]){if("string"==typeof b.partials[c]){if(!f)throw new Error(a.missingParser);d=f(b.partials[c],b.parseOptions),h(d,c,b.partials)}return j(b.partials[c])}},h=function(a,b,c){var e;if(d(a)){c[b]=a.main;for(e in a.partials)a.partials.hasOwnProperty(e)&&(c[e]=a.partials[e])}else c[b]=a},j=function(a){return 1===a.length&&"string"==typeof a[0]?a[0]:a},g}(xc,f,I,w,yc,vd),xd=function(a,b,c){var d,e;return c.push(function(){e=c.DomFragment}),d=function(c,d){var f,g=this.parentFragment=c.parentFragment;if(this.type=a.PARTIAL,this.name=c.descriptor.r,this.index=c.index,!c.descriptor.r)throw new Error("Partials must have a static reference (no expressions). This may change in a future version of Ractive.");f=b(g.root,c.descriptor.r),this.fragment=new e({descriptor:f,root:g.root,pNode:g.pNode,contextStack:g.contextStack,owner:this}),d&&d.appendChild(this.fragment.docFrag)},d.prototype={firstNode:function(){return this.fragment.firstNode()},findNextNode:function(){return this.parentFragment.findNextNode(this)},detach:function(){return this.fragment.detach()},teardown:function(a){this.fragment.teardown(a)},toString:function(){return this.fragment.toString()},find:function(a){return this.fragment.find(a)},findAll:function(a,b){return this.fragment.findAll(a,b)},findComponent:function(a){return this.fragment.findComponent(a)},findAllComponents:function(a,b){return this.fragment.findAllComponents(a,b)}},d}(k,wd,Eb),yd=function(a){var b=function(b,c,d){this.parentFragment=b.parentFragment,this.component=b,this.key=c,this.fragment=new a({descriptor:d,root:b.root,owner:this,contextStack:b.parentFragment.contextStack}),this.selfUpdating=this.fragment.isSimple(),this.value=this.fragment.getValue()};return b.prototype={bubble:function(){this.selfUpdating?this.update():!this.deferred&&this.ready&&(this.root._deferred.attrs.push(this),this.deferred=!0)},update:function(){var a=this.fragment.getValue();this.component.instance.set(this.key,a),this.value=a},teardown:function(){this.fragment.teardown()}},b}(ac),zd=function(a,b,c,d){function e(e,f,g,h){var i,j,k,l,m;return k=e.root,l=e.parentFragment,"string"==typeof g?(j=b(g),j?j.value:g):null===g?!0:1===g.length&&g[0].t===a.INTERPOLATOR&&g[0].r?l.indexRefs&&void 0!==l.indexRefs[g[0].r]?l.indexRefs[g[0].r]:(m=c(k,g[0].r,l.contextStack)||g[0].r,h.push({childKeypath:f,parentKeypath:m}),k.get(m)):(i=new d(e,f,g),e.complexParameters.push(i),i.value)}return function(a,b,c){var d,f,g;d={},a.complexParameters=[];for(f in b)b.hasOwnProperty(f)&&(g=e(a,f,b[f],c),void 0!==g&&(d[f]=g));return d}}(k,Xb,y,yd),Ad=function(){return function(a,b,c,d,e){var f,g,h,i;return g=a.parentFragment,i=a.root,h={content:e||[]},f=new b({el:g.pNode.cloneNode(!1),data:c,partials:h,_parent:i,adaptors:i.adaptors}),f.component=a,a.instance=f,f.insert(d),f.fragment.pNode=g.pNode,f}}(),Bd=function(){function a(a,c,d){var e,f,g,h,i,j,k;e=a.root,f=a.instance,i=a.observers,j=e.observe(c,function(a){g||e._wrapped[c]||(h=!0,f.set(d,a),h=!1)},b),i.push(j),f.twoway&&(j=f.observe(d,function(a){h||(g=!0,e.set(c,a),g=!1)},b),i.push(j),k=f.get(d),void 0!==k&&e.set(c,k))}var b={init:!1,debug:!0};return function(b,c){var d,e;for(b.observers=[],e=c.length;e--;)d=c[e],a(b,d.parentKeypath,d.childKeypath)}}(),Cd=function(a){function b(b,d,e,f){if("string"!=typeof f){if(d.debug)throw new Error(c);return a(c),void 0}b.on(e,function(){var a=Array.prototype.slice.call(arguments);a.unshift(f),d.fire.apply(d,a)})}var c="Components currently only support simple events - you cannot include arguments. Sorry!";return function(a,c){var d;for(d in c)c.hasOwnProperty(d)&&b(a.instance,a.root,d,c[d])}}(I),Dd=function(){return function(a){var b,c;for(b=a.root;b;)(c=b._liveComponentQueries[a.name])&&c.push(a.instance),b=b._parent}}(),Ed=function(a,b,c,d,e,f,g){return function(h,i,j){var k,l,m,n,o;if(k=h.parentFragment=i.parentFragment,l=k.root,h.root=l,h.type=a.COMPONENT,h.name=i.descriptor.e,h.index=i.index,h.observers=[],m=l.components[i.descriptor.e],!m)throw new Error('Component "'+i.descriptor.e+'" not found');o=[],n=c(h,i.descriptor.a,o),d(h,m,n,j,i.descriptor.f),e(h,o),f(h,i.descriptor.v),(i.descriptor.t1||i.descriptor.t2||i.descriptor.o)&&b('The "intro", "outro" and "decorator" directives have no effect on components'),g(h)}}(k,I,zd,Ad,Bd,Cd,Dd),Fd=function(a){var b=function(b,c){a(this,b,c)};return b.prototype={firstNode:function(){return this.instance.fragment.firstNode()},findNextNode:function(){return this.parentFragment.findNextNode(this)},detach:function(){return this.instance.fragment.detach()},teardown:function(){for(var a;this.complexParameters.length;)this.complexParameters.pop().teardown();for(;this.observers.length;)this.observers.pop().cancel();(a=this.root._liveComponentQueries[this.name])&&a._remove(this),this.instance.teardown()},toString:function(){return this.instance.fragment.toString()},find:function(a){return this.instance.fragment.find(a)},findAll:function(a,b){return this.instance.fragment.findAll(a,b)},findComponent:function(a){return a&&a!==this.name?null:this.instance},findAllComponents:function(a,b){b._test(this,!0),this.instance.fragment&&this.instance.fragment.findAllComponents(a,b)}},b}(Ed),Gd=function(a){var b=function(b,c){this.type=a.COMMENT,this.descriptor=b.descriptor,c&&(this.node=document.createComment(b.descriptor.f),c.appendChild(this.node))};return b.prototype={detach:function(){return this.node.parentNode.removeChild(this.node),this.node},teardown:function(a){a&&this.detach()},firstNode:function(){return this.node},toString:function(){return""}},b}(k),Hd=function(a,b,c,d,e,f,g,h,i,j,k,l,m){var n=function(a){a.pNode&&(this.docFrag=document.createDocumentFragment()),"string"==typeof a.descriptor?(this.html=a.descriptor,this.docFrag&&(this.nodes=d(this.html,a.pNode.tagName,this.docFrag))):c(this,a)};return n.prototype={detach:function(){var a,b;if(this.nodes)for(b=this.nodes.length;b--;)this.docFrag.appendChild(this.nodes[b]);else if(this.items)for(a=this.items.length,b=0;a>b;b+=1)this.docFrag.appendChild(this.items[b].detach());return this.docFrag},createItem:function(b){if("string"==typeof b.descriptor)return new e(b,this.docFrag);switch(b.descriptor.t){case a.INTERPOLATOR:return new f(b,this.docFrag);case a.SECTION:return new g(b,this.docFrag);case a.TRIPLE:return new h(b,this.docFrag);case a.ELEMENT:return this.root.components[b.descriptor.e]?new k(b,this.docFrag):new i(b,this.docFrag);case a.PARTIAL:return new j(b,this.docFrag);case a.COMMENT:return new l(b,this.docFrag);default:throw new Error("Something very strange happened. Please file an issue at https://github.com/RactiveJS/Ractive/issues. Thanks!")}},teardown:function(a){var b;if(this.nodes&&a)for(;b=this.nodes.pop();)b.parentNode.removeChild(b);else if(this.items)for(;this.items.length;)this.items.pop().teardown(a);this.nodes=this.items=this.docFrag=null},firstNode:function(){return this.items&&this.items[0]?this.items[0].firstNode():this.nodes?this.nodes[0]||null:null},findNextNode:function(a){var b=a.index;return this.items[b+1]?this.items[b+1].firstNode():this.owner===this.root?this.owner.component?this.owner.component.findNextNode():null:this.owner.findNextNode(this)},toString:function(){var a,b,c,d;if(this.html)return this.html;if(a="",!this.items)return a;for(c=this.items.length,b=0;c>b;b+=1)d=this.items[b],a+=d.toString();return a},find:function(a){var c,d,e,f,g;if(this.nodes){for(d=this.nodes.length,c=0;d>c;c+=1)if(f=this.nodes[c],1===f.nodeType){if(b(f,a))return f;if(g=f.querySelector(a))return g}return null}if(this.items){for(d=this.items.length,c=0;d>c;c+=1)if(e=this.items[c],e.find&&(g=e.find(a)))return g;return null}},findAll:function(a,c){var d,e,f,g,h,i,j;if(this.nodes){for(e=this.nodes.length,d=0;e>d;d+=1)if(g=this.nodes[d],1===g.nodeType&&(b(g,a)&&c.push(g),h=g.querySelectorAll(a)))for(i=h.length,j=0;i>j;j+=1)c.push(h[j])}else if(this.items)for(e=this.items.length,d=0;e>d;d+=1)f=this.items[d],f.findAll&&f.findAll(a,c);return c},findComponent:function(a){var b,c,d,e;if(this.items){for(b=this.items.length,c=0;b>c;c+=1)if(d=this.items[c],d.findComponent&&(e=d.findComponent(a)))return e;return null}},findAllComponents:function(a,b){var c,d,e;if(this.items)for(d=this.items.length,c=0;d>c;c+=1)e=this.items[c],e.findAllComponents&&e.findAllComponents(a,b);return b}},m.DomFragment=n,n}(k,Z,kb,lb,mb,zb,Fb,Gb,wc,xd,Fd,Gd,Eb),Id=function(a,b,c,d,e){return function(a,f){var g;if(!this._initing)throw new Error("You cannot call ractive.render() directly!");this._transitionManager=g=b(this,f),this.fragment=new e({descriptor:this.template,root:this,owner:this,pNode:a}),c(this),a&&a.appendChild(this.fragment.docFrag),d(this),this._transitionManager=null,g.ready(),this.rendered=!0}}(jb,q,o,p,Hd),Jd=function(a){return function(){return a("renderHTML() has been deprecated and will be removed in a future version. Please use toHTML() instead"),this.toHTML()}}(I),Kd=function(){return function(){return this.fragment.toString()}}(),Ld=function(a,b){return function(c){var d,e,f;for(this.fire("teardown"),f=this._transitionManager,this._transitionManager=e=a(this,c),this.fragment.teardown(!0);this._animations[0];)this._animations[0].stop();for(d in this._cache)b(this,d);this._transitionManager=f,e.ready()}}(q,m),Md=function(a){return function(b,c,d){var e;if("string"==typeof c&&a(d)){if(e=b.get(c),void 0===e&&(e=0),a(e))b.set(c,e+d);else if(b.debug)throw new Error("Cannot add to a non-numeric value")}else if(b.debug)throw new Error("Bad arguments")}}(J),Nd=function(a){return function(b,c){a(this,b,void 0===c?1:c)}}(Md),Od=function(a){return function(b,c){a(this,b,void 0===c?-1:-c)}}(Md),Pd=function(){return function(a){var b;if("string"==typeof a)b=this.get(a),this.set(a,!b);else if(this.debug)throw new Error("Bad arguments")}}(),Qd=function(){return function(a,b){var c,d,e,f,g;return c={},e=0,d=function(a,d){var f,h,i;h=e,i=b.length;do{if(f=b.indexOf(a,h),-1===f)return g=!0,-1;h=f+1}while(c[f]&&i>h);return f===e&&(e+=1),f!==d&&(g=!0),c[f]=!0,f},f=a.map(d),f.unchanged=!g,f}}(),Rd=function(a){return function(b,c,d,e){var f,g;for(f=c.length;f--;)g=c[f],g.type===a.REFERENCE?g.update():g.keypath===b&&g.type===a.SECTION&&!g.inverted&&g.docFrag?d[d.length]=g:e[e.length]=g}}(k),Sd=function(a,b,c,d,e,f,g,h,i,j){function k(a){return JSON.stringify(a)}function l(a){return m[a]||(m[a]=function(b){return b[a]}),m[a]}var m={};return function(m,n,o){var p,q,r,s,t,u,v,w,x,y,z,A,B,C,D;if(p=this.get(m),!b(p)||!b(n))return this.set(m,n,o&&o.complete);if(t=p.length===n.length,o&&o.compare){if(o.compare===!0)s=k;else if("string"==typeof o.compare)s=l(o.compare);else{if("function"!=typeof o.compare)throw new Error("The `compare` option must be a function, or a string representing an identifying field (or `true` to use JSON.stringify)");s=o.compare}try{q=p.map(s),r=n.map(s)}catch(E){if(this.debug)throw E;a("Merge operation: comparison failed. Falling back to identity checking"),q=p,r=n}}else q=p,r=n;if(v=i(q,r),c(this,m),h(this,m,n),!v.unchanged||!t){for(B=this._transitionManager,this._transitionManager=A=f(this,o&&o.complete),w=[],x=[],u=0;u 2 && args[1]) { - changed = Math.min(args[1], args.length - 2); - start = args[0]; - end = start + changed; - if (args[1] === args.length - 2) { - lengthUnchanged = true; - } - for (i = start; i < end; i += 1) { - childKeypath = keypath + '.' + i; - notifyDependants(root, childKeypath); - } - } - preDomUpdate(root); - upstreamQueue = []; - keys = keypath.split('.'); - while (keys.length) { - keys.pop(); - upstreamQueue[upstreamQueue.length] = keys.join('.'); - } - notifyDependants.multiple(root, upstreamQueue, true); - if (!lengthUnchanged) { - notifyDependants(root, keypath + '.length', true); - } - }; - queueDependants = function (keypath, deps, smartUpdateQueue, dumbUpdateQueue) { - var k, dependant; - k = deps.length; - while (k--) { - dependant = deps[k]; - if (dependant.type === types.REFERENCE) { - dependant.update(); - } else if (dependant.keypath === keypath && dependant.type === types.SECTION && !dependant.inverted && dependant.docFrag) { - smartUpdateQueue[smartUpdateQueue.length] = dependant; - } else { - dumbUpdateQueue[dumbUpdateQueue.length] = dependant; - } - } - }; - wrappers = array._ractive.wrappers; - i = wrappers.length; - while (i--) { - wrapper = wrappers[i]; - notifyKeypathDependants(wrapper.root, wrapper.keypath); - } - }; - patchedArrayProto = []; - mutatorMethods = [ - 'pop', - 'push', - 'reverse', - 'shift', - 'sort', - 'splice', - 'unshift' - ]; - noop = function () { - }; - mutatorMethods.forEach(function (methodName) { - var method = function () { - var result, instances, instance, i, previousTransitionManagers = {}, transitionManagers = {}; - result = Array.prototype[methodName].apply(this, arguments); - instances = this._ractive.instances; - i = instances.length; - while (i--) { - instance = instances[i]; - previousTransitionManagers[instance._guid] = instance._transitionManager; - instance._transitionManager = transitionManagers[instance._guid] = makeTransitionManager(instance, noop); - } - this._ractive.setting = true; - notifyArrayDependants(this, methodName, arguments); - this._ractive.setting = false; - i = instances.length; - while (i--) { - instance = instances[i]; - instance._transitionManager = previousTransitionManagers[instance._guid]; - transitionManagers[instance._guid].ready(); - preDomUpdate(instance); - postDomUpdate(instance); - } - return result; - }; - defineProperty(patchedArrayProto, methodName, { value: method }); - }); - testObj = {}; - if (testObj.__proto__) { - patchArrayMethods = function (array) { - array.__proto__ = patchedArrayProto; - }; - unpatchArrayMethods = function (array) { - array.__proto__ = Array.prototype; - }; - } else { - patchArrayMethods = function (array) { - var i, methodName; - i = mutatorMethods.length; - while (i--) { - methodName = mutatorMethods[i]; - defineProperty(array, methodName, { - value: patchedArrayProto[methodName], - configurable: true - }); - } - }; - unpatchArrayMethods = function (array) { - var i; - i = mutatorMethods.length; - while (i--) { - delete array[mutatorMethods[i]]; - } - }; - } - errorMessage = 'Something went wrong in a rather interesting way'; - return arrayAdaptor; - }(config_types, utils_defineProperty, utils_isArray, shared_clearCache, shared_preDomUpdate, shared_postDomUpdate, shared_makeTransitionManager, shared_notifyDependants); -var Ractive_prototype_get_magicAdaptor = function () { - - var magicAdaptor, MagicWrapper; - try { - Object.defineProperty({}, 'test', { value: 0 }); - } catch (err) { - return false; - } - magicAdaptor = { - filter: function (object, keypath) { - return !!keypath; - }, - wrap: function (ractive, object, keypath) { - return new MagicWrapper(ractive, object, keypath); - } - }; - MagicWrapper = function (ractive, object, keypath) { - var wrapper = this, keys, prop, objKeypath, descriptor, wrappers, oldGet, oldSet, get, set; - this.ractive = ractive; - this.keypath = keypath; - keys = keypath.split('.'); - this.prop = keys.pop(); - objKeypath = keys.join('.'); - this.obj = objKeypath ? ractive.get(objKeypath) : ractive.data; - descriptor = this.originalDescriptor = Object.getOwnPropertyDescriptor(this.obj, this.prop); - if (descriptor && descriptor.set && (wrappers = descriptor.set._ractiveWrappers)) { - if (wrappers.indexOf(this) === -1) { - wrappers.push(this); - } - return; - } - if (descriptor && !descriptor.configurable) { - throw new Error('Cannot use magic mode with property "' + prop + '" - object is not configurable'); - } - if (descriptor) { - this.value = descriptor.value; - oldGet = descriptor.get; - oldSet = descriptor.set; - } - get = oldGet || function () { - return wrapper.value; - }; - set = function (value) { - var wrappers, wrapper, i; - if (oldSet) { - oldSet(value); - } - wrappers = set._ractiveWrappers; - i = wrappers.length; - while (i--) { - wrapper = wrappers[i]; - if (!wrapper.resetting) { - wrapper.ractive.set(wrapper.keypath, value); - } - } - }; - set._ractiveWrappers = [this]; - Object.defineProperty(this.obj, this.prop, { - get: get, - set: set, - enumerable: true, - configurable: true - }); - }; - MagicWrapper.prototype = { - get: function () { - return this.value; - }, - reset: function (value) { - this.resetting = true; - this.value = value; - this.resetting = false; - }, - teardown: function () { - var descriptor, set, value, wrappers; - descriptor = Object.getOwnPropertyDescriptor(this.obj, this.prop); - set = descriptor.set; - wrappers = set._ractiveWrappers; - wrappers.splice(wrappers.indexOf(this), 1); - if (!wrappers.length) { - value = this.obj[this.prop]; - Object.defineProperty(this.obj, this.prop, this.originalDescriptor || { - writable: true, - enumerable: true, - configrable: true - }); - this.obj[this.prop] = value; - } - } - }; - return magicAdaptor; - }(); -var shared_adaptIfNecessary = function (adaptorRegistry, arrayAdaptor, magicAdaptor) { - - var prefixers = {}; - return function (ractive, keypath, value, isExpressionResult) { - var len, i, adaptor, wrapped; - len = ractive.adaptors.length; - for (i = 0; i < len; i += 1) { - adaptor = ractive.adaptors[i]; - if (typeof adaptor === 'string') { - if (!adaptorRegistry[adaptor]) { - throw new Error('Missing adaptor "' + adaptor + '"'); - } - adaptor = ractive.adaptors[i] = adaptorRegistry[adaptor]; - } - if (adaptor.filter(value, keypath, ractive)) { - wrapped = ractive._wrapped[keypath] = adaptor.wrap(ractive, value, keypath, getPrefixer(keypath)); - wrapped.value = value; - return; - } - } - if (!isExpressionResult) { - if (ractive.magic && magicAdaptor.filter(value, keypath, ractive)) { - ractive._wrapped[keypath] = magicAdaptor.wrap(ractive, value, keypath); - } else if (ractive.modifyArrays && arrayAdaptor.filter(value, keypath, ractive)) { - ractive._wrapped[keypath] = arrayAdaptor.wrap(ractive, value, keypath); - } - } - }; - function prefixKeypath(obj, prefix) { - var prefixed = {}, key; - if (!prefix) { - return obj; - } - prefix += '.'; - for (key in obj) { - if (obj.hasOwnProperty(key)) { - prefixed[prefix + key] = obj[key]; - } - } - return prefixed; - } - function getPrefixer(rootKeypath) { - var rootDot; - if (!prefixers[rootKeypath]) { - rootDot = rootKeypath ? rootKeypath + '.' : ''; - prefixers[rootKeypath] = function (relativeKeypath, value) { - var obj; - if (typeof relativeKeypath === 'string') { - obj = {}; - obj[rootDot + relativeKeypath] = value; - return obj; - } - if (typeof relativeKeypath === 'object') { - return rootDot ? prefixKeypath(relativeKeypath, rootKeypath) : relativeKeypath; - } - }; - } - return prefixers[rootKeypath]; - } - }(registries_adaptors, Ractive_prototype_get_arrayAdaptor, Ractive_prototype_get_magicAdaptor); -var Ractive_prototype_get__get = function (normaliseKeypath, adaptorRegistry, adaptIfNecessary) { - - var get, _get, retrieve; - get = function (keypath) { - if (this._captured && !this._captured[keypath]) { - this._captured.push(keypath); - this._captured[keypath] = true; - } - return _get(this, keypath); - }; - _get = function (ractive, keypath) { - var cache, cached, value, wrapped, evaluator; - keypath = normaliseKeypath(keypath); - cache = ractive._cache; - if ((cached = cache[keypath]) !== undefined) { - return cached; - } - if (wrapped = ractive._wrapped[keypath]) { - value = wrapped.value; - } else if (!keypath) { - adaptIfNecessary(ractive, '', ractive.data); - value = ractive.data; - } else if (evaluator = ractive._evaluators[keypath]) { - value = evaluator.value; - } else { - value = retrieve(ractive, keypath); - } - cache[keypath] = value; - return value; - }; - retrieve = function (ractive, keypath) { - var keys, key, parentKeypath, parentValue, cacheMap, value, wrapped; - keys = keypath.split('.'); - key = keys.pop(); - parentKeypath = keys.join('.'); - parentValue = _get(ractive, parentKeypath); - if (wrapped = ractive._wrapped[parentKeypath]) { - parentValue = wrapped.get(); - } - if (parentValue === null || parentValue === undefined) { - return; - } - if (!(cacheMap = ractive._cacheMap[parentKeypath])) { - ractive._cacheMap[parentKeypath] = [keypath]; - } else { - if (cacheMap.indexOf(keypath) === -1) { - cacheMap[cacheMap.length] = keypath; - } - } - value = parentValue[key]; - adaptIfNecessary(ractive, keypath, value); - ractive._cache[keypath] = value; - return value; - }; - return get; - }(utils_normaliseKeypath, registries_adaptors, shared_adaptIfNecessary); -var utils_isObject = function () { - - var toString = Object.prototype.toString; - return function (thing) { - return typeof thing === 'object' && toString.call(thing) === '[object Object]'; - }; - }(); -var utils_isEqual = function () { - - return function (a, b) { - if (a === null && b === null) { - return true; - } - if (typeof a === 'object' || typeof b === 'object') { - return false; - } - return a === b; - }; - }(); -var shared_resolveRef = function () { - - var resolveRef; - resolveRef = function (ractive, ref, contextStack) { - var keypath, keys, lastKey, contextKeys, innerMostContext, postfix, parentKeypath, parentValue, wrapped, context, ancestorErrorMessage; - ancestorErrorMessage = 'Could not resolve reference - too many "../" prefixes'; - if (ref === '.') { - if (!contextStack.length) { - return ''; - } - keypath = contextStack[contextStack.length - 1]; - } else if (ref.charAt(0) === '.') { - context = contextStack[contextStack.length - 1]; - contextKeys = context ? context.split('.') : []; - if (ref.substr(0, 3) === '../') { - while (ref.substr(0, 3) === '../') { - if (!contextKeys.length) { - throw new Error(ancestorErrorMessage); - } - contextKeys.pop(); - ref = ref.substring(3); - } - contextKeys.push(ref); - keypath = contextKeys.join('.'); - } else if (!context) { - keypath = ref.substring(1); - } else { - keypath = context + ref; - } - } else { - keys = ref.split('.'); - lastKey = keys.pop(); - postfix = keys.length ? '.' + keys.join('.') : ''; - contextStack = contextStack.concat(); - while (contextStack.length) { - innerMostContext = contextStack.pop(); - parentKeypath = innerMostContext + postfix; - parentValue = ractive.get(parentKeypath); - if (wrapped = ractive._wrapped[parentKeypath]) { - parentValue = wrapped.get(); - } - if (typeof parentValue === 'object' && parentValue !== null && parentValue.hasOwnProperty(lastKey)) { - keypath = innerMostContext + '.' + ref; - break; - } - } - if (!keypath && ractive.get(ref) !== undefined) { - keypath = ref; - } - } - return keypath ? keypath.replace(/^\./, '') : keypath; - }; - return resolveRef; - }(); -var shared_attemptKeypathResolution = function (resolveRef) { - - var push = Array.prototype.push; - return function (ractive) { - var unresolved, keypath, leftover; - while (unresolved = ractive._pendingResolution.pop()) { - keypath = resolveRef(ractive, unresolved.ref, unresolved.contextStack); - if (keypath !== undefined) { - unresolved.resolve(keypath); - } else { - (leftover || (leftover = [])).push(unresolved); - } - } - if (leftover) { - push.apply(ractive._pendingResolution, leftover); - } - }; - }(shared_resolveRef); -var shared_processDeferredUpdates = function (preDomUpdate, postDomUpdate) { - - return function (ractive) { - preDomUpdate(ractive); - postDomUpdate(ractive); - }; - }(shared_preDomUpdate, shared_postDomUpdate); -var Ractive_prototype_shared_replaceData = function () { - - return function (ractive, keypath, value) { - var keys, accumulated, wrapped, obj, key, currentKeypath, keypathToClear; - keys = keypath.split('.'); - accumulated = []; - if (wrapped = ractive._wrapped['']) { - if (wrapped.set) { - wrapped.set(keys.join('.'), value); - } - obj = wrapped.get(); - } else { - obj = ractive.data; - } - while (keys.length > 1) { - key = accumulated[accumulated.length] = keys.shift(); - currentKeypath = accumulated.join('.'); - if (wrapped = ractive._wrapped[currentKeypath]) { - if (wrapped.set) { - wrapped.set(keys.join('.'), value); - } - obj = wrapped.get(); - } else { - if (!obj.hasOwnProperty(key)) { - if (!keypathToClear) { - keypathToClear = currentKeypath; - } - obj[key] = /^\s*[0-9]+\s*$/.test(keys[0]) ? [] : {}; - } - obj = obj[key]; - } - } - key = keys[0]; - obj[key] = value; - return keypathToClear; - }; - }(); -var Ractive_prototype_set = function (isObject, isEqual, normaliseKeypath, clearCache, notifyDependants, attemptKeypathResolution, makeTransitionManager, processDeferredUpdates, replaceData) { - - var set, updateModel, getUpstreamChanges, resetWrapped; - set = function (keypath, value, complete) { - var map, changes, upstreamChanges, previousTransitionManager, transitionManager, i, changeHash; - changes = []; - if (isObject(keypath)) { - map = keypath; - complete = value; - } - if (map) { - for (keypath in map) { - if (map.hasOwnProperty(keypath)) { - value = map[keypath]; - keypath = normaliseKeypath(keypath); - updateModel(this, keypath, value, changes); - } - } - } else { - keypath = normaliseKeypath(keypath); - updateModel(this, keypath, value, changes); - } - if (!changes.length) { - return; - } - previousTransitionManager = this._transitionManager; - this._transitionManager = transitionManager = makeTransitionManager(this, complete); - upstreamChanges = getUpstreamChanges(changes); - if (upstreamChanges.length) { - notifyDependants.multiple(this, upstreamChanges, true); - } - notifyDependants.multiple(this, changes); - if (this._pendingResolution.length) { - attemptKeypathResolution(this); - } - processDeferredUpdates(this); - this._transitionManager = previousTransitionManager; - transitionManager.ready(); - if (!this.firingChangeEvent) { - this.firingChangeEvent = true; - changeHash = {}; - i = changes.length; - while (i--) { - changeHash[changes[i]] = this.get(changes[i]); - } - this.fire('change', changeHash); - this.firingChangeEvent = false; - } - return this; - }; - updateModel = function (ractive, keypath, value, changes) { - var cached, previous, wrapped, keypathToClear, evaluator; - if ((wrapped = ractive._wrapped[keypath]) && wrapped.reset) { - if (resetWrapped(ractive, keypath, value, wrapped, changes) !== false) { - return; - } - } - if (evaluator = ractive._evaluators[keypath]) { - evaluator.value = value; - } - cached = ractive._cache[keypath]; - previous = ractive.get(keypath); - if (previous !== value && !evaluator) { - keypathToClear = replaceData(ractive, keypath, value); - } else { - if (value === cached && typeof value !== 'object') { - return; - } - } - clearCache(ractive, keypathToClear || keypath); - changes[changes.length] = keypath; - }; - getUpstreamChanges = function (changes) { - var upstreamChanges = [''], i, keypath, keys, upstreamKeypath; - i = changes.length; - while (i--) { - keypath = changes[i]; - keys = keypath.split('.'); - while (keys.length > 1) { - keys.pop(); - upstreamKeypath = keys.join('.'); - if (!upstreamChanges[upstreamKeypath]) { - upstreamChanges[upstreamChanges.length] = upstreamKeypath; - upstreamChanges[upstreamKeypath] = true; - } - } - } - return upstreamChanges; - }; - resetWrapped = function (ractive, keypath, value, wrapped, changes) { - var previous, cached, cacheMap, i; - previous = wrapped.get(); - if (!isEqual(previous, value)) { - if (wrapped.reset(value) === false) { - return false; - } - } - value = wrapped.get(); - cached = ractive._cache[keypath]; - if (!isEqual(cached, value)) { - ractive._cache[keypath] = value; - cacheMap = ractive._cacheMap[keypath]; - if (cacheMap) { - i = cacheMap.length; - while (i--) { - clearCache(ractive, cacheMap[i]); - } - } - changes[changes.length] = keypath; - } - }; - return set; - }(utils_isObject, utils_isEqual, utils_normaliseKeypath, shared_clearCache, shared_notifyDependants, shared_attemptKeypathResolution, shared_makeTransitionManager, shared_processDeferredUpdates, Ractive_prototype_shared_replaceData); -var Ractive_prototype_update = function (makeTransitionManager, attemptKeypathResolution, clearCache, notifyDependants, processDeferredUpdates) { - - return function (keypath, complete) { - var transitionManager, previousTransitionManager; - if (typeof keypath === 'function') { - complete = keypath; - keypath = ''; - } - previousTransitionManager = this._transitionManager; - this._transitionManager = transitionManager = makeTransitionManager(this, complete); - attemptKeypathResolution(this); - clearCache(this, keypath || ''); - notifyDependants(this, keypath || ''); - processDeferredUpdates(this); - this._transitionManager = previousTransitionManager; - transitionManager.ready(); - if (typeof keypath === 'string') { - this.fire('update', keypath); - } else { - this.fire('update'); - } - return this; - }; - }(shared_makeTransitionManager, shared_attemptKeypathResolution, shared_clearCache, shared_notifyDependants, shared_processDeferredUpdates); -var utils_arrayContentsMatch = function (isArray) { - - return function (a, b) { - var i; - if (!isArray(a) || !isArray(b)) { - return false; - } - if (a.length !== b.length) { - return false; - } - i = a.length; - while (i--) { - if (a[i] !== b[i]) { - return false; - } - } - return true; - }; - }(utils_isArray); -var Ractive_prototype_updateModel = function (getValueFromCheckboxes, arrayContentsMatch, isEqual) { - - return function (keypath, cascade) { - var values, deferredCheckboxes, i; - if (typeof keypath !== 'string') { - keypath = ''; - cascade = true; - } - consolidateChangedValues(this, keypath, values = {}, deferredCheckboxes = [], cascade); - if (i = deferredCheckboxes.length) { - while (i--) { - keypath = deferredCheckboxes[i]; - values[keypath] = getValueFromCheckboxes(this, keypath); - } - } - this.set(values); - }; - function consolidateChangedValues(ractive, keypath, values, deferredCheckboxes, cascade) { - var bindings, childDeps, i, binding, oldValue, newValue; - bindings = ractive._twowayBindings[keypath]; - if (bindings) { - i = bindings.length; - while (i--) { - binding = bindings[i]; - if (binding.radioName && !binding.node.checked) { - continue; - } - if (binding.checkboxName) { - if (binding.changed() && !deferredCheckboxes[keypath]) { - deferredCheckboxes[keypath] = true; - deferredCheckboxes[deferredCheckboxes.length] = keypath; - } - continue; - } - oldValue = binding.attr.value; - newValue = binding.value(); - if (arrayContentsMatch(oldValue, newValue)) { - continue; - } - if (!isEqual(oldValue, newValue)) { - values[keypath] = newValue; - } - } - } - if (!cascade) { - return; - } - childDeps = ractive._depsMap[keypath]; - if (childDeps) { - i = childDeps.length; - while (i--) { - consolidateChangedValues(ractive, childDeps[i], values, deferredCheckboxes, cascade); - } - } - } - }(shared_getValueFromCheckboxes, utils_arrayContentsMatch, utils_isEqual); -var Ractive_prototype_animate_requestAnimationFrame = function () { - - if (typeof window === 'undefined') { - return; - } - (function (vendors, lastTime, window) { - var x, setTimeout; - if (window.requestAnimationFrame) { - return; - } - for (x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { - window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame']; - } - if (!window.requestAnimationFrame) { - setTimeout = window.setTimeout; - window.requestAnimationFrame = function (callback) { - var currTime, timeToCall, id; - currTime = Date.now(); - timeToCall = Math.max(0, 16 - (currTime - lastTime)); - id = setTimeout(function () { - callback(currTime + timeToCall); - }, timeToCall); - lastTime = currTime + timeToCall; - return id; - }; - } - }([ - 'ms', - 'moz', - 'webkit', - 'o' - ], 0, window)); - return window.requestAnimationFrame; - }(); -var Ractive_prototype_animate_animations = function (rAF) { - - var queue = []; - var animations = { - tick: function () { - var i, animation; - for (i = 0; i < queue.length; i += 1) { - animation = queue[i]; - if (!animation.tick()) { - queue.splice(i--, 1); - } - } - if (queue.length) { - rAF(animations.tick); - } else { - animations.running = false; - } - }, - add: function (animation) { - queue[queue.length] = animation; - if (!animations.running) { - animations.running = true; - animations.tick(); - } - }, - abort: function (keypath, root) { - var i = queue.length, animation; - while (i--) { - animation = queue[i]; - if (animation.root === root && animation.keypath === keypath) { - animation.stop(); - } - } - } - }; - return animations; - }(Ractive_prototype_animate_requestAnimationFrame); -var utils_warn = function () { - - if (typeof console !== 'undefined' && typeof console.warn === 'function' && typeof console.warn.apply === 'function') { - return function () { - console.warn.apply(console, arguments); - }; - } - return function () { - }; - }(); -var utils_isNumeric = function () { - - return function (thing) { - return !isNaN(parseFloat(thing)) && isFinite(thing); - }; - }(); -var shared_interpolate = function (isArray, isObject, isNumeric) { - - var interpolate = function (from, to) { - if (isNumeric(from) && isNumeric(to)) { - return makeNumberInterpolator(+from, +to); - } - if (isArray(from) && isArray(to)) { - return makeArrayInterpolator(from, to); - } - if (isObject(from) && isObject(to)) { - return makeObjectInterpolator(from, to); - } - return function () { - return to; - }; - }; - return interpolate; - function makeNumberInterpolator(from, to) { - var delta = to - from; - if (!delta) { - return function () { - return from; - }; - } - return function (t) { - return from + t * delta; - }; - } - function makeArrayInterpolator(from, to) { - var intermediate, interpolators, len, i; - intermediate = []; - interpolators = []; - i = len = Math.min(from.length, to.length); - while (i--) { - interpolators[i] = interpolate(from[i], to[i]); - } - for (i = len; i < from.length; i += 1) { - intermediate[i] = from[i]; - } - for (i = len; i < to.length; i += 1) { - intermediate[i] = to[i]; - } - return function (t) { - var i = len; - while (i--) { - intermediate[i] = interpolators[i](t); - } - return intermediate; - }; - } - function makeObjectInterpolator(from, to) { - var properties = [], len, interpolators, intermediate, prop; - intermediate = {}; - interpolators = {}; - for (prop in from) { - if (from.hasOwnProperty(prop)) { - if (to.hasOwnProperty(prop)) { - properties[properties.length] = prop; - interpolators[prop] = interpolate(from[prop], to[prop]); - } else { - intermediate[prop] = from[prop]; - } - } - } - for (prop in to) { - if (to.hasOwnProperty(prop) && !from.hasOwnProperty(prop)) { - intermediate[prop] = to[prop]; - } - } - len = properties.length; - return function (t) { - var i = len, prop; - while (i--) { - prop = properties[i]; - intermediate[prop] = interpolators[prop](t); - } - return intermediate; - }; - } - }(utils_isArray, utils_isObject, utils_isNumeric); -var Ractive_prototype_animate_Animation = function (warn, interpolate) { - - var Animation = function (options) { - var key; - this.startTime = Date.now(); - for (key in options) { - if (options.hasOwnProperty(key)) { - this[key] = options[key]; - } - } - this.interpolator = interpolate(this.from, this.to); - this.running = true; - }; - Animation.prototype = { - tick: function () { - var elapsed, t, value, timeNow, index, keypath; - keypath = this.keypath; - if (this.running) { - timeNow = Date.now(); - elapsed = timeNow - this.startTime; - if (elapsed >= this.duration) { - if (keypath !== null) { - this.root.set(keypath, this.to); - } - if (this.step) { - this.step(1, this.to); - } - if (this.complete) { - this.complete(1, this.to); - } - index = this.root._animations.indexOf(this); - if (index === -1) { - warn('Animation was not found'); - } - this.root._animations.splice(index, 1); - this.running = false; - return false; - } - t = this.easing ? this.easing(elapsed / this.duration) : elapsed / this.duration; - if (keypath !== null) { - value = this.interpolator(t); - this.root.set(keypath, value); - } - if (this.step) { - this.step(t, value); - } - return true; - } - return false; - }, - stop: function () { - var index; - this.running = false; - index = this.root._animations.indexOf(this); - if (index === -1) { - warn('Animation was not found'); - } - this.root._animations.splice(index, 1); - } - }; - return Animation; - }(utils_warn, shared_interpolate); -var registries_easing = function () { - - return { - linear: function (pos) { - return pos; - }, - easeIn: function (pos) { - return Math.pow(pos, 3); - }, - easeOut: function (pos) { - return Math.pow(pos - 1, 3) + 1; - }, - easeInOut: function (pos) { - if ((pos /= 0.5) < 1) { - return 0.5 * Math.pow(pos, 3); - } - return 0.5 * (Math.pow(pos - 2, 3) + 2); - } - }; - }(); -var Ractive_prototype_animate__animate = function (isEqual, animations, Animation, easingRegistry) { - - var noAnimation = { - stop: function () { - } - }; - return function (keypath, to, options) { - var k, animation, animations, easing, duration, step, complete, makeValueCollector, currentValues, collectValue, dummy, dummyOptions; - if (typeof keypath === 'object') { - options = to || {}; - easing = options.easing; - duration = options.duration; - animations = []; - step = options.step; - complete = options.complete; - if (step || complete) { - currentValues = {}; - options.step = null; - options.complete = null; - makeValueCollector = function (keypath) { - return function (t, value) { - currentValues[keypath] = value; - }; - }; - } - for (k in keypath) { - if (keypath.hasOwnProperty(k)) { - if (step || complete) { - collectValue = makeValueCollector(k); - options = { - easing: easing, - duration: duration - }; - if (step) { - options.step = collectValue; - } - if (complete) { - options.complete = collectValue; - } - } - animations[animations.length] = animate(this, k, keypath[k], options); - } - } - if (step || complete) { - dummyOptions = { - easing: easing, - duration: duration - }; - if (step) { - dummyOptions.step = function (t) { - step(t, currentValues); - }; - } - if (complete) { - dummyOptions.complete = function (t) { - complete(t, currentValues); - }; - } - animations[animations.length] = dummy = animate(this, null, null, dummyOptions); - } - return { - stop: function () { - while (animations.length) { - animations.pop().stop(); - } - if (dummy) { - dummy.stop(); - } - } - }; - } - options = options || {}; - animation = animate(this, keypath, to, options); - return { - stop: function () { - animation.stop(); - } - }; - }; - function animate(root, keypath, to, options) { - var easing, duration, animation, from; - if (keypath !== null) { - from = root.get(keypath); - } - animations.abort(keypath, root); - if (isEqual(from, to)) { - if (options.complete) { - options.complete(1, options.to); - } - return noAnimation; - } - if (options.easing) { - if (typeof options.easing === 'function') { - easing = options.easing; - } else { - if (root.easing && root.easing[options.easing]) { - easing = root.easing[options.easing]; - } else { - easing = easingRegistry[options.easing]; - } - } - if (typeof easing !== 'function') { - easing = null; - } - } - duration = options.duration === undefined ? 400 : options.duration; - animation = new Animation({ - keypath: keypath, - from: from, - to: to, - root: root, - duration: duration, - easing: easing, - step: options.step, - complete: options.complete - }); - animations.add(animation); - root._animations[root._animations.length] = animation; - return animation; - } - }(utils_isEqual, Ractive_prototype_animate_animations, Ractive_prototype_animate_Animation, registries_easing); -var Ractive_prototype_on = function () { - - return function (eventName, callback) { - var self = this, listeners, n; - if (typeof eventName === 'object') { - listeners = []; - for (n in eventName) { - if (eventName.hasOwnProperty(n)) { - listeners[listeners.length] = this.on(n, eventName[n]); - } - } - return { - cancel: function () { - while (listeners.length) { - listeners.pop().cancel(); - } - } - }; - } - if (!this._subs[eventName]) { - this._subs[eventName] = [callback]; - } else { - this._subs[eventName].push(callback); - } - return { - cancel: function () { - self.off(eventName, callback); - } - }; - }; - }(); -var Ractive_prototype_off = function () { - - return function (eventName, callback) { - var subscribers, index; - if (!callback) { - if (!eventName) { - for (eventName in this._subs) { - delete this._subs[eventName]; - } - } else { - this._subs[eventName] = []; - } - } - subscribers = this._subs[eventName]; - if (subscribers) { - index = subscribers.indexOf(callback); - if (index !== -1) { - subscribers.splice(index, 1); - } - } - }; - }(); -var shared_registerDependant = function () { - - return function (dependant) { - var depsByKeypath, deps, keys, parentKeypath, map, ractive, keypath, priority; - ractive = dependant.root; - keypath = dependant.keypath; - priority = dependant.priority; - depsByKeypath = ractive._deps[priority] || (ractive._deps[priority] = {}); - deps = depsByKeypath[keypath] || (depsByKeypath[keypath] = []); - deps[deps.length] = dependant; - dependant.registered = true; - if (!keypath) { - return; - } - keys = keypath.split('.'); - while (keys.length) { - keys.pop(); - parentKeypath = keys.join('.'); - map = ractive._depsMap[parentKeypath] || (ractive._depsMap[parentKeypath] = []); - if (map[keypath] === undefined) { - map[keypath] = 0; - map[map.length] = keypath; - } - map[keypath] += 1; - keypath = parentKeypath; - } - }; - }(); -var shared_unregisterDependant = function () { - - return function (dependant) { - var deps, index, keys, parentKeypath, map, ractive, keypath, priority; - ractive = dependant.root; - keypath = dependant.keypath; - priority = dependant.priority; - deps = ractive._deps[priority][keypath]; - index = deps.indexOf(dependant); - if (index === -1 || !dependant.registered) { - throw new Error('Attempted to remove a dependant that was no longer registered! This should not happen. If you are seeing this bug in development please raise an issue at https://github.com/RactiveJS/Ractive/issues - thanks'); - } - deps.splice(index, 1); - dependant.registered = false; - if (!keypath) { - return; - } - keys = keypath.split('.'); - while (keys.length) { - keys.pop(); - parentKeypath = keys.join('.'); - map = ractive._depsMap[parentKeypath]; - map[keypath] -= 1; - if (!map[keypath]) { - map.splice(map.indexOf(keypath), 1); - map[keypath] = undefined; - } - keypath = parentKeypath; - } - }; - }(); -var Ractive_prototype_observe_Observer = function (isEqual) { - - var Observer = function (ractive, keypath, callback, options) { - var self = this; - this.root = ractive; - this.keypath = keypath; - this.callback = callback; - this.defer = options.defer; - this.debug = options.debug; - this.proxy = { - update: function () { - self.reallyUpdate(); - } - }; - this.priority = 0; - this.context = options && options.context ? options.context : ractive; - }; - Observer.prototype = { - init: function (immediate) { - if (immediate !== false) { - this.update(); - } else { - this.value = this.root.get(this.keypath); - } - }, - update: function () { - if (this.defer && this.ready) { - this.root._deferred.observers.push(this.proxy); - return; - } - this.reallyUpdate(); - }, - reallyUpdate: function () { - var oldValue, newValue; - oldValue = this.value; - newValue = this.root.get(this.keypath); - this.value = newValue; - if (this.updating) { - return; - } - this.updating = true; - if (!isEqual(newValue, oldValue) || !this.ready) { - try { - this.callback.call(this.context, newValue, oldValue, this.keypath); - } catch (err) { - if (this.debug || this.root.debug) { - throw err; - } - } - } - this.updating = false; - } - }; - return Observer; - }(utils_isEqual); -var Ractive_prototype_observe_getPattern = function () { - - return function (ractive, pattern) { - var keys, key, values, toGet, newToGet, expand, concatenate; - keys = pattern.split('.'); - toGet = []; - expand = function (keypath) { - var value, key; - value = ractive._wrapped[keypath] ? ractive._wrapped[keypath].get() : ractive.get(keypath); - for (key in value) { - newToGet.push(keypath + '.' + key); - } - }; - concatenate = function (keypath) { - return keypath + '.' + key; - }; - while (key = keys.shift()) { - if (key === '*') { - newToGet = []; - toGet.forEach(expand); - toGet = newToGet; - } else { - if (!toGet[0]) { - toGet[0] = key; - } else { - toGet = toGet.map(concatenate); - } - } - } - values = {}; - toGet.forEach(function (keypath) { - values[keypath] = ractive.get(keypath); - }); - return values; - }; - }(); -var Ractive_prototype_observe_PatternObserver = function (isEqual, getPattern) { - - var PatternObserver, wildcard = /\*/; - PatternObserver = function (ractive, keypath, callback, options) { - this.root = ractive; - this.callback = callback; - this.defer = options.defer; - this.debug = options.debug; - this.keypath = keypath; - this.regex = new RegExp('^' + keypath.replace(/\./g, '\\.').replace(/\*/g, '[^\\.]+') + '$'); - this.values = {}; - if (this.defer) { - this.proxies = []; - } - this.priority = 'pattern'; - this.context = options && options.context ? options.context : ractive; - }; - PatternObserver.prototype = { - init: function (immediate) { - var values, keypath; - values = getPattern(this.root, this.keypath); - if (immediate !== false) { - for (keypath in values) { - if (values.hasOwnProperty(keypath)) { - this.update(keypath); - } - } - } else { - this.values = values; - } - }, - update: function (keypath) { - var values; - if (wildcard.test(keypath)) { - values = getPattern(this.root, keypath); - for (keypath in values) { - if (values.hasOwnProperty(keypath)) { - this.update(keypath); - } - } - return; - } - if (this.defer && this.ready) { - this.root._deferred.observers.push(this.getProxy(keypath)); - return; - } - this.reallyUpdate(keypath); - }, - reallyUpdate: function (keypath) { - var value = this.root.get(keypath); - if (this.updating) { - this.values[keypath] = value; - return; - } - this.updating = true; - if (!isEqual(value, this.values[keypath]) || !this.ready) { - try { - this.callback.call(this.context, value, this.values[keypath], keypath); - } catch (err) { - if (this.debug || this.root.debug) { - throw err; - } - } - this.values[keypath] = value; - } - this.updating = false; - }, - getProxy: function (keypath) { - var self = this; - if (!this.proxies[keypath]) { - this.proxies[keypath] = { - update: function () { - self.reallyUpdate(keypath); - } - }; - } - return this.proxies[keypath]; - } - }; - return PatternObserver; - }(utils_isEqual, Ractive_prototype_observe_getPattern); -var Ractive_prototype_observe_getObserverFacade = function (normaliseKeypath, registerDependant, unregisterDependant, Observer, PatternObserver) { - - var wildcard = /\*/, emptyObject = {}; - return function getObserverFacade(ractive, keypath, callback, options) { - var observer, isPatternObserver; - keypath = normaliseKeypath(keypath); - options = options || emptyObject; - if (wildcard.test(keypath)) { - observer = new PatternObserver(ractive, keypath, callback, options); - ractive._patternObservers.push(observer); - isPatternObserver = true; - } else { - observer = new Observer(ractive, keypath, callback, options); - } - registerDependant(observer); - observer.init(options.init); - observer.ready = true; - return { - cancel: function () { - var index; - if (isPatternObserver) { - index = ractive._patternObservers.indexOf(observer); - if (index !== -1) { - ractive._patternObservers.splice(index, 1); - } - } - unregisterDependant(observer); - } - }; - }; - }(utils_normaliseKeypath, shared_registerDependant, shared_unregisterDependant, Ractive_prototype_observe_Observer, Ractive_prototype_observe_PatternObserver); -var Ractive_prototype_observe__observe = function (isObject, getObserverFacade) { - - return function observe(keypath, callback, options) { - var observers = [], k; - if (isObject(keypath)) { - options = callback; - for (k in keypath) { - if (keypath.hasOwnProperty(k)) { - callback = keypath[k]; - observers[observers.length] = getObserverFacade(this, k, callback, options); - } - } - return { - cancel: function () { - while (observers.length) { - observers.pop().cancel(); - } - } - }; - } - return getObserverFacade(this, keypath, callback, options); - }; - }(utils_isObject, Ractive_prototype_observe_getObserverFacade); -var Ractive_prototype_fire = function () { - - return function (eventName) { - var args, i, len, subscribers = this._subs[eventName]; - if (!subscribers) { - return; - } - args = Array.prototype.slice.call(arguments, 1); - for (i = 0, len = subscribers.length; i < len; i += 1) { - subscribers[i].apply(this, args); - } - }; - }(); -var Ractive_prototype_find = function () { - - return function (selector) { - if (!this.el) { - return null; - } - return this.fragment.find(selector); - }; - }(); -var utils_matches = function (isClient, createElement) { - - var div, methodNames, unprefixed, prefixed, vendors, i, j, makeFunction; - if (!isClient) { - return; - } - div = createElement('div'); - methodNames = [ - 'matches', - 'matchesSelector' - ]; - vendors = [ - 'o', - 'ms', - 'moz', - 'webkit' - ]; - makeFunction = function (methodName) { - return function (node, selector) { - return node[methodName](selector); - }; - }; - i = methodNames.length; - while (i--) { - unprefixed = methodNames[i]; - if (div[unprefixed]) { - return makeFunction(unprefixed); - } - j = vendors.length; - while (j--) { - prefixed = vendors[i] + unprefixed.substr(0, 1).toUpperCase() + unprefixed.substring(1); - if (div[prefixed]) { - return makeFunction(prefixed); - } - } - } - return function (node, selector) { - var nodes, i; - nodes = (node.parentNode || node.document).querySelectorAll(selector); - i = nodes.length; - while (i--) { - if (nodes[i] === node) { - return true; - } - } - return false; - }; - }(config_isClient, utils_createElement); -var Ractive_prototype_shared_makeQuery_test = function (matches) { - - return function (item, noDirty) { - var itemMatches = this._isComponentQuery ? !this.selector || item.name === this.selector : matches(item.node, this.selector); - if (itemMatches) { - this.push(item.node || item.instance); - if (!noDirty) { - this._makeDirty(); - } - return true; - } - }; - }(utils_matches); -var Ractive_prototype_shared_makeQuery_cancel = function () { - - return function () { - var liveQueries, selector, index; - liveQueries = this._root[this._isComponentQuery ? 'liveComponentQueries' : 'liveQueries']; - selector = this.selector; - index = liveQueries.indexOf(selector); - if (index !== -1) { - liveQueries.splice(index, 1); - liveQueries[selector] = null; - } - }; - }(); -var Ractive_prototype_shared_makeQuery_sortByItemPosition = function () { - - return function (a, b) { - var ancestryA, ancestryB, oldestA, oldestB, mutualAncestor, indexA, indexB, fragments, fragmentA, fragmentB; - ancestryA = getAncestry(a.component || a._ractive.proxy); - ancestryB = getAncestry(b.component || b._ractive.proxy); - oldestA = ancestryA[ancestryA.length - 1]; - oldestB = ancestryB[ancestryB.length - 1]; - while (oldestA && oldestA === oldestB) { - ancestryA.pop(); - ancestryB.pop(); - mutualAncestor = oldestA; - oldestA = ancestryA[ancestryA.length - 1]; - oldestB = ancestryB[ancestryB.length - 1]; - } - oldestA = oldestA.component || oldestA; - oldestB = oldestB.component || oldestB; - fragmentA = oldestA.parentFragment; - fragmentB = oldestB.parentFragment; - if (fragmentA === fragmentB) { - indexA = fragmentA.items.indexOf(oldestA); - indexB = fragmentB.items.indexOf(oldestB); - return indexA - indexB || ancestryA.length - ancestryB.length; - } - if (fragments = mutualAncestor.fragments) { - indexA = fragments.indexOf(fragmentA); - indexB = fragments.indexOf(fragmentB); - return indexA - indexB || ancestryA.length - ancestryB.length; - } - throw new Error('An unexpected condition was met while comparing the position of two components. Please file an issue at https://github.com/RactiveJS/Ractive/issues - thanks!'); - }; - function getParent(item) { - var parentFragment; - if (parentFragment = item.parentFragment) { - return parentFragment.owner; - } - if (item.component && (parentFragment = item.component.parentFragment)) { - return parentFragment.owner; - } - } - function getAncestry(item) { - var ancestry, ancestor; - ancestry = [item]; - ancestor = getParent(item); - while (ancestor) { - ancestry.push(ancestor); - ancestor = getParent(ancestor); - } - return ancestry; - } - }(); -var Ractive_prototype_shared_makeQuery_sortByDocumentPosition = function (sortByItemPosition) { - - return function (node, otherNode) { - var bitmask; - if (node.compareDocumentPosition) { - bitmask = node.compareDocumentPosition(otherNode); - return bitmask & 2 ? 1 : -1; - } - return sortByItemPosition(node, otherNode); - }; - }(Ractive_prototype_shared_makeQuery_sortByItemPosition); -var Ractive_prototype_shared_makeQuery_sort = function (sortByDocumentPosition, sortByItemPosition) { - - return function () { - this.sort(this._isComponentQuery ? sortByItemPosition : sortByDocumentPosition); - this._dirty = false; - }; - }(Ractive_prototype_shared_makeQuery_sortByDocumentPosition, Ractive_prototype_shared_makeQuery_sortByItemPosition); -var Ractive_prototype_shared_makeQuery_dirty = function () { - - return function () { - if (!this._dirty) { - this._root._deferred.liveQueries.push(this); - this._dirty = true; - } - }; - }(); -var Ractive_prototype_shared_makeQuery_remove = function () { - - return function (item) { - var index = this.indexOf(this._isComponentQuery ? item.instance : item.node); - if (index !== -1) { - this.splice(index, 1); - } - }; - }(); -var Ractive_prototype_shared_makeQuery__makeQuery = function (defineProperties, test, cancel, sort, dirty, remove) { - - return function (ractive, selector, live, isComponentQuery) { - var query; - query = []; - defineProperties(query, { - selector: { value: selector }, - live: { value: live }, - _isComponentQuery: { value: isComponentQuery }, - _test: { value: test } - }); - if (!live) { - return query; - } - defineProperties(query, { - cancel: { value: cancel }, - _root: { value: ractive }, - _sort: { value: sort }, - _makeDirty: { value: dirty }, - _remove: { value: remove }, - _dirty: { - value: false, - writable: true - } - }); - return query; - }; - }(utils_defineProperties, Ractive_prototype_shared_makeQuery_test, Ractive_prototype_shared_makeQuery_cancel, Ractive_prototype_shared_makeQuery_sort, Ractive_prototype_shared_makeQuery_dirty, Ractive_prototype_shared_makeQuery_remove); -var Ractive_prototype_findAll = function (warn, matches, defineProperties, makeQuery) { - - return function (selector, options) { - var liveQueries, query; - if (!this.el) { - return []; - } - options = options || {}; - liveQueries = this._liveQueries; - if (query = liveQueries[selector]) { - return options && options.live ? query : query.slice(); - } - query = makeQuery(this, selector, !!options.live, false); - if (query.live) { - liveQueries.push(selector); - liveQueries[selector] = query; - } - this.fragment.findAll(selector, query); - return query; - }; - }(utils_warn, utils_matches, utils_defineProperties, Ractive_prototype_shared_makeQuery__makeQuery); -var Ractive_prototype_findComponent = function () { - - return function (selector) { - return this.fragment.findComponent(selector); - }; - }(); -var Ractive_prototype_findAllComponents = function (warn, matches, defineProperties, makeQuery) { - - return function (selector, options) { - var liveQueries, query; - options = options || {}; - liveQueries = this._liveComponentQueries; - if (query = liveQueries[selector]) { - return options && options.live ? query : query.slice(); - } - query = makeQuery(this, selector, !!options.live, true); - if (query.live) { - liveQueries.push(selector); - liveQueries[selector] = query; - } - this.fragment.findAllComponents(selector, query); - return query; - }; - }(utils_warn, utils_matches, utils_defineProperties, Ractive_prototype_shared_makeQuery__makeQuery); -var utils_getElement = function () { - - return function (input) { - var output; - if (typeof window === 'undefined' || !document || !input) { - return null; - } - if (input.nodeType) { - return input; - } - if (typeof input === 'string') { - output = document.getElementById(input); - if (!output && document.querySelector) { - output = document.querySelector(input); - } - if (output && output.nodeType) { - return output; - } - } - if (input[0] && input[0].nodeType) { - return input[0]; - } - return null; - }; - }(); -var render_shared_initFragment = function (types, create) { - - return function (fragment, options) { - var numItems, i, parentFragment, parentRefs, ref; - fragment.owner = options.owner; - parentFragment = fragment.owner.parentFragment; - fragment.root = options.root; - fragment.pNode = options.pNode; - fragment.contextStack = options.contextStack || []; - if (fragment.owner.type === types.SECTION) { - fragment.index = options.index; - } - if (parentFragment) { - parentRefs = parentFragment.indexRefs; - if (parentRefs) { - fragment.indexRefs = create(null); - for (ref in parentRefs) { - fragment.indexRefs[ref] = parentRefs[ref]; - } - } - } - fragment.priority = parentFragment ? parentFragment.priority + 1 : 1; - if (options.indexRef) { - if (!fragment.indexRefs) { - fragment.indexRefs = {}; - } - fragment.indexRefs[options.indexRef] = options.index; - } - fragment.items = []; - numItems = options.descriptor ? options.descriptor.length : 0; - for (i = 0; i < numItems; i += 1) { - fragment.items[fragment.items.length] = fragment.createItem({ - parentFragment: fragment, - descriptor: options.descriptor[i], - index: i - }); - } - }; - }(config_types, utils_create); -var render_DomFragment_shared_insertHtml = function (createElement) { - - var elementCache = {}; - return function (html, tagName, docFrag) { - var container, nodes = []; - if (html) { - container = elementCache[tagName] || (elementCache[tagName] = createElement(tagName)); - container.innerHTML = html; - while (container.firstChild) { - nodes[nodes.length] = container.firstChild; - docFrag.appendChild(container.firstChild); - } - } - return nodes; - }; - }(utils_createElement); -var render_DomFragment_Text = function (types) { - - var DomText, lessThan, greaterThan; - lessThan = //g; - DomText = function (options, docFrag) { - this.type = types.TEXT; - this.descriptor = options.descriptor; - if (docFrag) { - this.node = document.createTextNode(options.descriptor); - docFrag.appendChild(this.node); - } - }; - DomText.prototype = { - detach: function () { - this.node.parentNode.removeChild(this.node); - return this.node; - }, - teardown: function (destroy) { - if (destroy) { - this.detach(); - } - }, - firstNode: function () { - return this.node; - }, - toString: function () { - return ('' + this.descriptor).replace(lessThan, '<').replace(greaterThan, '>'); - } - }; - return DomText; - }(config_types); -var shared_teardown = function (unregisterDependant) { - - return function (thing) { - if (!thing.keypath) { - var index = thing.root._pendingResolution.indexOf(thing); - if (index !== -1) { - thing.root._pendingResolution.splice(index, 1); - } - } else { - unregisterDependant(thing); - } - }; - }(shared_unregisterDependant); -var render_shared_Evaluator_Reference = function (types, isEqual, defineProperty, registerDependant, unregisterDependant) { - - var Reference, thisPattern; - thisPattern = /this/; - Reference = function (root, keypath, evaluator, argNum, priority) { - var value; - this.evaluator = evaluator; - this.keypath = keypath; - this.root = root; - this.argNum = argNum; - this.type = types.REFERENCE; - this.priority = priority; - value = root.get(keypath); - if (typeof value === 'function') { - value = wrapFunction(value, root, evaluator); - } - this.value = evaluator.values[argNum] = value; - registerDependant(this); - }; - Reference.prototype = { - update: function () { - var value = this.root.get(this.keypath); - if (typeof value === 'function' && !value._nowrap) { - value = wrapFunction(value, this.root, this.evaluator); - } - if (!isEqual(value, this.value)) { - this.evaluator.values[this.argNum] = value; - this.evaluator.bubble(); - this.value = value; - } - }, - teardown: function () { - unregisterDependant(this); - } - }; - return Reference; - function wrapFunction(fn, ractive, evaluator) { - var prop, evaluators, index; - if (!thisPattern.test(fn.toString())) { - defineProperty(fn, '_nowrap', { value: true }); - return fn; - } - if (!fn['_' + ractive._guid]) { - defineProperty(fn, '_' + ractive._guid, { - value: function () { - var originalCaptured, result, i, evaluator; - originalCaptured = ractive._captured; - if (!originalCaptured) { - ractive._captured = []; - } - result = fn.apply(ractive, arguments); - if (ractive._captured.length) { - i = evaluators.length; - while (i--) { - evaluator = evaluators[i]; - evaluator.updateSoftDependencies(ractive._captured); - } - } - ractive._captured = originalCaptured; - return result; - }, - writable: true - }); - for (prop in fn) { - if (fn.hasOwnProperty(prop)) { - fn['_' + ractive._guid][prop] = fn[prop]; - } - } - fn['_' + ractive._guid + '_evaluators'] = []; - } - evaluators = fn['_' + ractive._guid + '_evaluators']; - index = evaluators.indexOf(evaluator); - if (index === -1) { - evaluators.push(evaluator); - } - return fn['_' + ractive._guid]; - } - }(config_types, utils_isEqual, utils_defineProperty, shared_registerDependant, shared_unregisterDependant); -var render_shared_Evaluator_SoftReference = function (isEqual, registerDependant, unregisterDependant) { - - var SoftReference = function (root, keypath, evaluator) { - this.root = root; - this.keypath = keypath; - this.priority = evaluator.priority; - this.evaluator = evaluator; - registerDependant(this); - }; - SoftReference.prototype = { - update: function () { - var value = this.root.get(this.keypath); - if (!isEqual(value, this.value)) { - this.evaluator.bubble(); - this.value = value; - } - }, - teardown: function () { - unregisterDependant(this); - } - }; - return SoftReference; - }(utils_isEqual, shared_registerDependant, shared_unregisterDependant); -var render_shared_Evaluator__Evaluator = function (isEqual, defineProperty, clearCache, notifyDependants, registerDependant, unregisterDependant, adaptIfNecessary, Reference, SoftReference) { - - var Evaluator, cache = {}; - Evaluator = function (root, keypath, functionStr, args, priority) { - var i, arg; - this.root = root; - this.keypath = keypath; - this.priority = priority; - this.fn = getFunctionFromString(functionStr, args.length); - this.values = []; - this.refs = []; - i = args.length; - while (i--) { - if (arg = args[i]) { - if (arg[0]) { - this.values[i] = arg[1]; - } else { - this.refs[this.refs.length] = new Reference(root, arg[1], this, i, priority); - } - } else { - this.values[i] = undefined; - } - } - this.selfUpdating = this.refs.length <= 1; - this.update(); - }; - Evaluator.prototype = { - bubble: function () { - if (this.selfUpdating) { - this.update(); - } else if (!this.deferred) { - this.root._deferred.evals.push(this); - this.deferred = true; - } - }, - update: function () { - var value; - if (this.evaluating) { - return this; - } - this.evaluating = true; - try { - value = this.fn.apply(null, this.values); - } catch (err) { - if (this.root.debug) { - throw err; - } else { - value = undefined; - } - } - if (!isEqual(value, this.value)) { - clearCache(this.root, this.keypath); - this.root._cache[this.keypath] = value; - adaptIfNecessary(this.root, this.keypath, value, true); - this.value = value; - notifyDependants(this.root, this.keypath); - } - this.evaluating = false; - return this; - }, - teardown: function () { - while (this.refs.length) { - this.refs.pop().teardown(); - } - clearCache(this.root, this.keypath); - this.root._evaluators[this.keypath] = null; - }, - refresh: function () { - if (!this.selfUpdating) { - this.deferred = true; - } - var i = this.refs.length; - while (i--) { - this.refs[i].update(); - } - if (this.deferred) { - this.update(); - this.deferred = false; - } - }, - updateSoftDependencies: function (softDeps) { - var i, keypath, ref; - if (!this.softRefs) { - this.softRefs = []; - } - i = this.softRefs.length; - while (i--) { - ref = this.softRefs[i]; - if (!softDeps[ref.keypath]) { - this.softRefs.splice(i, 1); - this.softRefs[ref.keypath] = false; - ref.teardown(); - } - } - i = softDeps.length; - while (i--) { - keypath = softDeps[i]; - if (!this.softRefs[keypath]) { - ref = new SoftReference(this.root, keypath, this); - this.softRefs[this.softRefs.length] = ref; - this.softRefs[keypath] = true; - } - } - this.selfUpdating = this.refs.length + this.softRefs.length <= 1; - } - }; - return Evaluator; - function getFunctionFromString(str, i) { - var fn, args; - str = str.replace(/\$\{([0-9]+)\}/g, '_$1'); - if (cache[str]) { - return cache[str]; - } - args = []; - while (i--) { - args[i] = '_' + i; - } - fn = new Function(args.join(','), 'return(' + str + ')'); - cache[str] = fn; - return fn; - } - }(utils_isEqual, utils_defineProperty, shared_clearCache, shared_notifyDependants, shared_registerDependant, shared_unregisterDependant, shared_adaptIfNecessary, render_shared_Evaluator_Reference, render_shared_Evaluator_SoftReference); -var render_shared_ExpressionResolver_ReferenceScout = function (resolveRef, teardown) { - - var ReferenceScout = function (resolver, ref, contextStack, argNum) { - var keypath, root; - root = this.root = resolver.root; - keypath = resolveRef(root, ref, contextStack); - if (keypath !== undefined) { - resolver.resolveRef(argNum, false, keypath); - } else { - this.ref = ref; - this.argNum = argNum; - this.resolver = resolver; - this.contextStack = contextStack; - root._pendingResolution[root._pendingResolution.length] = this; - } - }; - ReferenceScout.prototype = { - resolve: function (keypath) { - this.keypath = keypath; - this.resolver.resolveRef(this.argNum, false, keypath); - }, - teardown: function () { - if (!this.keypath) { - teardown(this); - } - } - }; - return ReferenceScout; - }(shared_resolveRef, shared_teardown); -var render_shared_ExpressionResolver_isRegularKeypath = function () { - - var keyPattern = /^(?:(?:[a-zA-Z$_][a-zA-Z$_0-9]*)|(?:[0-9]|[1-9][0-9]+))$/; - return function (keypath) { - var keys, key, i; - keys = keypath.split('.'); - i = keys.length; - while (i--) { - key = keys[i]; - if (key === 'undefined' || !keyPattern.test(key)) { - return false; - } - } - return true; - }; - }(); -var render_shared_ExpressionResolver_getKeypath = function (normaliseKeypath, isRegularKeypath) { - - return function (str, args) { - var unique, normalised; - unique = str.replace(/\$\{([0-9]+)\}/g, function (match, $1) { - return args[$1] ? args[$1][1] : 'undefined'; - }); - normalised = normaliseKeypath(unique); - if (isRegularKeypath(normalised)) { - return normalised; - } - return '${' + unique.replace(/[\.\[\]]/g, '-') + '}'; - }; - }(utils_normaliseKeypath, render_shared_ExpressionResolver_isRegularKeypath); -var render_shared_ExpressionResolver_reassignDependants = function (registerDependant, unregisterDependant) { - - return function (ractive, oldKeypath, newKeypath) { - var toReassign, i, dependant; - toReassign = []; - gatherDependants(ractive, oldKeypath, toReassign); - i = toReassign.length; - while (i--) { - dependant = toReassign[i]; - unregisterDependant(dependant); - dependant.keypath = dependant.keypath.replace(oldKeypath, newKeypath); - registerDependant(dependant); - dependant.update(); - } - }; - function cascade(ractive, oldKeypath, toReassign) { - var map, i; - map = ractive._depsMap[oldKeypath]; - if (!map) { - return; - } - i = map.length; - while (i--) { - gatherDependants(ractive, map[i], toReassign); - } - } - function gatherDependants(ractive, oldKeypath, toReassign) { - var priority, dependantsByKeypath, dependants, i; - priority = ractive._deps.length; - while (priority--) { - dependantsByKeypath = ractive._deps[priority]; - if (dependantsByKeypath) { - dependants = dependantsByKeypath[oldKeypath]; - if (dependants) { - i = dependants.length; - while (i--) { - toReassign.push(dependants[i]); - } - } - } - } - cascade(ractive, oldKeypath, toReassign); - } - }(shared_registerDependant, shared_unregisterDependant); -var render_shared_ExpressionResolver__ExpressionResolver = function (Evaluator, ReferenceScout, getKeypath, reassignDependants) { - - var ExpressionResolver = function (mustache) { - var expression, i, len, ref, indexRefs; - this.root = mustache.root; - this.mustache = mustache; - this.args = []; - this.scouts = []; - expression = mustache.descriptor.x; - indexRefs = mustache.parentFragment.indexRefs; - this.str = expression.s; - len = this.unresolved = this.args.length = expression.r ? expression.r.length : 0; - if (!len) { - this.resolved = this.ready = true; - this.bubble(); - return; - } - for (i = 0; i < len; i += 1) { - ref = expression.r[i]; - if (indexRefs && indexRefs[ref] !== undefined) { - this.resolveRef(i, true, indexRefs[ref]); - } else { - this.scouts[this.scouts.length] = new ReferenceScout(this, ref, mustache.contextStack, i); - } - } - this.ready = true; - this.bubble(); - }; - ExpressionResolver.prototype = { - bubble: function () { - var oldKeypath; - if (!this.ready) { - return; - } - oldKeypath = this.keypath; - this.keypath = getKeypath(this.str, this.args); - if (this.keypath.substr(0, 2) === '${') { - this.createEvaluator(); - } - if (oldKeypath) { - reassignDependants(this.root, oldKeypath, this.keypath); - } else { - this.mustache.resolve(this.keypath); - } - }, - teardown: function () { - while (this.scouts.length) { - this.scouts.pop().teardown(); - } - }, - resolveRef: function (argNum, isIndexRef, value) { - this.args[argNum] = [ - isIndexRef, - value - ]; - this.bubble(); - this.resolved = !--this.unresolved; - }, - createEvaluator: function () { - if (!this.root._evaluators[this.keypath]) { - this.root._evaluators[this.keypath] = new Evaluator(this.root, this.keypath, this.str, this.args, this.mustache.priority); - } else { - this.root._evaluators[this.keypath].refresh(); - } - } - }; - return ExpressionResolver; - }(render_shared_Evaluator__Evaluator, render_shared_ExpressionResolver_ReferenceScout, render_shared_ExpressionResolver_getKeypath, render_shared_ExpressionResolver_reassignDependants); -var render_shared_initMustache = function (resolveRef, ExpressionResolver) { - - return function (mustache, options) { - var keypath, indexRef, parentFragment; - parentFragment = mustache.parentFragment = options.parentFragment; - mustache.root = parentFragment.root; - mustache.contextStack = parentFragment.contextStack; - mustache.descriptor = options.descriptor; - mustache.index = options.index || 0; - mustache.priority = parentFragment.priority; - mustache.type = options.descriptor.t; - if (options.descriptor.r) { - if (parentFragment.indexRefs && parentFragment.indexRefs[options.descriptor.r] !== undefined) { - indexRef = parentFragment.indexRefs[options.descriptor.r]; - mustache.indexRef = options.descriptor.r; - mustache.value = indexRef; - mustache.render(mustache.value); - } else { - keypath = resolveRef(mustache.root, options.descriptor.r, mustache.contextStack); - if (keypath !== undefined) { - mustache.resolve(keypath); - } else { - mustache.ref = options.descriptor.r; - mustache.root._pendingResolution[mustache.root._pendingResolution.length] = mustache; - } - } - } - if (options.descriptor.x) { - mustache.expressionResolver = new ExpressionResolver(mustache); - } - if (mustache.descriptor.n && !mustache.hasOwnProperty('value')) { - mustache.render(undefined); - } - }; - }(shared_resolveRef, render_shared_ExpressionResolver__ExpressionResolver); -var render_shared_resolveMustache = function (types, registerDependant, unregisterDependant) { - - return function (keypath) { - if (keypath === this.keypath) { - return; - } - if (this.registered) { - unregisterDependant(this); - } - this.keypath = keypath; - registerDependant(this); - this.update(); - if (this.root.twoway && this.parentFragment.owner.type === types.ATTRIBUTE) { - this.parentFragment.owner.element.bind(); - } - if (this.expressionResolver && this.expressionResolver.resolved) { - this.expressionResolver = null; - } - }; - }(config_types, shared_registerDependant, shared_unregisterDependant); -var render_shared_updateMustache = function (isEqual) { - - return function () { - var wrapped, value; - value = this.root.get(this.keypath); - if (wrapped = this.root._wrapped[this.keypath]) { - value = wrapped.get(); - } - if (!isEqual(value, this.value)) { - this.render(value); - this.value = value; - } - }; - }(utils_isEqual); -var render_DomFragment_Interpolator = function (types, teardown, initMustache, resolveMustache, updateMustache) { - - var DomInterpolator, lessThan, greaterThan; - lessThan = //g; - DomInterpolator = function (options, docFrag) { - this.type = types.INTERPOLATOR; - if (docFrag) { - this.node = document.createTextNode(''); - docFrag.appendChild(this.node); - } - initMustache(this, options); - }; - DomInterpolator.prototype = { - update: updateMustache, - resolve: resolveMustache, - detach: function () { - this.node.parentNode.removeChild(this.node); - return this.node; - }, - teardown: function (destroy) { - if (destroy) { - this.detach(); - } - teardown(this); - }, - render: function (value) { - if (this.node) { - this.node.data = value == undefined ? '' : value; - } - }, - firstNode: function () { - return this.node; - }, - toString: function () { - var value = this.value != undefined ? '' + this.value : ''; - return value.replace(lessThan, '<').replace(greaterThan, '>'); - } - }; - return DomInterpolator; - }(config_types, shared_teardown, render_shared_initMustache, render_shared_resolveMustache, render_shared_updateMustache); -var render_shared_updateSection = function (isArray, isObject, create) { - - return function (section, value) { - var fragmentOptions; - fragmentOptions = { - descriptor: section.descriptor.f, - root: section.root, - pNode: section.parentFragment.pNode, - owner: section - }; - if (section.descriptor.n) { - updateConditionalSection(section, value, true, fragmentOptions); - return; - } - if (isArray(value)) { - updateListSection(section, value, fragmentOptions); - } else if (isObject(value)) { - if (section.descriptor.i) { - updateListObjectSection(section, value, fragmentOptions); - } else { - updateContextSection(section, fragmentOptions); - } - } else { - updateConditionalSection(section, value, false, fragmentOptions); - } - }; - function updateListSection(section, value, fragmentOptions) { - var i, length, fragmentsToRemove; - length = value.length; - if (length < section.length) { - fragmentsToRemove = section.fragments.splice(length, section.length - length); - while (fragmentsToRemove.length) { - fragmentsToRemove.pop().teardown(true); - } - } else { - if (length > section.length) { - for (i = section.length; i < length; i += 1) { - fragmentOptions.contextStack = section.contextStack.concat(section.keypath + '.' + i); - fragmentOptions.index = i; - if (section.descriptor.i) { - fragmentOptions.indexRef = section.descriptor.i; - } - section.fragments[i] = section.createFragment(fragmentOptions); - } - } - } - section.length = length; - } - function updateListObjectSection(section, value, fragmentOptions) { - var id, fragmentsById; - fragmentsById = section.fragmentsById || (section.fragmentsById = create(null)); - for (id in fragmentsById) { - if (value[id] === undefined && fragmentsById[id]) { - fragmentsById[id].teardown(true); - fragmentsById[id] = null; - } - } - for (id in value) { - if (value[id] !== undefined && !fragmentsById[id]) { - fragmentOptions.contextStack = section.contextStack.concat(section.keypath + '.' + id); - fragmentOptions.index = id; - if (section.descriptor.i) { - fragmentOptions.indexRef = section.descriptor.i; - } - fragmentsById[id] = section.createFragment(fragmentOptions); - } - } - } - function updateContextSection(section, fragmentOptions) { - if (!section.length) { - fragmentOptions.contextStack = section.contextStack.concat(section.keypath); - fragmentOptions.index = 0; - section.fragments[0] = section.createFragment(fragmentOptions); - section.length = 1; - } - } - function updateConditionalSection(section, value, inverted, fragmentOptions) { - var doRender, emptyArray, fragmentsToRemove, fragment; - emptyArray = isArray(value) && value.length === 0; - if (inverted) { - doRender = emptyArray || !value; - } else { - doRender = value && !emptyArray; - } - if (doRender) { - if (!section.length) { - fragmentOptions.contextStack = section.contextStack; - fragmentOptions.index = 0; - section.fragments[0] = section.createFragment(fragmentOptions); - section.length = 1; - } - if (section.length > 1) { - fragmentsToRemove = section.fragments.splice(1); - while (fragment = fragmentsToRemove.pop()) { - fragment.teardown(true); - } - } - } else if (section.length) { - section.teardownFragments(true); - section.length = 0; - } - } - }(utils_isArray, utils_isObject, utils_create); -var render_DomFragment_Section_reassignFragment = function (types, unregisterDependant, ExpressionResolver) { - - return reassignFragment; - function reassignFragment(fragment, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath) { - var i, item, context, query; - if (fragment.html) { - return; - } - if (fragment.indexRefs && fragment.indexRefs[indexRef] !== undefined) { - fragment.indexRefs[indexRef] = newIndex; - } - i = fragment.contextStack.length; - while (i--) { - context = fragment.contextStack[i]; - if (context.substr(0, oldKeypath.length) === oldKeypath) { - fragment.contextStack[i] = context.replace(oldKeypath, newKeypath); - } - } - i = fragment.items.length; - while (i--) { - item = fragment.items[i]; - switch (item.type) { - case types.ELEMENT: - reassignElement(item, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - break; - case types.PARTIAL: - reassignFragment(item.fragment, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - break; - case types.COMPONENT: - reassignFragment(item.instance.fragment, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - if (query = fragment.root._liveComponentQueries[item.name]) { - query._makeDirty(); - } - break; - case types.SECTION: - case types.INTERPOLATOR: - case types.TRIPLE: - reassignMustache(item, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - break; - } - } - } - function reassignElement(element, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath) { - var i, attribute, storage, masterEventName, proxies, proxy, binding, bindings, liveQueries, ractive; - i = element.attributes.length; - while (i--) { - attribute = element.attributes[i]; - if (attribute.fragment) { - reassignFragment(attribute.fragment, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - if (attribute.twoway) { - attribute.updateBindings(); - } - } - } - if (storage = element.node._ractive) { - if (storage.keypath.substr(0, oldKeypath.length) === oldKeypath) { - storage.keypath = storage.keypath.replace(oldKeypath, newKeypath); - } - if (indexRef !== undefined) { - storage.index[indexRef] = newIndex; - } - for (masterEventName in storage.events) { - proxies = storage.events[masterEventName].proxies; - i = proxies.length; - while (i--) { - proxy = proxies[i]; - if (typeof proxy.n === 'object') { - reassignFragment(proxy.a, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - } - if (proxy.d) { - reassignFragment(proxy.d, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - } - } - } - if (binding = storage.binding) { - if (binding.keypath.substr(0, oldKeypath.length) === oldKeypath) { - bindings = storage.root._twowayBindings[binding.keypath]; - bindings.splice(bindings.indexOf(binding), 1); - binding.keypath = binding.keypath.replace(oldKeypath, newKeypath); - bindings = storage.root._twowayBindings[binding.keypath] || (storage.root._twowayBindings[binding.keypath] = []); - bindings.push(binding); - } - } - } - if (element.fragment) { - reassignFragment(element.fragment, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - } - if (liveQueries = element.liveQueries) { - ractive = element.root; - i = liveQueries.length; - while (i--) { - ractive._liveQueries[liveQueries[i]]._makeDirty(); - } - } - } - function reassignMustache(mustache, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath) { - var i; - if (mustache.descriptor.x) { - if (mustache.expressionResolver) { - mustache.expressionResolver.teardown(); - } - mustache.expressionResolver = new ExpressionResolver(mustache); - } - if (mustache.keypath) { - if (mustache.keypath.substr(0, oldKeypath.length) === oldKeypath) { - mustache.resolve(mustache.keypath.replace(oldKeypath, newKeypath)); - } - } else if (mustache.indexRef === indexRef) { - mustache.value = newIndex; - mustache.render(newIndex); - } - if (mustache.fragments) { - i = mustache.fragments.length; - while (i--) { - reassignFragment(mustache.fragments[i], indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - } - } - } - }(config_types, shared_unregisterDependant, render_shared_ExpressionResolver__ExpressionResolver); -var render_DomFragment_Section_reassignFragments = function (types, reassignFragment, preDomUpdate) { - - return function (root, section, start, end, by) { - var i, fragment, indexRef, oldIndex, newIndex, oldKeypath, newKeypath; - indexRef = section.descriptor.i; - for (i = start; i < end; i += 1) { - fragment = section.fragments[i]; - oldIndex = i - by; - newIndex = i; - oldKeypath = section.keypath + '.' + (i - by); - newKeypath = section.keypath + '.' + i; - fragment.index += by; - reassignFragment(fragment, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - } - preDomUpdate(root); - }; - }(config_types, render_DomFragment_Section_reassignFragment, shared_preDomUpdate); -var render_DomFragment_Section_prototype_merge = function (reassignFragment) { - - return function (newIndices) { - var section = this, parentFragment, firstChange, changed, i, newLength, newFragments, toTeardown, fragmentOptions, fragment, nextNode; - parentFragment = this.parentFragment; - newFragments = []; - newIndices.forEach(function (newIndex, oldIndex) { - var by, oldKeypath, newKeypath; - if (newIndex === oldIndex) { - newFragments[newIndex] = section.fragments[oldIndex]; - return; - } - if (firstChange === undefined) { - firstChange = oldIndex; - } - if (newIndex === -1) { - (toTeardown || (toTeardown = [])).push(section.fragments[oldIndex]); - return; - } - by = newIndex - oldIndex; - oldKeypath = section.keypath + '.' + oldIndex; - newKeypath = section.keypath + '.' + newIndex; - reassignFragment(section.fragments[oldIndex], section.descriptor.i, oldIndex, newIndex, by, oldKeypath, newKeypath); - newFragments[newIndex] = section.fragments[oldIndex]; - changed = true; - }); - if (toTeardown) { - while (fragment = toTeardown.pop()) { - fragment.teardown(true); - } - } - if (firstChange === undefined) { - firstChange = this.length; - } - newLength = this.root.get(this.keypath).length; - if (newLength === firstChange) { - return; - } - fragmentOptions = { - descriptor: this.descriptor.f, - root: this.root, - pNode: parentFragment.pNode, - owner: this - }; - if (this.descriptor.i) { - fragmentOptions.indexRef = this.descriptor.i; - } - for (i = firstChange; i < newLength; i += 1) { - if (fragment = newFragments[i]) { - this.docFrag.appendChild(fragment.detach(false)); - } else { - fragmentOptions.contextStack = this.contextStack.concat(this.keypath + '.' + i); - fragmentOptions.index = i; - fragment = this.createFragment(fragmentOptions); - } - this.fragments[i] = fragment; - } - nextNode = parentFragment.findNextNode(this); - parentFragment.pNode.insertBefore(this.docFrag, nextNode); - this.length = newLength; - }; - }(render_DomFragment_Section_reassignFragment); -var circular = function () { - - return []; - }(); -var render_DomFragment_Section__Section = function (types, isClient, initMustache, updateMustache, resolveMustache, updateSection, reassignFragment, reassignFragments, merge, teardown, circular) { - - var DomSection, DomFragment; - circular.push(function () { - DomFragment = circular.DomFragment; - }); - DomSection = function (options, docFrag) { - this.type = types.SECTION; - this.inverted = !!options.descriptor.n; - this.fragments = []; - this.length = 0; - if (docFrag) { - this.docFrag = document.createDocumentFragment(); - } - this.initialising = true; - initMustache(this, options); - if (docFrag) { - docFrag.appendChild(this.docFrag); - } - this.initialising = false; - }; - DomSection.prototype = { - update: updateMustache, - resolve: resolveMustache, - smartUpdate: function (methodName, args) { - var fragmentOptions; - if (methodName === 'push' || methodName === 'unshift' || methodName === 'splice') { - fragmentOptions = { - descriptor: this.descriptor.f, - root: this.root, - pNode: this.parentFragment.pNode, - owner: this - }; - if (this.descriptor.i) { - fragmentOptions.indexRef = this.descriptor.i; - } - } - if (this[methodName]) { - this.rendering = true; - this[methodName](fragmentOptions, args); - this.rendering = false; - } - }, - pop: function () { - if (this.length) { - this.fragments.pop().teardown(true); - this.length -= 1; - } - }, - push: function (fragmentOptions, args) { - var start, end, i; - start = this.length; - end = start + args.length; - for (i = start; i < end; i += 1) { - fragmentOptions.contextStack = this.contextStack.concat(this.keypath + '.' + i); - fragmentOptions.index = i; - this.fragments[i] = this.createFragment(fragmentOptions); - } - this.length += args.length; - this.parentFragment.pNode.insertBefore(this.docFrag, this.parentFragment.findNextNode(this)); - }, - shift: function () { - this.splice(null, [ - 0, - 1 - ]); - }, - unshift: function (fragmentOptions, args) { - this.splice(fragmentOptions, [ - 0, - 0 - ].concat(new Array(args.length))); - }, - splice: function (fragmentOptions, args) { - var insertionPoint, addedItems, removedItems, balance, i, start, end, spliceArgs, reassignStart; - if (!args.length) { - return; - } - start = +(args[0] < 0 ? this.length + args[0] : args[0]); - addedItems = Math.max(0, args.length - 2); - removedItems = args[1] !== undefined ? args[1] : this.length - start; - removedItems = Math.min(removedItems, this.length - start); - balance = addedItems - removedItems; - if (!balance) { - return; - } - if (balance < 0) { - end = start - balance; - for (i = start; i < end; i += 1) { - this.fragments[i].teardown(true); - } - this.fragments.splice(start, -balance); - } else { - end = start + balance; - insertionPoint = this.fragments[start] ? this.fragments[start].firstNode() : this.parentFragment.findNextNode(this); - spliceArgs = [ - start, - 0 - ].concat(new Array(balance)); - this.fragments.splice.apply(this.fragments, spliceArgs); - for (i = start; i < end; i += 1) { - fragmentOptions.contextStack = this.contextStack.concat(this.keypath + '.' + i); - fragmentOptions.index = i; - this.fragments[i] = this.createFragment(fragmentOptions); - } - this.parentFragment.pNode.insertBefore(this.docFrag, insertionPoint); - } - this.length += balance; - reassignStart = start + addedItems; - reassignFragments(this.root, this, reassignStart, this.length, balance); - }, - merge: merge, - detach: function () { - var i, len; - len = this.fragments.length; - for (i = 0; i < len; i += 1) { - this.docFrag.appendChild(this.fragments[i].detach()); - } - return this.docFrag; - }, - teardown: function (destroy) { - this.teardownFragments(destroy); - teardown(this); - }, - firstNode: function () { - if (this.fragments[0]) { - return this.fragments[0].firstNode(); - } - return this.parentFragment.findNextNode(this); - }, - findNextNode: function (fragment) { - if (this.fragments[fragment.index + 1]) { - return this.fragments[fragment.index + 1].firstNode(); - } - return this.parentFragment.findNextNode(this); - }, - teardownFragments: function (destroy) { - var id, fragment; - while (fragment = this.fragments.shift()) { - fragment.teardown(destroy); - } - if (this.fragmentsById) { - for (id in this.fragmentsById) { - if (this.fragments[id]) { - this.fragmentsById[id].teardown(destroy); - this.fragmentsById[id] = null; - } - } - } - }, - render: function (value) { - var nextNode, wrapped; - if (wrapped = this.root._wrapped[this.keypath]) { - value = wrapped.get(); - } - if (this.rendering) { - return; - } - this.rendering = true; - updateSection(this, value); - this.rendering = false; - if (this.docFrag && !this.docFrag.childNodes.length) { - return; - } - if (!this.initialising && isClient) { - nextNode = this.parentFragment.findNextNode(this); - if (nextNode && nextNode.parentNode === this.parentFragment.pNode) { - this.parentFragment.pNode.insertBefore(this.docFrag, nextNode); - } else { - this.parentFragment.pNode.appendChild(this.docFrag); - } - } - }, - createFragment: function (options) { - var fragment = new DomFragment(options); - if (this.docFrag) { - this.docFrag.appendChild(fragment.docFrag); - } - return fragment; - }, - toString: function () { - var str, i, id, len; - str = ''; - i = 0; - len = this.length; - for (i = 0; i < len; i += 1) { - str += this.fragments[i].toString(); - } - if (this.fragmentsById) { - for (id in this.fragmentsById) { - if (this.fragmentsById[id]) { - str += this.fragmentsById[id].toString(); - } - } - } - return str; - }, - find: function (selector) { - var i, len, queryResult; - len = this.fragments.length; - for (i = 0; i < len; i += 1) { - if (queryResult = this.fragments[i].find(selector)) { - return queryResult; - } - } - return null; - }, - findAll: function (selector, query) { - var i, len; - len = this.fragments.length; - for (i = 0; i < len; i += 1) { - this.fragments[i].findAll(selector, query); - } - }, - findComponent: function (selector) { - var i, len, queryResult; - len = this.fragments.length; - for (i = 0; i < len; i += 1) { - if (queryResult = this.fragments[i].findComponent(selector)) { - return queryResult; - } - } - return null; - }, - findAllComponents: function (selector, query) { - var i, len; - len = this.fragments.length; - for (i = 0; i < len; i += 1) { - this.fragments[i].findAllComponents(selector, query); - } - } - }; - return DomSection; - }(config_types, config_isClient, render_shared_initMustache, render_shared_updateMustache, render_shared_resolveMustache, render_shared_updateSection, render_DomFragment_Section_reassignFragment, render_DomFragment_Section_reassignFragments, render_DomFragment_Section_prototype_merge, shared_teardown, circular); -var render_DomFragment_Triple = function (types, matches, initMustache, updateMustache, resolveMustache, insertHtml, teardown) { - - var DomTriple = function (options, docFrag) { - this.type = types.TRIPLE; - if (docFrag) { - this.nodes = []; - this.docFrag = document.createDocumentFragment(); - } - this.initialising = true; - initMustache(this, options); - if (docFrag) { - docFrag.appendChild(this.docFrag); - } - this.initialising = false; - }; - DomTriple.prototype = { - update: updateMustache, - resolve: resolveMustache, - detach: function () { - var i = this.nodes.length; - while (i--) { - this.docFrag.appendChild(this.nodes[i]); - } - return this.docFrag; - }, - teardown: function (destroy) { - if (destroy) { - this.detach(); - this.docFrag = this.nodes = null; - } - teardown(this); - }, - firstNode: function () { - if (this.nodes[0]) { - return this.nodes[0]; - } - return this.parentFragment.findNextNode(this); - }, - render: function (html) { - var node, pNode; - if (!this.nodes) { - return; - } - while (this.nodes.length) { - node = this.nodes.pop(); - node.parentNode.removeChild(node); - } - if (!html) { - this.nodes = []; - return; - } - pNode = this.parentFragment.pNode; - this.nodes = insertHtml(html, pNode.tagName, this.docFrag); - if (!this.initialising) { - pNode.insertBefore(this.docFrag, this.parentFragment.findNextNode(this)); - } - }, - toString: function () { - return this.value != undefined ? this.value : ''; - }, - find: function (selector) { - var i, len, node, queryResult; - len = this.nodes.length; - for (i = 0; i < len; i += 1) { - node = this.nodes[i]; - if (node.nodeType !== 1) { - continue; - } - if (matches(node, selector)) { - return node; - } - if (queryResult = node.querySelector(selector)) { - return queryResult; - } - } - return null; - }, - findAll: function (selector, queryResult) { - var i, len, node, queryAllResult, numNodes, j; - len = this.nodes.length; - for (i = 0; i < len; i += 1) { - node = this.nodes[i]; - if (node.nodeType !== 1) { - continue; - } - if (matches(node, selector)) { - queryResult.push(node); - } - if (queryAllResult = node.querySelectorAll(selector)) { - numNodes = queryAllResult.length; - for (j = 0; j < numNodes; j += 1) { - queryResult.push(queryAllResult[j]); - } - } - } - } - }; - return DomTriple; - }(config_types, utils_matches, render_shared_initMustache, render_shared_updateMustache, render_shared_resolveMustache, render_DomFragment_shared_insertHtml, shared_teardown); -var render_DomFragment_Element_initialise_getElementNamespace = function (namespaces) { - - return function (descriptor, parentNode) { - if (descriptor.a && descriptor.a.xmlns) { - return descriptor.a.xmlns; - } - return descriptor.e === 'svg' ? namespaces.svg : parentNode.namespaceURI || namespaces.html; - }; - }(config_namespaces); -var render_DomFragment_shared_enforceCase = function () { - - var svgCamelCaseElements, svgCamelCaseAttributes, createMap, map; - svgCamelCaseElements = 'altGlyph altGlyphDef altGlyphItem animateColor animateMotion animateTransform clipPath feBlend feColorMatrix feComponentTransfer feComposite feConvolveMatrix feDiffuseLighting feDisplacementMap feDistantLight feFlood feFuncA feFuncB feFuncG feFuncR feGaussianBlur feImage feMerge feMergeNode feMorphology feOffset fePointLight feSpecularLighting feSpotLight feTile feTurbulence foreignObject glyphRef linearGradient radialGradient textPath vkern'.split(' '); - svgCamelCaseAttributes = 'attributeName attributeType baseFrequency baseProfile calcMode clipPathUnits contentScriptType contentStyleType diffuseConstant edgeMode externalResourcesRequired filterRes filterUnits glyphRef gradientTransform gradientUnits kernelMatrix kernelUnitLength keyPoints keySplines keyTimes lengthAdjust limitingConeAngle markerHeight markerUnits markerWidth maskContentUnits maskUnits numOctaves pathLength patternContentUnits patternTransform patternUnits pointsAtX pointsAtY pointsAtZ preserveAlpha preserveAspectRatio primitiveUnits refX refY repeatCount repeatDur requiredExtensions requiredFeatures specularConstant specularExponent spreadMethod startOffset stdDeviation stitchTiles surfaceScale systemLanguage tableValues targetX targetY textLength viewBox viewTarget xChannelSelector yChannelSelector zoomAndPan'.split(' '); - createMap = function (items) { - var map = {}, i = items.length; - while (i--) { - map[items[i].toLowerCase()] = items[i]; - } - return map; - }; - map = createMap(svgCamelCaseElements.concat(svgCamelCaseAttributes)); - return function (elementName) { - var lowerCaseElementName = elementName.toLowerCase(); - return map[lowerCaseElementName] || lowerCaseElementName; - }; - }(); -var render_DomFragment_Attribute_helpers_determineNameAndNamespace = function (namespaces, enforceCase) { - - return function (attribute, name) { - var colonIndex, namespacePrefix; - colonIndex = name.indexOf(':'); - if (colonIndex !== -1) { - namespacePrefix = name.substr(0, colonIndex); - if (namespacePrefix !== 'xmlns') { - name = name.substring(colonIndex + 1); - attribute.name = enforceCase(name); - attribute.lcName = attribute.name.toLowerCase(); - attribute.namespace = namespaces[namespacePrefix.toLowerCase()]; - if (!attribute.namespace) { - throw 'Unknown namespace ("' + namespacePrefix + '")'; - } - return; - } - } - attribute.name = attribute.element.namespace !== namespaces.html ? enforceCase(name) : name; - attribute.lcName = attribute.name.toLowerCase(); - }; - }(config_namespaces, render_DomFragment_shared_enforceCase); -var render_DomFragment_Attribute_helpers_setStaticAttribute = function (namespaces) { - - return function (attribute, options) { - var node, value = options.value === null ? '' : options.value; - if (node = options.pNode) { - if (attribute.namespace) { - node.setAttributeNS(attribute.namespace, options.name, value); - } else { - if (options.name === 'style' && node.style.setAttribute) { - node.style.setAttribute('cssText', value); - } else if (options.name === 'class' && (!node.namespaceURI || node.namespaceURI === namespaces.html)) { - node.className = value; - } else { - node.setAttribute(options.name, value); - } - } - if (attribute.name === 'id') { - options.root.nodes[options.value] = node; - } - if (attribute.name === 'value') { - node._ractive.value = options.value; - } - } - attribute.value = options.value; - }; - }(config_namespaces); -var render_DomFragment_Attribute_helpers_determinePropertyName = function (namespaces) { - - var propertyNames = { - 'accept-charset': 'acceptCharset', - accesskey: 'accessKey', - bgcolor: 'bgColor', - 'class': 'className', - codebase: 'codeBase', - colspan: 'colSpan', - contenteditable: 'contentEditable', - datetime: 'dateTime', - dirname: 'dirName', - 'for': 'htmlFor', - 'http-equiv': 'httpEquiv', - ismap: 'isMap', - maxlength: 'maxLength', - novalidate: 'noValidate', - pubdate: 'pubDate', - readonly: 'readOnly', - rowspan: 'rowSpan', - tabindex: 'tabIndex', - usemap: 'useMap' - }; - return function (attribute, options) { - var propertyName; - if (attribute.pNode && !attribute.namespace && (!options.pNode.namespaceURI || options.pNode.namespaceURI === namespaces.html)) { - propertyName = propertyNames[attribute.name] || attribute.name; - if (options.pNode[propertyName] !== undefined) { - attribute.propertyName = propertyName; - } - if (typeof options.pNode[propertyName] === 'boolean' || propertyName === 'value') { - attribute.useProperty = true; - } - } - }; - }(config_namespaces); -var render_DomFragment_Attribute_prototype_bind = function (types, warn, arrayContentsMatch, getValueFromCheckboxes) { - - var bindAttribute, getInterpolator, updateModel, update, getBinding, inheritProperties, MultipleSelectBinding, SelectBinding, RadioNameBinding, CheckboxNameBinding, CheckedBinding, FileListBinding, ContentEditableBinding, GenericBinding; - bindAttribute = function () { - var node = this.pNode, interpolator, binding, bindings; - if (!this.fragment) { - return false; - } - interpolator = getInterpolator(this); - if (!interpolator) { - return false; - } - this.interpolator = interpolator; - this.keypath = interpolator.keypath || interpolator.descriptor.r; - binding = getBinding(this); - if (!binding) { - return false; - } - node._ractive.binding = this.element.binding = binding; - this.twoway = true; - bindings = this.root._twowayBindings[this.keypath] || (this.root._twowayBindings[this.keypath] = []); - bindings[bindings.length] = binding; - return true; - }; - updateModel = function () { - this._ractive.binding.update(); - }; - update = function () { - var value = this._ractive.root.get(this._ractive.binding.keypath); - this.value = value == undefined ? '' : value; - }; - getInterpolator = function (attribute) { - var item, errorMessage; - if (attribute.fragment.items.length !== 1) { - return null; - } - item = attribute.fragment.items[0]; - if (item.type !== types.INTERPOLATOR) { - return null; - } - if (!item.keypath && !item.ref) { - return null; - } - if (item.keypath && item.keypath.substr(0, 2) === '${') { - errorMessage = 'You cannot set up two-way binding against an expression ' + item.keypath; - if (attribute.root.debug) { - warn(errorMessage); - } - return null; - } - return item; - }; - getBinding = function (attribute) { - var node = attribute.pNode; - if (node.tagName === 'SELECT') { - return node.multiple ? new MultipleSelectBinding(attribute, node) : new SelectBinding(attribute, node); - } - if (node.type === 'checkbox' || node.type === 'radio') { - if (attribute.propertyName === 'name') { - if (node.type === 'checkbox') { - return new CheckboxNameBinding(attribute, node); - } - if (node.type === 'radio') { - return new RadioNameBinding(attribute, node); - } - } - if (attribute.propertyName === 'checked') { - return new CheckedBinding(attribute, node); - } - return null; - } - if (attribute.lcName !== 'value') { - warn('This is... odd'); - } - if (node.type === 'file') { - return new FileListBinding(attribute, node); - } - if (node.getAttribute('contenteditable')) { - return new ContentEditableBinding(attribute, node); - } - return new GenericBinding(attribute, node); - }; - MultipleSelectBinding = function (attribute, node) { - var valueFromModel; - inheritProperties(this, attribute, node); - node.addEventListener('change', updateModel, false); - valueFromModel = this.root.get(this.keypath); - if (valueFromModel === undefined) { - this.update(); - } - }; - MultipleSelectBinding.prototype = { - value: function () { - var value, options, i, len; - value = []; - options = this.node.options; - len = options.length; - for (i = 0; i < len; i += 1) { - if (options[i].selected) { - value[value.length] = options[i]._ractive.value; - } - } - return value; - }, - update: function () { - var attribute, previousValue, value; - attribute = this.attr; - previousValue = attribute.value; - value = this.value(); - if (previousValue === undefined || !arrayContentsMatch(value, previousValue)) { - attribute.receiving = true; - attribute.value = value; - this.root.set(this.keypath, value); - attribute.receiving = false; - } - return this; - }, - deferUpdate: function () { - if (this.deferred === true) { - return; - } - this.root._deferred.attrs.push(this); - this.deferred = true; - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - } - }; - SelectBinding = function (attribute, node) { - var valueFromModel; - inheritProperties(this, attribute, node); - node.addEventListener('change', updateModel, false); - valueFromModel = this.root.get(this.keypath); - if (valueFromModel === undefined) { - this.update(); - } - }; - SelectBinding.prototype = { - value: function () { - var options, i, len; - options = this.node.options; - len = options.length; - for (i = 0; i < len; i += 1) { - if (options[i].selected) { - return options[i]._ractive.value; - } - } - }, - update: function () { - var value = this.value(); - this.attr.receiving = true; - this.attr.value = value; - this.root.set(this.keypath, value); - this.attr.receiving = false; - return this; - }, - deferUpdate: function () { - if (this.deferred === true) { - return; - } - this.root._deferred.attrs.push(this); - this.deferred = true; - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - } - }; - RadioNameBinding = function (attribute, node) { - var valueFromModel; - this.radioName = true; - inheritProperties(this, attribute, node); - node.name = '{{' + attribute.keypath + '}}'; - node.addEventListener('change', updateModel, false); - if (node.attachEvent) { - node.addEventListener('click', updateModel, false); - } - valueFromModel = this.root.get(this.keypath); - if (valueFromModel !== undefined) { - node.checked = valueFromModel == node._ractive.value; - } else { - this.root._deferred.radios.push(this); - } - }; - RadioNameBinding.prototype = { - value: function () { - return this.node._ractive ? this.node._ractive.value : this.node.value; - }, - update: function () { - var node = this.node; - if (node.checked) { - this.attr.receiving = true; - this.root.set(this.keypath, this.value()); - this.attr.receiving = false; - } - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - this.node.removeEventListener('click', updateModel, false); - } - }; - CheckboxNameBinding = function (attribute, node) { - var valueFromModel, checked; - this.checkboxName = true; - inheritProperties(this, attribute, node); - node.name = '{{' + this.keypath + '}}'; - node.addEventListener('change', updateModel, false); - if (node.attachEvent) { - node.addEventListener('click', updateModel, false); - } - valueFromModel = this.root.get(this.keypath); - if (valueFromModel !== undefined) { - checked = valueFromModel.indexOf(node._ractive.value) !== -1; - node.checked = checked; - } else { - if (this.root._deferred.checkboxes.indexOf(this.keypath) === -1) { - this.root._deferred.checkboxes.push(this.keypath); - } - } - }; - CheckboxNameBinding.prototype = { - changed: function () { - return this.node.checked !== !!this.checked; - }, - update: function () { - this.checked = this.node.checked; - this.attr.receiving = true; - this.root.set(this.keypath, getValueFromCheckboxes(this.root, this.keypath)); - this.attr.receiving = false; - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - this.node.removeEventListener('click', updateModel, false); - } - }; - CheckedBinding = function (attribute, node) { - inheritProperties(this, attribute, node); - node.addEventListener('change', updateModel, false); - if (node.attachEvent) { - node.addEventListener('click', updateModel, false); - } - }; - CheckedBinding.prototype = { - value: function () { - return this.node.checked; - }, - update: function () { - this.attr.receiving = true; - this.root.set(this.keypath, this.value()); - this.attr.receiving = false; - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - this.node.removeEventListener('click', updateModel, false); - } - }; - FileListBinding = function (attribute, node) { - inheritProperties(this, attribute, node); - node.addEventListener('change', updateModel, false); - }; - FileListBinding.prototype = { - value: function () { - return this.attr.pNode.files; - }, - update: function () { - this.attr.root.set(this.attr.keypath, this.value()); - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - } - }; - ContentEditableBinding = function (attribute, node) { - inheritProperties(this, attribute, node); - node.addEventListener('change', updateModel, false); - if (!this.root.lazy) { - node.addEventListener('input', updateModel, false); - if (node.attachEvent) { - node.addEventListener('keyup', updateModel, false); - } - } - }; - ContentEditableBinding.prototype = { - update: function () { - this.attr.receiving = true; - this.root.set(this.keypath, this.node.innerHTML); - this.attr.receiving = false; - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - this.node.removeEventListener('input', updateModel, false); - this.node.removeEventListener('keyup', updateModel, false); - } - }; - GenericBinding = function (attribute, node) { - inheritProperties(this, attribute, node); - node.addEventListener('change', updateModel, false); - if (!this.root.lazy) { - node.addEventListener('input', updateModel, false); - if (node.attachEvent) { - node.addEventListener('keyup', updateModel, false); - } - } - this.node.addEventListener('blur', update, false); - }; - GenericBinding.prototype = { - value: function () { - var value = this.attr.pNode.value; - if (+value + '' === value && value.indexOf('e') === -1) { - value = +value; - } - return value; - }, - update: function () { - var attribute = this.attr, value = this.value(); - attribute.receiving = true; - attribute.root.set(attribute.keypath, value); - attribute.receiving = false; - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - this.node.removeEventListener('input', updateModel, false); - this.node.removeEventListener('keyup', updateModel, false); - this.node.removeEventListener('blur', update, false); - } - }; - inheritProperties = function (binding, attribute, node) { - binding.attr = attribute; - binding.node = node; - binding.root = attribute.root; - binding.keypath = attribute.keypath; - }; - return bindAttribute; - }(config_types, utils_warn, utils_arrayContentsMatch, shared_getValueFromCheckboxes); -var render_DomFragment_Attribute_prototype_update = function (isArray, namespaces) { - - var updateAttribute, updateFileInputValue, deferSelect, initSelect, updateSelect, updateMultipleSelect, updateRadioName, updateCheckboxName, updateIEStyleAttribute, updateClassName, updateContentEditableValue, updateEverythingElse; - updateAttribute = function () { - var node; - if (!this.ready) { - return this; - } - node = this.pNode; - if (node.tagName === 'SELECT' && this.lcName === 'value') { - this.update = deferSelect; - this.deferredUpdate = initSelect; - return this.update(); - } - if (this.isFileInputValue) { - this.update = updateFileInputValue; - return this; - } - if (this.twoway && this.lcName === 'name') { - if (node.type === 'radio') { - this.update = updateRadioName; - return this.update(); - } - if (node.type === 'checkbox') { - this.update = updateCheckboxName; - return this.update(); - } - } - if (this.lcName === 'style' && node.style.setAttribute) { - this.update = updateIEStyleAttribute; - return this.update(); - } - if (this.lcName === 'class' && (!node.namespaceURI || node.namespaceURI === namespaces.html)) { - this.update = updateClassName; - return this.update(); - } - if (node.getAttribute('contenteditable') && this.lcName === 'value') { - this.update = updateContentEditableValue; - return this.update(); - } - this.update = updateEverythingElse; - return this.update(); - }; - updateFileInputValue = function () { - return this; - }; - initSelect = function () { - this.deferredUpdate = this.pNode.multiple ? updateMultipleSelect : updateSelect; - this.deferredUpdate(); - }; - deferSelect = function () { - this.root._deferred.selectValues.push(this); - return this; - }; - updateSelect = function () { - var value = this.fragment.getValue(), options, option, i; - this.value = this.pNode._ractive.value = value; - options = this.pNode.options; - i = options.length; - while (i--) { - option = options[i]; - if (option._ractive.value == value) { - option.selected = true; - return this; - } - } - return this; - }; - updateMultipleSelect = function () { - var value = this.fragment.getValue(), options, i; - if (!isArray(value)) { - value = [value]; - } - options = this.pNode.options; - i = options.length; - while (i--) { - options[i].selected = value.indexOf(options[i]._ractive.value) !== -1; - } - this.value = value; - return this; - }; - updateRadioName = function () { - var node, value; - node = this.pNode; - value = this.fragment.getValue(); - node.checked = value == node._ractive.value; - return this; - }; - updateCheckboxName = function () { - var node, value; - node = this.pNode; - value = this.fragment.getValue(); - if (!isArray(value)) { - node.checked = value == node._ractive.value; - return this; - } - node.checked = value.indexOf(node._ractive.value) !== -1; - return this; - }; - updateIEStyleAttribute = function () { - var node, value; - node = this.pNode; - value = this.fragment.getValue(); - if (value === undefined) { - value = ''; - } - if (value !== this.value) { - node.style.setAttribute('cssText', value); - this.value = value; - } - return this; - }; - updateClassName = function () { - var node, value; - node = this.pNode; - value = this.fragment.getValue(); - if (value === undefined) { - value = ''; - } - if (value !== this.value) { - node.className = value; - this.value = value; - } - return this; - }; - updateContentEditableValue = function () { - var node, value; - node = this.pNode; - value = this.fragment.getValue(); - if (value === undefined) { - value = ''; - } - if (value !== this.value) { - if (!this.receiving) { - node.innerHTML = value; - } - this.value = value; - } - return this; - }; - updateEverythingElse = function () { - var node, value; - node = this.pNode; - value = this.fragment.getValue(); - if (this.isValueAttribute) { - node._ractive.value = value; - } - if (value === undefined) { - value = ''; - } - if (value !== this.value) { - if (this.useProperty) { - if (!this.receiving) { - node[this.propertyName] = value; - } - this.value = value; - return this; - } - if (this.namespace) { - node.setAttributeNS(this.namespace, this.name, value); - this.value = value; - return this; - } - if (this.lcName === 'id') { - if (this.value !== undefined) { - this.root.nodes[this.value] = undefined; - } - this.root.nodes[value] = node; - } - node.setAttribute(this.name, value); - this.value = value; - } - return this; - }; - return updateAttribute; - }(utils_isArray, config_namespaces); -var parse_Tokenizer_utils_getStringMatch = function () { - - return function (string) { - var substr; - substr = this.str.substr(this.pos, string.length); - if (substr === string) { - this.pos += string.length; - return string; - } - return null; - }; - }(); -var parse_Tokenizer_utils_allowWhitespace = function () { - - var leadingWhitespace = /^\s+/; - return function () { - var match = leadingWhitespace.exec(this.remaining()); - if (!match) { - return null; - } - this.pos += match[0].length; - return match[0]; - }; - }(); -var parse_Tokenizer_utils_makeRegexMatcher = function () { - - return function (regex) { - return function (tokenizer) { - var match = regex.exec(tokenizer.str.substring(tokenizer.pos)); - if (!match) { - return null; - } - tokenizer.pos += match[0].length; - return match[1] || match[0]; - }; - }; - }(); -var parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral_getEscapedChars = function () { - - return function (tokenizer) { - var chars = '', character; - character = getEscapedChar(tokenizer); - while (character) { - chars += character; - character = getEscapedChar(tokenizer); - } - return chars || null; - }; - function getEscapedChar(tokenizer) { - var character; - if (!tokenizer.getStringMatch('\\')) { - return null; - } - character = tokenizer.str.charAt(tokenizer.pos); - tokenizer.pos += 1; - return character; - } - }(); -var parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral_getQuotedString = function (makeRegexMatcher, getEscapedChars) { - - var getUnescapedDoubleQuotedChars = makeRegexMatcher(/^[^\\"]+/), getUnescapedSingleQuotedChars = makeRegexMatcher(/^[^\\']+/); - return function getQuotedString(tokenizer, singleQuotes) { - var start, string, escaped, unescaped, next, matcher; - start = tokenizer.pos; - string = ''; - matcher = singleQuotes ? getUnescapedSingleQuotedChars : getUnescapedDoubleQuotedChars; - escaped = getEscapedChars(tokenizer); - if (escaped) { - string += escaped; - } - unescaped = matcher(tokenizer); - if (unescaped) { - string += unescaped; - } - if (!string) { - return ''; - } - next = getQuotedString(tokenizer, singleQuotes); - while (next !== '') { - string += next; - } - return string; - }; - }(parse_Tokenizer_utils_makeRegexMatcher, parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral_getEscapedChars); -var parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral__getStringLiteral = function (types, getQuotedString) { - - return function (tokenizer) { - var start, string; - start = tokenizer.pos; - if (tokenizer.getStringMatch('"')) { - string = getQuotedString(tokenizer, false); - if (!tokenizer.getStringMatch('"')) { - tokenizer.pos = start; - return null; - } - return { - t: types.STRING_LITERAL, - v: string - }; - } - if (tokenizer.getStringMatch('\'')) { - string = getQuotedString(tokenizer, true); - if (!tokenizer.getStringMatch('\'')) { - tokenizer.pos = start; - return null; - } - return { - t: types.STRING_LITERAL, - v: string - }; - } - return null; - }; - }(config_types, parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral_getQuotedString); -var parse_Tokenizer_getExpression_getPrimary_getLiteral_getNumberLiteral = function (types, makeRegexMatcher) { - - var getNumber = makeRegexMatcher(/^(?:[+-]?)(?:(?:(?:0|[1-9]\d*)?\.\d+)|(?:(?:0|[1-9]\d*)\.)|(?:0|[1-9]\d*))(?:[eE][+-]?\d+)?/); - return function (tokenizer) { - var result; - if (result = getNumber(tokenizer)) { - return { - t: types.NUMBER_LITERAL, - v: result - }; - } - return null; - }; - }(config_types, parse_Tokenizer_utils_makeRegexMatcher); -var parse_Tokenizer_getExpression_shared_getName = function (makeRegexMatcher) { - - return makeRegexMatcher(/^[a-zA-Z_$][a-zA-Z_$0-9]*/); - }(parse_Tokenizer_utils_makeRegexMatcher); -var parse_Tokenizer_getExpression_shared_getKey = function (getStringLiteral, getNumberLiteral, getName) { - - var identifier = /^[a-zA-Z_$][a-zA-Z_$0-9]*$/; - return function (tokenizer) { - var token; - if (token = getStringLiteral(tokenizer)) { - return identifier.test(token.v) ? token.v : '"' + token.v.replace(/"/g, '\\"') + '"'; - } - if (token = getNumberLiteral(tokenizer)) { - return token.v; - } - if (token = getName(tokenizer)) { - return token; - } - }; - }(parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral__getStringLiteral, parse_Tokenizer_getExpression_getPrimary_getLiteral_getNumberLiteral, parse_Tokenizer_getExpression_shared_getName); -var utils_parseJSON = function (getStringMatch, allowWhitespace, getStringLiteral, getKey) { - - var Tokenizer, specials, specialsPattern, numberPattern, placeholderPattern, placeholderAtStartPattern; - specials = { - 'true': true, - 'false': false, - 'undefined': undefined, - 'null': null - }; - specialsPattern = new RegExp('^(?:' + Object.keys(specials).join('|') + ')'); - numberPattern = /^(?:[+-]?)(?:(?:(?:0|[1-9]\d*)?\.\d+)|(?:(?:0|[1-9]\d*)\.)|(?:0|[1-9]\d*))(?:[eE][+-]?\d+)?/; - placeholderPattern = /\$\{([^\}]+)\}/g; - placeholderAtStartPattern = /^\$\{([^\}]+)\}/; - Tokenizer = function (str, values) { - this.str = str; - this.values = values; - this.pos = 0; - this.result = this.getToken(); - }; - Tokenizer.prototype = { - remaining: function () { - return this.str.substring(this.pos); - }, - getStringMatch: getStringMatch, - getToken: function () { - this.allowWhitespace(); - return this.getPlaceholder() || this.getSpecial() || this.getNumber() || this.getString() || this.getObject() || this.getArray(); - }, - getPlaceholder: function () { - var match; - if (!this.values) { - return null; - } - if ((match = placeholderAtStartPattern.exec(this.remaining())) && this.values.hasOwnProperty(match[1])) { - this.pos += match[0].length; - return { v: this.values[match[1]] }; - } - }, - getSpecial: function () { - var match; - if (match = specialsPattern.exec(this.remaining())) { - this.pos += match[0].length; - return { v: specials[match[0]] }; - } - }, - getNumber: function () { - var match; - if (match = numberPattern.exec(this.remaining())) { - this.pos += match[0].length; - return { v: +match[0] }; - } - }, - getString: function () { - var stringLiteral = getStringLiteral(this), values; - if (stringLiteral && (values = this.values)) { - return { - v: stringLiteral.v.replace(placeholderPattern, function (match, $1) { - return values[$1] || $1; - }) - }; - } - return stringLiteral; - }, - getObject: function () { - var result, pair; - if (!this.getStringMatch('{')) { - return null; - } - result = {}; - while (pair = getKeyValuePair(this)) { - result[pair.key] = pair.value; - this.allowWhitespace(); - if (this.getStringMatch('}')) { - return { v: result }; - } - if (!this.getStringMatch(',')) { - return null; - } - } - return null; - }, - getArray: function () { - var result, valueToken; - if (!this.getStringMatch('[')) { - return null; - } - result = []; - while (valueToken = this.getToken()) { - result.push(valueToken.v); - if (this.getStringMatch(']')) { - return { v: result }; - } - if (!this.getStringMatch(',')) { - return null; - } - } - return null; - }, - allowWhitespace: allowWhitespace - }; - function getKeyValuePair(tokenizer) { - var key, valueToken, pair; - tokenizer.allowWhitespace(); - key = getKey(tokenizer); - if (!key) { - return null; - } - pair = { key: key }; - tokenizer.allowWhitespace(); - if (!tokenizer.getStringMatch(':')) { - return null; - } - tokenizer.allowWhitespace(); - valueToken = tokenizer.getToken(); - if (!valueToken) { - return null; - } - pair.value = valueToken.v; - return pair; - } - return function (str, values) { - var tokenizer = new Tokenizer(str, values); - if (tokenizer.result) { - return { - value: tokenizer.result.v, - remaining: tokenizer.remaining() - }; - } - return null; - }; - }(parse_Tokenizer_utils_getStringMatch, parse_Tokenizer_utils_allowWhitespace, parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral__getStringLiteral, parse_Tokenizer_getExpression_shared_getKey); -var render_StringFragment_Interpolator = function (types, teardown, initMustache, updateMustache, resolveMustache) { - - var StringInterpolator = function (options) { - this.type = types.INTERPOLATOR; - initMustache(this, options); - }; - StringInterpolator.prototype = { - update: updateMustache, - resolve: resolveMustache, - render: function (value) { - this.value = value; - this.parentFragment.bubble(); - }, - teardown: function () { - teardown(this); - }, - toString: function () { - if (this.value == undefined) { - return ''; - } - return stringify(this.value); - } - }; - return StringInterpolator; - function stringify(value) { - if (typeof value === 'string') { - return value; - } - return JSON.stringify(value); - } - }(config_types, shared_teardown, render_shared_initMustache, render_shared_updateMustache, render_shared_resolveMustache); -var render_StringFragment_Section = function (types, initMustache, updateMustache, resolveMustache, updateSection, teardown, circular) { - - var StringSection, StringFragment; - circular.push(function () { - StringFragment = circular.StringFragment; - }); - StringSection = function (options) { - this.type = types.SECTION; - this.fragments = []; - this.length = 0; - initMustache(this, options); - }; - StringSection.prototype = { - update: updateMustache, - resolve: resolveMustache, - teardown: function () { - this.teardownFragments(); - teardown(this); - }, - teardownFragments: function () { - while (this.fragments.length) { - this.fragments.shift().teardown(); - } - this.length = 0; - }, - bubble: function () { - this.value = this.fragments.join(''); - this.parentFragment.bubble(); - }, - render: function (value) { - var wrapped; - if (wrapped = this.root._wrapped[this.keypath]) { - value = wrapped.get(); - } - updateSection(this, value); - this.parentFragment.bubble(); - }, - createFragment: function (options) { - return new StringFragment(options); - }, - toString: function () { - return this.fragments.join(''); - } - }; - return StringSection; - }(config_types, render_shared_initMustache, render_shared_updateMustache, render_shared_resolveMustache, render_shared_updateSection, shared_teardown, circular); -var render_StringFragment_Text = function (types) { - - var StringText = function (text) { - this.type = types.TEXT; - this.text = text; - }; - StringText.prototype = { - toString: function () { - return this.text; - }, - teardown: function () { - } - }; - return StringText; - }(config_types); -var render_StringFragment_prototype_toArgsList = function (warn, parseJSON) { - - return function () { - var values, counter, jsonesque, guid, errorMessage, parsed, processItems; - if (!this.argsList || this.dirty) { - values = {}; - counter = 0; - guid = this.root._guid; - processItems = function (items) { - return items.map(function (item) { - var placeholderId, wrapped, value; - if (item.text) { - return item.text; - } - if (item.fragments) { - return item.fragments.map(function (fragment) { - return processItems(fragment.items); - }).join(''); - } - placeholderId = guid + '-' + counter++; - if (wrapped = item.root._wrapped[item.keypath]) { - value = wrapped.value; - } else { - value = item.value; - } - values[placeholderId] = value; - return '${' + placeholderId + '}'; - }).join(''); - }; - jsonesque = processItems(this.items); - parsed = parseJSON('[' + jsonesque + ']', values); - if (!parsed) { - errorMessage = 'Could not parse directive arguments (' + this.toString() + '). If you think this is a bug, please file an issue at http://github.com/RactiveJS/Ractive/issues'; - if (this.root.debug) { - throw new Error(errorMessage); - } else { - warn(errorMessage); - this.argsList = [jsonesque]; - } - } else { - this.argsList = parsed.value; - } - this.dirty = false; - } - return this.argsList; - }; - }(utils_warn, utils_parseJSON); -var render_StringFragment__StringFragment = function (types, parseJSON, initFragment, Interpolator, Section, Text, toArgsList, circular) { - - var StringFragment = function (options) { - initFragment(this, options); - }; - StringFragment.prototype = { - createItem: function (options) { - if (typeof options.descriptor === 'string') { - return new Text(options.descriptor); - } - switch (options.descriptor.t) { - case types.INTERPOLATOR: - return new Interpolator(options); - case types.TRIPLE: - return new Interpolator(options); - case types.SECTION: - return new Section(options); - default: - throw 'Something went wrong in a rather interesting way'; - } - }, - bubble: function () { - this.dirty = true; - this.owner.bubble(); - }, - teardown: function () { - var numItems, i; - numItems = this.items.length; - for (i = 0; i < numItems; i += 1) { - this.items[i].teardown(); - } - }, - getValue: function () { - var value; - if (this.items.length === 1 && this.items[0].type === types.INTERPOLATOR) { - value = this.items[0].value; - if (value !== undefined) { - return value; - } - } - return this.toString(); - }, - isSimple: function () { - var i, item, containsInterpolator; - if (this.simple !== undefined) { - return this.simple; - } - i = this.items.length; - while (i--) { - item = this.items[i]; - if (item.type === types.TEXT) { - continue; - } - if (item.type === types.INTERPOLATOR) { - if (containsInterpolator) { - return false; - } else { - containsInterpolator = true; - continue; - } - } - return this.simple = false; - } - return this.simple = true; - }, - toString: function () { - return this.items.join(''); - }, - toJSON: function () { - var value = this.getValue(), parsed; - if (typeof value === 'string') { - parsed = parseJSON(value); - value = parsed ? parsed.value : value; - } - return value; - }, - toArgsList: toArgsList - }; - circular.StringFragment = StringFragment; - return StringFragment; - }(config_types, utils_parseJSON, render_shared_initFragment, render_StringFragment_Interpolator, render_StringFragment_Section, render_StringFragment_Text, render_StringFragment_prototype_toArgsList, circular); -var render_DomFragment_Attribute__Attribute = function (types, determineNameAndNamespace, setStaticAttribute, determinePropertyName, bind, update, StringFragment) { - - var DomAttribute = function (options) { - this.type = types.ATTRIBUTE; - this.element = options.element; - determineNameAndNamespace(this, options.name); - if (options.value === null || typeof options.value === 'string') { - setStaticAttribute(this, options); - return; - } - this.root = options.root; - this.pNode = options.pNode; - this.parentFragment = this.element.parentFragment; - this.fragment = new StringFragment({ - descriptor: options.value, - root: this.root, - owner: this, - contextStack: options.contextStack - }); - if (!this.pNode) { - return; - } - if (this.name === 'value') { - this.isValueAttribute = true; - if (this.pNode.tagName === 'INPUT' && this.pNode.type === 'file') { - this.isFileInputValue = true; - } - } - determinePropertyName(this, options); - this.selfUpdating = this.fragment.isSimple(); - this.ready = true; - }; - DomAttribute.prototype = { - bind: bind, - update: update, - updateBindings: function () { - this.keypath = this.interpolator.keypath || this.interpolator.ref; - if (this.propertyName === 'name') { - this.pNode.name = '{{' + this.keypath + '}}'; - } - }, - teardown: function () { - var i; - if (this.boundEvents) { - i = this.boundEvents.length; - while (i--) { - this.pNode.removeEventListener(this.boundEvents[i], this.updateModel, false); - } - } - if (this.fragment) { - this.fragment.teardown(); - } - }, - bubble: function () { - if (this.selfUpdating) { - this.update(); - } else if (!this.deferred && this.ready) { - this.root._deferred.attrs.push(this); - this.deferred = true; - } - }, - toString: function () { - var str; - if (this.value === null) { - return this.name; - } - if (!this.fragment) { - return this.name + '=' + JSON.stringify(this.value); - } - str = this.fragment.toString(); - return this.name + '=' + JSON.stringify(str); - } - }; - return DomAttribute; - }(config_types, render_DomFragment_Attribute_helpers_determineNameAndNamespace, render_DomFragment_Attribute_helpers_setStaticAttribute, render_DomFragment_Attribute_helpers_determinePropertyName, render_DomFragment_Attribute_prototype_bind, render_DomFragment_Attribute_prototype_update, render_StringFragment__StringFragment); -var render_DomFragment_Element_initialise_createElementAttributes = function (DomAttribute) { - - return function (element, attributes) { - var attrName, attrValue, attr; - element.attributes = []; - for (attrName in attributes) { - if (attributes.hasOwnProperty(attrName)) { - attrValue = attributes[attrName]; - attr = new DomAttribute({ - element: element, - name: attrName, - value: attrValue, - root: element.root, - pNode: element.node, - contextStack: element.parentFragment.contextStack - }); - element.attributes[element.attributes.length] = element.attributes[attrName] = attr; - if (attrName !== 'name') { - attr.update(); - } - } - } - return element.attributes; - }; - }(render_DomFragment_Attribute__Attribute); -var render_DomFragment_Element_initialise_appendElementChildren = function (warn, namespaces, StringFragment, circular) { - - var DomFragment, updateCss, updateScript; - circular.push(function () { - DomFragment = circular.DomFragment; - }); - updateCss = function () { - var node = this.node, content = this.fragment.toString(); - if (node.styleSheet) { - node.styleSheet.cssText = content; - } - node.innerHTML = content; - }; - updateScript = function () { - if (!this.node.type || this.node.type === 'text/javascript') { - warn('Script tag was updated. This does not cause the code to be re-evaluated!'); - } - this.node.innerHTML = this.fragment.toString(); - }; - return function (element, node, descriptor, docFrag) { - var liveQueries, i, selector, queryAllResult, j; - if (element.lcName === 'script' || element.lcName === 'style') { - element.fragment = new StringFragment({ - descriptor: descriptor.f, - root: element.root, - contextStack: element.parentFragment.contextStack, - owner: element - }); - if (docFrag) { - if (element.lcName === 'script') { - element.bubble = updateScript; - element.node.innerHTML = element.fragment.toString(); - } else { - element.bubble = updateCss; - element.bubble(); - } - } - return; - } - if (typeof descriptor.f === 'string' && (!node || (!node.namespaceURI || node.namespaceURI === namespaces.html))) { - element.html = descriptor.f; - if (docFrag) { - node.innerHTML = element.html; - liveQueries = element.root._liveQueries; - i = liveQueries.length; - while (i--) { - selector = liveQueries[i]; - if ((queryAllResult = node.querySelectorAll(selector)) && (j = queryAllResult.length)) { - (element.liveQueries || (element.liveQueries = [])).push(selector); - element.liveQueries[selector] = []; - while (j--) { - element.liveQueries[selector][j] = queryAllResult[j]; - } - } - } - } - } else { - element.fragment = new DomFragment({ - descriptor: descriptor.f, - root: element.root, - pNode: node, - contextStack: element.parentFragment.contextStack, - owner: element - }); - if (docFrag) { - node.appendChild(element.fragment.docFrag); - } - } - }; - }(utils_warn, config_namespaces, render_StringFragment__StringFragment, circular); -var render_DomFragment_Element_initialise_decorate_Decorator = function (warn, StringFragment) { - - var Decorator = function (descriptor, root, owner, contextStack) { - var name, fragment, errorMessage; - this.root = root; - this.node = owner.node; - name = descriptor.n || descriptor; - if (typeof name !== 'string') { - fragment = new StringFragment({ - descriptor: name, - root: this.root, - owner: owner, - contextStack: contextStack - }); - name = fragment.toString(); - fragment.teardown(); - } - if (descriptor.a) { - this.params = descriptor.a; - } else if (descriptor.d) { - fragment = new StringFragment({ - descriptor: descriptor.d, - root: this.root, - owner: owner, - contextStack: contextStack - }); - this.params = fragment.toArgsList(); - fragment.teardown(); - } - this.fn = root.decorators[name]; - if (!this.fn) { - errorMessage = 'Missing "' + name + '" decorator. You may need to download a plugin via https://github.com/RactiveJS/Ractive/wiki/Plugins#decorators'; - if (root.debug) { - throw new Error(errorMessage); - } else { - warn(errorMessage); - } - } - }; - Decorator.prototype = { - init: function () { - var result, args; - if (this.params) { - args = [this.node].concat(this.params); - result = this.fn.apply(this.root, args); - } else { - result = this.fn.call(this.root, this.node); - } - if (!result || !result.teardown) { - throw new Error('Decorator definition must return an object with a teardown method'); - } - this.teardown = result.teardown; - } - }; - return Decorator; - }(utils_warn, render_StringFragment__StringFragment); -var render_DomFragment_Element_initialise_decorate__decorate = function (Decorator) { - - return function (descriptor, root, owner, contextStack) { - owner.decorator = new Decorator(descriptor, root, owner, contextStack); - if (owner.decorator.fn) { - root._deferred.decorators.push(owner.decorator); - } - }; - }(render_DomFragment_Element_initialise_decorate_Decorator); -var render_DomFragment_Element_initialise_addEventProxies_addEventProxy = function (warn, StringFragment) { - - var addEventProxy, MasterEventHandler, ProxyEvent, firePlainEvent, fireEventWithArgs, fireEventWithDynamicArgs, customHandlers, genericHandler, getCustomHandler; - addEventProxy = function (element, triggerEventName, proxyDescriptor, contextStack, indexRefs) { - var events, master; - events = element.node._ractive.events; - master = events[triggerEventName] || (events[triggerEventName] = new MasterEventHandler(element, triggerEventName, contextStack, indexRefs)); - master.add(proxyDescriptor); - }; - MasterEventHandler = function (element, eventName, contextStack) { - var definition; - this.element = element; - this.root = element.root; - this.node = element.node; - this.name = eventName; - this.contextStack = contextStack; - this.proxies = []; - if (definition = this.root.events[eventName]) { - this.custom = definition(this.node, getCustomHandler(eventName)); - } else { - if (!('on' + eventName in this.node)) { - warn('Missing "' + this.name + '" event. You may need to download a plugin via https://github.com/RactiveJS/Ractive/wiki/Plugins#events'); - } - this.node.addEventListener(eventName, genericHandler, false); - } - }; - MasterEventHandler.prototype = { - add: function (proxy) { - this.proxies[this.proxies.length] = new ProxyEvent(this.element, this.root, proxy, this.contextStack); - }, - teardown: function () { - var i; - if (this.custom) { - this.custom.teardown(); - } else { - this.node.removeEventListener(this.name, genericHandler, false); - } - i = this.proxies.length; - while (i--) { - this.proxies[i].teardown(); - } - }, - fire: function (event) { - var i = this.proxies.length; - while (i--) { - this.proxies[i].fire(event); - } - } - }; - ProxyEvent = function (element, ractive, descriptor, contextStack) { - var name; - this.root = ractive; - name = descriptor.n || descriptor; - if (typeof name === 'string') { - this.n = name; - } else { - this.n = new StringFragment({ - descriptor: descriptor.n, - root: this.root, - owner: element, - contextStack: contextStack - }); - } - if (descriptor.a) { - this.a = descriptor.a; - this.fire = fireEventWithArgs; - return; - } - if (descriptor.d) { - this.d = new StringFragment({ - descriptor: descriptor.d, - root: this.root, - owner: element, - contextStack: contextStack - }); - this.fire = fireEventWithDynamicArgs; - return; - } - this.fire = firePlainEvent; - }; - ProxyEvent.prototype = { - teardown: function () { - if (this.n.teardown) { - this.n.teardown(); - } - if (this.d) { - this.d.teardown(); - } - }, - bubble: function () { - } - }; - firePlainEvent = function (event) { - this.root.fire(this.n.toString(), event); - }; - fireEventWithArgs = function (event) { - this.root.fire.apply(this.root, [ - this.n.toString(), - event - ].concat(this.a)); - }; - fireEventWithDynamicArgs = function (event) { - var args = this.d.toArgsList(); - if (typeof args === 'string') { - args = args.substr(1, args.length - 2); - } - this.root.fire.apply(this.root, [ - this.n.toString(), - event - ].concat(args)); - }; - genericHandler = function (event) { - var storage = this._ractive; - storage.events[event.type].fire({ - node: this, - original: event, - index: storage.index, - keypath: storage.keypath, - context: storage.root.get(storage.keypath) - }); - }; - customHandlers = {}; - getCustomHandler = function (eventName) { - if (customHandlers[eventName]) { - return customHandlers[eventName]; - } - return customHandlers[eventName] = function (event) { - var storage = event.node._ractive; - event.index = storage.index; - event.keypath = storage.keypath; - event.context = storage.root.get(storage.keypath); - storage.events[eventName].fire(event); - }; - }; - return addEventProxy; - }(utils_warn, render_StringFragment__StringFragment); -var render_DomFragment_Element_initialise_addEventProxies__addEventProxies = function (addEventProxy) { - - return function (element, proxies) { - var i, eventName, eventNames; - for (eventName in proxies) { - if (proxies.hasOwnProperty(eventName)) { - eventNames = eventName.split('-'); - i = eventNames.length; - while (i--) { - addEventProxy(element, eventNames[i], proxies[eventName], element.parentFragment.contextStack); - } - } - } - }; - }(render_DomFragment_Element_initialise_addEventProxies_addEventProxy); -var render_DomFragment_Element_initialise_updateLiveQueries = function () { - - return function (element) { - var ractive, liveQueries, i, selector, query; - ractive = element.root; - liveQueries = ractive._liveQueries; - i = liveQueries.length; - while (i--) { - selector = liveQueries[i]; - query = liveQueries[selector]; - if (query._test(element)) { - (element.liveQueries || (element.liveQueries = [])).push(selector); - element.liveQueries[selector] = [element.node]; - } - } - }; - }(); -var utils_camelCase = function () { - - return function (hyphenatedStr) { - return hyphenatedStr.replace(/-([a-zA-Z])/g, function (match, $1) { - return $1.toUpperCase(); - }); - }; - }(); -var utils_fillGaps = function () { - - return function (target, source) { - var key; - for (key in source) { - if (source.hasOwnProperty(key) && !target.hasOwnProperty(key)) { - target[key] = source[key]; - } - } - return target; - }; - }(); -var render_DomFragment_Element_shared_executeTransition_Transition = function (isClient, createElement, warn, isNumeric, isArray, camelCase, fillGaps, StringFragment) { - - var Transition, testStyle, vendors, vendorPattern, unprefixPattern, prefixCache, CSS_TRANSITIONS_ENABLED, TRANSITION, TRANSITION_DURATION, TRANSITION_PROPERTY, TRANSITION_TIMING_FUNCTION, TRANSITIONEND; - if (!isClient) { - return; - } - testStyle = createElement('div').style; - (function () { - if (testStyle.transition !== undefined) { - TRANSITION = 'transition'; - TRANSITIONEND = 'transitionend'; - CSS_TRANSITIONS_ENABLED = true; - } else if (testStyle.webkitTransition !== undefined) { - TRANSITION = 'webkitTransition'; - TRANSITIONEND = 'webkitTransitionEnd'; - CSS_TRANSITIONS_ENABLED = true; - } else { - CSS_TRANSITIONS_ENABLED = false; - } - }()); - if (TRANSITION) { - TRANSITION_DURATION = TRANSITION + 'Duration'; - TRANSITION_PROPERTY = TRANSITION + 'Property'; - TRANSITION_TIMING_FUNCTION = TRANSITION + 'TimingFunction'; - } - Transition = function (descriptor, root, owner, contextStack, isIntro) { - var t = this, name, fragment, errorMessage; - this.root = root; - this.node = owner.node; - this.isIntro = isIntro; - this.originalStyle = this.node.getAttribute('style'); - this.complete = function (noReset) { - if (!noReset && t.isIntro) { - t.resetStyle(); - } - t._manager.pop(t.node); - t.node._ractive.transition = null; - }; - name = descriptor.n || descriptor; - if (typeof name !== 'string') { - fragment = new StringFragment({ - descriptor: name, - root: this.root, - owner: owner, - contextStack: contextStack - }); - name = fragment.toString(); - fragment.teardown(); - } - this.name = name; - if (descriptor.a) { - this.params = descriptor.a; - } else if (descriptor.d) { - fragment = new StringFragment({ - descriptor: descriptor.d, - root: this.root, - owner: owner, - contextStack: contextStack - }); - this.params = fragment.toArgsList(); - fragment.teardown(); - } - this._fn = root.transitions[name]; - if (!this._fn) { - errorMessage = 'Missing "' + name + '" transition. You may need to download a plugin via https://github.com/RactiveJS/Ractive/wiki/Plugins#transitions'; - if (root.debug) { - throw new Error(errorMessage); - } else { - warn(errorMessage); - } - return; - } - }; - Transition.prototype = { - init: function () { - if (this._inited) { - throw new Error('Cannot initialize a transition more than once'); - } - this._inited = true; - this._fn.apply(this.root, [this].concat(this.params)); - }, - getStyle: function (props) { - var computedStyle, styles, i, prop, value; - computedStyle = window.getComputedStyle(this.node); - if (typeof props === 'string') { - value = computedStyle[prefix(props)]; - if (value === '0px') { - value = 0; - } - return value; - } - if (!isArray(props)) { - throw new Error('Transition#getStyle must be passed a string, or an array of strings representing CSS properties'); - } - styles = {}; - i = props.length; - while (i--) { - prop = props[i]; - value = computedStyle[prefix(prop)]; - if (value === '0px') { - value = 0; - } - styles[prop] = value; - } - return styles; - }, - setStyle: function (style, value) { - var prop; - if (typeof style === 'string') { - this.node.style[prefix(style)] = value; - } else { - for (prop in style) { - if (style.hasOwnProperty(prop)) { - this.node.style[prefix(prop)] = style[prop]; - } - } - } - return this; - }, - animateStyle: function (style, value, options, complete) { - var t = this, propertyNames, changedProperties, computedStyle, current, to, from, transitionEndHandler, i, prop; - if (typeof style === 'string') { - to = {}; - to[style] = value; - } else { - to = style; - complete = options; - options = value; - } - if (!options) { - warn('The "' + t.name + '" transition does not supply an options object to `t.animateStyle()`. This will break in a future version of Ractive. For more info see https://github.com/RactiveJS/Ractive/issues/340'); - options = t; - complete = t.complete; - } - if (!options.duration) { - t.setStyle(to); - if (complete) { - complete(); - } - } - propertyNames = Object.keys(to); - changedProperties = []; - computedStyle = window.getComputedStyle(t.node); - from = {}; - i = propertyNames.length; - while (i--) { - prop = propertyNames[i]; - current = computedStyle[prefix(prop)]; - if (current === '0px') { - current = 0; - } - if (current != to[prop]) { - changedProperties[changedProperties.length] = prop; - t.node.style[prefix(prop)] = current; - } - } - if (!changedProperties.length) { - if (complete) { - complete(); - } - return; - } - setTimeout(function () { - t.node.style[TRANSITION_PROPERTY] = propertyNames.map(prefix).map(hyphenate).join(','); - t.node.style[TRANSITION_TIMING_FUNCTION] = hyphenate(options.easing || 'linear'); - t.node.style[TRANSITION_DURATION] = options.duration / 1000 + 's'; - transitionEndHandler = function (event) { - var index; - index = changedProperties.indexOf(camelCase(unprefix(event.propertyName))); - if (index !== -1) { - changedProperties.splice(index, 1); - } - if (changedProperties.length) { - return; - } - t.root.fire(t.name + ':end'); - t.node.removeEventListener(TRANSITIONEND, transitionEndHandler, false); - if (complete) { - complete(); - } - }; - t.node.addEventListener(TRANSITIONEND, transitionEndHandler, false); - setTimeout(function () { - var i = changedProperties.length; - while (i--) { - prop = changedProperties[i]; - t.node.style[prefix(prop)] = to[prop]; - } - }, 0); - }, options.delay || 0); - }, - resetStyle: function () { - if (this.originalStyle) { - this.node.setAttribute('style', this.originalStyle); - } else { - this.node.getAttribute('style'); - this.node.removeAttribute('style'); - } - }, - processParams: function (params, defaults) { - if (typeof params === 'number') { - params = { duration: params }; - } else if (typeof params === 'string') { - if (params === 'slow') { - params = { duration: 600 }; - } else if (params === 'fast') { - params = { duration: 200 }; - } else { - params = { duration: 400 }; - } - } else if (!params) { - params = {}; - } - return fillGaps(params, defaults); - } - }; - vendors = [ - 'o', - 'ms', - 'moz', - 'webkit' - ]; - vendorPattern = new RegExp('^(?:' + vendors.join('|') + ')([A-Z])'); - unprefixPattern = new RegExp('^-(?:' + vendors.join('|') + ')-'); - prefixCache = {}; - function prefix(prop) { - var i, vendor, capped; - if (!prefixCache[prop]) { - if (testStyle[prop] !== undefined) { - prefixCache[prop] = prop; - } else { - capped = prop.charAt(0).toUpperCase() + prop.substring(1); - i = vendors.length; - while (i--) { - vendor = vendors[i]; - if (testStyle[vendor + capped] !== undefined) { - prefixCache[prop] = vendor + capped; - break; - } - } - } - } - return prefixCache[prop]; - } - function unprefix(prop) { - return prop.replace(unprefixPattern, ''); - } - function hyphenate(str) { - var hyphenated; - if (vendorPattern.test(str)) { - str = '-' + str; - } - hyphenated = str.replace(/[A-Z]/g, function (match) { - return '-' + match.toLowerCase(); - }); - return hyphenated; - } - return Transition; - }(config_isClient, utils_createElement, utils_warn, utils_isNumeric, utils_isArray, utils_camelCase, utils_fillGaps, render_StringFragment__StringFragment); -var render_DomFragment_Element_shared_executeTransition__executeTransition = function (warn, Transition) { - - return function (descriptor, root, owner, contextStack, isIntro) { - var transition, node, oldTransition; - if (!root.transitionsEnabled || root._parent && !root._parent.transitionsEnabled) { - return; - } - transition = new Transition(descriptor, root, owner, contextStack, isIntro); - if (transition._fn) { - node = transition.node; - transition._manager = root._transitionManager; - if (oldTransition = node._ractive.transition) { - oldTransition.complete(); - } - node._ractive.transition = transition; - transition._manager.push(node); - if (isIntro) { - root._deferred.transitions.push(transition); - } else { - transition.init(); - } - } - }; - }(utils_warn, render_DomFragment_Element_shared_executeTransition_Transition); -var render_DomFragment_Element_initialise__initialise = function (types, namespaces, create, defineProperty, matches, warn, createElement, getElementNamespace, createElementAttributes, appendElementChildren, decorate, addEventProxies, updateLiveQueries, executeTransition, enforceCase) { - - return function (element, options, docFrag) { - var parentFragment, pNode, contextStack, descriptor, namespace, name, attributes, width, height, loadHandler, root, selectBinding, errorMessage; - element.type = types.ELEMENT; - parentFragment = element.parentFragment = options.parentFragment; - pNode = parentFragment.pNode; - contextStack = parentFragment.contextStack; - descriptor = element.descriptor = options.descriptor; - element.root = root = parentFragment.root; - element.index = options.index; - element.lcName = descriptor.e.toLowerCase(); - element.eventListeners = []; - element.customEventListeners = []; - if (pNode) { - namespace = element.namespace = getElementNamespace(descriptor, pNode); - name = namespace !== namespaces.html ? enforceCase(descriptor.e) : descriptor.e; - element.node = createElement(name, namespace); - defineProperty(element.node, '_ractive', { - value: { - proxy: element, - keypath: contextStack.length ? contextStack[contextStack.length - 1] : '', - index: parentFragment.indexRefs, - events: create(null), - root: root - } - }); - } - attributes = createElementAttributes(element, descriptor.a); - if (descriptor.f) { - if (element.node && element.node.getAttribute('contenteditable')) { - if (element.node.innerHTML) { - errorMessage = 'A pre-populated contenteditable element should not have children'; - if (root.debug) { - throw new Error(errorMessage); - } else { - warn(errorMessage); - } - } - } - appendElementChildren(element, element.node, descriptor, docFrag); - } - if (docFrag && descriptor.v) { - addEventProxies(element, descriptor.v); - } - if (docFrag) { - if (root.twoway) { - element.bind(); - if (element.node.getAttribute('contenteditable') && element.node._ractive.binding) { - element.node._ractive.binding.update(); - } - } - if (attributes.name && !attributes.name.twoway) { - attributes.name.update(); - } - if (element.node.tagName === 'IMG' && ((width = element.attributes.width) || (height = element.attributes.height))) { - element.node.addEventListener('load', loadHandler = function () { - if (width) { - element.node.width = width.value; - } - if (height) { - element.node.height = height.value; - } - element.node.removeEventListener('load', loadHandler, false); - }, false); - } - docFrag.appendChild(element.node); - if (descriptor.o) { - decorate(descriptor.o, root, element, contextStack); - } - if (descriptor.t1) { - executeTransition(descriptor.t1, root, element, contextStack, true); - } - if (element.node.tagName === 'OPTION') { - if (pNode.tagName === 'SELECT' && (selectBinding = pNode._ractive.binding)) { - selectBinding.deferUpdate(); - } - if (element.node._ractive.value == pNode._ractive.value) { - element.node.selected = true; - } - } - if (element.node.autofocus) { - root._deferred.focusable = element.node; - } - } - updateLiveQueries(element); - }; - }(config_types, config_namespaces, utils_create, utils_defineProperty, utils_matches, utils_warn, utils_createElement, render_DomFragment_Element_initialise_getElementNamespace, render_DomFragment_Element_initialise_createElementAttributes, render_DomFragment_Element_initialise_appendElementChildren, render_DomFragment_Element_initialise_decorate__decorate, render_DomFragment_Element_initialise_addEventProxies__addEventProxies, render_DomFragment_Element_initialise_updateLiveQueries, render_DomFragment_Element_shared_executeTransition__executeTransition, render_DomFragment_shared_enforceCase); -var render_DomFragment_Element_prototype_teardown = function (executeTransition) { - - return function (destroy) { - var eventName, binding, bindings, i, liveQueries, selector, query, nodesToRemove, j; - if (this.fragment) { - this.fragment.teardown(false); - } - while (this.attributes.length) { - this.attributes.pop().teardown(); - } - if (this.node) { - for (eventName in this.node._ractive.events) { - this.node._ractive.events[eventName].teardown(); - } - if (binding = this.node._ractive.binding) { - binding.teardown(); - bindings = this.root._twowayBindings[binding.attr.keypath]; - bindings.splice(bindings.indexOf(binding), 1); - } - } - if (this.decorator) { - this.decorator.teardown(); - } - if (this.descriptor.t2) { - executeTransition(this.descriptor.t2, this.root, this, this.parentFragment.contextStack, false); - } - if (destroy) { - this.root._transitionManager.detachWhenReady(this); - } - if (liveQueries = this.liveQueries) { - i = liveQueries.length; - while (i--) { - selector = liveQueries[i]; - if (nodesToRemove = this.liveQueries[selector]) { - j = nodesToRemove.length; - query = this.root._liveQueries[selector]; - while (j--) { - query._remove(nodesToRemove[j]); - } - } - } - } - }; - }(render_DomFragment_Element_shared_executeTransition__executeTransition); -var config_voidElementNames = function () { - - return 'area base br col command doctype embed hr img input keygen link meta param source track wbr'.split(' '); - }(); -var render_DomFragment_Element_prototype_toString = function (voidElementNames) { - - return function () { - var str, i, len; - str = '<' + (this.descriptor.y ? '!doctype' : this.descriptor.e); - len = this.attributes.length; - for (i = 0; i < len; i += 1) { - str += ' ' + this.attributes[i].toString(); - } - str += '>'; - if (this.html) { - str += this.html; - } else if (this.fragment) { - str += this.fragment.toString(); - } - if (voidElementNames.indexOf(this.descriptor.e) === -1) { - str += ''; - } - return str; - }; - }(config_voidElementNames); -var render_DomFragment_Element_prototype_find = function (matches) { - - return function (selector) { - var queryResult; - if (matches(this.node, selector)) { - return this.node; - } - if (this.html && (queryResult = this.node.querySelector(selector))) { - return queryResult; - } - if (this.fragment && this.fragment.find) { - return this.fragment.find(selector); - } - }; - }(utils_matches); -var render_DomFragment_Element_prototype_findAll = function () { - - return function (selector, query) { - var queryAllResult, i, numNodes, node, registeredNodes; - if (query._test(this, true) && query.live) { - (this.liveQueries || (this.liveQueries = [])).push(selector); - this.liveQueries[selector] = [this.node]; - } - if (this.html && (queryAllResult = this.node.querySelectorAll(selector)) && (numNodes = queryAllResult.length)) { - if (query.live) { - if (!this.liveQueries[selector]) { - (this.liveQueries || (this.liveQueries = [])).push(selector); - this.liveQueries[selector] = []; - } - registeredNodes = this.liveQueries[selector]; - } - for (i = 0; i < numNodes; i += 1) { - node = queryAllResult[i]; - query.push(node); - if (query.live) { - registeredNodes.push(node); - } - } - } - if (this.fragment) { - this.fragment.findAll(selector, query); - } - }; - }(); -var render_DomFragment_Element_prototype_findComponent = function () { - - return function (selector) { - if (this.fragment) { - return this.fragment.findComponent(selector); - } - }; - }(); -var render_DomFragment_Element_prototype_findAllComponents = function () { - - return function (selector, query) { - if (this.fragment) { - this.fragment.findAllComponents(selector, query); - } - }; - }(); -var render_DomFragment_Element_prototype_bind = function () { - - return function () { - var attributes = this.attributes; - if (!this.node) { - return; - } - if (this.binding) { - this.binding.teardown(); - this.binding = null; - } - if (this.node.getAttribute('contenteditable') && attributes.value && attributes.value.bind()) { - return; - } - switch (this.descriptor.e) { - case 'select': - case 'textarea': - if (attributes.value) { - attributes.value.bind(); - } - return; - case 'input': - if (this.node.type === 'radio' || this.node.type === 'checkbox') { - if (attributes.name && attributes.name.bind()) { - return; - } - if (attributes.checked && attributes.checked.bind()) { - return; - } - } - if (attributes.value && attributes.value.bind()) { - return; - } - } - }; - }(); -var render_DomFragment_Element__Element = function (initialise, teardown, toString, find, findAll, findComponent, findAllComponents, bind) { - - var DomElement = function (options, docFrag) { - initialise(this, options, docFrag); - }; - DomElement.prototype = { - detach: function () { - if (this.node) { - if (this.node.parentNode) { - this.node.parentNode.removeChild(this.node); - } - return this.node; - } - }, - teardown: teardown, - firstNode: function () { - return this.node; - }, - findNextNode: function () { - return null; - }, - bubble: function () { - }, - toString: toString, - find: find, - findAll: findAll, - findComponent: findComponent, - findAllComponents: findAllComponents, - bind: bind - }; - return DomElement; - }(render_DomFragment_Element_initialise__initialise, render_DomFragment_Element_prototype_teardown, render_DomFragment_Element_prototype_toString, render_DomFragment_Element_prototype_find, render_DomFragment_Element_prototype_findAll, render_DomFragment_Element_prototype_findComponent, render_DomFragment_Element_prototype_findAllComponents, render_DomFragment_Element_prototype_bind); -var config_errors = { missingParser: 'Missing Ractive.parse - cannot parse template. Either preparse or use the version that includes the parser' }; -var registries_partials = {}; -var render_DomFragment_Partial_getPartialDescriptor = function (errors, isClient, warn, isObject, partials, parse) { - - var getPartialDescriptor, registerPartial, getPartialFromRegistry, unpack; - getPartialDescriptor = function (root, name) { - var el, partial, errorMessage; - if (partial = getPartialFromRegistry(root, name)) { - return partial; - } - if (isClient) { - el = document.getElementById(name); - if (el && el.tagName === 'SCRIPT') { - if (!parse) { - throw new Error(errors.missingParser); - } - registerPartial(parse(el.innerHTML), name, partials); - } - } - partial = partials[name]; - if (!partial) { - errorMessage = 'Could not find descriptor for partial "' + name + '"'; - if (root.debug) { - throw new Error(errorMessage); - } else { - warn(errorMessage); - } - return []; - } - return unpack(partial); - }; - getPartialFromRegistry = function (registryOwner, name) { - var partial; - if (registryOwner.partials[name]) { - if (typeof registryOwner.partials[name] === 'string') { - if (!parse) { - throw new Error(errors.missingParser); - } - partial = parse(registryOwner.partials[name], registryOwner.parseOptions); - registerPartial(partial, name, registryOwner.partials); - } - return unpack(registryOwner.partials[name]); - } - }; - registerPartial = function (partial, name, registry) { - var key; - if (isObject(partial)) { - registry[name] = partial.main; - for (key in partial.partials) { - if (partial.partials.hasOwnProperty(key)) { - registry[key] = partial.partials[key]; - } - } - } else { - registry[name] = partial; - } - }; - unpack = function (partial) { - if (partial.length === 1 && typeof partial[0] === 'string') { - return partial[0]; - } - return partial; - }; - return getPartialDescriptor; - }(config_errors, config_isClient, utils_warn, utils_isObject, registries_partials, parse__parse); -var render_DomFragment_Partial__Partial = function (types, getPartialDescriptor, circular) { - - var DomPartial, DomFragment; - circular.push(function () { - DomFragment = circular.DomFragment; - }); - DomPartial = function (options, docFrag) { - var parentFragment = this.parentFragment = options.parentFragment, descriptor; - this.type = types.PARTIAL; - this.name = options.descriptor.r; - this.index = options.index; - if (!options.descriptor.r) { - throw new Error('Partials must have a static reference (no expressions). This may change in a future version of Ractive.'); - } - descriptor = getPartialDescriptor(parentFragment.root, options.descriptor.r); - this.fragment = new DomFragment({ - descriptor: descriptor, - root: parentFragment.root, - pNode: parentFragment.pNode, - contextStack: parentFragment.contextStack, - owner: this - }); - if (docFrag) { - docFrag.appendChild(this.fragment.docFrag); - } - }; - DomPartial.prototype = { - firstNode: function () { - return this.fragment.firstNode(); - }, - findNextNode: function () { - return this.parentFragment.findNextNode(this); - }, - detach: function () { - return this.fragment.detach(); - }, - teardown: function (destroy) { - this.fragment.teardown(destroy); - }, - toString: function () { - return this.fragment.toString(); - }, - find: function (selector) { - return this.fragment.find(selector); - }, - findAll: function (selector, query) { - return this.fragment.findAll(selector, query); - }, - findComponent: function (selector) { - return this.fragment.findComponent(selector); - }, - findAllComponents: function (selector, query) { - return this.fragment.findAllComponents(selector, query); - } - }; - return DomPartial; - }(config_types, render_DomFragment_Partial_getPartialDescriptor, circular); -var render_DomFragment_Component_initialise_createModel_ComponentParameter = function (StringFragment) { - - var ComponentParameter = function (component, key, value) { - this.parentFragment = component.parentFragment; - this.component = component; - this.key = key; - this.fragment = new StringFragment({ - descriptor: value, - root: component.root, - owner: this, - contextStack: component.parentFragment.contextStack - }); - this.selfUpdating = this.fragment.isSimple(); - this.value = this.fragment.getValue(); - }; - ComponentParameter.prototype = { - bubble: function () { - if (this.selfUpdating) { - this.update(); - } else if (!this.deferred && this.ready) { - this.root._deferred.attrs.push(this); - this.deferred = true; - } - }, - update: function () { - var value = this.fragment.getValue(); - this.component.instance.set(this.key, value); - this.value = value; - }, - teardown: function () { - this.fragment.teardown(); - } - }; - return ComponentParameter; - }(render_StringFragment__StringFragment); -var render_DomFragment_Component_initialise_createModel__createModel = function (types, parseJSON, resolveRef, ComponentParameter) { - - return function (component, attributes, toBind) { - var data, key, value; - data = {}; - component.complexParameters = []; - for (key in attributes) { - if (attributes.hasOwnProperty(key)) { - value = getValue(component, key, attributes[key], toBind); - if (value !== undefined) { - data[key] = value; - } - } - } - return data; - }; - function getValue(component, key, descriptor, toBind) { - var parameter, parsed, root, parentFragment, keypath; - root = component.root; - parentFragment = component.parentFragment; - if (typeof descriptor === 'string') { - parsed = parseJSON(descriptor); - return parsed ? parsed.value : descriptor; - } - if (descriptor === null) { - return true; - } - if (descriptor.length === 1 && descriptor[0].t === types.INTERPOLATOR && descriptor[0].r) { - if (parentFragment.indexRefs && parentFragment.indexRefs[descriptor[0].r] !== undefined) { - return parentFragment.indexRefs[descriptor[0].r]; - } - keypath = resolveRef(root, descriptor[0].r, parentFragment.contextStack) || descriptor[0].r; - toBind.push({ - childKeypath: key, - parentKeypath: keypath - }); - return root.get(keypath); - } - parameter = new ComponentParameter(component, key, descriptor); - component.complexParameters.push(parameter); - return parameter.value; - } - }(config_types, utils_parseJSON, shared_resolveRef, render_DomFragment_Component_initialise_createModel_ComponentParameter); -var render_DomFragment_Component_initialise_createInstance = function () { - - return function (component, Component, data, docFrag, contentDescriptor) { - var instance, parentFragment, partials, root; - parentFragment = component.parentFragment; - root = component.root; - partials = { content: contentDescriptor || [] }; - instance = new Component({ - el: parentFragment.pNode.cloneNode(false), - data: data, - partials: partials, - _parent: root, - adaptors: root.adaptors - }); - instance.component = component; - component.instance = instance; - instance.insert(docFrag); - instance.fragment.pNode = parentFragment.pNode; - return instance; - }; - }(); -var render_DomFragment_Component_initialise_createObservers = function () { - - var observeOptions = { - init: false, - debug: true - }; - return function (component, toBind) { - var pair, i; - component.observers = []; - i = toBind.length; - while (i--) { - pair = toBind[i]; - bind(component, pair.parentKeypath, pair.childKeypath); - } - }; - function bind(component, parentKeypath, childKeypath) { - var parentInstance, childInstance, settingParent, settingChild, observers, observer, value; - parentInstance = component.root; - childInstance = component.instance; - observers = component.observers; - observer = parentInstance.observe(parentKeypath, function (value) { - if (!settingParent && !parentInstance._wrapped[parentKeypath]) { - settingChild = true; - childInstance.set(childKeypath, value); - settingChild = false; - } - }, observeOptions); - observers.push(observer); - if (childInstance.twoway) { - observer = childInstance.observe(childKeypath, function (value) { - if (!settingChild) { - settingParent = true; - parentInstance.set(parentKeypath, value); - settingParent = false; - } - }, observeOptions); - observers.push(observer); - value = childInstance.get(childKeypath); - if (value !== undefined) { - parentInstance.set(parentKeypath, value); - } - } - } - }(); -var render_DomFragment_Component_initialise_propagateEvents = function (warn) { - - var errorMessage = 'Components currently only support simple events - you cannot include arguments. Sorry!'; - return function (component, eventsDescriptor) { - var eventName; - for (eventName in eventsDescriptor) { - if (eventsDescriptor.hasOwnProperty(eventName)) { - propagateEvent(component.instance, component.root, eventName, eventsDescriptor[eventName]); - } - } - }; - function propagateEvent(childInstance, parentInstance, eventName, proxyEventName) { - if (typeof proxyEventName !== 'string') { - if (parentInstance.debug) { - throw new Error(errorMessage); - } else { - warn(errorMessage); - return; - } - } - childInstance.on(eventName, function () { - var args = Array.prototype.slice.call(arguments); - args.unshift(proxyEventName); - parentInstance.fire.apply(parentInstance, args); - }); - } - }(utils_warn); -var render_DomFragment_Component_initialise_updateLiveQueries = function () { - - return function (component) { - var ancestor, query; - ancestor = component.root; - while (ancestor) { - if (query = ancestor._liveComponentQueries[component.name]) { - query.push(component.instance); - } - ancestor = ancestor._parent; - } - }; - }(); -var render_DomFragment_Component_initialise__initialise = function (types, warn, createModel, createInstance, createObservers, propagateEvents, updateLiveQueries) { - - return function (component, options, docFrag) { - var parentFragment, root, Component, data, toBind; - parentFragment = component.parentFragment = options.parentFragment; - root = parentFragment.root; - component.root = root; - component.type = types.COMPONENT; - component.name = options.descriptor.e; - component.index = options.index; - component.observers = []; - Component = root.components[options.descriptor.e]; - if (!Component) { - throw new Error('Component "' + options.descriptor.e + '" not found'); - } - toBind = []; - data = createModel(component, options.descriptor.a, toBind); - createInstance(component, Component, data, docFrag, options.descriptor.f); - createObservers(component, toBind); - propagateEvents(component, options.descriptor.v); - if (options.descriptor.t1 || options.descriptor.t2 || options.descriptor.o) { - warn('The "intro", "outro" and "decorator" directives have no effect on components'); - } - updateLiveQueries(component); - }; - }(config_types, utils_warn, render_DomFragment_Component_initialise_createModel__createModel, render_DomFragment_Component_initialise_createInstance, render_DomFragment_Component_initialise_createObservers, render_DomFragment_Component_initialise_propagateEvents, render_DomFragment_Component_initialise_updateLiveQueries); -var render_DomFragment_Component__Component = function (initialise) { - - var DomComponent = function (options, docFrag) { - initialise(this, options, docFrag); - }; - DomComponent.prototype = { - firstNode: function () { - return this.instance.fragment.firstNode(); - }, - findNextNode: function () { - return this.parentFragment.findNextNode(this); - }, - detach: function () { - return this.instance.fragment.detach(); - }, - teardown: function () { - var query; - while (this.complexParameters.length) { - this.complexParameters.pop().teardown(); - } - while (this.observers.length) { - this.observers.pop().cancel(); - } - if (query = this.root._liveComponentQueries[this.name]) { - query._remove(this); - } - this.instance.teardown(); - }, - toString: function () { - return this.instance.fragment.toString(); - }, - find: function (selector) { - return this.instance.fragment.find(selector); - }, - findAll: function (selector, query) { - return this.instance.fragment.findAll(selector, query); - }, - findComponent: function (selector) { - if (!selector || selector === this.name) { - return this.instance; - } - return null; - }, - findAllComponents: function (selector, query) { - query._test(this, true); - if (this.instance.fragment) { - this.instance.fragment.findAllComponents(selector, query); - } - } - }; - return DomComponent; - }(render_DomFragment_Component_initialise__initialise); -var render_DomFragment_Comment = function (types) { - - var DomComment = function (options, docFrag) { - this.type = types.COMMENT; - this.descriptor = options.descriptor; - if (docFrag) { - this.node = document.createComment(options.descriptor.f); - docFrag.appendChild(this.node); - } - }; - DomComment.prototype = { - detach: function () { - this.node.parentNode.removeChild(this.node); - return this.node; - }, - teardown: function (destroy) { - if (destroy) { - this.detach(); - } - }, - firstNode: function () { - return this.node; - }, - toString: function () { - return ''; - } - }; - return DomComment; - }(config_types); -var render_DomFragment__DomFragment = function (types, matches, initFragment, insertHtml, Text, Interpolator, Section, Triple, Element, Partial, Component, Comment, circular) { - - var DomFragment = function (options) { - if (options.pNode) { - this.docFrag = document.createDocumentFragment(); - } - if (typeof options.descriptor === 'string') { - this.html = options.descriptor; - if (this.docFrag) { - this.nodes = insertHtml(this.html, options.pNode.tagName, this.docFrag); - } - } else { - initFragment(this, options); - } - }; - DomFragment.prototype = { - detach: function () { - var len, i; - if (this.nodes) { - i = this.nodes.length; - while (i--) { - this.docFrag.appendChild(this.nodes[i]); - } - } else if (this.items) { - len = this.items.length; - for (i = 0; i < len; i += 1) { - this.docFrag.appendChild(this.items[i].detach()); - } - } - return this.docFrag; - }, - createItem: function (options) { - if (typeof options.descriptor === 'string') { - return new Text(options, this.docFrag); - } - switch (options.descriptor.t) { - case types.INTERPOLATOR: - return new Interpolator(options, this.docFrag); - case types.SECTION: - return new Section(options, this.docFrag); - case types.TRIPLE: - return new Triple(options, this.docFrag); - case types.ELEMENT: - if (this.root.components[options.descriptor.e]) { - return new Component(options, this.docFrag); - } - return new Element(options, this.docFrag); - case types.PARTIAL: - return new Partial(options, this.docFrag); - case types.COMMENT: - return new Comment(options, this.docFrag); - default: - throw new Error('Something very strange happened. Please file an issue at https://github.com/RactiveJS/Ractive/issues. Thanks!'); - } - }, - teardown: function (destroy) { - var node; - if (this.nodes && destroy) { - while (node = this.nodes.pop()) { - node.parentNode.removeChild(node); - } - } else if (this.items) { - while (this.items.length) { - this.items.pop().teardown(destroy); - } - } - this.nodes = this.items = this.docFrag = null; - }, - firstNode: function () { - if (this.items && this.items[0]) { - return this.items[0].firstNode(); - } else if (this.nodes) { - return this.nodes[0] || null; - } - return null; - }, - findNextNode: function (item) { - var index = item.index; - if (this.items[index + 1]) { - return this.items[index + 1].firstNode(); - } - if (this.owner === this.root) { - if (!this.owner.component) { - return null; - } - return this.owner.component.findNextNode(); - } - return this.owner.findNextNode(this); - }, - toString: function () { - var html, i, len, item; - if (this.html) { - return this.html; - } - html = ''; - if (!this.items) { - return html; - } - len = this.items.length; - for (i = 0; i < len; i += 1) { - item = this.items[i]; - html += item.toString(); - } - return html; - }, - find: function (selector) { - var i, len, item, node, queryResult; - if (this.nodes) { - len = this.nodes.length; - for (i = 0; i < len; i += 1) { - node = this.nodes[i]; - if (node.nodeType !== 1) { - continue; - } - if (matches(node, selector)) { - return node; - } - if (queryResult = node.querySelector(selector)) { - return queryResult; - } - } - return null; - } - if (this.items) { - len = this.items.length; - for (i = 0; i < len; i += 1) { - item = this.items[i]; - if (item.find && (queryResult = item.find(selector))) { - return queryResult; - } - } - return null; - } - }, - findAll: function (selector, query) { - var i, len, item, node, queryAllResult, numNodes, j; - if (this.nodes) { - len = this.nodes.length; - for (i = 0; i < len; i += 1) { - node = this.nodes[i]; - if (node.nodeType !== 1) { - continue; - } - if (matches(node, selector)) { - query.push(node); - } - if (queryAllResult = node.querySelectorAll(selector)) { - numNodes = queryAllResult.length; - for (j = 0; j < numNodes; j += 1) { - query.push(queryAllResult[j]); - } - } - } - } else if (this.items) { - len = this.items.length; - for (i = 0; i < len; i += 1) { - item = this.items[i]; - if (item.findAll) { - item.findAll(selector, query); - } - } - } - return query; - }, - findComponent: function (selector) { - var len, i, item, queryResult; - if (this.items) { - len = this.items.length; - for (i = 0; i < len; i += 1) { - item = this.items[i]; - if (item.findComponent && (queryResult = item.findComponent(selector))) { - return queryResult; - } - } - return null; - } - }, - findAllComponents: function (selector, query) { - var i, len, item; - if (this.items) { - len = this.items.length; - for (i = 0; i < len; i += 1) { - item = this.items[i]; - if (item.findAllComponents) { - item.findAllComponents(selector, query); - } - } - } - return query; - } - }; - circular.DomFragment = DomFragment; - return DomFragment; - }(config_types, utils_matches, render_shared_initFragment, render_DomFragment_shared_insertHtml, render_DomFragment_Text, render_DomFragment_Interpolator, render_DomFragment_Section__Section, render_DomFragment_Triple, render_DomFragment_Element__Element, render_DomFragment_Partial__Partial, render_DomFragment_Component__Component, render_DomFragment_Comment, circular); -var Ractive_prototype_render = function (getElement, makeTransitionManager, preDomUpdate, postDomUpdate, DomFragment) { - - return function (target, complete) { - var transitionManager; - if (!this._initing) { - throw new Error('You cannot call ractive.render() directly!'); - } - this._transitionManager = transitionManager = makeTransitionManager(this, complete); - this.fragment = new DomFragment({ - descriptor: this.template, - root: this, - owner: this, - pNode: target - }); - preDomUpdate(this); - if (target) { - target.appendChild(this.fragment.docFrag); - } - postDomUpdate(this); - this._transitionManager = null; - transitionManager.ready(); - this.rendered = true; - }; - }(utils_getElement, shared_makeTransitionManager, shared_preDomUpdate, shared_postDomUpdate, render_DomFragment__DomFragment); -var Ractive_prototype_renderHTML = function (warn) { - - return function () { - warn('renderHTML() has been deprecated and will be removed in a future version. Please use toHTML() instead'); - return this.toHTML(); - }; - }(utils_warn); -var Ractive_prototype_toHTML = function () { - - return function () { - return this.fragment.toString(); - }; - }(); -var Ractive_prototype_teardown = function (makeTransitionManager, clearCache) { - - return function (complete) { - var keypath, transitionManager, previousTransitionManager; - this.fire('teardown'); - previousTransitionManager = this._transitionManager; - this._transitionManager = transitionManager = makeTransitionManager(this, complete); - this.fragment.teardown(true); - while (this._animations[0]) { - this._animations[0].stop(); - } - for (keypath in this._cache) { - clearCache(this, keypath); - } - this._transitionManager = previousTransitionManager; - transitionManager.ready(); - }; - }(shared_makeTransitionManager, shared_clearCache); -var Ractive_prototype_shared_add = function (isNumeric) { - - return function (root, keypath, d) { - var value; - if (typeof keypath !== 'string' || !isNumeric(d)) { - if (root.debug) { - throw new Error('Bad arguments'); - } - return; - } - value = root.get(keypath); - if (value === undefined) { - value = 0; - } - if (!isNumeric(value)) { - if (root.debug) { - throw new Error('Cannot add to a non-numeric value'); - } - return; - } - root.set(keypath, value + d); - }; - }(utils_isNumeric); -var Ractive_prototype_add = function (add) { - - return function (keypath, d) { - add(this, keypath, d === undefined ? 1 : d); - }; - }(Ractive_prototype_shared_add); -var Ractive_prototype_subtract = function (add) { - - return function (keypath, d) { - add(this, keypath, d === undefined ? -1 : -d); - }; - }(Ractive_prototype_shared_add); -var Ractive_prototype_toggle = function () { - - return function (keypath) { - var value; - if (typeof keypath !== 'string') { - if (this.debug) { - throw new Error('Bad arguments'); - } - return; - } - value = this.get(keypath); - this.set(keypath, !value); - }; - }(); -var Ractive_prototype_merge_mapOldToNewIndex = function () { - - return function (oldArray, newArray) { - var usedIndices, mapper, firstUnusedIndex, newIndices, changed; - usedIndices = {}; - firstUnusedIndex = 0; - mapper = function (item, i) { - var index, start, len; - start = firstUnusedIndex; - len = newArray.length; - do { - index = newArray.indexOf(item, start); - if (index === -1) { - changed = true; - return -1; - } - start = index + 1; - } while (usedIndices[index] && start < len); - if (index === firstUnusedIndex) { - firstUnusedIndex += 1; - } - if (index !== i) { - changed = true; - } - usedIndices[index] = true; - return index; - }; - newIndices = oldArray.map(mapper); - newIndices.unchanged = !changed; - return newIndices; - }; - }(); -var Ractive_prototype_merge_queueDependants = function (types) { - - return function queueDependants(keypath, deps, mergeQueue, updateQueue) { - var i, dependant; - i = deps.length; - while (i--) { - dependant = deps[i]; - if (dependant.type === types.REFERENCE) { - dependant.update(); - } else if (dependant.keypath === keypath && dependant.type === types.SECTION && !dependant.inverted && dependant.docFrag) { - mergeQueue[mergeQueue.length] = dependant; - } else { - updateQueue[updateQueue.length] = dependant; - } - } - }; - }(config_types); -var Ractive_prototype_merge__merge = function (warn, isArray, clearCache, preDomUpdate, processDeferredUpdates, makeTransitionManager, notifyDependants, replaceData, mapOldToNewIndex, queueDependants) { - - var identifiers = {}; - return function (keypath, array, options) { - var currentArray, oldArray, newArray, identifier, lengthUnchanged, i, newIndices, mergeQueue, updateQueue, depsByKeypath, deps, transitionManager, previousTransitionManager, upstreamQueue, keys; - currentArray = this.get(keypath); - if (!isArray(currentArray) || !isArray(array)) { - return this.set(keypath, array, options && options.complete); - } - lengthUnchanged = currentArray.length === array.length; - if (options && options.compare) { - if (options.compare === true) { - identifier = stringify; - } else if (typeof options.compare === 'string') { - identifier = getIdentifier(options.compare); - } else if (typeof options.compare == 'function') { - identifier = options.compare; - } else { - throw new Error('The `compare` option must be a function, or a string representing an identifying field (or `true` to use JSON.stringify)'); - } - try { - oldArray = currentArray.map(identifier); - newArray = array.map(identifier); - } catch (err) { - if (this.debug) { - throw err; - } else { - warn('Merge operation: comparison failed. Falling back to identity checking'); - } - oldArray = currentArray; - newArray = array; - } - } else { - oldArray = currentArray; - newArray = array; - } - newIndices = mapOldToNewIndex(oldArray, newArray); - clearCache(this, keypath); - replaceData(this, keypath, array); - if (newIndices.unchanged && lengthUnchanged) { - return; - } - previousTransitionManager = this._transitionManager; - this._transitionManager = transitionManager = makeTransitionManager(this, options && options.complete); - mergeQueue = []; - updateQueue = []; - for (i = 0; i < this._deps.length; i += 1) { - depsByKeypath = this._deps[i]; - if (!depsByKeypath) { - continue; - } - deps = depsByKeypath[keypath]; - if (deps) { - queueDependants(keypath, deps, mergeQueue, updateQueue); - preDomUpdate(this); - while (mergeQueue.length) { - mergeQueue.pop().merge(newIndices); - } - while (updateQueue.length) { - updateQueue.pop().update(); - } - } - } - processDeferredUpdates(this); - upstreamQueue = []; - keys = keypath.split('.'); - while (keys.length) { - keys.pop(); - upstreamQueue[upstreamQueue.length] = keys.join('.'); - } - notifyDependants.multiple(this, upstreamQueue, true); - if (oldArray.length !== newArray.length) { - notifyDependants(this, keypath + '.length', true); - } - this._transitionManager = previousTransitionManager; - transitionManager.ready(); - }; - function stringify(item) { - return JSON.stringify(item); - } - function getIdentifier(str) { - if (!identifiers[str]) { - identifiers[str] = function (item) { - return item[str]; - }; - } - return identifiers[str]; - } - }(utils_warn, utils_isArray, shared_clearCache, shared_preDomUpdate, shared_processDeferredUpdates, shared_makeTransitionManager, shared_notifyDependants, Ractive_prototype_shared_replaceData, Ractive_prototype_merge_mapOldToNewIndex, Ractive_prototype_merge_queueDependants); -var Ractive_prototype_detach = function () { - - return function () { - return this.fragment.detach(); - }; - }(); -var Ractive_prototype_insert = function (getElement) { - - return function (target, anchor) { - target = getElement(target); - anchor = getElement(anchor) || null; - if (!target) { - throw new Error('You must specify a valid target to insert into'); - } - target.insertBefore(this.detach(), anchor); - this.fragment.pNode = target; - }; - }(utils_getElement); -var Ractive_prototype__prototype = function (get, set, update, updateModel, animate, on, off, observe, fire, find, findAll, findComponent, findAllComponents, render, renderHTML, toHTML, teardown, add, subtract, toggle, merge, detach, insert) { - - return { - get: get, - set: set, - update: update, - updateModel: updateModel, - animate: animate, - on: on, - off: off, - observe: observe, - fire: fire, - find: find, - findAll: findAll, - findComponent: findComponent, - findAllComponents: findAllComponents, - renderHTML: renderHTML, - toHTML: toHTML, - render: render, - teardown: teardown, - add: add, - subtract: subtract, - toggle: toggle, - merge: merge, - detach: detach, - insert: insert - }; - }(Ractive_prototype_get__get, Ractive_prototype_set, Ractive_prototype_update, Ractive_prototype_updateModel, Ractive_prototype_animate__animate, Ractive_prototype_on, Ractive_prototype_off, Ractive_prototype_observe__observe, Ractive_prototype_fire, Ractive_prototype_find, Ractive_prototype_findAll, Ractive_prototype_findComponent, Ractive_prototype_findAllComponents, Ractive_prototype_render, Ractive_prototype_renderHTML, Ractive_prototype_toHTML, Ractive_prototype_teardown, Ractive_prototype_add, Ractive_prototype_subtract, Ractive_prototype_toggle, Ractive_prototype_merge__merge, Ractive_prototype_detach, Ractive_prototype_insert); -var extend_registries = function () { - - return [ - 'partials', - 'transitions', - 'events', - 'components', - 'decorators', - 'data' - ]; - }(); -var extend_initOptions = function () { - - return [ - 'el', - 'template', - 'complete', - 'modifyArrays', - 'magic', - 'twoway', - 'lazy', - 'append', - 'preserveWhitespace', - 'sanitize', - 'stripComments', - 'noIntro', - 'transitionsEnabled', - 'adaptors' - ]; - }(); -var extend_inheritFromParent = function (registries, initOptions, create) { - - return function (Child, Parent) { - registries.forEach(function (property) { - if (Parent[property]) { - Child[property] = create(Parent[property]); - } - }); - initOptions.forEach(function (property) { - Child[property] = Parent[property]; - }); - }; - }(extend_registries, extend_initOptions, utils_create); -var extend_wrapMethod = function () { - - return function (method, superMethod) { - if (/_super/.test(method)) { - return function () { - var _super = this._super, result; - this._super = superMethod; - result = method.apply(this, arguments); - this._super = _super; - return result; - }; - } else { - return method; - } - }; - }(); -var extend_utils_augment = function () { - - return function (target, source) { - var key; - for (key in source) { - if (source.hasOwnProperty(key)) { - target[key] = source[key]; - } - } - return target; - }; - }(); -var extend_inheritFromChildProps = function (registries, initOptions, wrapMethod, augment) { - - var blacklist, blacklisted; - blacklist = registries.concat(initOptions); - blacklisted = {}; - blacklist.forEach(function (property) { - blacklisted[property] = true; - }); - return function (Child, childProps) { - var key, member; - registries.forEach(function (property) { - var value = childProps[property]; - if (value) { - if (Child[property]) { - augment(Child[property], value); - } else { - Child[property] = value; - } - } - }); - initOptions.forEach(function (property) { - var value = childProps[property]; - if (value !== undefined) { - if (typeof value === 'function' && typeof Child[property] === 'function') { - Child[property] = wrapMethod(value, Child[property]); - } else { - Child[property] = childProps[property]; - } - } - }); - for (key in childProps) { - if (childProps.hasOwnProperty(key) && !blacklisted[key]) { - member = childProps[key]; - if (typeof member === 'function' && typeof Child.prototype[key] === 'function') { - Child.prototype[key] = wrapMethod(member, Child.prototype[key]); - } else { - Child.prototype[key] = member; - } - } - } - }; - }(extend_registries, extend_initOptions, extend_wrapMethod, extend_utils_augment); -var extend_extractInlinePartials = function (isObject, augment) { - - return function (Child, childProps) { - if (isObject(Child.template)) { - if (!Child.partials) { - Child.partials = {}; - } - augment(Child.partials, Child.template.partials); - if (childProps.partials) { - augment(Child.partials, childProps.partials); - } - Child.template = Child.template.main; - } - }; - }(utils_isObject, extend_utils_augment); -var extend_conditionallyParseTemplate = function (errors, isClient, parse) { - - return function (Child) { - var templateEl; - if (typeof Child.template === 'string') { - if (!parse) { - throw new Error(errors.missingParser); - } - if (Child.template.charAt(0) === '#' && isClient) { - templateEl = document.getElementById(Child.template.substring(1)); - if (templateEl && templateEl.tagName === 'SCRIPT') { - Child.template = parse(templateEl.innerHTML, Child); - } else { - throw new Error('Could not find template element (' + Child.template + ')'); - } - } else { - Child.template = parse(Child.template, Child); - } - } - }; - }(config_errors, config_isClient, parse__parse); -var extend_conditionallyParsePartials = function (errors, parse) { - - return function (Child) { - var key; - if (Child.partials) { - for (key in Child.partials) { - if (Child.partials.hasOwnProperty(key) && typeof Child.partials[key] === 'string') { - if (!parse) { - throw new Error(errors.missingParser); - } - Child.partials[key] = parse(Child.partials[key], Child); - } - } - } - }; - }(config_errors, parse__parse); -var extend_utils_clone = function () { - - return function (source) { - var target = {}, key; - for (key in source) { - if (source.hasOwnProperty(key)) { - target[key] = source[key]; - } - } - return target; - }; - }(); -var utils_extend = function () { - - return function (target) { - var prop, source, sources = Array.prototype.slice.call(arguments, 1); - while (source = sources.shift()) { - for (prop in source) { - if (source.hasOwnProperty(prop)) { - target[prop] = source[prop]; - } - } - } - return target; - }; - }(); -var Ractive_initialise = function (isClient, errors, warn, create, extend, defineProperty, defineProperties, getElement, isObject, magicAdaptor, parse) { - - var getObject, getArray, defaultOptions, registries; - getObject = function () { - return {}; - }; - getArray = function () { - return []; - }; - defaultOptions = create(null); - defineProperties(defaultOptions, { - preserveWhitespace: { - enumerable: true, - value: false - }, - append: { - enumerable: true, - value: false - }, - twoway: { - enumerable: true, - value: true - }, - modifyArrays: { - enumerable: true, - value: true - }, - data: { - enumerable: true, - value: getObject - }, - lazy: { - enumerable: true, - value: false - }, - debug: { - enumerable: true, - value: false - }, - transitions: { - enumerable: true, - value: getObject - }, - decorators: { - enumerable: true, - value: getObject - }, - events: { - enumerable: true, - value: getObject - }, - noIntro: { - enumerable: true, - value: false - }, - transitionsEnabled: { - enumerable: true, - value: true - }, - magic: { - enumerable: true, - value: false - }, - adaptors: { - enumerable: true, - value: getArray - } - }); - registries = [ - 'components', - 'decorators', - 'events', - 'partials', - 'transitions', - 'data' - ]; - return function (ractive, options) { - var key, template, templateEl, parsedTemplate; - for (key in defaultOptions) { - if (options[key] === undefined) { - options[key] = typeof defaultOptions[key] === 'function' ? defaultOptions[key]() : defaultOptions[key]; - } - } - defineProperties(ractive, { - _initing: { - value: true, - writable: true - }, - _guid: { - value: 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { - var r, v; - r = Math.random() * 16 | 0; - v = c == 'x' ? r : r & 3 | 8; - return v.toString(16); - }) - }, - _subs: { - value: create(null), - configurable: true - }, - _cache: { value: {} }, - _cacheMap: { value: create(null) }, - _deps: { value: [] }, - _depsMap: { value: create(null) }, - _patternObservers: { value: [] }, - _pendingResolution: { value: [] }, - _deferred: { value: {} }, - _evaluators: { value: create(null) }, - _twowayBindings: { value: {} }, - _transitionManager: { - value: null, - writable: true - }, - _animations: { value: [] }, - nodes: { value: {} }, - _wrapped: { value: create(null) }, - _liveQueries: { value: [] }, - _liveComponentQueries: { value: [] } - }); - defineProperties(ractive._deferred, { - attrs: { value: [] }, - evals: { value: [] }, - selectValues: { value: [] }, - checkboxes: { value: [] }, - radios: { value: [] }, - observers: { value: [] }, - transitions: { value: [] }, - liveQueries: { value: [] }, - decorators: { value: [] }, - focusable: { - value: null, - writable: true - } - }); - ractive.adaptors = options.adaptors; - ractive.modifyArrays = options.modifyArrays; - ractive.magic = options.magic; - ractive.twoway = options.twoway; - ractive.lazy = options.lazy; - ractive.debug = options.debug; - if (ractive.magic && !magicAdaptor) { - throw new Error('Getters and setters (magic mode) are not supported in this browser'); - } - if (options._parent) { - defineProperty(ractive, '_parent', { value: options._parent }); - } - if (options.el) { - ractive.el = getElement(options.el); - if (!ractive.el && ractive.debug) { - throw new Error('Could not find container element'); - } - } - if (options.eventDefinitions) { - warn('ractive.eventDefinitions has been deprecated in favour of ractive.events. Support will be removed in future versions'); - options.events = options.eventDefinitions; - } - registries.forEach(function (registry) { - if (ractive.constructor[registry]) { - ractive[registry] = extend(create(ractive.constructor[registry] || {}), options[registry]); - } else if (options[registry]) { - ractive[registry] = options[registry]; - } - }); - template = options.template; - if (typeof template === 'string') { - if (!parse) { - throw new Error(errors.missingParser); - } - if (template.charAt(0) === '#' && isClient) { - templateEl = document.getElementById(template.substring(1)); - if (templateEl) { - parsedTemplate = parse(templateEl.innerHTML, options); - } else { - throw new Error('Could not find template element (' + template + ')'); - } - } else { - parsedTemplate = parse(template, options); - } - } else { - parsedTemplate = template; - } - if (isObject(parsedTemplate)) { - extend(ractive.partials, parsedTemplate.partials); - parsedTemplate = parsedTemplate.main; - } - if (parsedTemplate && parsedTemplate.length === 1 && typeof parsedTemplate[0] === 'string') { - parsedTemplate = parsedTemplate[0]; - } - ractive.template = parsedTemplate; - extend(ractive.partials, options.partials); - ractive.parseOptions = { - preserveWhitespace: options.preserveWhitespace, - sanitize: options.sanitize, - stripComments: options.stripComments - }; - ractive.transitionsEnabled = options.noIntro ? false : options.transitionsEnabled; - if (isClient && !ractive.el) { - ractive.el = document.createDocumentFragment(); - } - if (ractive.el && !options.append) { - ractive.el.innerHTML = ''; - } - ractive.render(ractive.el, options.complete); - ractive.transitionsEnabled = options.transitionsEnabled; - ractive._initing = false; - }; - }(config_isClient, config_errors, utils_warn, utils_create, utils_extend, utils_defineProperty, utils_defineProperties, utils_getElement, utils_isObject, Ractive_prototype_get_magicAdaptor, parse__parse); -var extend_initChildInstance = function (fillGaps, initOptions, clone, wrapMethod, initialise) { - - return function (child, Child, options) { - initOptions.forEach(function (property) { - var value = options[property], defaultValue = Child[property]; - if (typeof value === 'function' && typeof defaultValue === 'function') { - options[property] = wrapMethod(value, defaultValue); - } else if (value === undefined && defaultValue !== undefined) { - options[property] = defaultValue; - } - }); - if (child.beforeInit) { - child.beforeInit(options); - } - initialise(child, options); - if (child.init) { - child.init(options); - } - }; - }(utils_fillGaps, extend_initOptions, extend_utils_clone, extend_wrapMethod, Ractive_initialise); -var extend__extend = function (create, inheritFromParent, inheritFromChildProps, extractInlinePartials, conditionallyParseTemplate, conditionallyParsePartials, initChildInstance, circular) { - - var Ractive; - circular.push(function () { - Ractive = circular.Ractive; - }); - return function (childProps) { - var Parent = this, Child; - Child = function (options) { - initChildInstance(this, Child, options || {}); - }; - Child.prototype = create(Parent.prototype); - Child.prototype.constructor = Child; - inheritFromParent(Child, Parent); - inheritFromChildProps(Child, childProps); - conditionallyParseTemplate(Child); - extractInlinePartials(Child, childProps); - conditionallyParsePartials(Child); - Child.extend = Parent.extend; - return Child; - }; - }(utils_create, extend_inheritFromParent, extend_inheritFromChildProps, extend_extractInlinePartials, extend_conditionallyParseTemplate, extend_conditionallyParsePartials, extend_initChildInstance, circular); -var Ractive__Ractive = function (svg, create, defineProperties, prototype, partialRegistry, adaptorRegistry, easingRegistry, Ractive_extend, parse, initialise, circular) { - - var Ractive = function (options) { - initialise(this, options); - }; - defineProperties(Ractive, { - prototype: { value: prototype }, - partials: { value: partialRegistry }, - adaptors: { value: adaptorRegistry }, - easing: { value: easingRegistry }, - transitions: { value: {} }, - events: { value: {} }, - components: { value: {} }, - decorators: { value: {} }, - svg: { value: svg }, - VERSION: { value: '0.3.9' } - }); - Ractive.eventDefinitions = Ractive.events; - Ractive.prototype.constructor = Ractive; - Ractive.delimiters = [ - '{{', - '}}' - ]; - Ractive.tripleDelimiters = [ - '{{{', - '}}}' - ]; - Ractive.extend = Ractive_extend; - Ractive.parse = parse; - circular.Ractive = Ractive; - return Ractive; - }(config_svg, utils_create, utils_defineProperties, Ractive_prototype__prototype, registries_partials, registries_adaptors, registries_easing, extend__extend, parse__parse, Ractive_initialise, circular); -var Ractive = function (Ractive, circular) { - - if (typeof window !== 'undefined' && window.Node && !window.Node.prototype.contains && window.HTMLElement && window.HTMLElement.prototype.contains) { - window.Node.prototype.contains = window.HTMLElement.prototype.contains; - } - while (circular.length) { - circular.pop()(); - } - return Ractive; - }(Ractive__Ractive, circular); -// export as Common JS module... -if ( typeof module !== "undefined" && module.exports ) { - module.exports = Ractive; -} - -// ... or as AMD module -else if ( typeof define === "function" && define.amd ) { - define( function () { - return Ractive; - }); -} - -// ... or as browser global -else { - global.Ractive = Ractive; -} - -}( typeof window !== 'undefined' ? window : this )); \ No newline at end of file diff --git a/build/Ractive-legacy.runtime.min.js b/build/Ractive-legacy.runtime.min.js deleted file mode 100644 index ac34c3f32f..0000000000 --- a/build/Ractive-legacy.runtime.min.js +++ /dev/null @@ -1,4 +0,0 @@ -!function(a){"use strict";var b=a.document;b&&(Date.now||(Date.now=function(){return+new Date}),String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^\s+/,"").replace(/\s+$/,"")}),Object.keys||(Object.keys=function(){var a=Object.prototype.hasOwnProperty,b=!{toString:null}.propertyIsEnumerable("toString"),c=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],d=c.length;return function(e){if("object"!=typeof e&&"function"!=typeof e||null===e)throw new TypeError("Object.keys called on non-object");var f=[];for(var g in e)a.call(e,g)&&f.push(g);if(b)for(var h=0;d>h;h++)a.call(e,c[h])&&f.push(c[h]);return f}}()),Array.prototype.indexOf||(Array.prototype.indexOf=function(a,b){var c;for(void 0===b&&(b=0),0>b&&(b+=this.length),0>b&&(b=0),c=this.length;c>b;b++)if(this.hasOwnProperty(b)&&this[b]===a)return b;return-1}),Array.prototype.forEach||(Array.prototype.forEach=function(a,b){var c,d;for(c=0,d=this.length;d>c;c+=1)this.hasOwnProperty(c)&&a.call(b,this[c],c,this)}),Array.prototype.map||(Array.prototype.map=function(a,b){var c,d,e=[];for(c=0,d=this.length;d>c;c+=1)this.hasOwnProperty(c)&&(e[c]=a.call(b,this[c],c,this));return e}),Array.prototype.filter||(Array.prototype.filter=function(a,b){var c,d,e=[];for(c=0,d=this.length;d>c;c+=1)this.hasOwnProperty(c)&&a.call(b,this[c],c,this)&&(e[e.length]=this[c]);return e}),a.addEventListener||!function(a,b){var c,d,e,f,g,h;c=function(a,b){var c,d=this;for(c in a)d[c]=a[c];d.currentTarget=b,d.target=a.srcElement||b,d.timeStamp=+new Date,d.preventDefault=function(){a.returnValue=!1},d.stopPropagation=function(){a.cancelBubble=!0}},d=function(a,b){var d,e,f=this;d=f.listeners||(f.listeners=[]),e=d.length,d[e]=[b,function(a){b.call(f,new c(a,f))}],f.attachEvent("on"+a,d[e][1])},e=function(a,b){var c,d,e=this;if(e.listeners)for(c=e.listeners,d=c.length;d--;)c[d][0]===b&&e.detachEvent("on"+a,c[d][1])},a.addEventListener=b.addEventListener=d,a.removeEventListener=b.removeEventListener=e,"Element"in a?(Element.prototype.addEventListener=d,Element.prototype.removeEventListener=e):(h=b.createElement,b.createElement=function(a){var b=h(a);return b.addEventListener=d,b.removeEventListener=e,b},f=b.getElementsByTagName("head")[0],g=b.createElement("style"),f.insertBefore(g,f.firstChild))}(a,b),a.getComputedStyle||(a.getComputedStyle=function(){function a(b,c,d,e){var f,g=c[d],h=parseFloat(g),i=g.split(/\d/)[0];return e=null!=e?e:/%|em/.test(i)&&b.parentElement?a(b.parentElement,b.parentElement.currentStyle,"fontSize",null):16,f="fontSize"==d?e:/width/i.test(d)?b.clientWidth:b.clientHeight,"em"==i?h*e:"in"==i?96*h:"pt"==i?96*h/72:"%"==i?h/100*f:h}function b(a,b){var c="border"==b?"Width":"",d=b+"Top"+c,e=b+"Right"+c,f=b+"Bottom"+c,g=b+"Left"+c;a[b]=(a[d]==a[e]==a[f]==a[g]?[a[d]]:a[d]==a[f]&&a[g]==a[e]?[a[d],a[e]]:a[g]==a[e]?[a[d],a[e],a[f]]:[a[d],a[e],a[f],a[g]]).join(" ")}function c(c){var d,e,f,g;d=c.currentStyle,e=this,f=a(c,d,"fontSize",null);for(g in d)/width|height|margin.|padding.|border.+W/.test(g)&&"auto"!==e[g]?e[g]=a(c,d,g,f)+"px":"styleFloat"===g?e.float=d[g]:e[g]=d[g];return b(e,"margin"),b(e,"padding"),b(e,"border"),e.fontSize=f+"px",e}function d(a){return new c(a)}return c.prototype={constructor:c,getPropertyPriority:function(){},getPropertyValue:function(a){return this[a]||""},item:function(){},removeProperty:function(){},setProperty:function(){},getPropertyCSSValue:function(){}},d}()))}("undefined"!=typeof window?window:this),function(a){var b=function(){return"undefined"!=typeof document?document&&document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1"):void 0}(),c=function(){var a;try{Object.create(null),a=Object.create}catch(b){a=function(){var a=function(){};return function(b,c){var d;return null===b?{}:(a.prototype=b,d=new a,c&&Object.defineProperties(d,c),d)}}()}return a}(),d={html:"http://www.w3.org/1999/xhtml",mathml:"http://www.w3.org/1998/Math/MathML",svg:"http://www.w3.org/2000/svg",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"},e=function(a,b){return a?function(a,b){return b?document.createElementNS(b,a):document.createElement(a)}:function(a,c){if(c&&c!==b.html)throw"This browser does not support namespaces other than http://www.w3.org/1999/xhtml. The most likely cause of this error is that you're trying to render SVG in an older browser. See https://github.com/RactiveJS/Ractive/wiki/SVG-and-older-browsers for more information";return document.createElement(a)}}(b,d),f=function(){return"object"==typeof document?!0:!1}(),g=function(a){try{return Object.defineProperty({},"test",{value:0}),a&&Object.defineProperty(document.createElement("div"),"test",{value:0}),Object.defineProperty}catch(b){return function(a,b,c){a[b]=c.value}}}(f),h=function(a,b,c){try{try{Object.defineProperties({},{test:{value:0}})}catch(d){throw d}return c&&Object.defineProperties(a("div"),{test:{value:0}}),Object.defineProperties}catch(d){return function(a,c){var d;for(d in c)c.hasOwnProperty(d)&&b(a,d,c[d])}}}(e,g,f),i=function(){var a=/\[\s*(\*|[0-9]|[1-9][0-9]+)\s*\]/g;return function(b){return(b||"").replace(a,".$1")}}(),j={},k={TEXT:1,INTERPOLATOR:2,TRIPLE:3,SECTION:4,INVERTED:5,CLOSING:6,ELEMENT:7,PARTIAL:8,COMMENT:9,DELIMCHANGE:10,MUSTACHE:11,TAG:12,ATTRIBUTE:13,COMPONENT:15,NUMBER_LITERAL:20,STRING_LITERAL:21,ARRAY_LITERAL:22,OBJECT_LITERAL:23,BOOLEAN_LITERAL:24,GLOBAL:26,KEY_VALUE_PAIR:27,REFERENCE:30,REFINEMENT:31,MEMBER:32,PREFIX_OPERATOR:33,BRACKETED:34,CONDITIONAL:35,INFIX_OPERATOR:36,INVOCATION:40},l=function(){var a=Object.prototype.toString;return function(b){return"[object Array]"===a.call(b)}}(),m=function(){return function a(b,c){var d,e;if((e=b._wrapped[c])&&e.teardown()!==!1&&(b._wrapped[c]=null),b._cache[c]=void 0,d=b._cacheMap[c])for(;d.length;)a(b,d.pop())}}(),n=function(){return function(a,b){var c,d,e,f,g,h;for(c=[],h=a.rendered?a.el:a.fragment.docFrag,d=h.querySelectorAll('input[type="checkbox"][name="{{'+b+'}}"]'),f=d.length,g=0;f>g;g+=1)e=d[g],(e.hasAttribute("checked")||e.checked)&&(c[c.length]=e._ractive.value);return c}}(),o=function(a){return function(b){var c,d,e,f,g,h;for(c=b._deferred;d=c.evals.pop();)d.update().deferred=!1;for(;e=c.selectValues.pop();)e.deferredUpdate();for(;f=c.attrs.pop();)f.update().deferred=!1;for(;g=c.checkboxes.pop();)b.set(g,a(b,g));for(;h=c.radios.pop();)h.update()}}(n),p=function(){return function(a){var b,c,d,e,f,g;for(b=a._deferred,(c=b.focusable)&&(c.focus(),b.focusable=null);d=b.liveQueries.pop();)d._sort();for(;e=b.decorators.pop();)e.init();for(;f=b.transitions.pop();)f.init();for(;g=b.observers.pop();)g.update()}}(),q=function(){var a=function(a,b){var c,d,e,f;return a._parent&&a._parent._transitionManager?a._parent._transitionManager:(d=[],e=function(){var a,b;for(a=d.length;a--;)b=d[a],f(b.node)&&(b.detach(),d.splice(a,1))},f=function(a){var b,d;for(b=c.active.length;b--;)if(d=c.active[b],a.contains(d))return!1;return!0},c={active:[],push:function(a){c.active[c.active.length]=a},pop:function(a){var b;b=c.active.indexOf(a),-1!==b&&(c.active.splice(b,1),e(),!c.active.length&&c._ready&&c.complete())},complete:function(){b&&b.call(a)},ready:function(){e(),c._ready=!0,c.active.length||c.complete()},detachWhenReady:function(a){d[d.length]=a}})};return a}(),r=function(){function a(a,d,e,f){var g=a._deps[e];g&&(b(g[d]),f||c(a._depsMap[d],a,e))}function b(a){var b,c;if(a)for(c=a.length,b=0;c>b;b+=1)a[b].update()}function c(b,c,d,e){var f;if(b)for(f=b.length;f--;)a(c,b[f],d,e)}function d(a,b,c,f,g){var i,j,k,l,m,n,o,p;for(i=a._patternObservers.length;i--;)j=a._patternObservers[i],j.regex.test(c)&&j.update(c);f||(p=function(b){if(k=a._depsMap[b])for(i=k.length;i--;)l=k[i],m=h.exec(l)[0],n=c+"."+m,d(a,l,n)},g?(o=e(c),o.forEach(p)):p(b))}function e(a){var b,c,d,e,g,h;for(b=a.split("."),c=f(b.length),g=[],d=function(a,c){return a?"*":b[c]},e=c.length;e--;)h=c[e].map(d).join("."),g[h]||(g[g.length]=h,g[h]=!0);return g}function f(a){var b,c,d,e,f,g="";if(!i[a]){for(d=[];g.length=f;f+=1){for(c=f.toString(2);c.length2&&f[1])for(q=Math.min(f[1],f.length-2),r=f[0],s=r+q,f[1]===f.length-2&&(u=!0),p=r;s>p;p+=1)t=g+"."+p,h(a,t);for(e(a),m=[],l=g.split(".");l.length;)l.pop(),m[m.length]=l.join(".");h.multiple(a,m,!0),u||h(a,g+".length",!0)},i=function(b,c,d,e){var f,g;for(f=c.length;f--;)g=c[f],g.type===a.REFERENCE?g.update():g.keypath===b&&g.type===a.SECTION&&!g.inverted&&g.docFrag?d[d.length]=g:e[e.length]=g},j=b._ractive.wrappers,l=j.length;l--;)k=j[l],g(k.root,k.keypath)},n=[],p=["pop","push","reverse","shift","sort","splice","unshift"],q=function(){},p.forEach(function(a){var c=function(){var b,c,d,h,i={},k={};for(b=Array.prototype[a].apply(this,arguments),c=this._ractive.instances,h=c.length;h--;)d=c[h],i[d._guid]=d._transitionManager,d._transitionManager=k[d._guid]=g(d,q);for(this._ractive.setting=!0,j(this,a,arguments),this._ractive.setting=!1,h=c.length;h--;)d=c[h],d._transitionManager=i[d._guid],k[d._guid].ready(),e(d),f(d);return b};b(n,a,{value:c})}),o={},o.__proto__?(l=function(a){a.__proto__=n},m=function(a){a.__proto__=Array.prototype}):(l=function(a){var c,d;for(c=p.length;c--;)d=p[c],b(a,d,{value:n[d],configurable:!0})},m=function(a){var b;for(b=p.length;b--;)delete a[p[b]]}),r="Something went wrong in a rather interesting way",i}(k,g,l,m,o,p,q,r),t=function(){var a,b;try{Object.defineProperty({},"test",{value:0})}catch(c){return!1}return a={filter:function(a,b){return!!b},wrap:function(a,c,d){return new b(a,c,d)}},b=function(a,b,c){var d,e,f,g,h,i,j,k,l,m=this;if(this.ractive=a,this.keypath=c,d=c.split("."),this.prop=d.pop(),f=d.join("."),this.obj=f?a.get(f):a.data,g=this.originalDescriptor=Object.getOwnPropertyDescriptor(this.obj,this.prop),g&&g.set&&(h=g.set._ractiveWrappers))return-1===h.indexOf(this)&&h.push(this),void 0;if(g&&!g.configurable)throw new Error('Cannot use magic mode with property "'+e+'" - object is not configurable');g&&(this.value=g.value,i=g.get,j=g.set),k=i||function(){return m.value},l=function(a){var b,c,d;for(j&&j(a),b=l._ractiveWrappers,d=b.length;d--;)c=b[d],c.resetting||c.ractive.set(c.keypath,a)},l._ractiveWrappers=[this],Object.defineProperty(this.obj,this.prop,{get:k,set:l,enumerable:!0,configurable:!0})},b.prototype={get:function(){return this.value},reset:function(a){this.resetting=!0,this.value=a,this.resetting=!1},teardown:function(){var a,b,c,d;a=Object.getOwnPropertyDescriptor(this.obj,this.prop),b=a.set,d=b._ractiveWrappers,d.splice(d.indexOf(this),1),d.length||(c=this.obj[this.prop],Object.defineProperty(this.obj,this.prop,this.originalDescriptor||{writable:!0,enumerable:!0,configrable:!0}),this.obj[this.prop]=c)}},a}(),u=function(a,b,c){function d(a,b){var c,d={};if(!b)return a;b+=".";for(c in a)a.hasOwnProperty(c)&&(d[b+c]=a[c]);return d}function e(a){var b;return f[a]||(b=a?a+".":"",f[a]=function(c,e){var f;return"string"==typeof c?(f={},f[b+c]=e,f):"object"==typeof c?b?d(c,a):c:void 0}),f[a]}var f={};return function(d,f,g,h){var i,j,k,l;for(i=d.adaptors.length,j=0;i>j;j+=1){if(k=d.adaptors[j],"string"==typeof k){if(!a[k])throw new Error('Missing adaptor "'+k+'"');k=d.adaptors[j]=a[k]}if(k.filter(g,f,d))return l=d._wrapped[f]=k.wrap(d,g,f,e(f)),l.value=g,void 0}h||(d.magic&&c.filter(g,f,d)?d._wrapped[f]=c.wrap(d,g,f):d.modifyArrays&&b.filter(g,f,d)&&(d._wrapped[f]=b.wrap(d,g,f)))}}(j,s,t),v=function(a,b,c){var d,e,f;return d=function(a){return this._captured&&!this._captured[a]&&(this._captured.push(a),this._captured[a]=!0),e(this,a)},e=function(b,d){var e,g,h,i,j;return d=a(d),e=b._cache,void 0!==(g=e[d])?g:((i=b._wrapped[d])?h=i.value:d?h=(j=b._evaluators[d])?j.value:f(b,d):(c(b,"",b.data),h=b.data),e[d]=h,h)},f=function(a,b){var d,f,g,h,i,j,k;return d=b.split("."),f=d.pop(),g=d.join("."),h=e(a,g),(k=a._wrapped[g])&&(h=k.get()),null!==h&&void 0!==h?((i=a._cacheMap[g])?-1===i.indexOf(b)&&(i[i.length]=b):a._cacheMap[g]=[b],j=h[f],c(a,b,j),a._cache[b]=j,j):void 0},d}(i,j,u),w=function(){var a=Object.prototype.toString;return function(b){return"object"==typeof b&&"[object Object]"===a.call(b)}}(),x=function(){return function(a,b){return null===a&&null===b?!0:"object"==typeof a||"object"==typeof b?!1:a===b}}(),y=function(){var a;return a=function(a,b,c){var d,e,f,g,h,i,j,k,l,m,n;if(n='Could not resolve reference - too many "../" prefixes',"."===b){if(!c.length)return"";d=c[c.length-1]}else if("."===b.charAt(0))if(m=c[c.length-1],g=m?m.split("."):[],"../"===b.substr(0,3)){for(;"../"===b.substr(0,3);){if(!g.length)throw new Error(n);g.pop(),b=b.substring(3)}g.push(b),d=g.join(".")}else d=m?m+b:b.substring(1);else{for(e=b.split("."),f=e.pop(),i=e.length?"."+e.join("."):"",c=c.concat();c.length;)if(h=c.pop(),j=h+i,k=a.get(j),(l=a._wrapped[j])&&(k=l.get()),"object"==typeof k&&null!==k&&k.hasOwnProperty(f)){d=h+"."+b;break}d||void 0===a.get(b)||(d=b)}return d?d.replace(/^\./,""):d}}(),z=function(a){var b=Array.prototype.push;return function(c){for(var d,e,f;d=c._pendingResolution.pop();)e=a(c,d.ref,d.contextStack),void 0!==e?d.resolve(e):(f||(f=[])).push(d);f&&b.apply(c._pendingResolution,f)}}(y),A=function(a,b){return function(c){a(c),b(c)}}(o,p),B=function(){return function(a,b,c){var d,e,f,g,h,i,j;for(d=b.split("."),e=[],(f=a._wrapped[""])?(f.set&&f.set(d.join("."),c),g=f.get()):g=a.data;d.length>1;)h=e[e.length]=d.shift(),i=e.join("."),(f=a._wrapped[i])?(f.set&&f.set(d.join("."),c),g=f.get()):(g.hasOwnProperty(h)||(j||(j=i),g[h]=/^\s*[0-9]+\s*$/.test(d[0])?[]:{}),g=g[h]);return h=d[0],g[h]=c,j}}(),C=function(a,b,c,d,e,f,g,h,i){var j,k,l,m;return j=function(b,d,i){var j,m,n,o,p,q,r;if(m=[],a(b)&&(j=b,i=d),j)for(b in j)j.hasOwnProperty(b)&&(d=j[b],b=c(b),k(this,b,d,m));else b=c(b),k(this,b,d,m);if(m.length){if(o=this._transitionManager,this._transitionManager=p=g(this,i),n=l(m),n.length&&e.multiple(this,n,!0),e.multiple(this,m),this._pendingResolution.length&&f(this),h(this),this._transitionManager=o,p.ready(),!this.firingChangeEvent){for(this.firingChangeEvent=!0,r={},q=m.length;q--;)r[m[q]]=this.get(m[q]);this.fire("change",r),this.firingChangeEvent=!1}return this}},k=function(a,b,c,e){var f,g,h,j,k;if(!(h=a._wrapped[b])||!h.reset||m(a,b,c,h,e)===!1){if((k=a._evaluators[b])&&(k.value=c),f=a._cache[b],g=a.get(b),g===c||k){if(c===f&&"object"!=typeof c)return}else j=i(a,b,c);d(a,j||b),e[e.length]=b}},l=function(a){var b,c,d,e,f=[""];for(b=a.length;b--;)for(c=a[b],d=c.split(".");d.length>1;)d.pop(),e=d.join("."),f[e]||(f[f.length]=e,f[e]=!0);return f},m=function(a,c,e,f,g){var h,i,j,k;if(h=f.get(),!b(h,e)&&f.reset(e)===!1)return!1;if(e=f.get(),i=a._cache[c],!b(i,e)){if(a._cache[c]=e,j=a._cacheMap[c])for(k=j.length;k--;)d(a,j[k]);g[g.length]=c}},j}(w,x,i,m,r,z,q,A,B),D=function(a,b,c,d,e){return function(f,g){var h,i;return"function"==typeof f&&(g=f,f=""),i=this._transitionManager,this._transitionManager=h=a(this,g),b(this),c(this,f||""),d(this,f||""),e(this),this._transitionManager=i,h.ready(),"string"==typeof f?this.fire("update",f):this.fire("update"),this}}(q,z,m,r,A),E=function(a){return function(b,c){var d;if(!a(b)||!a(c))return!1;if(b.length!==c.length)return!1;for(d=b.length;d--;)if(b[d]!==c[d])return!1;return!0}}(l),F=function(a,b,c){function d(a,e,f,g,h){var i,j,k,l,m,n;if(i=a._twowayBindings[e])for(k=i.length;k--;)l=i[k],(!l.radioName||l.node.checked)&&(l.checkboxName?l.changed()&&!g[e]&&(g[e]=!0,g[g.length]=e):(m=l.attr.value,n=l.value(),b(m,n)||c(m,n)||(f[e]=n)));if(h&&(j=a._depsMap[e]))for(k=j.length;k--;)d(a,j[k],f,g,h)}return function(b,c){var e,f,g;if("string"!=typeof b&&(b="",c=!0),d(this,b,e={},f=[],c),g=f.length)for(;g--;)b=f[g],e[b]=a(this,b);this.set(e)}}(n,E,x),G=function(){return"undefined"!=typeof window?(function(a,b,c){var d,e;if(!c.requestAnimationFrame){for(d=0;d=this.duration?(null!==g&&this.root.set(g,this.to),this.step&&this.step(1,this.to),this.complete&&this.complete(1,this.to),f=this.root._animations.indexOf(this),-1===f&&a("Animation was not found"),this.root._animations.splice(f,1),this.running=!1,!1):(c=this.easing?this.easing(b/this.duration):b/this.duration,null!==g&&(d=this.interpolator(c),this.root.set(g,d)),this.step&&this.step(c,d),!0)):!1},stop:function(){var b;this.running=!1,b=this.root._animations.indexOf(this),-1===b&&a("Animation was not found"),this.root._animations.splice(b,1)}},c}(I,K),M=function(){return{linear:function(a){return a},easeIn:function(a){return Math.pow(a,3)},easeOut:function(a){return Math.pow(a-1,3)+1},easeInOut:function(a){return(a/=.5)<1?.5*Math.pow(a,3):.5*(Math.pow(a-2,3)+2)}}}(),N=function(a,b,c,d){function e(e,g,h,i){var j,k,l,m;return null!==g&&(m=e.get(g)),b.abort(g,e),a(m,h)?(i.complete&&i.complete(1,i.to),f):(i.easing&&(j="function"==typeof i.easing?i.easing:e.easing&&e.easing[i.easing]?e.easing[i.easing]:d[i.easing],"function"!=typeof j&&(j=null)),k=void 0===i.duration?400:i.duration,l=new c({keypath:g,from:m,to:h,root:e,duration:k,easing:j,step:i.step,complete:i.complete}),b.add(l),e._animations[e._animations.length]=l,l)}var f={stop:function(){}};return function(a,b,c){var d,f,g,h,i,j,k,l,m,n,o,p;if("object"==typeof a){c=b||{},h=c.easing,i=c.duration,g=[],j=c.step,k=c.complete,(j||k)&&(m={},c.step=null,c.complete=null,l=function(a){return function(b,c){m[a]=c}});for(d in a)a.hasOwnProperty(d)&&((j||k)&&(n=l(d),c={easing:h,duration:i},j&&(c.step=n),k&&(c.complete=n)),g[g.length]=e(this,d,a[d],c));return(j||k)&&(p={easing:h,duration:i},j&&(p.step=function(a){j(a,m)}),k&&(p.complete=function(a){k(a,m)}),g[g.length]=o=e(this,null,null,p)),{stop:function(){for(;g.length;)g.pop().stop();o&&o.stop()}}}return c=c||{},f=e(this,a,b,c),{stop:function(){f.stop()}}}}(x,H,L,M),O=function(){return function(a,b){var c,d,e=this;if("object"==typeof a){c=[];for(d in a)a.hasOwnProperty(d)&&(c[c.length]=this.on(d,a[d]));return{cancel:function(){for(;c.length;)c.pop().cancel()}}}return this._subs[a]?this._subs[a].push(b):this._subs[a]=[b],{cancel:function(){e.off(a,b)}}}}(),P=function(){return function(a,b){var c,d;if(!b)if(a)this._subs[a]=[];else for(a in this._subs)delete this._subs[a];c=this._subs[a],c&&(d=c.indexOf(b),-1!==d&&c.splice(d,1))}}(),Q=function(){return function(a){var b,c,d,e,f,g,h,i;if(g=a.root,h=a.keypath,i=a.priority,b=g._deps[i]||(g._deps[i]={}),c=b[h]||(b[h]=[]),c[c.length]=a,a.registered=!0,h)for(d=h.split(".");d.length;)d.pop(),e=d.join("."),f=g._depsMap[e]||(g._depsMap[e]=[]),void 0===f[h]&&(f[h]=0,f[f.length]=h),f[h]+=1,h=e}}(),R=function(){return function(a){var b,c,d,e,f,g,h,i;if(g=a.root,h=a.keypath,i=a.priority,b=g._deps[i][h],c=b.indexOf(a),-1===c||!a.registered)throw new Error("Attempted to remove a dependant that was no longer registered! This should not happen. If you are seeing this bug in development please raise an issue at https://github.com/RactiveJS/Ractive/issues - thanks");if(b.splice(c,1),a.registered=!1,h)for(d=h.split(".");d.length;)d.pop(),e=d.join("."),f=g._depsMap[e],f[h]-=1,f[h]||(f.splice(f.indexOf(h),1),f[h]=void 0),h=e}}(),S=function(a){var b=function(a,b,c,d){var e=this;this.root=a,this.keypath=b,this.callback=c,this.defer=d.defer,this.debug=d.debug,this.proxy={update:function(){e.reallyUpdate()}},this.priority=0,this.context=d&&d.context?d.context:a};return b.prototype={init:function(a){a!==!1?this.update():this.value=this.root.get(this.keypath)},update:function(){return this.defer&&this.ready?(this.root._deferred.observers.push(this.proxy),void 0):(this.reallyUpdate(),void 0)},reallyUpdate:function(){var b,c;if(b=this.value,c=this.root.get(this.keypath),this.value=c,!this.updating){if(this.updating=!0,!a(c,b)||!this.ready)try{this.callback.call(this.context,c,b,this.keypath)}catch(d){if(this.debug||this.root.debug)throw d}this.updating=!1}}},b}(x),T=function(){return function(a,b){var c,d,e,f,g,h,i;for(c=b.split("."),f=[],h=function(b){var c,d;c=a._wrapped[b]?a._wrapped[b].get():a.get(b);for(d in c)g.push(b+"."+d)},i=function(a){return a+"."+d};d=c.shift();)"*"===d?(g=[],f.forEach(h),f=g):f[0]?f=f.map(i):f[0]=d;return e={},f.forEach(function(b){e[b]=a.get(b)}),e}}(),U=function(a,b){var c,d=/\*/;return c=function(a,b,c,d){this.root=a,this.callback=c,this.defer=d.defer,this.debug=d.debug,this.keypath=b,this.regex=new RegExp("^"+b.replace(/\./g,"\\.").replace(/\*/g,"[^\\.]+")+"$"),this.values={},this.defer&&(this.proxies=[]),this.priority="pattern",this.context=d&&d.context?d.context:a},c.prototype={init:function(a){var c,d;if(c=b(this.root,this.keypath),a!==!1)for(d in c)c.hasOwnProperty(d)&&this.update(d);else this.values=c},update:function(a){var c;{if(!d.test(a))return this.defer&&this.ready?(this.root._deferred.observers.push(this.getProxy(a)),void 0):(this.reallyUpdate(a),void 0);c=b(this.root,a);for(a in c)c.hasOwnProperty(a)&&this.update(a)}},reallyUpdate:function(b){var c=this.root.get(b);if(this.updating)return this.values[b]=c,void 0;if(this.updating=!0,!a(c,this.values[b])||!this.ready){try{this.callback.call(this.context,c,this.values[b],b)}catch(d){if(this.debug||this.root.debug)throw d}this.values[b]=c}this.updating=!1},getProxy:function(a){var b=this;return this.proxies[a]||(this.proxies[a]={update:function(){b.reallyUpdate(a)}}),this.proxies[a]}},c}(x,T),V=function(a,b,c,d,e){var f=/\*/,g={};return function(h,i,j,k){var l,m;return i=a(i),k=k||g,f.test(i)?(l=new e(h,i,j,k),h._patternObservers.push(l),m=!0):l=new d(h,i,j,k),b(l),l.init(k.init),l.ready=!0,{cancel:function(){var a;m&&(a=h._patternObservers.indexOf(l),-1!==a&&h._patternObservers.splice(a,1)),c(l)}}}}(i,Q,R,S,U),W=function(a,b){return function(c,d,e){var f,g=[];if(a(c)){e=d;for(f in c)c.hasOwnProperty(f)&&(d=c[f],g[g.length]=b(this,f,d,e));return{cancel:function(){for(;g.length;)g.pop().cancel()}}}return b(this,c,d,e)}}(w,V),X=function(){return function(a){var b,c,d,e=this._subs[a];if(e)for(b=Array.prototype.slice.call(arguments,1),c=0,d=e.length;d>c;c+=1)e[c].apply(this,b)}}(),Y=function(){return function(a){return this.el?this.fragment.find(a):null}}(),Z=function(a,b){var c,d,e,f,g,h,i,j;if(a){for(c=b("div"),d=["matches","matchesSelector"],g=["o","ms","moz","webkit"],j=function(a){return function(b,c){return b[a](c)}},h=d.length;h--;){if(e=d[h],c[e])return j(e);for(i=g.length;i--;)if(f=g[h]+e.substr(0,1).toUpperCase()+e.substring(1),c[f])return j(f)}return function(a,b){var c,d;for(c=(a.parentNode||a.document).querySelectorAll(b),d=c.length;d--;)if(c[d]===a)return!0;return!1}}}(f,e),$=function(a){return function(b,c){var d=this._isComponentQuery?!this.selector||b.name===this.selector:a(b.node,this.selector);return d?(this.push(b.node||b.instance),c||this._makeDirty(),!0):void 0}}(Z),_=function(){return function(){var a,b,c;a=this._root[this._isComponentQuery?"liveComponentQueries":"liveQueries"],b=this.selector,c=a.indexOf(b),-1!==c&&(a.splice(c,1),a[b]=null)}}(),ab=function(){function a(a){var b;return(b=a.parentFragment)?b.owner:a.component&&(b=a.component.parentFragment)?b.owner:void 0}function b(b){var c,d;for(c=[b],d=a(b);d;)c.push(d),d=a(d);return c}return function(a,c){var d,e,f,g,h,i,j,k,l,m;for(d=b(a.component||a._ractive.proxy),e=b(c.component||c._ractive.proxy),f=d[d.length-1],g=e[e.length-1];f&&f===g;)d.pop(),e.pop(),h=f,f=d[d.length-1],g=e[e.length-1];if(f=f.component||f,g=g.component||g,l=f.parentFragment,m=g.parentFragment,l===m)return i=l.items.indexOf(f),j=m.items.indexOf(g),i-j||d.length-e.length;if(k=h.fragments)return i=k.indexOf(l),j=k.indexOf(m),i-j||d.length-e.length;throw new Error("An unexpected condition was met while comparing the position of two components. Please file an issue at https://github.com/RactiveJS/Ractive/issues - thanks!")}}(),bb=function(a){return function(b,c){var d;return b.compareDocumentPosition?(d=b.compareDocumentPosition(c),2&d?1:-1):a(b,c)}}(ab),cb=function(a,b){return function(){this.sort(this._isComponentQuery?b:a),this._dirty=!1}}(bb,ab),db=function(){return function(){this._dirty||(this._root._deferred.liveQueries.push(this),this._dirty=!0)}}(),eb=function(){return function(a){var b=this.indexOf(this._isComponentQuery?a.instance:a.node);-1!==b&&this.splice(b,1)}}(),fb=function(a,b,c,d,e,f){return function(g,h,i,j){var k;return k=[],a(k,{selector:{value:h},live:{value:i},_isComponentQuery:{value:j},_test:{value:b}}),i?(a(k,{cancel:{value:c},_root:{value:g},_sort:{value:d},_makeDirty:{value:e},_remove:{value:f},_dirty:{value:!1,writable:!0}}),k):k}}(h,$,_,cb,db,eb),gb=function(a,b,c,d){return function(a,b){var c,e;return this.el?(b=b||{},c=this._liveQueries,(e=c[a])?b&&b.live?e:e.slice():(e=d(this,a,!!b.live,!1),e.live&&(c.push(a),c[a]=e),this.fragment.findAll(a,e),e)):[]}}(I,Z,h,fb),hb=function(){return function(a){return this.fragment.findComponent(a)}}(),ib=function(a,b,c,d){return function(a,b){var c,e;return b=b||{},c=this._liveComponentQueries,(e=c[a])?b&&b.live?e:e.slice():(e=d(this,a,!!b.live,!0),e.live&&(c.push(a),c[a]=e),this.fragment.findAllComponents(a,e),e)}}(I,Z,h,fb),jb=function(){return function(a){var b;return"undefined"!=typeof window&&document&&a?a.nodeType?a:"string"==typeof a&&(b=document.getElementById(a),!b&&document.querySelector&&(b=document.querySelector(a)),b&&b.nodeType)?b:a[0]&&a[0].nodeType?a[0]:null:null}}(),kb=function(a,b){return function(c,d){var e,f,g,h,i;if(c.owner=d.owner,g=c.owner.parentFragment,c.root=d.root,c.pNode=d.pNode,c.contextStack=d.contextStack||[],c.owner.type===a.SECTION&&(c.index=d.index),g&&(h=g.indexRefs)){c.indexRefs=b(null);for(i in h)c.indexRefs[i]=h[i]}for(c.priority=g?g.priority+1:1,d.indexRef&&(c.indexRefs||(c.indexRefs={}),c.indexRefs[d.indexRef]=d.index),c.items=[],e=d.descriptor?d.descriptor.length:0,f=0;e>f;f+=1)c.items[c.items.length]=c.createItem({parentFragment:c,descriptor:d.descriptor[f],index:f})}}(k,c),lb=function(a){var b={};return function(c,d,e){var f,g=[];if(c)for(f=b[d]||(b[d]=a(d)),f.innerHTML=c;f.firstChild;)g[g.length]=f.firstChild,e.appendChild(f.firstChild);return g}}(e),mb=function(a){var b,c,d;return c=//g,b=function(b,c){this.type=a.TEXT,this.descriptor=b.descriptor,c&&(this.node=document.createTextNode(b.descriptor),c.appendChild(this.node))},b.prototype={detach:function(){return this.node.parentNode.removeChild(this.node),this.node},teardown:function(a){a&&this.detach()},firstNode:function(){return this.node},toString:function(){return(""+this.descriptor).replace(c,"<").replace(d,">")}},b}(k),nb=function(a){return function(b){if(b.keypath)a(b);else{var c=b.root._pendingResolution.indexOf(b);-1!==c&&b.root._pendingResolution.splice(c,1)}}}(R),ob=function(a,b,c,d,e){function f(a,b,d){var e,f,g;if(!h.test(a.toString()))return c(a,"_nowrap",{value:!0}),a;if(!a["_"+b._guid]){c(a,"_"+b._guid,{value:function(){var c,d,e,g;if(c=b._captured,c||(b._captured=[]),d=a.apply(b,arguments),b._captured.length)for(e=f.length;e--;)g=f[e],g.updateSoftDependencies(b._captured);return b._captured=c,d},writable:!0});for(e in a)a.hasOwnProperty(e)&&(a["_"+b._guid][e]=a[e]);a["_"+b._guid+"_evaluators"]=[]}return f=a["_"+b._guid+"_evaluators"],g=f.indexOf(d),-1===g&&f.push(d),a["_"+b._guid]}var g,h;return h=/this/,g=function(b,c,e,g,h){var i;this.evaluator=e,this.keypath=c,this.root=b,this.argNum=g,this.type=a.REFERENCE,this.priority=h,i=b.get(c),"function"==typeof i&&(i=f(i,b,e)),this.value=e.values[g]=i,d(this)},g.prototype={update:function(){var a=this.root.get(this.keypath);"function"!=typeof a||a._nowrap||(a=f(a,this.root,this.evaluator)),b(a,this.value)||(this.evaluator.values[this.argNum]=a,this.evaluator.bubble(),this.value=a)},teardown:function(){e(this)}},g}(k,x,g,Q,R),pb=function(a,b,c){var d=function(a,c,d){this.root=a,this.keypath=c,this.priority=d.priority,this.evaluator=d,b(this)};return d.prototype={update:function(){var b=this.root.get(this.keypath);a(b,this.value)||(this.evaluator.bubble(),this.value=b)},teardown:function(){c(this)}},d}(x,Q,R),qb=function(a,b,c,d,e,f,g,h,i){function j(a,b){var c,d;if(a=a.replace(/\$\{([0-9]+)\}/g,"_$1"),l[a])return l[a];for(d=[];b--;)d[b]="_"+b;return c=new Function(d.join(","),"return("+a+")"),l[a]=c,c}var k,l={};return k=function(a,b,c,d,e){var f,g;for(this.root=a,this.keypath=b,this.priority=e,this.fn=j(c,d.length),this.values=[],this.refs=[],f=d.length;f--;)(g=d[f])?g[0]?this.values[f]=g[1]:this.refs[this.refs.length]=new h(a,g[1],this,f,e):this.values[f]=void 0;this.selfUpdating=this.refs.length<=1,this.update()},k.prototype={bubble:function(){this.selfUpdating?this.update():this.deferred||(this.root._deferred.evals.push(this),this.deferred=!0) -},update:function(){var b;if(this.evaluating)return this;this.evaluating=!0;try{b=this.fn.apply(null,this.values)}catch(e){if(this.root.debug)throw e;b=void 0}return a(b,this.value)||(c(this.root,this.keypath),this.root._cache[this.keypath]=b,g(this.root,this.keypath,b,!0),this.value=b,d(this.root,this.keypath)),this.evaluating=!1,this},teardown:function(){for(;this.refs.length;)this.refs.pop().teardown();c(this.root,this.keypath),this.root._evaluators[this.keypath]=null},refresh:function(){this.selfUpdating||(this.deferred=!0);for(var a=this.refs.length;a--;)this.refs[a].update();this.deferred&&(this.update(),this.deferred=!1)},updateSoftDependencies:function(a){var b,c,d;for(this.softRefs||(this.softRefs=[]),b=this.softRefs.length;b--;)d=this.softRefs[b],a[d.keypath]||(this.softRefs.splice(b,1),this.softRefs[d.keypath]=!1,d.teardown());for(b=a.length;b--;)c=a[b],this.softRefs[c]||(d=new i(this.root,c,this),this.softRefs[this.softRefs.length]=d,this.softRefs[c]=!0);this.selfUpdating=this.refs.length+this.softRefs.length<=1}},k}(x,g,m,r,Q,R,u,ob,pb),rb=function(a,b){var c=function(b,c,d,e){var f,g;g=this.root=b.root,f=a(g,c,d),void 0!==f?b.resolveRef(e,!1,f):(this.ref=c,this.argNum=e,this.resolver=b,this.contextStack=d,g._pendingResolution[g._pendingResolution.length]=this)};return c.prototype={resolve:function(a){this.keypath=a,this.resolver.resolveRef(this.argNum,!1,a)},teardown:function(){this.keypath||b(this)}},c}(y,nb),sb=function(){var a=/^(?:(?:[a-zA-Z$_][a-zA-Z$_0-9]*)|(?:[0-9]|[1-9][0-9]+))$/;return function(b){var c,d,e;for(c=b.split("."),e=c.length;e--;)if(d=c[e],"undefined"===d||!a.test(d))return!1;return!0}}(),tb=function(a,b){return function(c,d){var e,f;return e=c.replace(/\$\{([0-9]+)\}/g,function(a,b){return d[b]?d[b][1]:"undefined"}),f=a(e),b(f)?f:"${"+e.replace(/[\.\[\]]/g,"-")+"}"}}(i,sb),ub=function(a,b){function c(a,b,c){var e,f;if(e=a._depsMap[b])for(f=e.length;f--;)d(a,e[f],c)}function d(a,b,d){var e,f,g,h;for(e=a._deps.length;e--;)if(f=a._deps[e],f&&(g=f[b]))for(h=g.length;h--;)d.push(g[h]);c(a,b,d)}return function(c,e,f){var g,h,i;for(g=[],d(c,e,g),h=g.length;h--;)i=g[h],b(i),i.keypath=i.keypath.replace(e,f),a(i),i.update()}}(Q,R),vb=function(a,b,c,d){var e=function(a){var c,d,e,f,g;if(this.root=a.root,this.mustache=a,this.args=[],this.scouts=[],c=a.descriptor.x,g=a.parentFragment.indexRefs,this.str=c.s,e=this.unresolved=this.args.length=c.r?c.r.length:0,!e)return this.resolved=this.ready=!0,this.bubble(),void 0;for(d=0;e>d;d+=1)f=c.r[d],g&&void 0!==g[f]?this.resolveRef(d,!0,g[f]):this.scouts[this.scouts.length]=new b(this,f,a.contextStack,d);this.ready=!0,this.bubble()};return e.prototype={bubble:function(){var a;this.ready&&(a=this.keypath,this.keypath=c(this.str,this.args),"${"===this.keypath.substr(0,2)&&this.createEvaluator(),a?d(this.root,a,this.keypath):this.mustache.resolve(this.keypath))},teardown:function(){for(;this.scouts.length;)this.scouts.pop().teardown()},resolveRef:function(a,b,c){this.args[a]=[b,c],this.bubble(),this.resolved=!--this.unresolved},createEvaluator:function(){this.root._evaluators[this.keypath]?this.root._evaluators[this.keypath].refresh():this.root._evaluators[this.keypath]=new a(this.root,this.keypath,this.str,this.args,this.mustache.priority)}},e}(qb,rb,tb,ub),wb=function(a,b){return function(c,d){var e,f,g;g=c.parentFragment=d.parentFragment,c.root=g.root,c.contextStack=g.contextStack,c.descriptor=d.descriptor,c.index=d.index||0,c.priority=g.priority,c.type=d.descriptor.t,d.descriptor.r&&(g.indexRefs&&void 0!==g.indexRefs[d.descriptor.r]?(f=g.indexRefs[d.descriptor.r],c.indexRef=d.descriptor.r,c.value=f,c.render(c.value)):(e=a(c.root,d.descriptor.r,c.contextStack),void 0!==e?c.resolve(e):(c.ref=d.descriptor.r,c.root._pendingResolution[c.root._pendingResolution.length]=c))),d.descriptor.x&&(c.expressionResolver=new b(c)),c.descriptor.n&&!c.hasOwnProperty("value")&&c.render(void 0)}}(y,vb),xb=function(a,b,c){return function(d){d!==this.keypath&&(this.registered&&c(this),this.keypath=d,b(this),this.update(),this.root.twoway&&this.parentFragment.owner.type===a.ATTRIBUTE&&this.parentFragment.owner.element.bind(),this.expressionResolver&&this.expressionResolver.resolved&&(this.expressionResolver=null))}}(k,Q,R),yb=function(a){return function(){var b,c;c=this.root.get(this.keypath),(b=this.root._wrapped[this.keypath])&&(c=b.get()),a(c,this.value)||(this.render(c),this.value=c)}}(x),zb=function(a,b,c,d,e){var f,g,h;return g=//g,f=function(b,d){this.type=a.INTERPOLATOR,d&&(this.node=document.createTextNode(""),d.appendChild(this.node)),c(this,b)},f.prototype={update:e,resolve:d,detach:function(){return this.node.parentNode.removeChild(this.node),this.node},teardown:function(a){a&&this.detach(),b(this)},render:function(a){this.node&&(this.node.data=void 0==a?"":a)},firstNode:function(){return this.node},toString:function(){var a=void 0!=this.value?""+this.value:"";return a.replace(g,"<").replace(h,">")}},f}(k,nb,wb,xb,yb),Ab=function(a,b,c){function d(a,b,c){var d,e,f;if(e=b.length,ea.length)for(d=a.length;e>d;d+=1)c.contextStack=a.contextStack.concat(a.keypath+"."+d),c.index=d,a.descriptor.i&&(c.indexRef=a.descriptor.i),a.fragments[d]=a.createFragment(c);a.length=e}function e(a,b,d){var e,f;f=a.fragmentsById||(a.fragmentsById=c(null));for(e in f)void 0===b[e]&&f[e]&&(f[e].teardown(!0),f[e]=null);for(e in b)void 0===b[e]||f[e]||(d.contextStack=a.contextStack.concat(a.keypath+"."+e),d.index=e,a.descriptor.i&&(d.indexRef=a.descriptor.i),f[e]=a.createFragment(d))}function f(a,b){a.length||(b.contextStack=a.contextStack.concat(a.keypath),b.index=0,a.fragments[0]=a.createFragment(b),a.length=1)}function g(b,c,d,e){var f,g,h,i;if(g=a(c)&&0===c.length,f=d?g||!c:c&&!g){if(b.length||(e.contextStack=b.contextStack,e.index=0,b.fragments[0]=b.createFragment(e),b.length=1),b.length>1)for(h=b.fragments.splice(1);i=h.pop();)i.teardown(!0)}else b.length&&(b.teardownFragments(!0),b.length=0)}return function(c,h){var i;return i={descriptor:c.descriptor.f,root:c.root,pNode:c.parentFragment.pNode,owner:c},c.descriptor.n?(g(c,h,!0,i),void 0):(a(h)?d(c,h,i):b(h)?c.descriptor.i?e(c,h,i):f(c,i):g(c,h,!1,i),void 0)}}(l,w,c),Bb=function(a,b,c){function d(b,c,g,h,i,j,k){var l,m,n,o;if(!b.html){for(b.indexRefs&&void 0!==b.indexRefs[c]&&(b.indexRefs[c]=h),l=b.contextStack.length;l--;)n=b.contextStack[l],n.substr(0,j.length)===j&&(b.contextStack[l]=n.replace(j,k));for(l=b.items.length;l--;)switch(m=b.items[l],m.type){case a.ELEMENT:e(m,c,g,h,i,j,k);break;case a.PARTIAL:d(m.fragment,c,g,h,i,j,k);break;case a.COMPONENT:d(m.instance.fragment,c,g,h,i,j,k),(o=b.root._liveComponentQueries[m.name])&&o._makeDirty();break;case a.SECTION:case a.INTERPOLATOR:case a.TRIPLE:f(m,c,g,h,i,j,k)}}}function e(a,b,c,e,f,g,h){var i,j,k,l,m,n,o,p,q,r;for(i=a.attributes.length;i--;)j=a.attributes[i],j.fragment&&(d(j.fragment,b,c,e,f,g,h),j.twoway&&j.updateBindings());if(k=a.node._ractive){k.keypath.substr(0,g.length)===g&&(k.keypath=k.keypath.replace(g,h)),void 0!==b&&(k.index[b]=e);for(l in k.events)for(m=k.events[l].proxies,i=m.length;i--;)n=m[i],"object"==typeof n.n&&d(n.a,b,c,e,f,g,h),n.d&&d(n.d,b,c,e,f,g,h);(o=k.binding)&&o.keypath.substr(0,g.length)===g&&(p=k.root._twowayBindings[o.keypath],p.splice(p.indexOf(o),1),o.keypath=o.keypath.replace(g,h),p=k.root._twowayBindings[o.keypath]||(k.root._twowayBindings[o.keypath]=[]),p.push(o))}if(a.fragment&&d(a.fragment,b,c,e,f,g,h),q=a.liveQueries)for(r=a.root,i=q.length;i--;)r._liveQueries[q[i]]._makeDirty()}function f(a,b,e,f,g,h,i){var j;if(a.descriptor.x&&(a.expressionResolver&&a.expressionResolver.teardown(),a.expressionResolver=new c(a)),a.keypath?a.keypath.substr(0,h.length)===h&&a.resolve(a.keypath.replace(h,i)):a.indexRef===b&&(a.value=f,a.render(f)),a.fragments)for(j=a.fragments.length;j--;)d(a.fragments[j],b,e,f,g,h,i)}return d}(k,R,vb),Cb=function(a,b,c){return function(a,d,e,f,g){var h,i,j,k,l,m,n;for(j=d.descriptor.i,h=e;f>h;h+=1)i=d.fragments[h],k=h-g,l=h,m=d.keypath+"."+(h-g),n=d.keypath+"."+h,i.index+=g,b(i,j,k,l,g,m,n);c(a)}}(k,Bb,o),Db=function(a){return function(b){var c,d,e,f,g,h,i,j,k,l,m=this;if(c=this.parentFragment,h=[],b.forEach(function(b,c){var f,g,j;return b===c?(h[b]=m.fragments[c],void 0):(void 0===d&&(d=c),-1===b?((i||(i=[])).push(m.fragments[c]),void 0):(f=b-c,g=m.keypath+"."+c,j=m.keypath+"."+b,a(m.fragments[c],m.descriptor.i,c,b,f,g,j),h[b]=m.fragments[c],e=!0,void 0))}),i)for(;k=i.pop();)k.teardown(!0);if(void 0===d&&(d=this.length),g=this.root.get(this.keypath).length,g!==d){for(j={descriptor:this.descriptor.f,root:this.root,pNode:c.pNode,owner:this},this.descriptor.i&&(j.indexRef=this.descriptor.i),f=d;g>f;f+=1)(k=h[f])?this.docFrag.appendChild(k.detach(!1)):(j.contextStack=this.contextStack.concat(this.keypath+"."+f),j.index=f,k=this.createFragment(j)),this.fragments[f]=k;l=c.findNextNode(this),c.pNode.insertBefore(this.docFrag,l),this.length=g}}}(Bb),Eb=function(){return[]}(),Fb=function(a,b,c,d,e,f,g,h,i,j,k){var l,m;return k.push(function(){m=k.DomFragment}),l=function(b,d){this.type=a.SECTION,this.inverted=!!b.descriptor.n,this.fragments=[],this.length=0,d&&(this.docFrag=document.createDocumentFragment()),this.initialising=!0,c(this,b),d&&d.appendChild(this.docFrag),this.initialising=!1},l.prototype={update:d,resolve:e,smartUpdate:function(a,b){var c;("push"===a||"unshift"===a||"splice"===a)&&(c={descriptor:this.descriptor.f,root:this.root,pNode:this.parentFragment.pNode,owner:this},this.descriptor.i&&(c.indexRef=this.descriptor.i)),this[a]&&(this.rendering=!0,this[a](c,b),this.rendering=!1)},pop:function(){this.length&&(this.fragments.pop().teardown(!0),this.length-=1)},push:function(a,b){var c,d,e;for(c=this.length,d=c+b.length,e=c;d>e;e+=1)a.contextStack=this.contextStack.concat(this.keypath+"."+e),a.index=e,this.fragments[e]=this.createFragment(a);this.length+=b.length,this.parentFragment.pNode.insertBefore(this.docFrag,this.parentFragment.findNextNode(this))},shift:function(){this.splice(null,[0,1])},unshift:function(a,b){this.splice(a,[0,0].concat(new Array(b.length)))},splice:function(a,b){var c,d,e,f,g,i,j,k,l;if(b.length&&(i=+(b[0]<0?this.length+b[0]:b[0]),d=Math.max(0,b.length-2),e=void 0!==b[1]?b[1]:this.length-i,e=Math.min(e,this.length-i),f=d-e)){if(0>f){for(j=i-f,g=i;j>g;g+=1)this.fragments[g].teardown(!0);this.fragments.splice(i,-f)}else{for(j=i+f,c=this.fragments[i]?this.fragments[i].firstNode():this.parentFragment.findNextNode(this),k=[i,0].concat(new Array(f)),this.fragments.splice.apply(this.fragments,k),g=i;j>g;g+=1)a.contextStack=this.contextStack.concat(this.keypath+"."+g),a.index=g,this.fragments[g]=this.createFragment(a);this.parentFragment.pNode.insertBefore(this.docFrag,c)}this.length+=f,l=i+d,h(this.root,this,l,this.length,f)}},merge:i,detach:function(){var a,b;for(b=this.fragments.length,a=0;b>a;a+=1)this.docFrag.appendChild(this.fragments[a].detach());return this.docFrag},teardown:function(a){this.teardownFragments(a),j(this)},firstNode:function(){return this.fragments[0]?this.fragments[0].firstNode():this.parentFragment.findNextNode(this)},findNextNode:function(a){return this.fragments[a.index+1]?this.fragments[a.index+1].firstNode():this.parentFragment.findNextNode(this)},teardownFragments:function(a){for(var b,c;c=this.fragments.shift();)c.teardown(a);if(this.fragmentsById)for(b in this.fragmentsById)this.fragments[b]&&(this.fragmentsById[b].teardown(a),this.fragmentsById[b]=null)},render:function(a){var c,d;(d=this.root._wrapped[this.keypath])&&(a=d.get()),this.rendering||(this.rendering=!0,f(this,a),this.rendering=!1,(!this.docFrag||this.docFrag.childNodes.length)&&!this.initialising&&b&&(c=this.parentFragment.findNextNode(this),c&&c.parentNode===this.parentFragment.pNode?this.parentFragment.pNode.insertBefore(this.docFrag,c):this.parentFragment.pNode.appendChild(this.docFrag)))},createFragment:function(a){var b=new m(a);return this.docFrag&&this.docFrag.appendChild(b.docFrag),b},toString:function(){var a,b,c,d;for(a="",b=0,d=this.length,b=0;d>b;b+=1)a+=this.fragments[b].toString();if(this.fragmentsById)for(c in this.fragmentsById)this.fragmentsById[c]&&(a+=this.fragmentsById[c].toString());return a},find:function(a){var b,c,d;for(c=this.fragments.length,b=0;c>b;b+=1)if(d=this.fragments[b].find(a))return d;return null},findAll:function(a,b){var c,d;for(d=this.fragments.length,c=0;d>c;c+=1)this.fragments[c].findAll(a,b)},findComponent:function(a){var b,c,d;for(c=this.fragments.length,b=0;c>b;b+=1)if(d=this.fragments[b].findComponent(a))return d;return null},findAllComponents:function(a,b){var c,d;for(d=this.fragments.length,c=0;d>c;c+=1)this.fragments[c].findAllComponents(a,b)}},l}(k,f,wb,yb,xb,Ab,Bb,Cb,Db,nb,Eb),Gb=function(a,b,c,d,e,f,g){var h=function(b,d){this.type=a.TRIPLE,d&&(this.nodes=[],this.docFrag=document.createDocumentFragment()),this.initialising=!0,c(this,b),d&&d.appendChild(this.docFrag),this.initialising=!1};return h.prototype={update:d,resolve:e,detach:function(){for(var a=this.nodes.length;a--;)this.docFrag.appendChild(this.nodes[a]);return this.docFrag},teardown:function(a){a&&(this.detach(),this.docFrag=this.nodes=null),g(this)},firstNode:function(){return this.nodes[0]?this.nodes[0]:this.parentFragment.findNextNode(this)},render:function(a){var b,c;if(this.nodes){for(;this.nodes.length;)b=this.nodes.pop(),b.parentNode.removeChild(b);if(!a)return this.nodes=[],void 0;c=this.parentFragment.pNode,this.nodes=f(a,c.tagName,this.docFrag),this.initialising||c.insertBefore(this.docFrag,this.parentFragment.findNextNode(this))}},toString:function(){return void 0!=this.value?this.value:""},find:function(a){var c,d,e,f;for(d=this.nodes.length,c=0;d>c;c+=1)if(e=this.nodes[c],1===e.nodeType){if(b(e,a))return e;if(f=e.querySelector(a))return f}return null},findAll:function(a,c){var d,e,f,g,h,i;for(e=this.nodes.length,d=0;e>d;d+=1)if(f=this.nodes[d],1===f.nodeType&&(b(f,a)&&c.push(f),g=f.querySelectorAll(a)))for(h=g.length,i=0;h>i;i+=1)c.push(g[i])}},h}(k,Z,wb,yb,xb,lb,nb),Hb=function(a){return function(b,c){return b.a&&b.a.xmlns?b.a.xmlns:"svg"===b.e?a.svg:c.namespaceURI||a.html}}(d),Ib=function(){var a,b,c,d;return a="altGlyph altGlyphDef altGlyphItem animateColor animateMotion animateTransform clipPath feBlend feColorMatrix feComponentTransfer feComposite feConvolveMatrix feDiffuseLighting feDisplacementMap feDistantLight feFlood feFuncA feFuncB feFuncG feFuncR feGaussianBlur feImage feMerge feMergeNode feMorphology feOffset fePointLight feSpecularLighting feSpotLight feTile feTurbulence foreignObject glyphRef linearGradient radialGradient textPath vkern".split(" "),b="attributeName attributeType baseFrequency baseProfile calcMode clipPathUnits contentScriptType contentStyleType diffuseConstant edgeMode externalResourcesRequired filterRes filterUnits glyphRef gradientTransform gradientUnits kernelMatrix kernelUnitLength keyPoints keySplines keyTimes lengthAdjust limitingConeAngle markerHeight markerUnits markerWidth maskContentUnits maskUnits numOctaves pathLength patternContentUnits patternTransform patternUnits pointsAtX pointsAtY pointsAtZ preserveAlpha preserveAspectRatio primitiveUnits refX refY repeatCount repeatDur requiredExtensions requiredFeatures specularConstant specularExponent spreadMethod startOffset stdDeviation stitchTiles surfaceScale systemLanguage tableValues targetX targetY textLength viewBox viewTarget xChannelSelector yChannelSelector zoomAndPan".split(" "),c=function(a){for(var b={},c=a.length;c--;)b[a[c].toLowerCase()]=a[c];return b},d=c(a.concat(b)),function(a){var b=a.toLowerCase();return d[b]||b}}(),Jb=function(a,b){return function(c,d){var e,f;if(e=d.indexOf(":"),-1===e||(f=d.substr(0,e),"xmlns"===f))c.name=c.element.namespace!==a.html?b(d):d,c.lcName=c.name.toLowerCase();else if(d=d.substring(e+1),c.name=b(d),c.lcName=c.name.toLowerCase(),c.namespace=a[f.toLowerCase()],!c.namespace)throw'Unknown namespace ("'+f+'")'}}(d,Ib),Kb=function(a){return function(b,c){var d,e=null===c.value?"":c.value;(d=c.pNode)&&(b.namespace?d.setAttributeNS(b.namespace,c.name,e):"style"===c.name&&d.style.setAttribute?d.style.setAttribute("cssText",e):"class"!==c.name||d.namespaceURI&&d.namespaceURI!==a.html?d.setAttribute(c.name,e):d.className=e,"id"===b.name&&(c.root.nodes[c.value]=d),"value"===b.name&&(d._ractive.value=c.value)),b.value=c.value}}(d),Lb=function(a){var b={"accept-charset":"acceptCharset",accesskey:"accessKey",bgcolor:"bgColor","class":"className",codebase:"codeBase",colspan:"colSpan",contenteditable:"contentEditable",datetime:"dateTime",dirname:"dirName","for":"htmlFor","http-equiv":"httpEquiv",ismap:"isMap",maxlength:"maxLength",novalidate:"noValidate",pubdate:"pubDate",readonly:"readOnly",rowspan:"rowSpan",tabindex:"tabIndex",usemap:"useMap"};return function(c,d){var e;!c.pNode||c.namespace||d.pNode.namespaceURI&&d.pNode.namespaceURI!==a.html||(e=b[c.name]||c.name,void 0!==d.pNode[e]&&(c.propertyName=e),("boolean"==typeof d.pNode[e]||"value"===e)&&(c.useProperty=!0))}}(d),Mb=function(a,b,c,d){var e,f,g,h,i,j,k,l,m,n,o,p,q,r;return e=function(){var a,b,c,d=this.pNode;return this.fragment?(a=f(this))?(this.interpolator=a,this.keypath=a.keypath||a.descriptor.r,(b=i(this))?(d._ractive.binding=this.element.binding=b,this.twoway=!0,c=this.root._twowayBindings[this.keypath]||(this.root._twowayBindings[this.keypath]=[]),c[c.length]=b,!0):!1):!1:!1},g=function(){this._ractive.binding.update()},h=function(){var a=this._ractive.root.get(this._ractive.binding.keypath);this.value=void 0==a?"":a},f=function(c){var d,e;return 1!==c.fragment.items.length?null:(d=c.fragment.items[0],d.type!==a.INTERPOLATOR?null:d.keypath||d.ref?d.keypath&&"${"===d.keypath.substr(0,2)?(e="You cannot set up two-way binding against an expression "+d.keypath,c.root.debug&&b(e),null):d:null)},i=function(a){var c=a.pNode;if("SELECT"===c.tagName)return c.multiple?new k(a,c):new l(a,c);if("checkbox"===c.type||"radio"===c.type){if("name"===a.propertyName){if("checkbox"===c.type)return new n(a,c);if("radio"===c.type)return new m(a,c)}return"checked"===a.propertyName?new o(a,c):null}return"value"!==a.lcName&&b("This is... odd"),"file"===c.type?new p(a,c):c.getAttribute("contenteditable")?new q(a,c):new r(a,c)},k=function(a,b){var c;j(this,a,b),b.addEventListener("change",g,!1),c=this.root.get(this.keypath),void 0===c&&this.update()},k.prototype={value:function(){var a,b,c,d;for(a=[],b=this.node.options,d=b.length,c=0;d>c;c+=1)b[c].selected&&(a[a.length]=b[c]._ractive.value);return a},update:function(){var a,b,d;return a=this.attr,b=a.value,d=this.value(),void 0!==b&&c(d,b)||(a.receiving=!0,a.value=d,this.root.set(this.keypath,d),a.receiving=!1),this},deferUpdate:function(){this.deferred!==!0&&(this.root._deferred.attrs.push(this),this.deferred=!0)},teardown:function(){this.node.removeEventListener("change",g,!1)}},l=function(a,b){var c;j(this,a,b),b.addEventListener("change",g,!1),c=this.root.get(this.keypath),void 0===c&&this.update()},l.prototype={value:function(){var a,b,c;for(a=this.node.options,c=a.length,b=0;c>b;b+=1)if(a[b].selected)return a[b]._ractive.value},update:function(){var a=this.value();return this.attr.receiving=!0,this.attr.value=a,this.root.set(this.keypath,a),this.attr.receiving=!1,this},deferUpdate:function(){this.deferred!==!0&&(this.root._deferred.attrs.push(this),this.deferred=!0)},teardown:function(){this.node.removeEventListener("change",g,!1)}},m=function(a,b){var c;this.radioName=!0,j(this,a,b),b.name="{{"+a.keypath+"}}",b.addEventListener("change",g,!1),b.attachEvent&&b.addEventListener("click",g,!1),c=this.root.get(this.keypath),void 0!==c?b.checked=c==b._ractive.value:this.root._deferred.radios.push(this)},m.prototype={value:function(){return this.node._ractive?this.node._ractive.value:this.node.value},update:function(){var a=this.node;a.checked&&(this.attr.receiving=!0,this.root.set(this.keypath,this.value()),this.attr.receiving=!1)},teardown:function(){this.node.removeEventListener("change",g,!1),this.node.removeEventListener("click",g,!1)}},n=function(a,b){var c,d;this.checkboxName=!0,j(this,a,b),b.name="{{"+this.keypath+"}}",b.addEventListener("change",g,!1),b.attachEvent&&b.addEventListener("click",g,!1),c=this.root.get(this.keypath),void 0!==c?(d=-1!==c.indexOf(b._ractive.value),b.checked=d):-1===this.root._deferred.checkboxes.indexOf(this.keypath)&&this.root._deferred.checkboxes.push(this.keypath)},n.prototype={changed:function(){return this.node.checked!==!!this.checked},update:function(){this.checked=this.node.checked,this.attr.receiving=!0,this.root.set(this.keypath,d(this.root,this.keypath)),this.attr.receiving=!1},teardown:function(){this.node.removeEventListener("change",g,!1),this.node.removeEventListener("click",g,!1)}},o=function(a,b){j(this,a,b),b.addEventListener("change",g,!1),b.attachEvent&&b.addEventListener("click",g,!1)},o.prototype={value:function(){return this.node.checked},update:function(){this.attr.receiving=!0,this.root.set(this.keypath,this.value()),this.attr.receiving=!1},teardown:function(){this.node.removeEventListener("change",g,!1),this.node.removeEventListener("click",g,!1)}},p=function(a,b){j(this,a,b),b.addEventListener("change",g,!1)},p.prototype={value:function(){return this.attr.pNode.files},update:function(){this.attr.root.set(this.attr.keypath,this.value())},teardown:function(){this.node.removeEventListener("change",g,!1)}},q=function(a,b){j(this,a,b),b.addEventListener("change",g,!1),this.root.lazy||(b.addEventListener("input",g,!1),b.attachEvent&&b.addEventListener("keyup",g,!1))},q.prototype={update:function(){this.attr.receiving=!0,this.root.set(this.keypath,this.node.innerHTML),this.attr.receiving=!1},teardown:function(){this.node.removeEventListener("change",g,!1),this.node.removeEventListener("input",g,!1),this.node.removeEventListener("keyup",g,!1)}},r=function(a,b){j(this,a,b),b.addEventListener("change",g,!1),this.root.lazy||(b.addEventListener("input",g,!1),b.attachEvent&&b.addEventListener("keyup",g,!1)),this.node.addEventListener("blur",h,!1)},r.prototype={value:function(){var a=this.attr.pNode.value;return+a+""===a&&-1===a.indexOf("e")&&(a=+a),a},update:function(){var a=this.attr,b=this.value();a.receiving=!0,a.root.set(a.keypath,b),a.receiving=!1},teardown:function(){this.node.removeEventListener("change",g,!1),this.node.removeEventListener("input",g,!1),this.node.removeEventListener("keyup",g,!1),this.node.removeEventListener("blur",h,!1)}},j=function(a,b,c){a.attr=b,a.node=c,a.root=b.root,a.keypath=b.keypath},e}(k,I,E,n),Nb=function(a,b){var c,d,e,f,g,h,i,j,k,l,m,n;return c=function(){var a;if(!this.ready)return this;if(a=this.pNode,"SELECT"===a.tagName&&"value"===this.lcName)return this.update=e,this.deferredUpdate=f,this.update();if(this.isFileInputValue)return this.update=d,this;if(this.twoway&&"name"===this.lcName){if("radio"===a.type)return this.update=i,this.update();if("checkbox"===a.type)return this.update=j,this.update()}return"style"===this.lcName&&a.style.setAttribute?(this.update=k,this.update()):"class"!==this.lcName||a.namespaceURI&&a.namespaceURI!==b.html?a.getAttribute("contenteditable")&&"value"===this.lcName?(this.update=m,this.update()):(this.update=n,this.update()):(this.update=l,this.update())},d=function(){return this},f=function(){this.deferredUpdate=this.pNode.multiple?h:g,this.deferredUpdate()},e=function(){return this.root._deferred.selectValues.push(this),this},g=function(){var a,b,c,d=this.fragment.getValue();for(this.value=this.pNode._ractive.value=d,a=this.pNode.options,c=a.length;c--;)if(b=a[c],b._ractive.value==d)return b.selected=!0,this;return this},h=function(){var b,c,d=this.fragment.getValue();for(a(d)||(d=[d]),b=this.pNode.options,c=b.length;c--;)b[c].selected=-1!==d.indexOf(b[c]._ractive.value);return this.value=d,this},i=function(){var a,b;return a=this.pNode,b=this.fragment.getValue(),a.checked=b==a._ractive.value,this},j=function(){var b,c;return b=this.pNode,c=this.fragment.getValue(),a(c)?(b.checked=-1!==c.indexOf(b._ractive.value),this):(b.checked=c==b._ractive.value,this)},k=function(){var a,b;return a=this.pNode,b=this.fragment.getValue(),void 0===b&&(b=""),b!==this.value&&(a.style.setAttribute("cssText",b),this.value=b),this},l=function(){var a,b;return a=this.pNode,b=this.fragment.getValue(),void 0===b&&(b=""),b!==this.value&&(a.className=b,this.value=b),this},m=function(){var a,b;return a=this.pNode,b=this.fragment.getValue(),void 0===b&&(b=""),b!==this.value&&(this.receiving||(a.innerHTML=b),this.value=b),this},n=function(){var a,b;if(a=this.pNode,b=this.fragment.getValue(),this.isValueAttribute&&(a._ractive.value=b),void 0===b&&(b=""),b!==this.value){if(this.useProperty)return this.receiving||(a[this.propertyName]=b),this.value=b,this;if(this.namespace)return a.setAttributeNS(this.namespace,this.name,b),this.value=b,this;"id"===this.lcName&&(void 0!==this.value&&(this.root.nodes[this.value]=void 0),this.root.nodes[b]=a),a.setAttribute(this.name,b),this.value=b}return this},c}(l,d),Ob=function(){return function(a){var b;return b=this.str.substr(this.pos,a.length),b===a?(this.pos+=a.length,a):null}}(),Pb=function(){var a=/^\s+/;return function(){var b=a.exec(this.remaining());return b?(this.pos+=b[0].length,b[0]):null}}(),Qb=function(){return function(a){return function(b){var c=a.exec(b.str.substring(b.pos));return c?(b.pos+=c[0].length,c[1]||c[0]):null}}}(),Rb=function(){function a(a){var b;return a.getStringMatch("\\")?(b=a.str.charAt(a.pos),a.pos+=1,b):null}return function(b){var c,d="";for(c=a(b);c;)d+=c,c=a(b);return d||null}}(),Sb=function(a,b){var c=a(/^[^\\"]+/),d=a(/^[^\\']+/);return function e(a,f){var g,h,i,j,k,l;if(g=a.pos,h="",l=f?d:c,i=b(a),i&&(h+=i),j=l(a),j&&(h+=j),!h)return"";for(k=e(a,f);""!==k;)h+=k;return h}}(Qb,Rb),Tb=function(a,b){return function(c){var d,e;return d=c.pos,c.getStringMatch('"')?(e=b(c,!1),c.getStringMatch('"')?{t:a.STRING_LITERAL,v:e}:(c.pos=d,null)):c.getStringMatch("'")?(e=b(c,!0),c.getStringMatch("'")?{t:a.STRING_LITERAL,v:e}:(c.pos=d,null)):null}}(k,Sb),Ub=function(a,b){var c=b(/^(?:[+-]?)(?:(?:(?:0|[1-9]\d*)?\.\d+)|(?:(?:0|[1-9]\d*)\.)|(?:0|[1-9]\d*))(?:[eE][+-]?\d+)?/);return function(b){var d;return(d=c(b))?{t:a.NUMBER_LITERAL,v:d}:null}}(k,Qb),Vb=function(a){return a(/^[a-zA-Z_$][a-zA-Z_$0-9]*/)}(Qb),Wb=function(a,b,c){var d=/^[a-zA-Z_$][a-zA-Z_$0-9]*$/;return function(e){var f;return(f=a(e))?d.test(f.v)?f.v:'"'+f.v.replace(/"/g,'\\"')+'"':(f=b(e))?f.v:(f=c(e))?f:void 0}}(Tb,Ub,Vb),Xb=function(a,b,c,d){function e(a){var b,c,e;return a.allowWhitespace(),(b=d(a))?(e={key:b},a.allowWhitespace(),a.getStringMatch(":")?(a.allowWhitespace(),(c=a.getToken())?(e.value=c.v,e):null):null):null}var f,g,h,i,j,k;return g={"true":!0,"false":!1,undefined:void 0,"null":null},h=new RegExp("^(?:"+Object.keys(g).join("|")+")"),i=/^(?:[+-]?)(?:(?:(?:0|[1-9]\d*)?\.\d+)|(?:(?:0|[1-9]\d*)\.)|(?:0|[1-9]\d*))(?:[eE][+-]?\d+)?/,j=/\$\{([^\}]+)\}/g,k=/^\$\{([^\}]+)\}/,f=function(a,b){this.str=a,this.values=b,this.pos=0,this.result=this.getToken()},f.prototype={remaining:function(){return this.str.substring(this.pos)},getStringMatch:a,getToken:function(){return this.allowWhitespace(),this.getPlaceholder()||this.getSpecial()||this.getNumber()||this.getString()||this.getObject()||this.getArray()},getPlaceholder:function(){var a;return this.values?(a=k.exec(this.remaining()))&&this.values.hasOwnProperty(a[1])?(this.pos+=a[0].length,{v:this.values[a[1]]}):void 0:null},getSpecial:function(){var a;return(a=h.exec(this.remaining()))?(this.pos+=a[0].length,{v:g[a[0]]}):void 0},getNumber:function(){var a;return(a=i.exec(this.remaining()))?(this.pos+=a[0].length,{v:+a[0]}):void 0},getString:function(){var a,b=c(this);return b&&(a=this.values)?{v:b.v.replace(j,function(b,c){return a[c]||c})}:b},getObject:function(){var a,b;if(!this.getStringMatch("{"))return null;for(a={};b=e(this);){if(a[b.key]=b.value,this.allowWhitespace(),this.getStringMatch("}"))return{v:a};if(!this.getStringMatch(","))return null}return null},getArray:function(){var a,b;if(!this.getStringMatch("["))return null;for(a=[];b=this.getToken();){if(a.push(b.v),this.getStringMatch("]"))return{v:a};if(!this.getStringMatch(","))return null}return null},allowWhitespace:b},function(a,b){var c=new f(a,b);return c.result?{value:c.result.v,remaining:c.remaining()}:null}}(Ob,Pb,Tb,Wb),Yb=function(a,b,c,d,e){function f(a){return"string"==typeof a?a:JSON.stringify(a)}var g=function(b){this.type=a.INTERPOLATOR,c(this,b)};return g.prototype={update:d,resolve:e,render:function(a){this.value=a,this.parentFragment.bubble()},teardown:function(){b(this)},toString:function(){return void 0==this.value?"":f(this.value)}},g}(k,nb,wb,yb,xb),Zb=function(a,b,c,d,e,f,g){var h,i;return g.push(function(){i=g.StringFragment}),h=function(c){this.type=a.SECTION,this.fragments=[],this.length=0,b(this,c)},h.prototype={update:c,resolve:d,teardown:function(){this.teardownFragments(),f(this)},teardownFragments:function(){for(;this.fragments.length;)this.fragments.shift().teardown();this.length=0},bubble:function(){this.value=this.fragments.join(""),this.parentFragment.bubble()},render:function(a){var b;(b=this.root._wrapped[this.keypath])&&(a=b.get()),e(this,a),this.parentFragment.bubble()},createFragment:function(a){return new i(a)},toString:function(){return this.fragments.join("")}},h}(k,wb,yb,xb,Ab,nb,Eb),$b=function(a){var b=function(b){this.type=a.TEXT,this.text=b};return b.prototype={toString:function(){return this.text},teardown:function(){}},b}(k),_b=function(a,b){return function(){var c,d,e,f,g,h,i;if(!this.argsList||this.dirty){if(c={},d=0,f=this.root._guid,i=function(a){return a.map(function(a){var b,e,g;return a.text?a.text:a.fragments?a.fragments.map(function(a){return i(a.items)}).join(""):(b=f+"-"+d++,g=(e=a.root._wrapped[a.keypath])?e.value:a.value,c[b]=g,"${"+b+"}")}).join("")},e=i(this.items),h=b("["+e+"]",c))this.argsList=h.value;else{if(g="Could not parse directive arguments ("+this.toString()+"). If you think this is a bug, please file an issue at http://github.com/RactiveJS/Ractive/issues",this.root.debug)throw new Error(g);a(g),this.argsList=[e]}this.dirty=!1}return this.argsList}}(I,Xb),ac=function(a,b,c,d,e,f,g,h){var i=function(a){c(this,a)};return i.prototype={createItem:function(b){if("string"==typeof b.descriptor)return new f(b.descriptor);switch(b.descriptor.t){case a.INTERPOLATOR:return new d(b);case a.TRIPLE:return new d(b);case a.SECTION:return new e(b);default:throw"Something went wrong in a rather interesting way"}},bubble:function(){this.dirty=!0,this.owner.bubble()},teardown:function(){var a,b;for(a=this.items.length,b=0;a>b;b+=1)this.items[b].teardown()},getValue:function(){var b;return 1===this.items.length&&this.items[0].type===a.INTERPOLATOR&&(b=this.items[0].value,void 0!==b)?b:this.toString()},isSimple:function(){var b,c,d;if(void 0!==this.simple)return this.simple;for(b=this.items.length;b--;)if(c=this.items[b],c.type!==a.TEXT){if(c.type!==a.INTERPOLATOR)return this.simple=!1;if(d)return!1;d=!0}return this.simple=!0},toString:function(){return this.items.join("")},toJSON:function(){var a,c=this.getValue();return"string"==typeof c&&(a=b(c),c=a?a.value:c),c},toArgsList:g},h.StringFragment=i,i}(k,Xb,kb,Yb,Zb,$b,_b,Eb),bc=function(a,b,c,d,e,f,g){var h=function(e){return this.type=a.ATTRIBUTE,this.element=e.element,b(this,e.name),null===e.value||"string"==typeof e.value?(c(this,e),void 0):(this.root=e.root,this.pNode=e.pNode,this.parentFragment=this.element.parentFragment,this.fragment=new g({descriptor:e.value,root:this.root,owner:this,contextStack:e.contextStack}),this.pNode&&("value"===this.name&&(this.isValueAttribute=!0,"INPUT"===this.pNode.tagName&&"file"===this.pNode.type&&(this.isFileInputValue=!0)),d(this,e),this.selfUpdating=this.fragment.isSimple(),this.ready=!0),void 0)};return h.prototype={bind:e,update:f,updateBindings:function(){this.keypath=this.interpolator.keypath||this.interpolator.ref,"name"===this.propertyName&&(this.pNode.name="{{"+this.keypath+"}}") -},teardown:function(){var a;if(this.boundEvents)for(a=this.boundEvents.length;a--;)this.pNode.removeEventListener(this.boundEvents[a],this.updateModel,!1);this.fragment&&this.fragment.teardown()},bubble:function(){this.selfUpdating?this.update():!this.deferred&&this.ready&&(this.root._deferred.attrs.push(this),this.deferred=!0)},toString:function(){var a;return null===this.value?this.name:this.fragment?(a=this.fragment.toString(),this.name+"="+JSON.stringify(a)):this.name+"="+JSON.stringify(this.value)}},h}(k,Jb,Kb,Lb,Mb,Nb,ac),cc=function(a){return function(b,c){var d,e,f;b.attributes=[];for(d in c)c.hasOwnProperty(d)&&(e=c[d],f=new a({element:b,name:d,value:e,root:b.root,pNode:b.node,contextStack:b.parentFragment.contextStack}),b.attributes[b.attributes.length]=b.attributes[d]=f,"name"!==d&&f.update());return b.attributes}}(bc),dc=function(a,b,c,d){var e,f,g;return d.push(function(){e=d.DomFragment}),f=function(){var a=this.node,b=this.fragment.toString();a.styleSheet&&(a.styleSheet.cssText=b),a.innerHTML=b},g=function(){this.node.type&&"text/javascript"!==this.node.type||a("Script tag was updated. This does not cause the code to be re-evaluated!"),this.node.innerHTML=this.fragment.toString()},function(a,d,h,i){var j,k,l,m,n;if("script"===a.lcName||"style"===a.lcName)return a.fragment=new c({descriptor:h.f,root:a.root,contextStack:a.parentFragment.contextStack,owner:a}),i&&("script"===a.lcName?(a.bubble=g,a.node.innerHTML=a.fragment.toString()):(a.bubble=f,a.bubble())),void 0;if("string"!=typeof h.f||d&&d.namespaceURI&&d.namespaceURI!==b.html)a.fragment=new e({descriptor:h.f,root:a.root,pNode:d,contextStack:a.parentFragment.contextStack,owner:a}),i&&d.appendChild(a.fragment.docFrag);else if(a.html=h.f,i)for(d.innerHTML=a.html,j=a.root._liveQueries,k=j.length;k--;)if(l=j[k],(m=d.querySelectorAll(l))&&(n=m.length))for((a.liveQueries||(a.liveQueries=[])).push(l),a.liveQueries[l]=[];n--;)a.liveQueries[l][n]=m[n]}}(I,d,ac,Eb),ec=function(a,b){var c=function(c,d,e,f){var g,h,i;if(this.root=d,this.node=e.node,g=c.n||c,"string"!=typeof g&&(h=new b({descriptor:g,root:this.root,owner:e,contextStack:f}),g=h.toString(),h.teardown()),c.a?this.params=c.a:c.d&&(h=new b({descriptor:c.d,root:this.root,owner:e,contextStack:f}),this.params=h.toArgsList(),h.teardown()),this.fn=d.decorators[g],!this.fn){if(i='Missing "'+g+'" decorator. You may need to download a plugin via https://github.com/RactiveJS/Ractive/wiki/Plugins#decorators',d.debug)throw new Error(i);a(i)}};return c.prototype={init:function(){var a,b;if(this.params?(b=[this.node].concat(this.params),a=this.fn.apply(this.root,b)):a=this.fn.call(this.root,this.node),!a||!a.teardown)throw new Error("Decorator definition must return an object with a teardown method");this.teardown=a.teardown}},c}(I,ac),fc=function(a){return function(b,c,d,e){d.decorator=new a(b,c,d,e),d.decorator.fn&&c._deferred.decorators.push(d.decorator)}}(ec),gc=function(a,b){var c,d,e,f,g,h,i,j,k;return c=function(a,b,c,e,f){var g,h;g=a.node._ractive.events,h=g[b]||(g[b]=new d(a,b,e,f)),h.add(c)},d=function(b,c,d){var e;this.element=b,this.root=b.root,this.node=b.node,this.name=c,this.contextStack=d,this.proxies=[],(e=this.root.events[c])?this.custom=e(this.node,k(c)):("on"+c in this.node||a('Missing "'+this.name+'" event. You may need to download a plugin via https://github.com/RactiveJS/Ractive/wiki/Plugins#events'),this.node.addEventListener(c,j,!1))},d.prototype={add:function(a){this.proxies[this.proxies.length]=new e(this.element,this.root,a,this.contextStack)},teardown:function(){var a;for(this.custom?this.custom.teardown():this.node.removeEventListener(this.name,j,!1),a=this.proxies.length;a--;)this.proxies[a].teardown()},fire:function(a){for(var b=this.proxies.length;b--;)this.proxies[b].fire(a)}},e=function(a,c,d,e){var i;return this.root=c,i=d.n||d,this.n="string"==typeof i?i:new b({descriptor:d.n,root:this.root,owner:a,contextStack:e}),d.a?(this.a=d.a,this.fire=g,void 0):d.d?(this.d=new b({descriptor:d.d,root:this.root,owner:a,contextStack:e}),this.fire=h,void 0):(this.fire=f,void 0)},e.prototype={teardown:function(){this.n.teardown&&this.n.teardown(),this.d&&this.d.teardown()},bubble:function(){}},f=function(a){this.root.fire(this.n.toString(),a)},g=function(a){this.root.fire.apply(this.root,[this.n.toString(),a].concat(this.a))},h=function(a){var b=this.d.toArgsList();"string"==typeof b&&(b=b.substr(1,b.length-2)),this.root.fire.apply(this.root,[this.n.toString(),a].concat(b))},j=function(a){var b=this._ractive;b.events[a.type].fire({node:this,original:a,index:b.index,keypath:b.keypath,context:b.root.get(b.keypath)})},i={},k=function(a){return i[a]?i[a]:i[a]=function(b){var c=b.node._ractive;b.index=c.index,b.keypath=c.keypath,b.context=c.root.get(c.keypath),c.events[a].fire(b)}},c}(I,ac),hc=function(a){return function(b,c){var d,e,f;for(e in c)if(c.hasOwnProperty(e))for(f=e.split("-"),d=f.length;d--;)a(b,f[d],c[e],b.parentFragment.contextStack)}}(gc),ic=function(){return function(a){var b,c,d,e,f;for(b=a.root,c=b._liveQueries,d=c.length;d--;)e=c[d],f=c[e],f._test(a)&&((a.liveQueries||(a.liveQueries=[])).push(e),a.liveQueries[e]=[a.node])}}(),jc=function(){return function(a){return a.replace(/-([a-zA-Z])/g,function(a,b){return b.toUpperCase()})}}(),kc=function(){return function(a,b){var c;for(c in b)b.hasOwnProperty(c)&&!a.hasOwnProperty(c)&&(a[c]=b[c]);return a}}(),lc=function(a,b,c,d,e,f,g,h){function i(a){var b,c,d;if(!q[a])if(void 0!==m[a])q[a]=a;else for(d=a.charAt(0).toUpperCase()+a.substring(1),b=n.length;b--;)if(c=n[b],void 0!==m[c+d]){q[a]=c+d;break}return q[a]}function j(a){return a.replace(p,"")}function k(a){var b;return o.test(a)&&(a="-"+a),b=a.replace(/[A-Z]/g,function(a){return"-"+a.toLowerCase()})}var l,m,n,o,p,q,r,s,t,u,v,w;if(a)return m=b("div").style,function(){void 0!==m.transition?(s="transition",w="transitionend",r=!0):void 0!==m.webkitTransition?(s="webkitTransition",w="webkitTransitionEnd",r=!0):r=!1}(),s&&(t=s+"Duration",u=s+"Property",v=s+"TimingFunction"),l=function(a,b,d,e,f){var g,i,j,k=this;if(this.root=b,this.node=d.node,this.isIntro=f,this.originalStyle=this.node.getAttribute("style"),this.complete=function(a){!a&&k.isIntro&&k.resetStyle(),k._manager.pop(k.node),k.node._ractive.transition=null},g=a.n||a,"string"!=typeof g&&(i=new h({descriptor:g,root:this.root,owner:d,contextStack:e}),g=i.toString(),i.teardown()),this.name=g,a.a?this.params=a.a:a.d&&(i=new h({descriptor:a.d,root:this.root,owner:d,contextStack:e}),this.params=i.toArgsList(),i.teardown()),this._fn=b.transitions[g],!this._fn){if(j='Missing "'+g+'" transition. You may need to download a plugin via https://github.com/RactiveJS/Ractive/wiki/Plugins#transitions',b.debug)throw new Error(j);return c(j),void 0}},l.prototype={init:function(){if(this._inited)throw new Error("Cannot initialize a transition more than once");this._inited=!0,this._fn.apply(this.root,[this].concat(this.params))},getStyle:function(a){var b,c,d,f,g;if(b=window.getComputedStyle(this.node),"string"==typeof a)return g=b[i(a)],"0px"===g&&(g=0),g;if(!e(a))throw new Error("Transition#getStyle must be passed a string, or an array of strings representing CSS properties");for(c={},d=a.length;d--;)f=a[d],g=b[i(f)],"0px"===g&&(g=0),c[f]=g;return c},setStyle:function(a,b){var c;if("string"==typeof a)this.node.style[i(a)]=b;else for(c in a)a.hasOwnProperty(c)&&(this.node.style[i(c)]=a[c]);return this},animateStyle:function(a,b,d,e){var g,h,l,m,n,o,p,q,r,s=this;for("string"==typeof a?(n={},n[a]=b):(n=a,e=d,d=b),d||(c('The "'+s.name+'" transition does not supply an options object to `t.animateStyle()`. This will break in a future version of Ractive. For more info see https://github.com/RactiveJS/Ractive/issues/340'),d=s,e=s.complete),d.duration||(s.setStyle(n),e&&e()),g=Object.keys(n),h=[],l=window.getComputedStyle(s.node),o={},q=g.length;q--;)r=g[q],m=l[i(r)],"0px"===m&&(m=0),m!=n[r]&&(h[h.length]=r,s.node.style[i(r)]=m);return h.length?(setTimeout(function(){s.node.style[u]=g.map(i).map(k).join(","),s.node.style[v]=k(d.easing||"linear"),s.node.style[t]=d.duration/1e3+"s",p=function(a){var b;b=h.indexOf(f(j(a.propertyName))),-1!==b&&h.splice(b,1),h.length||(s.root.fire(s.name+":end"),s.node.removeEventListener(w,p,!1),e&&e())},s.node.addEventListener(w,p,!1),setTimeout(function(){for(var a=h.length;a--;)r=h[a],s.node.style[i(r)]=n[r]},0)},d.delay||0),void 0):(e&&e(),void 0)},resetStyle:function(){this.originalStyle?this.node.setAttribute("style",this.originalStyle):(this.node.getAttribute("style"),this.node.removeAttribute("style"))},processParams:function(a,b){return"number"==typeof a?a={duration:a}:"string"==typeof a?a="slow"===a?{duration:600}:"fast"===a?{duration:200}:{duration:400}:a||(a={}),g(a,b)}},n=["o","ms","moz","webkit"],o=new RegExp("^(?:"+n.join("|")+")([A-Z])"),p=new RegExp("^-(?:"+n.join("|")+")-"),q={},l}(f,e,I,J,l,jc,kc,ac),mc=function(a,b){return function(a,c,d,e,f){var g,h,i;!c.transitionsEnabled||c._parent&&!c._parent.transitionsEnabled||(g=new b(a,c,d,e,f),g._fn&&(h=g.node,g._manager=c._transitionManager,(i=h._ractive.transition)&&i.complete(),h._ractive.transition=g,g._manager.push(h),f?c._deferred.transitions.push(g):g.init()))}}(I,lc),nc=function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){return function(e,p,q){var r,s,t,u,v,w,x,y,z,A,B,C,D;if(e.type=a.ELEMENT,r=e.parentFragment=p.parentFragment,s=r.pNode,t=r.contextStack,u=e.descriptor=p.descriptor,e.root=B=r.root,e.index=p.index,e.lcName=u.e.toLowerCase(),e.eventListeners=[],e.customEventListeners=[],s&&(v=e.namespace=h(u,s),w=v!==b.html?o(u.e):u.e,e.node=g(w,v),d(e.node,"_ractive",{value:{proxy:e,keypath:t.length?t[t.length-1]:"",index:r.indexRefs,events:c(null),root:B}})),x=i(e,u.a),u.f){if(e.node&&e.node.getAttribute("contenteditable")&&e.node.innerHTML){if(D="A pre-populated contenteditable element should not have children",B.debug)throw new Error(D);f(D)}j(e,e.node,u,q)}q&&u.v&&l(e,u.v),q&&(B.twoway&&(e.bind(),e.node.getAttribute("contenteditable")&&e.node._ractive.binding&&e.node._ractive.binding.update()),x.name&&!x.name.twoway&&x.name.update(),"IMG"===e.node.tagName&&((y=e.attributes.width)||(z=e.attributes.height))&&e.node.addEventListener("load",A=function(){y&&(e.node.width=y.value),z&&(e.node.height=z.value),e.node.removeEventListener("load",A,!1)},!1),q.appendChild(e.node),u.o&&k(u.o,B,e,t),u.t1&&n(u.t1,B,e,t,!0),"OPTION"===e.node.tagName&&("SELECT"===s.tagName&&(C=s._ractive.binding)&&C.deferUpdate(),e.node._ractive.value==s._ractive.value&&(e.node.selected=!0)),e.node.autofocus&&(B._deferred.focusable=e.node)),m(e)}}(k,d,c,g,Z,I,e,Hb,cc,dc,fc,hc,ic,mc,Ib),oc=function(a){return function(b){var c,d,e,f,g,h,i,j,k;for(this.fragment&&this.fragment.teardown(!1);this.attributes.length;)this.attributes.pop().teardown();if(this.node){for(c in this.node._ractive.events)this.node._ractive.events[c].teardown();(d=this.node._ractive.binding)&&(d.teardown(),e=this.root._twowayBindings[d.attr.keypath],e.splice(e.indexOf(d),1))}if(this.decorator&&this.decorator.teardown(),this.descriptor.t2&&a(this.descriptor.t2,this.root,this,this.parentFragment.contextStack,!1),b&&this.root._transitionManager.detachWhenReady(this),g=this.liveQueries)for(f=g.length;f--;)if(h=g[f],j=this.liveQueries[h])for(k=j.length,i=this.root._liveQueries[h];k--;)i._remove(j[k])}}(mc),pc=function(){return"area base br col command doctype embed hr img input keygen link meta param source track wbr".split(" ")}(),qc=function(a){return function(){var b,c,d;for(b="<"+(this.descriptor.y?"!doctype":this.descriptor.e),d=this.attributes.length,c=0;d>c;c+=1)b+=" "+this.attributes[c].toString();return b+=">",this.html?b+=this.html:this.fragment&&(b+=this.fragment.toString()),-1===a.indexOf(this.descriptor.e)&&(b+=""),b}}(pc),rc=function(a){return function(b){var c;return a(this.node,b)?this.node:this.html&&(c=this.node.querySelector(b))?c:this.fragment&&this.fragment.find?this.fragment.find(b):void 0}}(Z),sc=function(){return function(a,b){var c,d,e,f,g;if(b._test(this,!0)&&b.live&&((this.liveQueries||(this.liveQueries=[])).push(a),this.liveQueries[a]=[this.node]),this.html&&(c=this.node.querySelectorAll(a))&&(e=c.length))for(b.live&&(this.liveQueries[a]||((this.liveQueries||(this.liveQueries=[])).push(a),this.liveQueries[a]=[]),g=this.liveQueries[a]),d=0;e>d;d+=1)f=c[d],b.push(f),b.live&&g.push(f);this.fragment&&this.fragment.findAll(a,b)}}(),tc=function(){return function(a){return this.fragment?this.fragment.findComponent(a):void 0}}(),uc=function(){return function(a,b){this.fragment&&this.fragment.findAllComponents(a,b)}}(),vc=function(){return function(){var a=this.attributes;if(this.node&&(this.binding&&(this.binding.teardown(),this.binding=null),!(this.node.getAttribute("contenteditable")&&a.value&&a.value.bind())))switch(this.descriptor.e){case"select":case"textarea":return a.value&&a.value.bind(),void 0;case"input":if("radio"===this.node.type||"checkbox"===this.node.type){if(a.name&&a.name.bind())return;if(a.checked&&a.checked.bind())return}if(a.value&&a.value.bind())return}}}(),wc=function(a,b,c,d,e,f,g,h){var i=function(b,c){a(this,b,c)};return i.prototype={detach:function(){return this.node?(this.node.parentNode&&this.node.parentNode.removeChild(this.node),this.node):void 0},teardown:b,firstNode:function(){return this.node},findNextNode:function(){return null},bubble:function(){},toString:c,find:d,findAll:e,findComponent:f,findAllComponents:g,bind:h},i}(nc,oc,qc,rc,sc,tc,uc,vc),xc={missingParser:"Missing Ractive.parse - cannot parse template. Either preparse or use the version that includes the parser"},yc={},zc=function(a,b,c,d,e,f){var g,h,i,j;return g=function(d,g){var k,l,m;if(l=i(d,g))return l;if(b&&(k=document.getElementById(g),k&&"SCRIPT"===k.tagName)){if(!f)throw new Error(a.missingParser);h(f(k.innerHTML),g,e)}if(l=e[g],!l){if(m='Could not find descriptor for partial "'+g+'"',d.debug)throw new Error(m);return c(m),[]}return j(l)},i=function(b,c){var d;if(b.partials[c]){if("string"==typeof b.partials[c]){if(!f)throw new Error(a.missingParser);d=f(b.partials[c],b.parseOptions),h(d,c,b.partials)}return j(b.partials[c])}},h=function(a,b,c){var e;if(d(a)){c[b]=a.main;for(e in a.partials)a.partials.hasOwnProperty(e)&&(c[e]=a.partials[e])}else c[b]=a},j=function(a){return 1===a.length&&"string"==typeof a[0]?a[0]:a},g}(xc,f,I,w,yc,parse__parse),Ac=function(a,b,c){var d,e;return c.push(function(){e=c.DomFragment}),d=function(c,d){var f,g=this.parentFragment=c.parentFragment;if(this.type=a.PARTIAL,this.name=c.descriptor.r,this.index=c.index,!c.descriptor.r)throw new Error("Partials must have a static reference (no expressions). This may change in a future version of Ractive.");f=b(g.root,c.descriptor.r),this.fragment=new e({descriptor:f,root:g.root,pNode:g.pNode,contextStack:g.contextStack,owner:this}),d&&d.appendChild(this.fragment.docFrag)},d.prototype={firstNode:function(){return this.fragment.firstNode()},findNextNode:function(){return this.parentFragment.findNextNode(this)},detach:function(){return this.fragment.detach()},teardown:function(a){this.fragment.teardown(a)},toString:function(){return this.fragment.toString()},find:function(a){return this.fragment.find(a)},findAll:function(a,b){return this.fragment.findAll(a,b)},findComponent:function(a){return this.fragment.findComponent(a)},findAllComponents:function(a,b){return this.fragment.findAllComponents(a,b)}},d}(k,zc,Eb),Bc=function(a){var b=function(b,c,d){this.parentFragment=b.parentFragment,this.component=b,this.key=c,this.fragment=new a({descriptor:d,root:b.root,owner:this,contextStack:b.parentFragment.contextStack}),this.selfUpdating=this.fragment.isSimple(),this.value=this.fragment.getValue()};return b.prototype={bubble:function(){this.selfUpdating?this.update():!this.deferred&&this.ready&&(this.root._deferred.attrs.push(this),this.deferred=!0)},update:function(){var a=this.fragment.getValue();this.component.instance.set(this.key,a),this.value=a},teardown:function(){this.fragment.teardown()}},b}(ac),Cc=function(a,b,c,d){function e(e,f,g,h){var i,j,k,l,m;return k=e.root,l=e.parentFragment,"string"==typeof g?(j=b(g),j?j.value:g):null===g?!0:1===g.length&&g[0].t===a.INTERPOLATOR&&g[0].r?l.indexRefs&&void 0!==l.indexRefs[g[0].r]?l.indexRefs[g[0].r]:(m=c(k,g[0].r,l.contextStack)||g[0].r,h.push({childKeypath:f,parentKeypath:m}),k.get(m)):(i=new d(e,f,g),e.complexParameters.push(i),i.value)}return function(a,b,c){var d,f,g;d={},a.complexParameters=[];for(f in b)b.hasOwnProperty(f)&&(g=e(a,f,b[f],c),void 0!==g&&(d[f]=g));return d}}(k,Xb,y,Bc),Dc=function(){return function(a,b,c,d,e){var f,g,h,i;return g=a.parentFragment,i=a.root,h={content:e||[]},f=new b({el:g.pNode.cloneNode(!1),data:c,partials:h,_parent:i,adaptors:i.adaptors}),f.component=a,a.instance=f,f.insert(d),f.fragment.pNode=g.pNode,f}}(),Ec=function(){function a(a,c,d){var e,f,g,h,i,j,k;e=a.root,f=a.instance,i=a.observers,j=e.observe(c,function(a){g||e._wrapped[c]||(h=!0,f.set(d,a),h=!1)},b),i.push(j),f.twoway&&(j=f.observe(d,function(a){h||(g=!0,e.set(c,a),g=!1)},b),i.push(j),k=f.get(d),void 0!==k&&e.set(c,k))}var b={init:!1,debug:!0};return function(b,c){var d,e;for(b.observers=[],e=c.length;e--;)d=c[e],a(b,d.parentKeypath,d.childKeypath)}}(),Fc=function(a){function b(b,d,e,f){if("string"!=typeof f){if(d.debug)throw new Error(c);return a(c),void 0}b.on(e,function(){var a=Array.prototype.slice.call(arguments);a.unshift(f),d.fire.apply(d,a)})}var c="Components currently only support simple events - you cannot include arguments. Sorry!";return function(a,c){var d;for(d in c)c.hasOwnProperty(d)&&b(a.instance,a.root,d,c[d])}}(I),Gc=function(){return function(a){var b,c;for(b=a.root;b;)(c=b._liveComponentQueries[a.name])&&c.push(a.instance),b=b._parent}}(),Hc=function(a,b,c,d,e,f,g){return function(h,i,j){var k,l,m,n,o;if(k=h.parentFragment=i.parentFragment,l=k.root,h.root=l,h.type=a.COMPONENT,h.name=i.descriptor.e,h.index=i.index,h.observers=[],m=l.components[i.descriptor.e],!m)throw new Error('Component "'+i.descriptor.e+'" not found');o=[],n=c(h,i.descriptor.a,o),d(h,m,n,j,i.descriptor.f),e(h,o),f(h,i.descriptor.v),(i.descriptor.t1||i.descriptor.t2||i.descriptor.o)&&b('The "intro", "outro" and "decorator" directives have no effect on components'),g(h)}}(k,I,Cc,Dc,Ec,Fc,Gc),Ic=function(a){var b=function(b,c){a(this,b,c)};return b.prototype={firstNode:function(){return this.instance.fragment.firstNode()},findNextNode:function(){return this.parentFragment.findNextNode(this)},detach:function(){return this.instance.fragment.detach()},teardown:function(){for(var a;this.complexParameters.length;)this.complexParameters.pop().teardown();for(;this.observers.length;)this.observers.pop().cancel();(a=this.root._liveComponentQueries[this.name])&&a._remove(this),this.instance.teardown()},toString:function(){return this.instance.fragment.toString()},find:function(a){return this.instance.fragment.find(a)},findAll:function(a,b){return this.instance.fragment.findAll(a,b)},findComponent:function(a){return a&&a!==this.name?null:this.instance},findAllComponents:function(a,b){b._test(this,!0),this.instance.fragment&&this.instance.fragment.findAllComponents(a,b)}},b}(Hc),Jc=function(a){var b=function(b,c){this.type=a.COMMENT,this.descriptor=b.descriptor,c&&(this.node=document.createComment(b.descriptor.f),c.appendChild(this.node))};return b.prototype={detach:function(){return this.node.parentNode.removeChild(this.node),this.node},teardown:function(a){a&&this.detach()},firstNode:function(){return this.node},toString:function(){return""}},b}(k),Kc=function(a,b,c,d,e,f,g,h,i,j,k,l,m){var n=function(a){a.pNode&&(this.docFrag=document.createDocumentFragment()),"string"==typeof a.descriptor?(this.html=a.descriptor,this.docFrag&&(this.nodes=d(this.html,a.pNode.tagName,this.docFrag))):c(this,a)};return n.prototype={detach:function(){var a,b;if(this.nodes)for(b=this.nodes.length;b--;)this.docFrag.appendChild(this.nodes[b]);else if(this.items)for(a=this.items.length,b=0;a>b;b+=1)this.docFrag.appendChild(this.items[b].detach());return this.docFrag},createItem:function(b){if("string"==typeof b.descriptor)return new e(b,this.docFrag);switch(b.descriptor.t){case a.INTERPOLATOR:return new f(b,this.docFrag);case a.SECTION:return new g(b,this.docFrag);case a.TRIPLE:return new h(b,this.docFrag);case a.ELEMENT:return this.root.components[b.descriptor.e]?new k(b,this.docFrag):new i(b,this.docFrag);case a.PARTIAL:return new j(b,this.docFrag);case a.COMMENT:return new l(b,this.docFrag);default:throw new Error("Something very strange happened. Please file an issue at https://github.com/RactiveJS/Ractive/issues. Thanks!")}},teardown:function(a){var b;if(this.nodes&&a)for(;b=this.nodes.pop();)b.parentNode.removeChild(b);else if(this.items)for(;this.items.length;)this.items.pop().teardown(a);this.nodes=this.items=this.docFrag=null},firstNode:function(){return this.items&&this.items[0]?this.items[0].firstNode():this.nodes?this.nodes[0]||null:null},findNextNode:function(a){var b=a.index;return this.items[b+1]?this.items[b+1].firstNode():this.owner===this.root?this.owner.component?this.owner.component.findNextNode():null:this.owner.findNextNode(this)},toString:function(){var a,b,c,d;if(this.html)return this.html;if(a="",!this.items)return a;for(c=this.items.length,b=0;c>b;b+=1)d=this.items[b],a+=d.toString();return a},find:function(a){var c,d,e,f,g;if(this.nodes){for(d=this.nodes.length,c=0;d>c;c+=1)if(f=this.nodes[c],1===f.nodeType){if(b(f,a))return f;if(g=f.querySelector(a))return g}return null}if(this.items){for(d=this.items.length,c=0;d>c;c+=1)if(e=this.items[c],e.find&&(g=e.find(a)))return g;return null}},findAll:function(a,c){var d,e,f,g,h,i,j;if(this.nodes){for(e=this.nodes.length,d=0;e>d;d+=1)if(g=this.nodes[d],1===g.nodeType&&(b(g,a)&&c.push(g),h=g.querySelectorAll(a)))for(i=h.length,j=0;i>j;j+=1)c.push(h[j])}else if(this.items)for(e=this.items.length,d=0;e>d;d+=1)f=this.items[d],f.findAll&&f.findAll(a,c);return c},findComponent:function(a){var b,c,d,e;if(this.items){for(b=this.items.length,c=0;b>c;c+=1)if(d=this.items[c],d.findComponent&&(e=d.findComponent(a)))return e;return null}},findAllComponents:function(a,b){var c,d,e;if(this.items)for(d=this.items.length,c=0;d>c;c+=1)e=this.items[c],e.findAllComponents&&e.findAllComponents(a,b);return b}},m.DomFragment=n,n}(k,Z,kb,lb,mb,zb,Fb,Gb,wc,Ac,Ic,Jc,Eb),Lc=function(a,b,c,d,e){return function(a,f){var g;if(!this._initing)throw new Error("You cannot call ractive.render() directly!");this._transitionManager=g=b(this,f),this.fragment=new e({descriptor:this.template,root:this,owner:this,pNode:a}),c(this),a&&a.appendChild(this.fragment.docFrag),d(this),this._transitionManager=null,g.ready(),this.rendered=!0}}(jb,q,o,p,Kc),Mc=function(a){return function(){return a("renderHTML() has been deprecated and will be removed in a future version. Please use toHTML() instead"),this.toHTML()}}(I),Nc=function(){return function(){return this.fragment.toString()}}(),Oc=function(a,b){return function(c){var d,e,f;for(this.fire("teardown"),f=this._transitionManager,this._transitionManager=e=a(this,c),this.fragment.teardown(!0);this._animations[0];)this._animations[0].stop();for(d in this._cache)b(this,d);this._transitionManager=f,e.ready()}}(q,m),Pc=function(a){return function(b,c,d){var e;if("string"==typeof c&&a(d)){if(e=b.get(c),void 0===e&&(e=0),a(e))b.set(c,e+d);else if(b.debug)throw new Error("Cannot add to a non-numeric value")}else if(b.debug)throw new Error("Bad arguments")}}(J),Qc=function(a){return function(b,c){a(this,b,void 0===c?1:c)}}(Pc),Rc=function(a){return function(b,c){a(this,b,void 0===c?-1:-c)}}(Pc),Sc=function(){return function(a){var b;if("string"==typeof a)b=this.get(a),this.set(a,!b);else if(this.debug)throw new Error("Bad arguments")}}(),Tc=function(){return function(a,b){var c,d,e,f,g;return c={},e=0,d=function(a,d){var f,h,i;h=e,i=b.length;do{if(f=b.indexOf(a,h),-1===f)return g=!0,-1;h=f+1}while(c[f]&&i>h);return f===e&&(e+=1),f!==d&&(g=!0),c[f]=!0,f},f=a.map(d),f.unchanged=!g,f}}(),Uc=function(a){return function(b,c,d,e){var f,g;for(f=c.length;f--;)g=c[f],g.type===a.REFERENCE?g.update():g.keypath===b&&g.type===a.SECTION&&!g.inverted&&g.docFrag?d[d.length]=g:e[e.length]=g}}(k),Vc=function(a,b,c,d,e,f,g,h,i,j){function k(a){return JSON.stringify(a)}function l(a){return m[a]||(m[a]=function(b){return b[a]}),m[a]}var m={};return function(m,n,o){var p,q,r,s,t,u,v,w,x,y,z,A,B,C,D;if(p=this.get(m),!b(p)||!b(n))return this.set(m,n,o&&o.complete);if(t=p.length===n.length,o&&o.compare){if(o.compare===!0)s=k;else if("string"==typeof o.compare)s=l(o.compare);else{if("function"!=typeof o.compare)throw new Error("The `compare` option must be a function, or a string representing an identifying field (or `true` to use JSON.stringify)");s=o.compare}try{q=p.map(s),r=n.map(s)}catch(E){if(this.debug)throw E;a("Merge operation: comparison failed. Falling back to identity checking"),q=p,r=n}}else q=p,r=n;if(v=i(q,r),c(this,m),h(this,m,n),!v.unchanged||!t){for(B=this._transitionManager,this._transitionManager=A=f(this,o&&o.complete),w=[],x=[],u=0;u 2 && args[1]) { - changed = Math.min(args[1], args.length - 2); - start = args[0]; - end = start + changed; - if (args[1] === args.length - 2) { - lengthUnchanged = true; - } - for (i = start; i < end; i += 1) { - childKeypath = keypath + '.' + i; - notifyDependants(root, childKeypath); - } - } - preDomUpdate(root); - upstreamQueue = []; - keys = keypath.split('.'); - while (keys.length) { - keys.pop(); - upstreamQueue[upstreamQueue.length] = keys.join('.'); - } - notifyDependants.multiple(root, upstreamQueue, true); - if (!lengthUnchanged) { - notifyDependants(root, keypath + '.length', true); - } - }; - queueDependants = function (keypath, deps, smartUpdateQueue, dumbUpdateQueue) { - var k, dependant; - k = deps.length; - while (k--) { - dependant = deps[k]; - if (dependant.type === types.REFERENCE) { - dependant.update(); - } else if (dependant.keypath === keypath && dependant.type === types.SECTION && !dependant.inverted && dependant.docFrag) { - smartUpdateQueue[smartUpdateQueue.length] = dependant; - } else { - dumbUpdateQueue[dumbUpdateQueue.length] = dependant; - } - } - }; - wrappers = array._ractive.wrappers; - i = wrappers.length; - while (i--) { - wrapper = wrappers[i]; - notifyKeypathDependants(wrapper.root, wrapper.keypath); - } - }; - patchedArrayProto = []; - mutatorMethods = [ - 'pop', - 'push', - 'reverse', - 'shift', - 'sort', - 'splice', - 'unshift' - ]; - noop = function () { - }; - mutatorMethods.forEach(function (methodName) { - var method = function () { - var result, instances, instance, i, previousTransitionManagers = {}, transitionManagers = {}; - result = Array.prototype[methodName].apply(this, arguments); - instances = this._ractive.instances; - i = instances.length; - while (i--) { - instance = instances[i]; - previousTransitionManagers[instance._guid] = instance._transitionManager; - instance._transitionManager = transitionManagers[instance._guid] = makeTransitionManager(instance, noop); - } - this._ractive.setting = true; - notifyArrayDependants(this, methodName, arguments); - this._ractive.setting = false; - i = instances.length; - while (i--) { - instance = instances[i]; - instance._transitionManager = previousTransitionManagers[instance._guid]; - transitionManagers[instance._guid].ready(); - preDomUpdate(instance); - postDomUpdate(instance); - } - return result; - }; - defineProperty(patchedArrayProto, methodName, { value: method }); - }); - testObj = {}; - if (testObj.__proto__) { - patchArrayMethods = function (array) { - array.__proto__ = patchedArrayProto; - }; - unpatchArrayMethods = function (array) { - array.__proto__ = Array.prototype; - }; - } else { - patchArrayMethods = function (array) { - var i, methodName; - i = mutatorMethods.length; - while (i--) { - methodName = mutatorMethods[i]; - defineProperty(array, methodName, { - value: patchedArrayProto[methodName], - configurable: true - }); - } - }; - unpatchArrayMethods = function (array) { - var i; - i = mutatorMethods.length; - while (i--) { - delete array[mutatorMethods[i]]; - } - }; - } - errorMessage = 'Something went wrong in a rather interesting way'; - return arrayAdaptor; - }(config_types, utils_defineProperty, utils_isArray, shared_clearCache, shared_preDomUpdate, shared_postDomUpdate, shared_makeTransitionManager, shared_notifyDependants); -var Ractive_prototype_get_magicAdaptor = function () { - - var magicAdaptor, MagicWrapper; - try { - Object.defineProperty({}, 'test', { value: 0 }); - } catch (err) { - return false; - } - magicAdaptor = { - filter: function (object, keypath) { - return !!keypath; - }, - wrap: function (ractive, object, keypath) { - return new MagicWrapper(ractive, object, keypath); - } - }; - MagicWrapper = function (ractive, object, keypath) { - var wrapper = this, keys, prop, objKeypath, descriptor, wrappers, oldGet, oldSet, get, set; - this.ractive = ractive; - this.keypath = keypath; - keys = keypath.split('.'); - this.prop = keys.pop(); - objKeypath = keys.join('.'); - this.obj = objKeypath ? ractive.get(objKeypath) : ractive.data; - descriptor = this.originalDescriptor = Object.getOwnPropertyDescriptor(this.obj, this.prop); - if (descriptor && descriptor.set && (wrappers = descriptor.set._ractiveWrappers)) { - if (wrappers.indexOf(this) === -1) { - wrappers.push(this); - } - return; - } - if (descriptor && !descriptor.configurable) { - throw new Error('Cannot use magic mode with property "' + prop + '" - object is not configurable'); - } - if (descriptor) { - this.value = descriptor.value; - oldGet = descriptor.get; - oldSet = descriptor.set; - } - get = oldGet || function () { - return wrapper.value; - }; - set = function (value) { - var wrappers, wrapper, i; - if (oldSet) { - oldSet(value); - } - wrappers = set._ractiveWrappers; - i = wrappers.length; - while (i--) { - wrapper = wrappers[i]; - if (!wrapper.resetting) { - wrapper.ractive.set(wrapper.keypath, value); - } - } - }; - set._ractiveWrappers = [this]; - Object.defineProperty(this.obj, this.prop, { - get: get, - set: set, - enumerable: true, - configurable: true - }); - }; - MagicWrapper.prototype = { - get: function () { - return this.value; - }, - reset: function (value) { - this.resetting = true; - this.value = value; - this.resetting = false; - }, - teardown: function () { - var descriptor, set, value, wrappers; - descriptor = Object.getOwnPropertyDescriptor(this.obj, this.prop); - set = descriptor.set; - wrappers = set._ractiveWrappers; - wrappers.splice(wrappers.indexOf(this), 1); - if (!wrappers.length) { - value = this.obj[this.prop]; - Object.defineProperty(this.obj, this.prop, this.originalDescriptor || { - writable: true, - enumerable: true, - configrable: true - }); - this.obj[this.prop] = value; - } - } - }; - return magicAdaptor; - }(); -var shared_adaptIfNecessary = function (adaptorRegistry, arrayAdaptor, magicAdaptor) { - - var prefixers = {}; - return function (ractive, keypath, value, isExpressionResult) { - var len, i, adaptor, wrapped; - len = ractive.adaptors.length; - for (i = 0; i < len; i += 1) { - adaptor = ractive.adaptors[i]; - if (typeof adaptor === 'string') { - if (!adaptorRegistry[adaptor]) { - throw new Error('Missing adaptor "' + adaptor + '"'); - } - adaptor = ractive.adaptors[i] = adaptorRegistry[adaptor]; - } - if (adaptor.filter(value, keypath, ractive)) { - wrapped = ractive._wrapped[keypath] = adaptor.wrap(ractive, value, keypath, getPrefixer(keypath)); - wrapped.value = value; - return; - } - } - if (!isExpressionResult) { - if (ractive.magic && magicAdaptor.filter(value, keypath, ractive)) { - ractive._wrapped[keypath] = magicAdaptor.wrap(ractive, value, keypath); - } else if (ractive.modifyArrays && arrayAdaptor.filter(value, keypath, ractive)) { - ractive._wrapped[keypath] = arrayAdaptor.wrap(ractive, value, keypath); - } - } - }; - function prefixKeypath(obj, prefix) { - var prefixed = {}, key; - if (!prefix) { - return obj; - } - prefix += '.'; - for (key in obj) { - if (obj.hasOwnProperty(key)) { - prefixed[prefix + key] = obj[key]; - } - } - return prefixed; - } - function getPrefixer(rootKeypath) { - var rootDot; - if (!prefixers[rootKeypath]) { - rootDot = rootKeypath ? rootKeypath + '.' : ''; - prefixers[rootKeypath] = function (relativeKeypath, value) { - var obj; - if (typeof relativeKeypath === 'string') { - obj = {}; - obj[rootDot + relativeKeypath] = value; - return obj; - } - if (typeof relativeKeypath === 'object') { - return rootDot ? prefixKeypath(relativeKeypath, rootKeypath) : relativeKeypath; - } - }; - } - return prefixers[rootKeypath]; - } - }(registries_adaptors, Ractive_prototype_get_arrayAdaptor, Ractive_prototype_get_magicAdaptor); -var Ractive_prototype_get__get = function (normaliseKeypath, adaptorRegistry, adaptIfNecessary) { - - var get, _get, retrieve; - get = function (keypath) { - if (this._captured && !this._captured[keypath]) { - this._captured.push(keypath); - this._captured[keypath] = true; - } - return _get(this, keypath); - }; - _get = function (ractive, keypath) { - var cache, cached, value, wrapped, evaluator; - keypath = normaliseKeypath(keypath); - cache = ractive._cache; - if ((cached = cache[keypath]) !== undefined) { - return cached; - } - if (wrapped = ractive._wrapped[keypath]) { - value = wrapped.value; - } else if (!keypath) { - adaptIfNecessary(ractive, '', ractive.data); - value = ractive.data; - } else if (evaluator = ractive._evaluators[keypath]) { - value = evaluator.value; - } else { - value = retrieve(ractive, keypath); - } - cache[keypath] = value; - return value; - }; - retrieve = function (ractive, keypath) { - var keys, key, parentKeypath, parentValue, cacheMap, value, wrapped; - keys = keypath.split('.'); - key = keys.pop(); - parentKeypath = keys.join('.'); - parentValue = _get(ractive, parentKeypath); - if (wrapped = ractive._wrapped[parentKeypath]) { - parentValue = wrapped.get(); - } - if (parentValue === null || parentValue === undefined) { - return; - } - if (!(cacheMap = ractive._cacheMap[parentKeypath])) { - ractive._cacheMap[parentKeypath] = [keypath]; - } else { - if (cacheMap.indexOf(keypath) === -1) { - cacheMap[cacheMap.length] = keypath; - } - } - value = parentValue[key]; - adaptIfNecessary(ractive, keypath, value); - ractive._cache[keypath] = value; - return value; - }; - return get; - }(utils_normaliseKeypath, registries_adaptors, shared_adaptIfNecessary); -var utils_isObject = function () { - - var toString = Object.prototype.toString; - return function (thing) { - return typeof thing === 'object' && toString.call(thing) === '[object Object]'; - }; - }(); -var utils_isEqual = function () { - - return function (a, b) { - if (a === null && b === null) { - return true; - } - if (typeof a === 'object' || typeof b === 'object') { - return false; - } - return a === b; - }; - }(); -var shared_resolveRef = function () { - - var resolveRef; - resolveRef = function (ractive, ref, contextStack) { - var keypath, keys, lastKey, contextKeys, innerMostContext, postfix, parentKeypath, parentValue, wrapped, context, ancestorErrorMessage; - ancestorErrorMessage = 'Could not resolve reference - too many "../" prefixes'; - if (ref === '.') { - if (!contextStack.length) { - return ''; - } - keypath = contextStack[contextStack.length - 1]; - } else if (ref.charAt(0) === '.') { - context = contextStack[contextStack.length - 1]; - contextKeys = context ? context.split('.') : []; - if (ref.substr(0, 3) === '../') { - while (ref.substr(0, 3) === '../') { - if (!contextKeys.length) { - throw new Error(ancestorErrorMessage); - } - contextKeys.pop(); - ref = ref.substring(3); - } - contextKeys.push(ref); - keypath = contextKeys.join('.'); - } else if (!context) { - keypath = ref.substring(1); - } else { - keypath = context + ref; - } - } else { - keys = ref.split('.'); - lastKey = keys.pop(); - postfix = keys.length ? '.' + keys.join('.') : ''; - contextStack = contextStack.concat(); - while (contextStack.length) { - innerMostContext = contextStack.pop(); - parentKeypath = innerMostContext + postfix; - parentValue = ractive.get(parentKeypath); - if (wrapped = ractive._wrapped[parentKeypath]) { - parentValue = wrapped.get(); - } - if (typeof parentValue === 'object' && parentValue !== null && parentValue.hasOwnProperty(lastKey)) { - keypath = innerMostContext + '.' + ref; - break; - } - } - if (!keypath && ractive.get(ref) !== undefined) { - keypath = ref; - } - } - return keypath ? keypath.replace(/^\./, '') : keypath; - }; - return resolveRef; - }(); -var shared_attemptKeypathResolution = function (resolveRef) { - - var push = Array.prototype.push; - return function (ractive) { - var unresolved, keypath, leftover; - while (unresolved = ractive._pendingResolution.pop()) { - keypath = resolveRef(ractive, unresolved.ref, unresolved.contextStack); - if (keypath !== undefined) { - unresolved.resolve(keypath); - } else { - (leftover || (leftover = [])).push(unresolved); - } - } - if (leftover) { - push.apply(ractive._pendingResolution, leftover); - } - }; - }(shared_resolveRef); -var shared_processDeferredUpdates = function (preDomUpdate, postDomUpdate) { - - return function (ractive) { - preDomUpdate(ractive); - postDomUpdate(ractive); - }; - }(shared_preDomUpdate, shared_postDomUpdate); -var Ractive_prototype_shared_replaceData = function () { - - return function (ractive, keypath, value) { - var keys, accumulated, wrapped, obj, key, currentKeypath, keypathToClear; - keys = keypath.split('.'); - accumulated = []; - if (wrapped = ractive._wrapped['']) { - if (wrapped.set) { - wrapped.set(keys.join('.'), value); - } - obj = wrapped.get(); - } else { - obj = ractive.data; - } - while (keys.length > 1) { - key = accumulated[accumulated.length] = keys.shift(); - currentKeypath = accumulated.join('.'); - if (wrapped = ractive._wrapped[currentKeypath]) { - if (wrapped.set) { - wrapped.set(keys.join('.'), value); - } - obj = wrapped.get(); - } else { - if (!obj.hasOwnProperty(key)) { - if (!keypathToClear) { - keypathToClear = currentKeypath; - } - obj[key] = /^\s*[0-9]+\s*$/.test(keys[0]) ? [] : {}; - } - obj = obj[key]; - } - } - key = keys[0]; - obj[key] = value; - return keypathToClear; - }; - }(); -var Ractive_prototype_set = function (isObject, isEqual, normaliseKeypath, clearCache, notifyDependants, attemptKeypathResolution, makeTransitionManager, processDeferredUpdates, replaceData) { - - var set, updateModel, getUpstreamChanges, resetWrapped; - set = function (keypath, value, complete) { - var map, changes, upstreamChanges, previousTransitionManager, transitionManager, i, changeHash; - changes = []; - if (isObject(keypath)) { - map = keypath; - complete = value; - } - if (map) { - for (keypath in map) { - if (map.hasOwnProperty(keypath)) { - value = map[keypath]; - keypath = normaliseKeypath(keypath); - updateModel(this, keypath, value, changes); - } - } - } else { - keypath = normaliseKeypath(keypath); - updateModel(this, keypath, value, changes); - } - if (!changes.length) { - return; - } - previousTransitionManager = this._transitionManager; - this._transitionManager = transitionManager = makeTransitionManager(this, complete); - upstreamChanges = getUpstreamChanges(changes); - if (upstreamChanges.length) { - notifyDependants.multiple(this, upstreamChanges, true); - } - notifyDependants.multiple(this, changes); - if (this._pendingResolution.length) { - attemptKeypathResolution(this); - } - processDeferredUpdates(this); - this._transitionManager = previousTransitionManager; - transitionManager.ready(); - if (!this.firingChangeEvent) { - this.firingChangeEvent = true; - changeHash = {}; - i = changes.length; - while (i--) { - changeHash[changes[i]] = this.get(changes[i]); - } - this.fire('change', changeHash); - this.firingChangeEvent = false; - } - return this; - }; - updateModel = function (ractive, keypath, value, changes) { - var cached, previous, wrapped, keypathToClear, evaluator; - if ((wrapped = ractive._wrapped[keypath]) && wrapped.reset) { - if (resetWrapped(ractive, keypath, value, wrapped, changes) !== false) { - return; - } - } - if (evaluator = ractive._evaluators[keypath]) { - evaluator.value = value; - } - cached = ractive._cache[keypath]; - previous = ractive.get(keypath); - if (previous !== value && !evaluator) { - keypathToClear = replaceData(ractive, keypath, value); - } else { - if (value === cached && typeof value !== 'object') { - return; - } - } - clearCache(ractive, keypathToClear || keypath); - changes[changes.length] = keypath; - }; - getUpstreamChanges = function (changes) { - var upstreamChanges = [''], i, keypath, keys, upstreamKeypath; - i = changes.length; - while (i--) { - keypath = changes[i]; - keys = keypath.split('.'); - while (keys.length > 1) { - keys.pop(); - upstreamKeypath = keys.join('.'); - if (!upstreamChanges[upstreamKeypath]) { - upstreamChanges[upstreamChanges.length] = upstreamKeypath; - upstreamChanges[upstreamKeypath] = true; - } - } - } - return upstreamChanges; - }; - resetWrapped = function (ractive, keypath, value, wrapped, changes) { - var previous, cached, cacheMap, i; - previous = wrapped.get(); - if (!isEqual(previous, value)) { - if (wrapped.reset(value) === false) { - return false; - } - } - value = wrapped.get(); - cached = ractive._cache[keypath]; - if (!isEqual(cached, value)) { - ractive._cache[keypath] = value; - cacheMap = ractive._cacheMap[keypath]; - if (cacheMap) { - i = cacheMap.length; - while (i--) { - clearCache(ractive, cacheMap[i]); - } - } - changes[changes.length] = keypath; - } - }; - return set; - }(utils_isObject, utils_isEqual, utils_normaliseKeypath, shared_clearCache, shared_notifyDependants, shared_attemptKeypathResolution, shared_makeTransitionManager, shared_processDeferredUpdates, Ractive_prototype_shared_replaceData); -var Ractive_prototype_update = function (makeTransitionManager, attemptKeypathResolution, clearCache, notifyDependants, processDeferredUpdates) { - - return function (keypath, complete) { - var transitionManager, previousTransitionManager; - if (typeof keypath === 'function') { - complete = keypath; - keypath = ''; - } - previousTransitionManager = this._transitionManager; - this._transitionManager = transitionManager = makeTransitionManager(this, complete); - attemptKeypathResolution(this); - clearCache(this, keypath || ''); - notifyDependants(this, keypath || ''); - processDeferredUpdates(this); - this._transitionManager = previousTransitionManager; - transitionManager.ready(); - if (typeof keypath === 'string') { - this.fire('update', keypath); - } else { - this.fire('update'); - } - return this; - }; - }(shared_makeTransitionManager, shared_attemptKeypathResolution, shared_clearCache, shared_notifyDependants, shared_processDeferredUpdates); -var utils_arrayContentsMatch = function (isArray) { - - return function (a, b) { - var i; - if (!isArray(a) || !isArray(b)) { - return false; - } - if (a.length !== b.length) { - return false; - } - i = a.length; - while (i--) { - if (a[i] !== b[i]) { - return false; - } - } - return true; - }; - }(utils_isArray); -var Ractive_prototype_updateModel = function (getValueFromCheckboxes, arrayContentsMatch, isEqual) { - - return function (keypath, cascade) { - var values, deferredCheckboxes, i; - if (typeof keypath !== 'string') { - keypath = ''; - cascade = true; - } - consolidateChangedValues(this, keypath, values = {}, deferredCheckboxes = [], cascade); - if (i = deferredCheckboxes.length) { - while (i--) { - keypath = deferredCheckboxes[i]; - values[keypath] = getValueFromCheckboxes(this, keypath); - } - } - this.set(values); - }; - function consolidateChangedValues(ractive, keypath, values, deferredCheckboxes, cascade) { - var bindings, childDeps, i, binding, oldValue, newValue; - bindings = ractive._twowayBindings[keypath]; - if (bindings) { - i = bindings.length; - while (i--) { - binding = bindings[i]; - if (binding.radioName && !binding.node.checked) { - continue; - } - if (binding.checkboxName) { - if (binding.changed() && !deferredCheckboxes[keypath]) { - deferredCheckboxes[keypath] = true; - deferredCheckboxes[deferredCheckboxes.length] = keypath; - } - continue; - } - oldValue = binding.attr.value; - newValue = binding.value(); - if (arrayContentsMatch(oldValue, newValue)) { - continue; - } - if (!isEqual(oldValue, newValue)) { - values[keypath] = newValue; - } - } - } - if (!cascade) { - return; - } - childDeps = ractive._depsMap[keypath]; - if (childDeps) { - i = childDeps.length; - while (i--) { - consolidateChangedValues(ractive, childDeps[i], values, deferredCheckboxes, cascade); - } - } - } - }(shared_getValueFromCheckboxes, utils_arrayContentsMatch, utils_isEqual); -var Ractive_prototype_animate_requestAnimationFrame = function () { - - if (typeof window === 'undefined') { - return; - } - (function (vendors, lastTime, window) { - var x, setTimeout; - if (window.requestAnimationFrame) { - return; - } - for (x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { - window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame']; - } - if (!window.requestAnimationFrame) { - setTimeout = window.setTimeout; - window.requestAnimationFrame = function (callback) { - var currTime, timeToCall, id; - currTime = Date.now(); - timeToCall = Math.max(0, 16 - (currTime - lastTime)); - id = setTimeout(function () { - callback(currTime + timeToCall); - }, timeToCall); - lastTime = currTime + timeToCall; - return id; - }; - } - }([ - 'ms', - 'moz', - 'webkit', - 'o' - ], 0, window)); - return window.requestAnimationFrame; - }(); -var Ractive_prototype_animate_animations = function (rAF) { - - var queue = []; - var animations = { - tick: function () { - var i, animation; - for (i = 0; i < queue.length; i += 1) { - animation = queue[i]; - if (!animation.tick()) { - queue.splice(i--, 1); - } - } - if (queue.length) { - rAF(animations.tick); - } else { - animations.running = false; - } - }, - add: function (animation) { - queue[queue.length] = animation; - if (!animations.running) { - animations.running = true; - animations.tick(); - } - }, - abort: function (keypath, root) { - var i = queue.length, animation; - while (i--) { - animation = queue[i]; - if (animation.root === root && animation.keypath === keypath) { - animation.stop(); - } - } - } - }; - return animations; - }(Ractive_prototype_animate_requestAnimationFrame); -var utils_warn = function () { - - if (typeof console !== 'undefined' && typeof console.warn === 'function' && typeof console.warn.apply === 'function') { - return function () { - console.warn.apply(console, arguments); - }; - } - return function () { - }; - }(); -var utils_isNumeric = function () { - - return function (thing) { - return !isNaN(parseFloat(thing)) && isFinite(thing); - }; - }(); -var shared_interpolate = function (isArray, isObject, isNumeric) { - - var interpolate = function (from, to) { - if (isNumeric(from) && isNumeric(to)) { - return makeNumberInterpolator(+from, +to); - } - if (isArray(from) && isArray(to)) { - return makeArrayInterpolator(from, to); - } - if (isObject(from) && isObject(to)) { - return makeObjectInterpolator(from, to); - } - return function () { - return to; - }; - }; - return interpolate; - function makeNumberInterpolator(from, to) { - var delta = to - from; - if (!delta) { - return function () { - return from; - }; - } - return function (t) { - return from + t * delta; - }; - } - function makeArrayInterpolator(from, to) { - var intermediate, interpolators, len, i; - intermediate = []; - interpolators = []; - i = len = Math.min(from.length, to.length); - while (i--) { - interpolators[i] = interpolate(from[i], to[i]); - } - for (i = len; i < from.length; i += 1) { - intermediate[i] = from[i]; - } - for (i = len; i < to.length; i += 1) { - intermediate[i] = to[i]; - } - return function (t) { - var i = len; - while (i--) { - intermediate[i] = interpolators[i](t); - } - return intermediate; - }; - } - function makeObjectInterpolator(from, to) { - var properties = [], len, interpolators, intermediate, prop; - intermediate = {}; - interpolators = {}; - for (prop in from) { - if (from.hasOwnProperty(prop)) { - if (to.hasOwnProperty(prop)) { - properties[properties.length] = prop; - interpolators[prop] = interpolate(from[prop], to[prop]); - } else { - intermediate[prop] = from[prop]; - } - } - } - for (prop in to) { - if (to.hasOwnProperty(prop) && !from.hasOwnProperty(prop)) { - intermediate[prop] = to[prop]; - } - } - len = properties.length; - return function (t) { - var i = len, prop; - while (i--) { - prop = properties[i]; - intermediate[prop] = interpolators[prop](t); - } - return intermediate; - }; - } - }(utils_isArray, utils_isObject, utils_isNumeric); -var Ractive_prototype_animate_Animation = function (warn, interpolate) { - - var Animation = function (options) { - var key; - this.startTime = Date.now(); - for (key in options) { - if (options.hasOwnProperty(key)) { - this[key] = options[key]; - } - } - this.interpolator = interpolate(this.from, this.to); - this.running = true; - }; - Animation.prototype = { - tick: function () { - var elapsed, t, value, timeNow, index, keypath; - keypath = this.keypath; - if (this.running) { - timeNow = Date.now(); - elapsed = timeNow - this.startTime; - if (elapsed >= this.duration) { - if (keypath !== null) { - this.root.set(keypath, this.to); - } - if (this.step) { - this.step(1, this.to); - } - if (this.complete) { - this.complete(1, this.to); - } - index = this.root._animations.indexOf(this); - if (index === -1) { - warn('Animation was not found'); - } - this.root._animations.splice(index, 1); - this.running = false; - return false; - } - t = this.easing ? this.easing(elapsed / this.duration) : elapsed / this.duration; - if (keypath !== null) { - value = this.interpolator(t); - this.root.set(keypath, value); - } - if (this.step) { - this.step(t, value); - } - return true; - } - return false; - }, - stop: function () { - var index; - this.running = false; - index = this.root._animations.indexOf(this); - if (index === -1) { - warn('Animation was not found'); - } - this.root._animations.splice(index, 1); - } - }; - return Animation; - }(utils_warn, shared_interpolate); -var registries_easing = function () { - - return { - linear: function (pos) { - return pos; - }, - easeIn: function (pos) { - return Math.pow(pos, 3); - }, - easeOut: function (pos) { - return Math.pow(pos - 1, 3) + 1; - }, - easeInOut: function (pos) { - if ((pos /= 0.5) < 1) { - return 0.5 * Math.pow(pos, 3); - } - return 0.5 * (Math.pow(pos - 2, 3) + 2); - } - }; - }(); -var Ractive_prototype_animate__animate = function (isEqual, animations, Animation, easingRegistry) { - - var noAnimation = { - stop: function () { - } - }; - return function (keypath, to, options) { - var k, animation, animations, easing, duration, step, complete, makeValueCollector, currentValues, collectValue, dummy, dummyOptions; - if (typeof keypath === 'object') { - options = to || {}; - easing = options.easing; - duration = options.duration; - animations = []; - step = options.step; - complete = options.complete; - if (step || complete) { - currentValues = {}; - options.step = null; - options.complete = null; - makeValueCollector = function (keypath) { - return function (t, value) { - currentValues[keypath] = value; - }; - }; - } - for (k in keypath) { - if (keypath.hasOwnProperty(k)) { - if (step || complete) { - collectValue = makeValueCollector(k); - options = { - easing: easing, - duration: duration - }; - if (step) { - options.step = collectValue; - } - if (complete) { - options.complete = collectValue; - } - } - animations[animations.length] = animate(this, k, keypath[k], options); - } - } - if (step || complete) { - dummyOptions = { - easing: easing, - duration: duration - }; - if (step) { - dummyOptions.step = function (t) { - step(t, currentValues); - }; - } - if (complete) { - dummyOptions.complete = function (t) { - complete(t, currentValues); - }; - } - animations[animations.length] = dummy = animate(this, null, null, dummyOptions); - } - return { - stop: function () { - while (animations.length) { - animations.pop().stop(); - } - if (dummy) { - dummy.stop(); - } - } - }; - } - options = options || {}; - animation = animate(this, keypath, to, options); - return { - stop: function () { - animation.stop(); - } - }; - }; - function animate(root, keypath, to, options) { - var easing, duration, animation, from; - if (keypath !== null) { - from = root.get(keypath); - } - animations.abort(keypath, root); - if (isEqual(from, to)) { - if (options.complete) { - options.complete(1, options.to); - } - return noAnimation; - } - if (options.easing) { - if (typeof options.easing === 'function') { - easing = options.easing; - } else { - if (root.easing && root.easing[options.easing]) { - easing = root.easing[options.easing]; - } else { - easing = easingRegistry[options.easing]; - } - } - if (typeof easing !== 'function') { - easing = null; - } - } - duration = options.duration === undefined ? 400 : options.duration; - animation = new Animation({ - keypath: keypath, - from: from, - to: to, - root: root, - duration: duration, - easing: easing, - step: options.step, - complete: options.complete - }); - animations.add(animation); - root._animations[root._animations.length] = animation; - return animation; - } - }(utils_isEqual, Ractive_prototype_animate_animations, Ractive_prototype_animate_Animation, registries_easing); -var Ractive_prototype_on = function () { - - return function (eventName, callback) { - var self = this, listeners, n; - if (typeof eventName === 'object') { - listeners = []; - for (n in eventName) { - if (eventName.hasOwnProperty(n)) { - listeners[listeners.length] = this.on(n, eventName[n]); - } - } - return { - cancel: function () { - while (listeners.length) { - listeners.pop().cancel(); - } - } - }; - } - if (!this._subs[eventName]) { - this._subs[eventName] = [callback]; - } else { - this._subs[eventName].push(callback); - } - return { - cancel: function () { - self.off(eventName, callback); - } - }; - }; - }(); -var Ractive_prototype_off = function () { - - return function (eventName, callback) { - var subscribers, index; - if (!callback) { - if (!eventName) { - for (eventName in this._subs) { - delete this._subs[eventName]; - } - } else { - this._subs[eventName] = []; - } - } - subscribers = this._subs[eventName]; - if (subscribers) { - index = subscribers.indexOf(callback); - if (index !== -1) { - subscribers.splice(index, 1); - } - } - }; - }(); -var shared_registerDependant = function () { - - return function (dependant) { - var depsByKeypath, deps, keys, parentKeypath, map, ractive, keypath, priority; - ractive = dependant.root; - keypath = dependant.keypath; - priority = dependant.priority; - depsByKeypath = ractive._deps[priority] || (ractive._deps[priority] = {}); - deps = depsByKeypath[keypath] || (depsByKeypath[keypath] = []); - deps[deps.length] = dependant; - dependant.registered = true; - if (!keypath) { - return; - } - keys = keypath.split('.'); - while (keys.length) { - keys.pop(); - parentKeypath = keys.join('.'); - map = ractive._depsMap[parentKeypath] || (ractive._depsMap[parentKeypath] = []); - if (map[keypath] === undefined) { - map[keypath] = 0; - map[map.length] = keypath; - } - map[keypath] += 1; - keypath = parentKeypath; - } - }; - }(); -var shared_unregisterDependant = function () { - - return function (dependant) { - var deps, index, keys, parentKeypath, map, ractive, keypath, priority; - ractive = dependant.root; - keypath = dependant.keypath; - priority = dependant.priority; - deps = ractive._deps[priority][keypath]; - index = deps.indexOf(dependant); - if (index === -1 || !dependant.registered) { - throw new Error('Attempted to remove a dependant that was no longer registered! This should not happen. If you are seeing this bug in development please raise an issue at https://github.com/RactiveJS/Ractive/issues - thanks'); - } - deps.splice(index, 1); - dependant.registered = false; - if (!keypath) { - return; - } - keys = keypath.split('.'); - while (keys.length) { - keys.pop(); - parentKeypath = keys.join('.'); - map = ractive._depsMap[parentKeypath]; - map[keypath] -= 1; - if (!map[keypath]) { - map.splice(map.indexOf(keypath), 1); - map[keypath] = undefined; - } - keypath = parentKeypath; - } - }; - }(); -var Ractive_prototype_observe_Observer = function (isEqual) { - - var Observer = function (ractive, keypath, callback, options) { - var self = this; - this.root = ractive; - this.keypath = keypath; - this.callback = callback; - this.defer = options.defer; - this.debug = options.debug; - this.proxy = { - update: function () { - self.reallyUpdate(); - } - }; - this.priority = 0; - this.context = options && options.context ? options.context : ractive; - }; - Observer.prototype = { - init: function (immediate) { - if (immediate !== false) { - this.update(); - } else { - this.value = this.root.get(this.keypath); - } - }, - update: function () { - if (this.defer && this.ready) { - this.root._deferred.observers.push(this.proxy); - return; - } - this.reallyUpdate(); - }, - reallyUpdate: function () { - var oldValue, newValue; - oldValue = this.value; - newValue = this.root.get(this.keypath); - this.value = newValue; - if (this.updating) { - return; - } - this.updating = true; - if (!isEqual(newValue, oldValue) || !this.ready) { - try { - this.callback.call(this.context, newValue, oldValue, this.keypath); - } catch (err) { - if (this.debug || this.root.debug) { - throw err; - } - } - } - this.updating = false; - } - }; - return Observer; - }(utils_isEqual); -var Ractive_prototype_observe_getPattern = function () { - - return function (ractive, pattern) { - var keys, key, values, toGet, newToGet, expand, concatenate; - keys = pattern.split('.'); - toGet = []; - expand = function (keypath) { - var value, key; - value = ractive._wrapped[keypath] ? ractive._wrapped[keypath].get() : ractive.get(keypath); - for (key in value) { - newToGet.push(keypath + '.' + key); - } - }; - concatenate = function (keypath) { - return keypath + '.' + key; - }; - while (key = keys.shift()) { - if (key === '*') { - newToGet = []; - toGet.forEach(expand); - toGet = newToGet; - } else { - if (!toGet[0]) { - toGet[0] = key; - } else { - toGet = toGet.map(concatenate); - } - } - } - values = {}; - toGet.forEach(function (keypath) { - values[keypath] = ractive.get(keypath); - }); - return values; - }; - }(); -var Ractive_prototype_observe_PatternObserver = function (isEqual, getPattern) { - - var PatternObserver, wildcard = /\*/; - PatternObserver = function (ractive, keypath, callback, options) { - this.root = ractive; - this.callback = callback; - this.defer = options.defer; - this.debug = options.debug; - this.keypath = keypath; - this.regex = new RegExp('^' + keypath.replace(/\./g, '\\.').replace(/\*/g, '[^\\.]+') + '$'); - this.values = {}; - if (this.defer) { - this.proxies = []; - } - this.priority = 'pattern'; - this.context = options && options.context ? options.context : ractive; - }; - PatternObserver.prototype = { - init: function (immediate) { - var values, keypath; - values = getPattern(this.root, this.keypath); - if (immediate !== false) { - for (keypath in values) { - if (values.hasOwnProperty(keypath)) { - this.update(keypath); - } - } - } else { - this.values = values; - } - }, - update: function (keypath) { - var values; - if (wildcard.test(keypath)) { - values = getPattern(this.root, keypath); - for (keypath in values) { - if (values.hasOwnProperty(keypath)) { - this.update(keypath); - } - } - return; - } - if (this.defer && this.ready) { - this.root._deferred.observers.push(this.getProxy(keypath)); - return; - } - this.reallyUpdate(keypath); - }, - reallyUpdate: function (keypath) { - var value = this.root.get(keypath); - if (this.updating) { - this.values[keypath] = value; - return; - } - this.updating = true; - if (!isEqual(value, this.values[keypath]) || !this.ready) { - try { - this.callback.call(this.context, value, this.values[keypath], keypath); - } catch (err) { - if (this.debug || this.root.debug) { - throw err; - } - } - this.values[keypath] = value; - } - this.updating = false; - }, - getProxy: function (keypath) { - var self = this; - if (!this.proxies[keypath]) { - this.proxies[keypath] = { - update: function () { - self.reallyUpdate(keypath); - } - }; - } - return this.proxies[keypath]; - } - }; - return PatternObserver; - }(utils_isEqual, Ractive_prototype_observe_getPattern); -var Ractive_prototype_observe_getObserverFacade = function (normaliseKeypath, registerDependant, unregisterDependant, Observer, PatternObserver) { - - var wildcard = /\*/, emptyObject = {}; - return function getObserverFacade(ractive, keypath, callback, options) { - var observer, isPatternObserver; - keypath = normaliseKeypath(keypath); - options = options || emptyObject; - if (wildcard.test(keypath)) { - observer = new PatternObserver(ractive, keypath, callback, options); - ractive._patternObservers.push(observer); - isPatternObserver = true; - } else { - observer = new Observer(ractive, keypath, callback, options); - } - registerDependant(observer); - observer.init(options.init); - observer.ready = true; - return { - cancel: function () { - var index; - if (isPatternObserver) { - index = ractive._patternObservers.indexOf(observer); - if (index !== -1) { - ractive._patternObservers.splice(index, 1); - } - } - unregisterDependant(observer); - } - }; - }; - }(utils_normaliseKeypath, shared_registerDependant, shared_unregisterDependant, Ractive_prototype_observe_Observer, Ractive_prototype_observe_PatternObserver); -var Ractive_prototype_observe__observe = function (isObject, getObserverFacade) { - - return function observe(keypath, callback, options) { - var observers = [], k; - if (isObject(keypath)) { - options = callback; - for (k in keypath) { - if (keypath.hasOwnProperty(k)) { - callback = keypath[k]; - observers[observers.length] = getObserverFacade(this, k, callback, options); - } - } - return { - cancel: function () { - while (observers.length) { - observers.pop().cancel(); - } - } - }; - } - return getObserverFacade(this, keypath, callback, options); - }; - }(utils_isObject, Ractive_prototype_observe_getObserverFacade); -var Ractive_prototype_fire = function () { - - return function (eventName) { - var args, i, len, subscribers = this._subs[eventName]; - if (!subscribers) { - return; - } - args = Array.prototype.slice.call(arguments, 1); - for (i = 0, len = subscribers.length; i < len; i += 1) { - subscribers[i].apply(this, args); - } - }; - }(); -var Ractive_prototype_find = function () { - - return function (selector) { - if (!this.el) { - return null; - } - return this.fragment.find(selector); - }; - }(); -var utils_matches = function (isClient, createElement) { - - var div, methodNames, unprefixed, prefixed, vendors, i, j, makeFunction; - if (!isClient) { - return; - } - div = createElement('div'); - methodNames = [ - 'matches', - 'matchesSelector' - ]; - vendors = [ - 'o', - 'ms', - 'moz', - 'webkit' - ]; - makeFunction = function (methodName) { - return function (node, selector) { - return node[methodName](selector); - }; - }; - i = methodNames.length; - while (i--) { - unprefixed = methodNames[i]; - if (div[unprefixed]) { - return makeFunction(unprefixed); - } - j = vendors.length; - while (j--) { - prefixed = vendors[i] + unprefixed.substr(0, 1).toUpperCase() + unprefixed.substring(1); - if (div[prefixed]) { - return makeFunction(prefixed); - } - } - } - return function (node, selector) { - var nodes, i; - nodes = (node.parentNode || node.document).querySelectorAll(selector); - i = nodes.length; - while (i--) { - if (nodes[i] === node) { - return true; - } - } - return false; - }; - }(config_isClient, utils_createElement); -var Ractive_prototype_shared_makeQuery_test = function (matches) { - - return function (item, noDirty) { - var itemMatches = this._isComponentQuery ? !this.selector || item.name === this.selector : matches(item.node, this.selector); - if (itemMatches) { - this.push(item.node || item.instance); - if (!noDirty) { - this._makeDirty(); - } - return true; - } - }; - }(utils_matches); -var Ractive_prototype_shared_makeQuery_cancel = function () { - - return function () { - var liveQueries, selector, index; - liveQueries = this._root[this._isComponentQuery ? 'liveComponentQueries' : 'liveQueries']; - selector = this.selector; - index = liveQueries.indexOf(selector); - if (index !== -1) { - liveQueries.splice(index, 1); - liveQueries[selector] = null; - } - }; - }(); -var Ractive_prototype_shared_makeQuery_sortByItemPosition = function () { - - return function (a, b) { - var ancestryA, ancestryB, oldestA, oldestB, mutualAncestor, indexA, indexB, fragments, fragmentA, fragmentB; - ancestryA = getAncestry(a.component || a._ractive.proxy); - ancestryB = getAncestry(b.component || b._ractive.proxy); - oldestA = ancestryA[ancestryA.length - 1]; - oldestB = ancestryB[ancestryB.length - 1]; - while (oldestA && oldestA === oldestB) { - ancestryA.pop(); - ancestryB.pop(); - mutualAncestor = oldestA; - oldestA = ancestryA[ancestryA.length - 1]; - oldestB = ancestryB[ancestryB.length - 1]; - } - oldestA = oldestA.component || oldestA; - oldestB = oldestB.component || oldestB; - fragmentA = oldestA.parentFragment; - fragmentB = oldestB.parentFragment; - if (fragmentA === fragmentB) { - indexA = fragmentA.items.indexOf(oldestA); - indexB = fragmentB.items.indexOf(oldestB); - return indexA - indexB || ancestryA.length - ancestryB.length; - } - if (fragments = mutualAncestor.fragments) { - indexA = fragments.indexOf(fragmentA); - indexB = fragments.indexOf(fragmentB); - return indexA - indexB || ancestryA.length - ancestryB.length; - } - throw new Error('An unexpected condition was met while comparing the position of two components. Please file an issue at https://github.com/RactiveJS/Ractive/issues - thanks!'); - }; - function getParent(item) { - var parentFragment; - if (parentFragment = item.parentFragment) { - return parentFragment.owner; - } - if (item.component && (parentFragment = item.component.parentFragment)) { - return parentFragment.owner; - } - } - function getAncestry(item) { - var ancestry, ancestor; - ancestry = [item]; - ancestor = getParent(item); - while (ancestor) { - ancestry.push(ancestor); - ancestor = getParent(ancestor); - } - return ancestry; - } - }(); -var Ractive_prototype_shared_makeQuery_sortByDocumentPosition = function (sortByItemPosition) { - - return function (node, otherNode) { - var bitmask; - if (node.compareDocumentPosition) { - bitmask = node.compareDocumentPosition(otherNode); - return bitmask & 2 ? 1 : -1; - } - return sortByItemPosition(node, otherNode); - }; - }(Ractive_prototype_shared_makeQuery_sortByItemPosition); -var Ractive_prototype_shared_makeQuery_sort = function (sortByDocumentPosition, sortByItemPosition) { - - return function () { - this.sort(this._isComponentQuery ? sortByItemPosition : sortByDocumentPosition); - this._dirty = false; - }; - }(Ractive_prototype_shared_makeQuery_sortByDocumentPosition, Ractive_prototype_shared_makeQuery_sortByItemPosition); -var Ractive_prototype_shared_makeQuery_dirty = function () { - - return function () { - if (!this._dirty) { - this._root._deferred.liveQueries.push(this); - this._dirty = true; - } - }; - }(); -var Ractive_prototype_shared_makeQuery_remove = function () { - - return function (item) { - var index = this.indexOf(this._isComponentQuery ? item.instance : item.node); - if (index !== -1) { - this.splice(index, 1); - } - }; - }(); -var Ractive_prototype_shared_makeQuery__makeQuery = function (defineProperties, test, cancel, sort, dirty, remove) { - - return function (ractive, selector, live, isComponentQuery) { - var query; - query = []; - defineProperties(query, { - selector: { value: selector }, - live: { value: live }, - _isComponentQuery: { value: isComponentQuery }, - _test: { value: test } - }); - if (!live) { - return query; - } - defineProperties(query, { - cancel: { value: cancel }, - _root: { value: ractive }, - _sort: { value: sort }, - _makeDirty: { value: dirty }, - _remove: { value: remove }, - _dirty: { - value: false, - writable: true - } - }); - return query; - }; - }(utils_defineProperties, Ractive_prototype_shared_makeQuery_test, Ractive_prototype_shared_makeQuery_cancel, Ractive_prototype_shared_makeQuery_sort, Ractive_prototype_shared_makeQuery_dirty, Ractive_prototype_shared_makeQuery_remove); -var Ractive_prototype_findAll = function (warn, matches, defineProperties, makeQuery) { - - return function (selector, options) { - var liveQueries, query; - if (!this.el) { - return []; - } - options = options || {}; - liveQueries = this._liveQueries; - if (query = liveQueries[selector]) { - return options && options.live ? query : query.slice(); - } - query = makeQuery(this, selector, !!options.live, false); - if (query.live) { - liveQueries.push(selector); - liveQueries[selector] = query; - } - this.fragment.findAll(selector, query); - return query; - }; - }(utils_warn, utils_matches, utils_defineProperties, Ractive_prototype_shared_makeQuery__makeQuery); -var Ractive_prototype_findComponent = function () { - - return function (selector) { - return this.fragment.findComponent(selector); - }; - }(); -var Ractive_prototype_findAllComponents = function (warn, matches, defineProperties, makeQuery) { - - return function (selector, options) { - var liveQueries, query; - options = options || {}; - liveQueries = this._liveComponentQueries; - if (query = liveQueries[selector]) { - return options && options.live ? query : query.slice(); - } - query = makeQuery(this, selector, !!options.live, true); - if (query.live) { - liveQueries.push(selector); - liveQueries[selector] = query; - } - this.fragment.findAllComponents(selector, query); - return query; - }; - }(utils_warn, utils_matches, utils_defineProperties, Ractive_prototype_shared_makeQuery__makeQuery); -var utils_getElement = function () { - - return function (input) { - var output; - if (typeof window === 'undefined' || !document || !input) { - return null; - } - if (input.nodeType) { - return input; - } - if (typeof input === 'string') { - output = document.getElementById(input); - if (!output && document.querySelector) { - output = document.querySelector(input); - } - if (output && output.nodeType) { - return output; - } - } - if (input[0] && input[0].nodeType) { - return input[0]; - } - return null; - }; - }(); -var render_shared_initFragment = function (types, create) { - - return function (fragment, options) { - var numItems, i, parentFragment, parentRefs, ref; - fragment.owner = options.owner; - parentFragment = fragment.owner.parentFragment; - fragment.root = options.root; - fragment.pNode = options.pNode; - fragment.contextStack = options.contextStack || []; - if (fragment.owner.type === types.SECTION) { - fragment.index = options.index; - } - if (parentFragment) { - parentRefs = parentFragment.indexRefs; - if (parentRefs) { - fragment.indexRefs = create(null); - for (ref in parentRefs) { - fragment.indexRefs[ref] = parentRefs[ref]; - } - } - } - fragment.priority = parentFragment ? parentFragment.priority + 1 : 1; - if (options.indexRef) { - if (!fragment.indexRefs) { - fragment.indexRefs = {}; - } - fragment.indexRefs[options.indexRef] = options.index; - } - fragment.items = []; - numItems = options.descriptor ? options.descriptor.length : 0; - for (i = 0; i < numItems; i += 1) { - fragment.items[fragment.items.length] = fragment.createItem({ - parentFragment: fragment, - descriptor: options.descriptor[i], - index: i - }); - } - }; - }(config_types, utils_create); -var render_DomFragment_shared_insertHtml = function (createElement) { - - var elementCache = {}; - return function (html, tagName, docFrag) { - var container, nodes = []; - if (html) { - container = elementCache[tagName] || (elementCache[tagName] = createElement(tagName)); - container.innerHTML = html; - while (container.firstChild) { - nodes[nodes.length] = container.firstChild; - docFrag.appendChild(container.firstChild); - } - } - return nodes; - }; - }(utils_createElement); -var render_DomFragment_Text = function (types) { - - var DomText, lessThan, greaterThan; - lessThan = //g; - DomText = function (options, docFrag) { - this.type = types.TEXT; - this.descriptor = options.descriptor; - if (docFrag) { - this.node = document.createTextNode(options.descriptor); - docFrag.appendChild(this.node); - } - }; - DomText.prototype = { - detach: function () { - this.node.parentNode.removeChild(this.node); - return this.node; - }, - teardown: function (destroy) { - if (destroy) { - this.detach(); - } - }, - firstNode: function () { - return this.node; - }, - toString: function () { - return ('' + this.descriptor).replace(lessThan, '<').replace(greaterThan, '>'); - } - }; - return DomText; - }(config_types); -var shared_teardown = function (unregisterDependant) { - - return function (thing) { - if (!thing.keypath) { - var index = thing.root._pendingResolution.indexOf(thing); - if (index !== -1) { - thing.root._pendingResolution.splice(index, 1); - } - } else { - unregisterDependant(thing); - } - }; - }(shared_unregisterDependant); -var render_shared_Evaluator_Reference = function (types, isEqual, defineProperty, registerDependant, unregisterDependant) { - - var Reference, thisPattern; - thisPattern = /this/; - Reference = function (root, keypath, evaluator, argNum, priority) { - var value; - this.evaluator = evaluator; - this.keypath = keypath; - this.root = root; - this.argNum = argNum; - this.type = types.REFERENCE; - this.priority = priority; - value = root.get(keypath); - if (typeof value === 'function') { - value = wrapFunction(value, root, evaluator); - } - this.value = evaluator.values[argNum] = value; - registerDependant(this); - }; - Reference.prototype = { - update: function () { - var value = this.root.get(this.keypath); - if (typeof value === 'function' && !value._nowrap) { - value = wrapFunction(value, this.root, this.evaluator); - } - if (!isEqual(value, this.value)) { - this.evaluator.values[this.argNum] = value; - this.evaluator.bubble(); - this.value = value; - } - }, - teardown: function () { - unregisterDependant(this); - } - }; - return Reference; - function wrapFunction(fn, ractive, evaluator) { - var prop, evaluators, index; - if (!thisPattern.test(fn.toString())) { - defineProperty(fn, '_nowrap', { value: true }); - return fn; - } - if (!fn['_' + ractive._guid]) { - defineProperty(fn, '_' + ractive._guid, { - value: function () { - var originalCaptured, result, i, evaluator; - originalCaptured = ractive._captured; - if (!originalCaptured) { - ractive._captured = []; - } - result = fn.apply(ractive, arguments); - if (ractive._captured.length) { - i = evaluators.length; - while (i--) { - evaluator = evaluators[i]; - evaluator.updateSoftDependencies(ractive._captured); - } - } - ractive._captured = originalCaptured; - return result; - }, - writable: true - }); - for (prop in fn) { - if (fn.hasOwnProperty(prop)) { - fn['_' + ractive._guid][prop] = fn[prop]; - } - } - fn['_' + ractive._guid + '_evaluators'] = []; - } - evaluators = fn['_' + ractive._guid + '_evaluators']; - index = evaluators.indexOf(evaluator); - if (index === -1) { - evaluators.push(evaluator); - } - return fn['_' + ractive._guid]; - } - }(config_types, utils_isEqual, utils_defineProperty, shared_registerDependant, shared_unregisterDependant); -var render_shared_Evaluator_SoftReference = function (isEqual, registerDependant, unregisterDependant) { - - var SoftReference = function (root, keypath, evaluator) { - this.root = root; - this.keypath = keypath; - this.priority = evaluator.priority; - this.evaluator = evaluator; - registerDependant(this); - }; - SoftReference.prototype = { - update: function () { - var value = this.root.get(this.keypath); - if (!isEqual(value, this.value)) { - this.evaluator.bubble(); - this.value = value; - } - }, - teardown: function () { - unregisterDependant(this); - } - }; - return SoftReference; - }(utils_isEqual, shared_registerDependant, shared_unregisterDependant); -var render_shared_Evaluator__Evaluator = function (isEqual, defineProperty, clearCache, notifyDependants, registerDependant, unregisterDependant, adaptIfNecessary, Reference, SoftReference) { - - var Evaluator, cache = {}; - Evaluator = function (root, keypath, functionStr, args, priority) { - var i, arg; - this.root = root; - this.keypath = keypath; - this.priority = priority; - this.fn = getFunctionFromString(functionStr, args.length); - this.values = []; - this.refs = []; - i = args.length; - while (i--) { - if (arg = args[i]) { - if (arg[0]) { - this.values[i] = arg[1]; - } else { - this.refs[this.refs.length] = new Reference(root, arg[1], this, i, priority); - } - } else { - this.values[i] = undefined; - } - } - this.selfUpdating = this.refs.length <= 1; - this.update(); - }; - Evaluator.prototype = { - bubble: function () { - if (this.selfUpdating) { - this.update(); - } else if (!this.deferred) { - this.root._deferred.evals.push(this); - this.deferred = true; - } - }, - update: function () { - var value; - if (this.evaluating) { - return this; - } - this.evaluating = true; - try { - value = this.fn.apply(null, this.values); - } catch (err) { - if (this.root.debug) { - throw err; - } else { - value = undefined; - } - } - if (!isEqual(value, this.value)) { - clearCache(this.root, this.keypath); - this.root._cache[this.keypath] = value; - adaptIfNecessary(this.root, this.keypath, value, true); - this.value = value; - notifyDependants(this.root, this.keypath); - } - this.evaluating = false; - return this; - }, - teardown: function () { - while (this.refs.length) { - this.refs.pop().teardown(); - } - clearCache(this.root, this.keypath); - this.root._evaluators[this.keypath] = null; - }, - refresh: function () { - if (!this.selfUpdating) { - this.deferred = true; - } - var i = this.refs.length; - while (i--) { - this.refs[i].update(); - } - if (this.deferred) { - this.update(); - this.deferred = false; - } - }, - updateSoftDependencies: function (softDeps) { - var i, keypath, ref; - if (!this.softRefs) { - this.softRefs = []; - } - i = this.softRefs.length; - while (i--) { - ref = this.softRefs[i]; - if (!softDeps[ref.keypath]) { - this.softRefs.splice(i, 1); - this.softRefs[ref.keypath] = false; - ref.teardown(); - } - } - i = softDeps.length; - while (i--) { - keypath = softDeps[i]; - if (!this.softRefs[keypath]) { - ref = new SoftReference(this.root, keypath, this); - this.softRefs[this.softRefs.length] = ref; - this.softRefs[keypath] = true; - } - } - this.selfUpdating = this.refs.length + this.softRefs.length <= 1; - } - }; - return Evaluator; - function getFunctionFromString(str, i) { - var fn, args; - str = str.replace(/\$\{([0-9]+)\}/g, '_$1'); - if (cache[str]) { - return cache[str]; - } - args = []; - while (i--) { - args[i] = '_' + i; - } - fn = new Function(args.join(','), 'return(' + str + ')'); - cache[str] = fn; - return fn; - } - }(utils_isEqual, utils_defineProperty, shared_clearCache, shared_notifyDependants, shared_registerDependant, shared_unregisterDependant, shared_adaptIfNecessary, render_shared_Evaluator_Reference, render_shared_Evaluator_SoftReference); -var render_shared_ExpressionResolver_ReferenceScout = function (resolveRef, teardown) { - - var ReferenceScout = function (resolver, ref, contextStack, argNum) { - var keypath, root; - root = this.root = resolver.root; - keypath = resolveRef(root, ref, contextStack); - if (keypath !== undefined) { - resolver.resolveRef(argNum, false, keypath); - } else { - this.ref = ref; - this.argNum = argNum; - this.resolver = resolver; - this.contextStack = contextStack; - root._pendingResolution[root._pendingResolution.length] = this; - } - }; - ReferenceScout.prototype = { - resolve: function (keypath) { - this.keypath = keypath; - this.resolver.resolveRef(this.argNum, false, keypath); - }, - teardown: function () { - if (!this.keypath) { - teardown(this); - } - } - }; - return ReferenceScout; - }(shared_resolveRef, shared_teardown); -var render_shared_ExpressionResolver_isRegularKeypath = function () { - - var keyPattern = /^(?:(?:[a-zA-Z$_][a-zA-Z$_0-9]*)|(?:[0-9]|[1-9][0-9]+))$/; - return function (keypath) { - var keys, key, i; - keys = keypath.split('.'); - i = keys.length; - while (i--) { - key = keys[i]; - if (key === 'undefined' || !keyPattern.test(key)) { - return false; - } - } - return true; - }; - }(); -var render_shared_ExpressionResolver_getKeypath = function (normaliseKeypath, isRegularKeypath) { - - return function (str, args) { - var unique, normalised; - unique = str.replace(/\$\{([0-9]+)\}/g, function (match, $1) { - return args[$1] ? args[$1][1] : 'undefined'; - }); - normalised = normaliseKeypath(unique); - if (isRegularKeypath(normalised)) { - return normalised; - } - return '${' + unique.replace(/[\.\[\]]/g, '-') + '}'; - }; - }(utils_normaliseKeypath, render_shared_ExpressionResolver_isRegularKeypath); -var render_shared_ExpressionResolver_reassignDependants = function (registerDependant, unregisterDependant) { - - return function (ractive, oldKeypath, newKeypath) { - var toReassign, i, dependant; - toReassign = []; - gatherDependants(ractive, oldKeypath, toReassign); - i = toReassign.length; - while (i--) { - dependant = toReassign[i]; - unregisterDependant(dependant); - dependant.keypath = dependant.keypath.replace(oldKeypath, newKeypath); - registerDependant(dependant); - dependant.update(); - } - }; - function cascade(ractive, oldKeypath, toReassign) { - var map, i; - map = ractive._depsMap[oldKeypath]; - if (!map) { - return; - } - i = map.length; - while (i--) { - gatherDependants(ractive, map[i], toReassign); - } - } - function gatherDependants(ractive, oldKeypath, toReassign) { - var priority, dependantsByKeypath, dependants, i; - priority = ractive._deps.length; - while (priority--) { - dependantsByKeypath = ractive._deps[priority]; - if (dependantsByKeypath) { - dependants = dependantsByKeypath[oldKeypath]; - if (dependants) { - i = dependants.length; - while (i--) { - toReassign.push(dependants[i]); - } - } - } - } - cascade(ractive, oldKeypath, toReassign); - } - }(shared_registerDependant, shared_unregisterDependant); -var render_shared_ExpressionResolver__ExpressionResolver = function (Evaluator, ReferenceScout, getKeypath, reassignDependants) { - - var ExpressionResolver = function (mustache) { - var expression, i, len, ref, indexRefs; - this.root = mustache.root; - this.mustache = mustache; - this.args = []; - this.scouts = []; - expression = mustache.descriptor.x; - indexRefs = mustache.parentFragment.indexRefs; - this.str = expression.s; - len = this.unresolved = this.args.length = expression.r ? expression.r.length : 0; - if (!len) { - this.resolved = this.ready = true; - this.bubble(); - return; - } - for (i = 0; i < len; i += 1) { - ref = expression.r[i]; - if (indexRefs && indexRefs[ref] !== undefined) { - this.resolveRef(i, true, indexRefs[ref]); - } else { - this.scouts[this.scouts.length] = new ReferenceScout(this, ref, mustache.contextStack, i); - } - } - this.ready = true; - this.bubble(); - }; - ExpressionResolver.prototype = { - bubble: function () { - var oldKeypath; - if (!this.ready) { - return; - } - oldKeypath = this.keypath; - this.keypath = getKeypath(this.str, this.args); - if (this.keypath.substr(0, 2) === '${') { - this.createEvaluator(); - } - if (oldKeypath) { - reassignDependants(this.root, oldKeypath, this.keypath); - } else { - this.mustache.resolve(this.keypath); - } - }, - teardown: function () { - while (this.scouts.length) { - this.scouts.pop().teardown(); - } - }, - resolveRef: function (argNum, isIndexRef, value) { - this.args[argNum] = [ - isIndexRef, - value - ]; - this.bubble(); - this.resolved = !--this.unresolved; - }, - createEvaluator: function () { - if (!this.root._evaluators[this.keypath]) { - this.root._evaluators[this.keypath] = new Evaluator(this.root, this.keypath, this.str, this.args, this.mustache.priority); - } else { - this.root._evaluators[this.keypath].refresh(); - } - } - }; - return ExpressionResolver; - }(render_shared_Evaluator__Evaluator, render_shared_ExpressionResolver_ReferenceScout, render_shared_ExpressionResolver_getKeypath, render_shared_ExpressionResolver_reassignDependants); -var render_shared_initMustache = function (resolveRef, ExpressionResolver) { - - return function (mustache, options) { - var keypath, indexRef, parentFragment; - parentFragment = mustache.parentFragment = options.parentFragment; - mustache.root = parentFragment.root; - mustache.contextStack = parentFragment.contextStack; - mustache.descriptor = options.descriptor; - mustache.index = options.index || 0; - mustache.priority = parentFragment.priority; - mustache.type = options.descriptor.t; - if (options.descriptor.r) { - if (parentFragment.indexRefs && parentFragment.indexRefs[options.descriptor.r] !== undefined) { - indexRef = parentFragment.indexRefs[options.descriptor.r]; - mustache.indexRef = options.descriptor.r; - mustache.value = indexRef; - mustache.render(mustache.value); - } else { - keypath = resolveRef(mustache.root, options.descriptor.r, mustache.contextStack); - if (keypath !== undefined) { - mustache.resolve(keypath); - } else { - mustache.ref = options.descriptor.r; - mustache.root._pendingResolution[mustache.root._pendingResolution.length] = mustache; - } - } - } - if (options.descriptor.x) { - mustache.expressionResolver = new ExpressionResolver(mustache); - } - if (mustache.descriptor.n && !mustache.hasOwnProperty('value')) { - mustache.render(undefined); - } - }; - }(shared_resolveRef, render_shared_ExpressionResolver__ExpressionResolver); -var render_shared_resolveMustache = function (types, registerDependant, unregisterDependant) { - - return function (keypath) { - if (keypath === this.keypath) { - return; - } - if (this.registered) { - unregisterDependant(this); - } - this.keypath = keypath; - registerDependant(this); - this.update(); - if (this.root.twoway && this.parentFragment.owner.type === types.ATTRIBUTE) { - this.parentFragment.owner.element.bind(); - } - if (this.expressionResolver && this.expressionResolver.resolved) { - this.expressionResolver = null; - } - }; - }(config_types, shared_registerDependant, shared_unregisterDependant); -var render_shared_updateMustache = function (isEqual) { - - return function () { - var wrapped, value; - value = this.root.get(this.keypath); - if (wrapped = this.root._wrapped[this.keypath]) { - value = wrapped.get(); - } - if (!isEqual(value, this.value)) { - this.render(value); - this.value = value; - } - }; - }(utils_isEqual); -var render_DomFragment_Interpolator = function (types, teardown, initMustache, resolveMustache, updateMustache) { - - var DomInterpolator, lessThan, greaterThan; - lessThan = //g; - DomInterpolator = function (options, docFrag) { - this.type = types.INTERPOLATOR; - if (docFrag) { - this.node = document.createTextNode(''); - docFrag.appendChild(this.node); - } - initMustache(this, options); - }; - DomInterpolator.prototype = { - update: updateMustache, - resolve: resolveMustache, - detach: function () { - this.node.parentNode.removeChild(this.node); - return this.node; - }, - teardown: function (destroy) { - if (destroy) { - this.detach(); - } - teardown(this); - }, - render: function (value) { - if (this.node) { - this.node.data = value == undefined ? '' : value; - } - }, - firstNode: function () { - return this.node; - }, - toString: function () { - var value = this.value != undefined ? '' + this.value : ''; - return value.replace(lessThan, '<').replace(greaterThan, '>'); - } - }; - return DomInterpolator; - }(config_types, shared_teardown, render_shared_initMustache, render_shared_resolveMustache, render_shared_updateMustache); -var render_shared_updateSection = function (isArray, isObject, create) { - - return function (section, value) { - var fragmentOptions; - fragmentOptions = { - descriptor: section.descriptor.f, - root: section.root, - pNode: section.parentFragment.pNode, - owner: section - }; - if (section.descriptor.n) { - updateConditionalSection(section, value, true, fragmentOptions); - return; - } - if (isArray(value)) { - updateListSection(section, value, fragmentOptions); - } else if (isObject(value)) { - if (section.descriptor.i) { - updateListObjectSection(section, value, fragmentOptions); - } else { - updateContextSection(section, fragmentOptions); - } - } else { - updateConditionalSection(section, value, false, fragmentOptions); - } - }; - function updateListSection(section, value, fragmentOptions) { - var i, length, fragmentsToRemove; - length = value.length; - if (length < section.length) { - fragmentsToRemove = section.fragments.splice(length, section.length - length); - while (fragmentsToRemove.length) { - fragmentsToRemove.pop().teardown(true); - } - } else { - if (length > section.length) { - for (i = section.length; i < length; i += 1) { - fragmentOptions.contextStack = section.contextStack.concat(section.keypath + '.' + i); - fragmentOptions.index = i; - if (section.descriptor.i) { - fragmentOptions.indexRef = section.descriptor.i; - } - section.fragments[i] = section.createFragment(fragmentOptions); - } - } - } - section.length = length; - } - function updateListObjectSection(section, value, fragmentOptions) { - var id, fragmentsById; - fragmentsById = section.fragmentsById || (section.fragmentsById = create(null)); - for (id in fragmentsById) { - if (value[id] === undefined && fragmentsById[id]) { - fragmentsById[id].teardown(true); - fragmentsById[id] = null; - } - } - for (id in value) { - if (value[id] !== undefined && !fragmentsById[id]) { - fragmentOptions.contextStack = section.contextStack.concat(section.keypath + '.' + id); - fragmentOptions.index = id; - if (section.descriptor.i) { - fragmentOptions.indexRef = section.descriptor.i; - } - fragmentsById[id] = section.createFragment(fragmentOptions); - } - } - } - function updateContextSection(section, fragmentOptions) { - if (!section.length) { - fragmentOptions.contextStack = section.contextStack.concat(section.keypath); - fragmentOptions.index = 0; - section.fragments[0] = section.createFragment(fragmentOptions); - section.length = 1; - } - } - function updateConditionalSection(section, value, inverted, fragmentOptions) { - var doRender, emptyArray, fragmentsToRemove, fragment; - emptyArray = isArray(value) && value.length === 0; - if (inverted) { - doRender = emptyArray || !value; - } else { - doRender = value && !emptyArray; - } - if (doRender) { - if (!section.length) { - fragmentOptions.contextStack = section.contextStack; - fragmentOptions.index = 0; - section.fragments[0] = section.createFragment(fragmentOptions); - section.length = 1; - } - if (section.length > 1) { - fragmentsToRemove = section.fragments.splice(1); - while (fragment = fragmentsToRemove.pop()) { - fragment.teardown(true); - } - } - } else if (section.length) { - section.teardownFragments(true); - section.length = 0; - } - } - }(utils_isArray, utils_isObject, utils_create); -var render_DomFragment_Section_reassignFragment = function (types, unregisterDependant, ExpressionResolver) { - - return reassignFragment; - function reassignFragment(fragment, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath) { - var i, item, context, query; - if (fragment.html) { - return; - } - if (fragment.indexRefs && fragment.indexRefs[indexRef] !== undefined) { - fragment.indexRefs[indexRef] = newIndex; - } - i = fragment.contextStack.length; - while (i--) { - context = fragment.contextStack[i]; - if (context.substr(0, oldKeypath.length) === oldKeypath) { - fragment.contextStack[i] = context.replace(oldKeypath, newKeypath); - } - } - i = fragment.items.length; - while (i--) { - item = fragment.items[i]; - switch (item.type) { - case types.ELEMENT: - reassignElement(item, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - break; - case types.PARTIAL: - reassignFragment(item.fragment, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - break; - case types.COMPONENT: - reassignFragment(item.instance.fragment, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - if (query = fragment.root._liveComponentQueries[item.name]) { - query._makeDirty(); - } - break; - case types.SECTION: - case types.INTERPOLATOR: - case types.TRIPLE: - reassignMustache(item, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - break; - } - } - } - function reassignElement(element, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath) { - var i, attribute, storage, masterEventName, proxies, proxy, binding, bindings, liveQueries, ractive; - i = element.attributes.length; - while (i--) { - attribute = element.attributes[i]; - if (attribute.fragment) { - reassignFragment(attribute.fragment, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - if (attribute.twoway) { - attribute.updateBindings(); - } - } - } - if (storage = element.node._ractive) { - if (storage.keypath.substr(0, oldKeypath.length) === oldKeypath) { - storage.keypath = storage.keypath.replace(oldKeypath, newKeypath); - } - if (indexRef !== undefined) { - storage.index[indexRef] = newIndex; - } - for (masterEventName in storage.events) { - proxies = storage.events[masterEventName].proxies; - i = proxies.length; - while (i--) { - proxy = proxies[i]; - if (typeof proxy.n === 'object') { - reassignFragment(proxy.a, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - } - if (proxy.d) { - reassignFragment(proxy.d, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - } - } - } - if (binding = storage.binding) { - if (binding.keypath.substr(0, oldKeypath.length) === oldKeypath) { - bindings = storage.root._twowayBindings[binding.keypath]; - bindings.splice(bindings.indexOf(binding), 1); - binding.keypath = binding.keypath.replace(oldKeypath, newKeypath); - bindings = storage.root._twowayBindings[binding.keypath] || (storage.root._twowayBindings[binding.keypath] = []); - bindings.push(binding); - } - } - } - if (element.fragment) { - reassignFragment(element.fragment, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - } - if (liveQueries = element.liveQueries) { - ractive = element.root; - i = liveQueries.length; - while (i--) { - ractive._liveQueries[liveQueries[i]]._makeDirty(); - } - } - } - function reassignMustache(mustache, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath) { - var i; - if (mustache.descriptor.x) { - if (mustache.expressionResolver) { - mustache.expressionResolver.teardown(); - } - mustache.expressionResolver = new ExpressionResolver(mustache); - } - if (mustache.keypath) { - if (mustache.keypath.substr(0, oldKeypath.length) === oldKeypath) { - mustache.resolve(mustache.keypath.replace(oldKeypath, newKeypath)); - } - } else if (mustache.indexRef === indexRef) { - mustache.value = newIndex; - mustache.render(newIndex); - } - if (mustache.fragments) { - i = mustache.fragments.length; - while (i--) { - reassignFragment(mustache.fragments[i], indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - } - } - } - }(config_types, shared_unregisterDependant, render_shared_ExpressionResolver__ExpressionResolver); -var render_DomFragment_Section_reassignFragments = function (types, reassignFragment, preDomUpdate) { - - return function (root, section, start, end, by) { - var i, fragment, indexRef, oldIndex, newIndex, oldKeypath, newKeypath; - indexRef = section.descriptor.i; - for (i = start; i < end; i += 1) { - fragment = section.fragments[i]; - oldIndex = i - by; - newIndex = i; - oldKeypath = section.keypath + '.' + (i - by); - newKeypath = section.keypath + '.' + i; - fragment.index += by; - reassignFragment(fragment, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - } - preDomUpdate(root); - }; - }(config_types, render_DomFragment_Section_reassignFragment, shared_preDomUpdate); -var render_DomFragment_Section_prototype_merge = function (reassignFragment) { - - return function (newIndices) { - var section = this, parentFragment, firstChange, changed, i, newLength, newFragments, toTeardown, fragmentOptions, fragment, nextNode; - parentFragment = this.parentFragment; - newFragments = []; - newIndices.forEach(function (newIndex, oldIndex) { - var by, oldKeypath, newKeypath; - if (newIndex === oldIndex) { - newFragments[newIndex] = section.fragments[oldIndex]; - return; - } - if (firstChange === undefined) { - firstChange = oldIndex; - } - if (newIndex === -1) { - (toTeardown || (toTeardown = [])).push(section.fragments[oldIndex]); - return; - } - by = newIndex - oldIndex; - oldKeypath = section.keypath + '.' + oldIndex; - newKeypath = section.keypath + '.' + newIndex; - reassignFragment(section.fragments[oldIndex], section.descriptor.i, oldIndex, newIndex, by, oldKeypath, newKeypath); - newFragments[newIndex] = section.fragments[oldIndex]; - changed = true; - }); - if (toTeardown) { - while (fragment = toTeardown.pop()) { - fragment.teardown(true); - } - } - if (firstChange === undefined) { - firstChange = this.length; - } - newLength = this.root.get(this.keypath).length; - if (newLength === firstChange) { - return; - } - fragmentOptions = { - descriptor: this.descriptor.f, - root: this.root, - pNode: parentFragment.pNode, - owner: this - }; - if (this.descriptor.i) { - fragmentOptions.indexRef = this.descriptor.i; - } - for (i = firstChange; i < newLength; i += 1) { - if (fragment = newFragments[i]) { - this.docFrag.appendChild(fragment.detach(false)); - } else { - fragmentOptions.contextStack = this.contextStack.concat(this.keypath + '.' + i); - fragmentOptions.index = i; - fragment = this.createFragment(fragmentOptions); - } - this.fragments[i] = fragment; - } - nextNode = parentFragment.findNextNode(this); - parentFragment.pNode.insertBefore(this.docFrag, nextNode); - this.length = newLength; - }; - }(render_DomFragment_Section_reassignFragment); -var circular = function () { - - return []; - }(); -var render_DomFragment_Section__Section = function (types, isClient, initMustache, updateMustache, resolveMustache, updateSection, reassignFragment, reassignFragments, merge, teardown, circular) { - - var DomSection, DomFragment; - circular.push(function () { - DomFragment = circular.DomFragment; - }); - DomSection = function (options, docFrag) { - this.type = types.SECTION; - this.inverted = !!options.descriptor.n; - this.fragments = []; - this.length = 0; - if (docFrag) { - this.docFrag = document.createDocumentFragment(); - } - this.initialising = true; - initMustache(this, options); - if (docFrag) { - docFrag.appendChild(this.docFrag); - } - this.initialising = false; - }; - DomSection.prototype = { - update: updateMustache, - resolve: resolveMustache, - smartUpdate: function (methodName, args) { - var fragmentOptions; - if (methodName === 'push' || methodName === 'unshift' || methodName === 'splice') { - fragmentOptions = { - descriptor: this.descriptor.f, - root: this.root, - pNode: this.parentFragment.pNode, - owner: this - }; - if (this.descriptor.i) { - fragmentOptions.indexRef = this.descriptor.i; - } - } - if (this[methodName]) { - this.rendering = true; - this[methodName](fragmentOptions, args); - this.rendering = false; - } - }, - pop: function () { - if (this.length) { - this.fragments.pop().teardown(true); - this.length -= 1; - } - }, - push: function (fragmentOptions, args) { - var start, end, i; - start = this.length; - end = start + args.length; - for (i = start; i < end; i += 1) { - fragmentOptions.contextStack = this.contextStack.concat(this.keypath + '.' + i); - fragmentOptions.index = i; - this.fragments[i] = this.createFragment(fragmentOptions); - } - this.length += args.length; - this.parentFragment.pNode.insertBefore(this.docFrag, this.parentFragment.findNextNode(this)); - }, - shift: function () { - this.splice(null, [ - 0, - 1 - ]); - }, - unshift: function (fragmentOptions, args) { - this.splice(fragmentOptions, [ - 0, - 0 - ].concat(new Array(args.length))); - }, - splice: function (fragmentOptions, args) { - var insertionPoint, addedItems, removedItems, balance, i, start, end, spliceArgs, reassignStart; - if (!args.length) { - return; - } - start = +(args[0] < 0 ? this.length + args[0] : args[0]); - addedItems = Math.max(0, args.length - 2); - removedItems = args[1] !== undefined ? args[1] : this.length - start; - removedItems = Math.min(removedItems, this.length - start); - balance = addedItems - removedItems; - if (!balance) { - return; - } - if (balance < 0) { - end = start - balance; - for (i = start; i < end; i += 1) { - this.fragments[i].teardown(true); - } - this.fragments.splice(start, -balance); - } else { - end = start + balance; - insertionPoint = this.fragments[start] ? this.fragments[start].firstNode() : this.parentFragment.findNextNode(this); - spliceArgs = [ - start, - 0 - ].concat(new Array(balance)); - this.fragments.splice.apply(this.fragments, spliceArgs); - for (i = start; i < end; i += 1) { - fragmentOptions.contextStack = this.contextStack.concat(this.keypath + '.' + i); - fragmentOptions.index = i; - this.fragments[i] = this.createFragment(fragmentOptions); - } - this.parentFragment.pNode.insertBefore(this.docFrag, insertionPoint); - } - this.length += balance; - reassignStart = start + addedItems; - reassignFragments(this.root, this, reassignStart, this.length, balance); - }, - merge: merge, - detach: function () { - var i, len; - len = this.fragments.length; - for (i = 0; i < len; i += 1) { - this.docFrag.appendChild(this.fragments[i].detach()); - } - return this.docFrag; - }, - teardown: function (destroy) { - this.teardownFragments(destroy); - teardown(this); - }, - firstNode: function () { - if (this.fragments[0]) { - return this.fragments[0].firstNode(); - } - return this.parentFragment.findNextNode(this); - }, - findNextNode: function (fragment) { - if (this.fragments[fragment.index + 1]) { - return this.fragments[fragment.index + 1].firstNode(); - } - return this.parentFragment.findNextNode(this); - }, - teardownFragments: function (destroy) { - var id, fragment; - while (fragment = this.fragments.shift()) { - fragment.teardown(destroy); - } - if (this.fragmentsById) { - for (id in this.fragmentsById) { - if (this.fragments[id]) { - this.fragmentsById[id].teardown(destroy); - this.fragmentsById[id] = null; - } - } - } - }, - render: function (value) { - var nextNode, wrapped; - if (wrapped = this.root._wrapped[this.keypath]) { - value = wrapped.get(); - } - if (this.rendering) { - return; - } - this.rendering = true; - updateSection(this, value); - this.rendering = false; - if (this.docFrag && !this.docFrag.childNodes.length) { - return; - } - if (!this.initialising && isClient) { - nextNode = this.parentFragment.findNextNode(this); - if (nextNode && nextNode.parentNode === this.parentFragment.pNode) { - this.parentFragment.pNode.insertBefore(this.docFrag, nextNode); - } else { - this.parentFragment.pNode.appendChild(this.docFrag); - } - } - }, - createFragment: function (options) { - var fragment = new DomFragment(options); - if (this.docFrag) { - this.docFrag.appendChild(fragment.docFrag); - } - return fragment; - }, - toString: function () { - var str, i, id, len; - str = ''; - i = 0; - len = this.length; - for (i = 0; i < len; i += 1) { - str += this.fragments[i].toString(); - } - if (this.fragmentsById) { - for (id in this.fragmentsById) { - if (this.fragmentsById[id]) { - str += this.fragmentsById[id].toString(); - } - } - } - return str; - }, - find: function (selector) { - var i, len, queryResult; - len = this.fragments.length; - for (i = 0; i < len; i += 1) { - if (queryResult = this.fragments[i].find(selector)) { - return queryResult; - } - } - return null; - }, - findAll: function (selector, query) { - var i, len; - len = this.fragments.length; - for (i = 0; i < len; i += 1) { - this.fragments[i].findAll(selector, query); - } - }, - findComponent: function (selector) { - var i, len, queryResult; - len = this.fragments.length; - for (i = 0; i < len; i += 1) { - if (queryResult = this.fragments[i].findComponent(selector)) { - return queryResult; - } - } - return null; - }, - findAllComponents: function (selector, query) { - var i, len; - len = this.fragments.length; - for (i = 0; i < len; i += 1) { - this.fragments[i].findAllComponents(selector, query); - } - } - }; - return DomSection; - }(config_types, config_isClient, render_shared_initMustache, render_shared_updateMustache, render_shared_resolveMustache, render_shared_updateSection, render_DomFragment_Section_reassignFragment, render_DomFragment_Section_reassignFragments, render_DomFragment_Section_prototype_merge, shared_teardown, circular); -var render_DomFragment_Triple = function (types, matches, initMustache, updateMustache, resolveMustache, insertHtml, teardown) { - - var DomTriple = function (options, docFrag) { - this.type = types.TRIPLE; - if (docFrag) { - this.nodes = []; - this.docFrag = document.createDocumentFragment(); - } - this.initialising = true; - initMustache(this, options); - if (docFrag) { - docFrag.appendChild(this.docFrag); - } - this.initialising = false; - }; - DomTriple.prototype = { - update: updateMustache, - resolve: resolveMustache, - detach: function () { - var i = this.nodes.length; - while (i--) { - this.docFrag.appendChild(this.nodes[i]); - } - return this.docFrag; - }, - teardown: function (destroy) { - if (destroy) { - this.detach(); - this.docFrag = this.nodes = null; - } - teardown(this); - }, - firstNode: function () { - if (this.nodes[0]) { - return this.nodes[0]; - } - return this.parentFragment.findNextNode(this); - }, - render: function (html) { - var node, pNode; - if (!this.nodes) { - return; - } - while (this.nodes.length) { - node = this.nodes.pop(); - node.parentNode.removeChild(node); - } - if (!html) { - this.nodes = []; - return; - } - pNode = this.parentFragment.pNode; - this.nodes = insertHtml(html, pNode.tagName, this.docFrag); - if (!this.initialising) { - pNode.insertBefore(this.docFrag, this.parentFragment.findNextNode(this)); - } - }, - toString: function () { - return this.value != undefined ? this.value : ''; - }, - find: function (selector) { - var i, len, node, queryResult; - len = this.nodes.length; - for (i = 0; i < len; i += 1) { - node = this.nodes[i]; - if (node.nodeType !== 1) { - continue; - } - if (matches(node, selector)) { - return node; - } - if (queryResult = node.querySelector(selector)) { - return queryResult; - } - } - return null; - }, - findAll: function (selector, queryResult) { - var i, len, node, queryAllResult, numNodes, j; - len = this.nodes.length; - for (i = 0; i < len; i += 1) { - node = this.nodes[i]; - if (node.nodeType !== 1) { - continue; - } - if (matches(node, selector)) { - queryResult.push(node); - } - if (queryAllResult = node.querySelectorAll(selector)) { - numNodes = queryAllResult.length; - for (j = 0; j < numNodes; j += 1) { - queryResult.push(queryAllResult[j]); - } - } - } - } - }; - return DomTriple; - }(config_types, utils_matches, render_shared_initMustache, render_shared_updateMustache, render_shared_resolveMustache, render_DomFragment_shared_insertHtml, shared_teardown); -var render_DomFragment_Element_initialise_getElementNamespace = function (namespaces) { - - return function (descriptor, parentNode) { - if (descriptor.a && descriptor.a.xmlns) { - return descriptor.a.xmlns; - } - return descriptor.e === 'svg' ? namespaces.svg : parentNode.namespaceURI || namespaces.html; - }; - }(config_namespaces); -var render_DomFragment_shared_enforceCase = function () { - - var svgCamelCaseElements, svgCamelCaseAttributes, createMap, map; - svgCamelCaseElements = 'altGlyph altGlyphDef altGlyphItem animateColor animateMotion animateTransform clipPath feBlend feColorMatrix feComponentTransfer feComposite feConvolveMatrix feDiffuseLighting feDisplacementMap feDistantLight feFlood feFuncA feFuncB feFuncG feFuncR feGaussianBlur feImage feMerge feMergeNode feMorphology feOffset fePointLight feSpecularLighting feSpotLight feTile feTurbulence foreignObject glyphRef linearGradient radialGradient textPath vkern'.split(' '); - svgCamelCaseAttributes = 'attributeName attributeType baseFrequency baseProfile calcMode clipPathUnits contentScriptType contentStyleType diffuseConstant edgeMode externalResourcesRequired filterRes filterUnits glyphRef gradientTransform gradientUnits kernelMatrix kernelUnitLength keyPoints keySplines keyTimes lengthAdjust limitingConeAngle markerHeight markerUnits markerWidth maskContentUnits maskUnits numOctaves pathLength patternContentUnits patternTransform patternUnits pointsAtX pointsAtY pointsAtZ preserveAlpha preserveAspectRatio primitiveUnits refX refY repeatCount repeatDur requiredExtensions requiredFeatures specularConstant specularExponent spreadMethod startOffset stdDeviation stitchTiles surfaceScale systemLanguage tableValues targetX targetY textLength viewBox viewTarget xChannelSelector yChannelSelector zoomAndPan'.split(' '); - createMap = function (items) { - var map = {}, i = items.length; - while (i--) { - map[items[i].toLowerCase()] = items[i]; - } - return map; - }; - map = createMap(svgCamelCaseElements.concat(svgCamelCaseAttributes)); - return function (elementName) { - var lowerCaseElementName = elementName.toLowerCase(); - return map[lowerCaseElementName] || lowerCaseElementName; - }; - }(); -var render_DomFragment_Attribute_helpers_determineNameAndNamespace = function (namespaces, enforceCase) { - - return function (attribute, name) { - var colonIndex, namespacePrefix; - colonIndex = name.indexOf(':'); - if (colonIndex !== -1) { - namespacePrefix = name.substr(0, colonIndex); - if (namespacePrefix !== 'xmlns') { - name = name.substring(colonIndex + 1); - attribute.name = enforceCase(name); - attribute.lcName = attribute.name.toLowerCase(); - attribute.namespace = namespaces[namespacePrefix.toLowerCase()]; - if (!attribute.namespace) { - throw 'Unknown namespace ("' + namespacePrefix + '")'; - } - return; - } - } - attribute.name = attribute.element.namespace !== namespaces.html ? enforceCase(name) : name; - attribute.lcName = attribute.name.toLowerCase(); - }; - }(config_namespaces, render_DomFragment_shared_enforceCase); -var render_DomFragment_Attribute_helpers_setStaticAttribute = function (namespaces) { - - return function (attribute, options) { - var node, value = options.value === null ? '' : options.value; - if (node = options.pNode) { - if (attribute.namespace) { - node.setAttributeNS(attribute.namespace, options.name, value); - } else { - if (options.name === 'style' && node.style.setAttribute) { - node.style.setAttribute('cssText', value); - } else if (options.name === 'class' && (!node.namespaceURI || node.namespaceURI === namespaces.html)) { - node.className = value; - } else { - node.setAttribute(options.name, value); - } - } - if (attribute.name === 'id') { - options.root.nodes[options.value] = node; - } - if (attribute.name === 'value') { - node._ractive.value = options.value; - } - } - attribute.value = options.value; - }; - }(config_namespaces); -var render_DomFragment_Attribute_helpers_determinePropertyName = function (namespaces) { - - var propertyNames = { - 'accept-charset': 'acceptCharset', - accesskey: 'accessKey', - bgcolor: 'bgColor', - 'class': 'className', - codebase: 'codeBase', - colspan: 'colSpan', - contenteditable: 'contentEditable', - datetime: 'dateTime', - dirname: 'dirName', - 'for': 'htmlFor', - 'http-equiv': 'httpEquiv', - ismap: 'isMap', - maxlength: 'maxLength', - novalidate: 'noValidate', - pubdate: 'pubDate', - readonly: 'readOnly', - rowspan: 'rowSpan', - tabindex: 'tabIndex', - usemap: 'useMap' - }; - return function (attribute, options) { - var propertyName; - if (attribute.pNode && !attribute.namespace && (!options.pNode.namespaceURI || options.pNode.namespaceURI === namespaces.html)) { - propertyName = propertyNames[attribute.name] || attribute.name; - if (options.pNode[propertyName] !== undefined) { - attribute.propertyName = propertyName; - } - if (typeof options.pNode[propertyName] === 'boolean' || propertyName === 'value') { - attribute.useProperty = true; - } - } - }; - }(config_namespaces); -var render_DomFragment_Attribute_prototype_bind = function (types, warn, arrayContentsMatch, getValueFromCheckboxes) { - - var bindAttribute, getInterpolator, updateModel, update, getBinding, inheritProperties, MultipleSelectBinding, SelectBinding, RadioNameBinding, CheckboxNameBinding, CheckedBinding, FileListBinding, ContentEditableBinding, GenericBinding; - bindAttribute = function () { - var node = this.pNode, interpolator, binding, bindings; - if (!this.fragment) { - return false; - } - interpolator = getInterpolator(this); - if (!interpolator) { - return false; - } - this.interpolator = interpolator; - this.keypath = interpolator.keypath || interpolator.descriptor.r; - binding = getBinding(this); - if (!binding) { - return false; - } - node._ractive.binding = this.element.binding = binding; - this.twoway = true; - bindings = this.root._twowayBindings[this.keypath] || (this.root._twowayBindings[this.keypath] = []); - bindings[bindings.length] = binding; - return true; - }; - updateModel = function () { - this._ractive.binding.update(); - }; - update = function () { - var value = this._ractive.root.get(this._ractive.binding.keypath); - this.value = value == undefined ? '' : value; - }; - getInterpolator = function (attribute) { - var item, errorMessage; - if (attribute.fragment.items.length !== 1) { - return null; - } - item = attribute.fragment.items[0]; - if (item.type !== types.INTERPOLATOR) { - return null; - } - if (!item.keypath && !item.ref) { - return null; - } - if (item.keypath && item.keypath.substr(0, 2) === '${') { - errorMessage = 'You cannot set up two-way binding against an expression ' + item.keypath; - if (attribute.root.debug) { - warn(errorMessage); - } - return null; - } - return item; - }; - getBinding = function (attribute) { - var node = attribute.pNode; - if (node.tagName === 'SELECT') { - return node.multiple ? new MultipleSelectBinding(attribute, node) : new SelectBinding(attribute, node); - } - if (node.type === 'checkbox' || node.type === 'radio') { - if (attribute.propertyName === 'name') { - if (node.type === 'checkbox') { - return new CheckboxNameBinding(attribute, node); - } - if (node.type === 'radio') { - return new RadioNameBinding(attribute, node); - } - } - if (attribute.propertyName === 'checked') { - return new CheckedBinding(attribute, node); - } - return null; - } - if (attribute.lcName !== 'value') { - warn('This is... odd'); - } - if (node.type === 'file') { - return new FileListBinding(attribute, node); - } - if (node.getAttribute('contenteditable')) { - return new ContentEditableBinding(attribute, node); - } - return new GenericBinding(attribute, node); - }; - MultipleSelectBinding = function (attribute, node) { - var valueFromModel; - inheritProperties(this, attribute, node); - node.addEventListener('change', updateModel, false); - valueFromModel = this.root.get(this.keypath); - if (valueFromModel === undefined) { - this.update(); - } - }; - MultipleSelectBinding.prototype = { - value: function () { - var value, options, i, len; - value = []; - options = this.node.options; - len = options.length; - for (i = 0; i < len; i += 1) { - if (options[i].selected) { - value[value.length] = options[i]._ractive.value; - } - } - return value; - }, - update: function () { - var attribute, previousValue, value; - attribute = this.attr; - previousValue = attribute.value; - value = this.value(); - if (previousValue === undefined || !arrayContentsMatch(value, previousValue)) { - attribute.receiving = true; - attribute.value = value; - this.root.set(this.keypath, value); - attribute.receiving = false; - } - return this; - }, - deferUpdate: function () { - if (this.deferred === true) { - return; - } - this.root._deferred.attrs.push(this); - this.deferred = true; - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - } - }; - SelectBinding = function (attribute, node) { - var valueFromModel; - inheritProperties(this, attribute, node); - node.addEventListener('change', updateModel, false); - valueFromModel = this.root.get(this.keypath); - if (valueFromModel === undefined) { - this.update(); - } - }; - SelectBinding.prototype = { - value: function () { - var options, i, len; - options = this.node.options; - len = options.length; - for (i = 0; i < len; i += 1) { - if (options[i].selected) { - return options[i]._ractive.value; - } - } - }, - update: function () { - var value = this.value(); - this.attr.receiving = true; - this.attr.value = value; - this.root.set(this.keypath, value); - this.attr.receiving = false; - return this; - }, - deferUpdate: function () { - if (this.deferred === true) { - return; - } - this.root._deferred.attrs.push(this); - this.deferred = true; - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - } - }; - RadioNameBinding = function (attribute, node) { - var valueFromModel; - this.radioName = true; - inheritProperties(this, attribute, node); - node.name = '{{' + attribute.keypath + '}}'; - node.addEventListener('change', updateModel, false); - if (node.attachEvent) { - node.addEventListener('click', updateModel, false); - } - valueFromModel = this.root.get(this.keypath); - if (valueFromModel !== undefined) { - node.checked = valueFromModel == node._ractive.value; - } else { - this.root._deferred.radios.push(this); - } - }; - RadioNameBinding.prototype = { - value: function () { - return this.node._ractive ? this.node._ractive.value : this.node.value; - }, - update: function () { - var node = this.node; - if (node.checked) { - this.attr.receiving = true; - this.root.set(this.keypath, this.value()); - this.attr.receiving = false; - } - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - this.node.removeEventListener('click', updateModel, false); - } - }; - CheckboxNameBinding = function (attribute, node) { - var valueFromModel, checked; - this.checkboxName = true; - inheritProperties(this, attribute, node); - node.name = '{{' + this.keypath + '}}'; - node.addEventListener('change', updateModel, false); - if (node.attachEvent) { - node.addEventListener('click', updateModel, false); - } - valueFromModel = this.root.get(this.keypath); - if (valueFromModel !== undefined) { - checked = valueFromModel.indexOf(node._ractive.value) !== -1; - node.checked = checked; - } else { - if (this.root._deferred.checkboxes.indexOf(this.keypath) === -1) { - this.root._deferred.checkboxes.push(this.keypath); - } - } - }; - CheckboxNameBinding.prototype = { - changed: function () { - return this.node.checked !== !!this.checked; - }, - update: function () { - this.checked = this.node.checked; - this.attr.receiving = true; - this.root.set(this.keypath, getValueFromCheckboxes(this.root, this.keypath)); - this.attr.receiving = false; - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - this.node.removeEventListener('click', updateModel, false); - } - }; - CheckedBinding = function (attribute, node) { - inheritProperties(this, attribute, node); - node.addEventListener('change', updateModel, false); - if (node.attachEvent) { - node.addEventListener('click', updateModel, false); - } - }; - CheckedBinding.prototype = { - value: function () { - return this.node.checked; - }, - update: function () { - this.attr.receiving = true; - this.root.set(this.keypath, this.value()); - this.attr.receiving = false; - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - this.node.removeEventListener('click', updateModel, false); - } - }; - FileListBinding = function (attribute, node) { - inheritProperties(this, attribute, node); - node.addEventListener('change', updateModel, false); - }; - FileListBinding.prototype = { - value: function () { - return this.attr.pNode.files; - }, - update: function () { - this.attr.root.set(this.attr.keypath, this.value()); - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - } - }; - ContentEditableBinding = function (attribute, node) { - inheritProperties(this, attribute, node); - node.addEventListener('change', updateModel, false); - if (!this.root.lazy) { - node.addEventListener('input', updateModel, false); - if (node.attachEvent) { - node.addEventListener('keyup', updateModel, false); - } - } - }; - ContentEditableBinding.prototype = { - update: function () { - this.attr.receiving = true; - this.root.set(this.keypath, this.node.innerHTML); - this.attr.receiving = false; - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - this.node.removeEventListener('input', updateModel, false); - this.node.removeEventListener('keyup', updateModel, false); - } - }; - GenericBinding = function (attribute, node) { - inheritProperties(this, attribute, node); - node.addEventListener('change', updateModel, false); - if (!this.root.lazy) { - node.addEventListener('input', updateModel, false); - if (node.attachEvent) { - node.addEventListener('keyup', updateModel, false); - } - } - this.node.addEventListener('blur', update, false); - }; - GenericBinding.prototype = { - value: function () { - var value = this.attr.pNode.value; - if (+value + '' === value && value.indexOf('e') === -1) { - value = +value; - } - return value; - }, - update: function () { - var attribute = this.attr, value = this.value(); - attribute.receiving = true; - attribute.root.set(attribute.keypath, value); - attribute.receiving = false; - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - this.node.removeEventListener('input', updateModel, false); - this.node.removeEventListener('keyup', updateModel, false); - this.node.removeEventListener('blur', update, false); - } - }; - inheritProperties = function (binding, attribute, node) { - binding.attr = attribute; - binding.node = node; - binding.root = attribute.root; - binding.keypath = attribute.keypath; - }; - return bindAttribute; - }(config_types, utils_warn, utils_arrayContentsMatch, shared_getValueFromCheckboxes); -var render_DomFragment_Attribute_prototype_update = function (isArray, namespaces) { - - var updateAttribute, updateFileInputValue, deferSelect, initSelect, updateSelect, updateMultipleSelect, updateRadioName, updateCheckboxName, updateIEStyleAttribute, updateClassName, updateContentEditableValue, updateEverythingElse; - updateAttribute = function () { - var node; - if (!this.ready) { - return this; - } - node = this.pNode; - if (node.tagName === 'SELECT' && this.lcName === 'value') { - this.update = deferSelect; - this.deferredUpdate = initSelect; - return this.update(); - } - if (this.isFileInputValue) { - this.update = updateFileInputValue; - return this; - } - if (this.twoway && this.lcName === 'name') { - if (node.type === 'radio') { - this.update = updateRadioName; - return this.update(); - } - if (node.type === 'checkbox') { - this.update = updateCheckboxName; - return this.update(); - } - } - if (this.lcName === 'style' && node.style.setAttribute) { - this.update = updateIEStyleAttribute; - return this.update(); - } - if (this.lcName === 'class' && (!node.namespaceURI || node.namespaceURI === namespaces.html)) { - this.update = updateClassName; - return this.update(); - } - if (node.getAttribute('contenteditable') && this.lcName === 'value') { - this.update = updateContentEditableValue; - return this.update(); - } - this.update = updateEverythingElse; - return this.update(); - }; - updateFileInputValue = function () { - return this; - }; - initSelect = function () { - this.deferredUpdate = this.pNode.multiple ? updateMultipleSelect : updateSelect; - this.deferredUpdate(); - }; - deferSelect = function () { - this.root._deferred.selectValues.push(this); - return this; - }; - updateSelect = function () { - var value = this.fragment.getValue(), options, option, i; - this.value = this.pNode._ractive.value = value; - options = this.pNode.options; - i = options.length; - while (i--) { - option = options[i]; - if (option._ractive.value == value) { - option.selected = true; - return this; - } - } - return this; - }; - updateMultipleSelect = function () { - var value = this.fragment.getValue(), options, i; - if (!isArray(value)) { - value = [value]; - } - options = this.pNode.options; - i = options.length; - while (i--) { - options[i].selected = value.indexOf(options[i]._ractive.value) !== -1; - } - this.value = value; - return this; - }; - updateRadioName = function () { - var node, value; - node = this.pNode; - value = this.fragment.getValue(); - node.checked = value == node._ractive.value; - return this; - }; - updateCheckboxName = function () { - var node, value; - node = this.pNode; - value = this.fragment.getValue(); - if (!isArray(value)) { - node.checked = value == node._ractive.value; - return this; - } - node.checked = value.indexOf(node._ractive.value) !== -1; - return this; - }; - updateIEStyleAttribute = function () { - var node, value; - node = this.pNode; - value = this.fragment.getValue(); - if (value === undefined) { - value = ''; - } - if (value !== this.value) { - node.style.setAttribute('cssText', value); - this.value = value; - } - return this; - }; - updateClassName = function () { - var node, value; - node = this.pNode; - value = this.fragment.getValue(); - if (value === undefined) { - value = ''; - } - if (value !== this.value) { - node.className = value; - this.value = value; - } - return this; - }; - updateContentEditableValue = function () { - var node, value; - node = this.pNode; - value = this.fragment.getValue(); - if (value === undefined) { - value = ''; - } - if (value !== this.value) { - if (!this.receiving) { - node.innerHTML = value; - } - this.value = value; - } - return this; - }; - updateEverythingElse = function () { - var node, value; - node = this.pNode; - value = this.fragment.getValue(); - if (this.isValueAttribute) { - node._ractive.value = value; - } - if (value === undefined) { - value = ''; - } - if (value !== this.value) { - if (this.useProperty) { - if (!this.receiving) { - node[this.propertyName] = value; - } - this.value = value; - return this; - } - if (this.namespace) { - node.setAttributeNS(this.namespace, this.name, value); - this.value = value; - return this; - } - if (this.lcName === 'id') { - if (this.value !== undefined) { - this.root.nodes[this.value] = undefined; - } - this.root.nodes[value] = node; - } - node.setAttribute(this.name, value); - this.value = value; - } - return this; - }; - return updateAttribute; - }(utils_isArray, config_namespaces); -var parse_Tokenizer_utils_getStringMatch = function () { - - return function (string) { - var substr; - substr = this.str.substr(this.pos, string.length); - if (substr === string) { - this.pos += string.length; - return string; - } - return null; - }; - }(); -var parse_Tokenizer_utils_allowWhitespace = function () { - - var leadingWhitespace = /^\s+/; - return function () { - var match = leadingWhitespace.exec(this.remaining()); - if (!match) { - return null; - } - this.pos += match[0].length; - return match[0]; - }; - }(); -var parse_Tokenizer_utils_makeRegexMatcher = function () { - - return function (regex) { - return function (tokenizer) { - var match = regex.exec(tokenizer.str.substring(tokenizer.pos)); - if (!match) { - return null; - } - tokenizer.pos += match[0].length; - return match[1] || match[0]; - }; - }; - }(); -var parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral_getEscapedChars = function () { - - return function (tokenizer) { - var chars = '', character; - character = getEscapedChar(tokenizer); - while (character) { - chars += character; - character = getEscapedChar(tokenizer); - } - return chars || null; - }; - function getEscapedChar(tokenizer) { - var character; - if (!tokenizer.getStringMatch('\\')) { - return null; - } - character = tokenizer.str.charAt(tokenizer.pos); - tokenizer.pos += 1; - return character; - } - }(); -var parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral_getQuotedString = function (makeRegexMatcher, getEscapedChars) { - - var getUnescapedDoubleQuotedChars = makeRegexMatcher(/^[^\\"]+/), getUnescapedSingleQuotedChars = makeRegexMatcher(/^[^\\']+/); - return function getQuotedString(tokenizer, singleQuotes) { - var start, string, escaped, unescaped, next, matcher; - start = tokenizer.pos; - string = ''; - matcher = singleQuotes ? getUnescapedSingleQuotedChars : getUnescapedDoubleQuotedChars; - escaped = getEscapedChars(tokenizer); - if (escaped) { - string += escaped; - } - unescaped = matcher(tokenizer); - if (unescaped) { - string += unescaped; - } - if (!string) { - return ''; - } - next = getQuotedString(tokenizer, singleQuotes); - while (next !== '') { - string += next; - } - return string; - }; - }(parse_Tokenizer_utils_makeRegexMatcher, parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral_getEscapedChars); -var parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral__getStringLiteral = function (types, getQuotedString) { - - return function (tokenizer) { - var start, string; - start = tokenizer.pos; - if (tokenizer.getStringMatch('"')) { - string = getQuotedString(tokenizer, false); - if (!tokenizer.getStringMatch('"')) { - tokenizer.pos = start; - return null; - } - return { - t: types.STRING_LITERAL, - v: string - }; - } - if (tokenizer.getStringMatch('\'')) { - string = getQuotedString(tokenizer, true); - if (!tokenizer.getStringMatch('\'')) { - tokenizer.pos = start; - return null; - } - return { - t: types.STRING_LITERAL, - v: string - }; - } - return null; - }; - }(config_types, parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral_getQuotedString); -var parse_Tokenizer_getExpression_getPrimary_getLiteral_getNumberLiteral = function (types, makeRegexMatcher) { - - var getNumber = makeRegexMatcher(/^(?:[+-]?)(?:(?:(?:0|[1-9]\d*)?\.\d+)|(?:(?:0|[1-9]\d*)\.)|(?:0|[1-9]\d*))(?:[eE][+-]?\d+)?/); - return function (tokenizer) { - var result; - if (result = getNumber(tokenizer)) { - return { - t: types.NUMBER_LITERAL, - v: result - }; - } - return null; - }; - }(config_types, parse_Tokenizer_utils_makeRegexMatcher); -var parse_Tokenizer_getExpression_shared_getName = function (makeRegexMatcher) { - - return makeRegexMatcher(/^[a-zA-Z_$][a-zA-Z_$0-9]*/); - }(parse_Tokenizer_utils_makeRegexMatcher); -var parse_Tokenizer_getExpression_shared_getKey = function (getStringLiteral, getNumberLiteral, getName) { - - var identifier = /^[a-zA-Z_$][a-zA-Z_$0-9]*$/; - return function (tokenizer) { - var token; - if (token = getStringLiteral(tokenizer)) { - return identifier.test(token.v) ? token.v : '"' + token.v.replace(/"/g, '\\"') + '"'; - } - if (token = getNumberLiteral(tokenizer)) { - return token.v; - } - if (token = getName(tokenizer)) { - return token; - } - }; - }(parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral__getStringLiteral, parse_Tokenizer_getExpression_getPrimary_getLiteral_getNumberLiteral, parse_Tokenizer_getExpression_shared_getName); -var utils_parseJSON = function (getStringMatch, allowWhitespace, getStringLiteral, getKey) { - - var Tokenizer, specials, specialsPattern, numberPattern, placeholderPattern, placeholderAtStartPattern; - specials = { - 'true': true, - 'false': false, - 'undefined': undefined, - 'null': null - }; - specialsPattern = new RegExp('^(?:' + Object.keys(specials).join('|') + ')'); - numberPattern = /^(?:[+-]?)(?:(?:(?:0|[1-9]\d*)?\.\d+)|(?:(?:0|[1-9]\d*)\.)|(?:0|[1-9]\d*))(?:[eE][+-]?\d+)?/; - placeholderPattern = /\$\{([^\}]+)\}/g; - placeholderAtStartPattern = /^\$\{([^\}]+)\}/; - Tokenizer = function (str, values) { - this.str = str; - this.values = values; - this.pos = 0; - this.result = this.getToken(); - }; - Tokenizer.prototype = { - remaining: function () { - return this.str.substring(this.pos); - }, - getStringMatch: getStringMatch, - getToken: function () { - this.allowWhitespace(); - return this.getPlaceholder() || this.getSpecial() || this.getNumber() || this.getString() || this.getObject() || this.getArray(); - }, - getPlaceholder: function () { - var match; - if (!this.values) { - return null; - } - if ((match = placeholderAtStartPattern.exec(this.remaining())) && this.values.hasOwnProperty(match[1])) { - this.pos += match[0].length; - return { v: this.values[match[1]] }; - } - }, - getSpecial: function () { - var match; - if (match = specialsPattern.exec(this.remaining())) { - this.pos += match[0].length; - return { v: specials[match[0]] }; - } - }, - getNumber: function () { - var match; - if (match = numberPattern.exec(this.remaining())) { - this.pos += match[0].length; - return { v: +match[0] }; - } - }, - getString: function () { - var stringLiteral = getStringLiteral(this), values; - if (stringLiteral && (values = this.values)) { - return { - v: stringLiteral.v.replace(placeholderPattern, function (match, $1) { - return values[$1] || $1; - }) - }; - } - return stringLiteral; - }, - getObject: function () { - var result, pair; - if (!this.getStringMatch('{')) { - return null; - } - result = {}; - while (pair = getKeyValuePair(this)) { - result[pair.key] = pair.value; - this.allowWhitespace(); - if (this.getStringMatch('}')) { - return { v: result }; - } - if (!this.getStringMatch(',')) { - return null; - } - } - return null; - }, - getArray: function () { - var result, valueToken; - if (!this.getStringMatch('[')) { - return null; - } - result = []; - while (valueToken = this.getToken()) { - result.push(valueToken.v); - if (this.getStringMatch(']')) { - return { v: result }; - } - if (!this.getStringMatch(',')) { - return null; - } - } - return null; - }, - allowWhitespace: allowWhitespace - }; - function getKeyValuePair(tokenizer) { - var key, valueToken, pair; - tokenizer.allowWhitespace(); - key = getKey(tokenizer); - if (!key) { - return null; - } - pair = { key: key }; - tokenizer.allowWhitespace(); - if (!tokenizer.getStringMatch(':')) { - return null; - } - tokenizer.allowWhitespace(); - valueToken = tokenizer.getToken(); - if (!valueToken) { - return null; - } - pair.value = valueToken.v; - return pair; - } - return function (str, values) { - var tokenizer = new Tokenizer(str, values); - if (tokenizer.result) { - return { - value: tokenizer.result.v, - remaining: tokenizer.remaining() - }; - } - return null; - }; - }(parse_Tokenizer_utils_getStringMatch, parse_Tokenizer_utils_allowWhitespace, parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral__getStringLiteral, parse_Tokenizer_getExpression_shared_getKey); -var render_StringFragment_Interpolator = function (types, teardown, initMustache, updateMustache, resolveMustache) { - - var StringInterpolator = function (options) { - this.type = types.INTERPOLATOR; - initMustache(this, options); - }; - StringInterpolator.prototype = { - update: updateMustache, - resolve: resolveMustache, - render: function (value) { - this.value = value; - this.parentFragment.bubble(); - }, - teardown: function () { - teardown(this); - }, - toString: function () { - if (this.value == undefined) { - return ''; - } - return stringify(this.value); - } - }; - return StringInterpolator; - function stringify(value) { - if (typeof value === 'string') { - return value; - } - return JSON.stringify(value); - } - }(config_types, shared_teardown, render_shared_initMustache, render_shared_updateMustache, render_shared_resolveMustache); -var render_StringFragment_Section = function (types, initMustache, updateMustache, resolveMustache, updateSection, teardown, circular) { - - var StringSection, StringFragment; - circular.push(function () { - StringFragment = circular.StringFragment; - }); - StringSection = function (options) { - this.type = types.SECTION; - this.fragments = []; - this.length = 0; - initMustache(this, options); - }; - StringSection.prototype = { - update: updateMustache, - resolve: resolveMustache, - teardown: function () { - this.teardownFragments(); - teardown(this); - }, - teardownFragments: function () { - while (this.fragments.length) { - this.fragments.shift().teardown(); - } - this.length = 0; - }, - bubble: function () { - this.value = this.fragments.join(''); - this.parentFragment.bubble(); - }, - render: function (value) { - var wrapped; - if (wrapped = this.root._wrapped[this.keypath]) { - value = wrapped.get(); - } - updateSection(this, value); - this.parentFragment.bubble(); - }, - createFragment: function (options) { - return new StringFragment(options); - }, - toString: function () { - return this.fragments.join(''); - } - }; - return StringSection; - }(config_types, render_shared_initMustache, render_shared_updateMustache, render_shared_resolveMustache, render_shared_updateSection, shared_teardown, circular); -var render_StringFragment_Text = function (types) { - - var StringText = function (text) { - this.type = types.TEXT; - this.text = text; - }; - StringText.prototype = { - toString: function () { - return this.text; - }, - teardown: function () { - } - }; - return StringText; - }(config_types); -var render_StringFragment_prototype_toArgsList = function (warn, parseJSON) { - - return function () { - var values, counter, jsonesque, guid, errorMessage, parsed, processItems; - if (!this.argsList || this.dirty) { - values = {}; - counter = 0; - guid = this.root._guid; - processItems = function (items) { - return items.map(function (item) { - var placeholderId, wrapped, value; - if (item.text) { - return item.text; - } - if (item.fragments) { - return item.fragments.map(function (fragment) { - return processItems(fragment.items); - }).join(''); - } - placeholderId = guid + '-' + counter++; - if (wrapped = item.root._wrapped[item.keypath]) { - value = wrapped.value; - } else { - value = item.value; - } - values[placeholderId] = value; - return '${' + placeholderId + '}'; - }).join(''); - }; - jsonesque = processItems(this.items); - parsed = parseJSON('[' + jsonesque + ']', values); - if (!parsed) { - errorMessage = 'Could not parse directive arguments (' + this.toString() + '). If you think this is a bug, please file an issue at http://github.com/RactiveJS/Ractive/issues'; - if (this.root.debug) { - throw new Error(errorMessage); - } else { - warn(errorMessage); - this.argsList = [jsonesque]; - } - } else { - this.argsList = parsed.value; - } - this.dirty = false; - } - return this.argsList; - }; - }(utils_warn, utils_parseJSON); -var render_StringFragment__StringFragment = function (types, parseJSON, initFragment, Interpolator, Section, Text, toArgsList, circular) { - - var StringFragment = function (options) { - initFragment(this, options); - }; - StringFragment.prototype = { - createItem: function (options) { - if (typeof options.descriptor === 'string') { - return new Text(options.descriptor); - } - switch (options.descriptor.t) { - case types.INTERPOLATOR: - return new Interpolator(options); - case types.TRIPLE: - return new Interpolator(options); - case types.SECTION: - return new Section(options); - default: - throw 'Something went wrong in a rather interesting way'; - } - }, - bubble: function () { - this.dirty = true; - this.owner.bubble(); - }, - teardown: function () { - var numItems, i; - numItems = this.items.length; - for (i = 0; i < numItems; i += 1) { - this.items[i].teardown(); - } - }, - getValue: function () { - var value; - if (this.items.length === 1 && this.items[0].type === types.INTERPOLATOR) { - value = this.items[0].value; - if (value !== undefined) { - return value; - } - } - return this.toString(); - }, - isSimple: function () { - var i, item, containsInterpolator; - if (this.simple !== undefined) { - return this.simple; - } - i = this.items.length; - while (i--) { - item = this.items[i]; - if (item.type === types.TEXT) { - continue; - } - if (item.type === types.INTERPOLATOR) { - if (containsInterpolator) { - return false; - } else { - containsInterpolator = true; - continue; - } - } - return this.simple = false; - } - return this.simple = true; - }, - toString: function () { - return this.items.join(''); - }, - toJSON: function () { - var value = this.getValue(), parsed; - if (typeof value === 'string') { - parsed = parseJSON(value); - value = parsed ? parsed.value : value; - } - return value; - }, - toArgsList: toArgsList - }; - circular.StringFragment = StringFragment; - return StringFragment; - }(config_types, utils_parseJSON, render_shared_initFragment, render_StringFragment_Interpolator, render_StringFragment_Section, render_StringFragment_Text, render_StringFragment_prototype_toArgsList, circular); -var render_DomFragment_Attribute__Attribute = function (types, determineNameAndNamespace, setStaticAttribute, determinePropertyName, bind, update, StringFragment) { - - var DomAttribute = function (options) { - this.type = types.ATTRIBUTE; - this.element = options.element; - determineNameAndNamespace(this, options.name); - if (options.value === null || typeof options.value === 'string') { - setStaticAttribute(this, options); - return; - } - this.root = options.root; - this.pNode = options.pNode; - this.parentFragment = this.element.parentFragment; - this.fragment = new StringFragment({ - descriptor: options.value, - root: this.root, - owner: this, - contextStack: options.contextStack - }); - if (!this.pNode) { - return; - } - if (this.name === 'value') { - this.isValueAttribute = true; - if (this.pNode.tagName === 'INPUT' && this.pNode.type === 'file') { - this.isFileInputValue = true; - } - } - determinePropertyName(this, options); - this.selfUpdating = this.fragment.isSimple(); - this.ready = true; - }; - DomAttribute.prototype = { - bind: bind, - update: update, - updateBindings: function () { - this.keypath = this.interpolator.keypath || this.interpolator.ref; - if (this.propertyName === 'name') { - this.pNode.name = '{{' + this.keypath + '}}'; - } - }, - teardown: function () { - var i; - if (this.boundEvents) { - i = this.boundEvents.length; - while (i--) { - this.pNode.removeEventListener(this.boundEvents[i], this.updateModel, false); - } - } - if (this.fragment) { - this.fragment.teardown(); - } - }, - bubble: function () { - if (this.selfUpdating) { - this.update(); - } else if (!this.deferred && this.ready) { - this.root._deferred.attrs.push(this); - this.deferred = true; - } - }, - toString: function () { - var str; - if (this.value === null) { - return this.name; - } - if (!this.fragment) { - return this.name + '=' + JSON.stringify(this.value); - } - str = this.fragment.toString(); - return this.name + '=' + JSON.stringify(str); - } - }; - return DomAttribute; - }(config_types, render_DomFragment_Attribute_helpers_determineNameAndNamespace, render_DomFragment_Attribute_helpers_setStaticAttribute, render_DomFragment_Attribute_helpers_determinePropertyName, render_DomFragment_Attribute_prototype_bind, render_DomFragment_Attribute_prototype_update, render_StringFragment__StringFragment); -var render_DomFragment_Element_initialise_createElementAttributes = function (DomAttribute) { - - return function (element, attributes) { - var attrName, attrValue, attr; - element.attributes = []; - for (attrName in attributes) { - if (attributes.hasOwnProperty(attrName)) { - attrValue = attributes[attrName]; - attr = new DomAttribute({ - element: element, - name: attrName, - value: attrValue, - root: element.root, - pNode: element.node, - contextStack: element.parentFragment.contextStack - }); - element.attributes[element.attributes.length] = element.attributes[attrName] = attr; - if (attrName !== 'name') { - attr.update(); - } - } - } - return element.attributes; - }; - }(render_DomFragment_Attribute__Attribute); -var render_DomFragment_Element_initialise_appendElementChildren = function (warn, namespaces, StringFragment, circular) { - - var DomFragment, updateCss, updateScript; - circular.push(function () { - DomFragment = circular.DomFragment; - }); - updateCss = function () { - var node = this.node, content = this.fragment.toString(); - if (node.styleSheet) { - node.styleSheet.cssText = content; - } - node.innerHTML = content; - }; - updateScript = function () { - if (!this.node.type || this.node.type === 'text/javascript') { - warn('Script tag was updated. This does not cause the code to be re-evaluated!'); - } - this.node.innerHTML = this.fragment.toString(); - }; - return function (element, node, descriptor, docFrag) { - var liveQueries, i, selector, queryAllResult, j; - if (element.lcName === 'script' || element.lcName === 'style') { - element.fragment = new StringFragment({ - descriptor: descriptor.f, - root: element.root, - contextStack: element.parentFragment.contextStack, - owner: element - }); - if (docFrag) { - if (element.lcName === 'script') { - element.bubble = updateScript; - element.node.innerHTML = element.fragment.toString(); - } else { - element.bubble = updateCss; - element.bubble(); - } - } - return; - } - if (typeof descriptor.f === 'string' && (!node || (!node.namespaceURI || node.namespaceURI === namespaces.html))) { - element.html = descriptor.f; - if (docFrag) { - node.innerHTML = element.html; - liveQueries = element.root._liveQueries; - i = liveQueries.length; - while (i--) { - selector = liveQueries[i]; - if ((queryAllResult = node.querySelectorAll(selector)) && (j = queryAllResult.length)) { - (element.liveQueries || (element.liveQueries = [])).push(selector); - element.liveQueries[selector] = []; - while (j--) { - element.liveQueries[selector][j] = queryAllResult[j]; - } - } - } - } - } else { - element.fragment = new DomFragment({ - descriptor: descriptor.f, - root: element.root, - pNode: node, - contextStack: element.parentFragment.contextStack, - owner: element - }); - if (docFrag) { - node.appendChild(element.fragment.docFrag); - } - } - }; - }(utils_warn, config_namespaces, render_StringFragment__StringFragment, circular); -var render_DomFragment_Element_initialise_decorate_Decorator = function (warn, StringFragment) { - - var Decorator = function (descriptor, root, owner, contextStack) { - var name, fragment, errorMessage; - this.root = root; - this.node = owner.node; - name = descriptor.n || descriptor; - if (typeof name !== 'string') { - fragment = new StringFragment({ - descriptor: name, - root: this.root, - owner: owner, - contextStack: contextStack - }); - name = fragment.toString(); - fragment.teardown(); - } - if (descriptor.a) { - this.params = descriptor.a; - } else if (descriptor.d) { - fragment = new StringFragment({ - descriptor: descriptor.d, - root: this.root, - owner: owner, - contextStack: contextStack - }); - this.params = fragment.toArgsList(); - fragment.teardown(); - } - this.fn = root.decorators[name]; - if (!this.fn) { - errorMessage = 'Missing "' + name + '" decorator. You may need to download a plugin via https://github.com/RactiveJS/Ractive/wiki/Plugins#decorators'; - if (root.debug) { - throw new Error(errorMessage); - } else { - warn(errorMessage); - } - } - }; - Decorator.prototype = { - init: function () { - var result, args; - if (this.params) { - args = [this.node].concat(this.params); - result = this.fn.apply(this.root, args); - } else { - result = this.fn.call(this.root, this.node); - } - if (!result || !result.teardown) { - throw new Error('Decorator definition must return an object with a teardown method'); - } - this.teardown = result.teardown; - } - }; - return Decorator; - }(utils_warn, render_StringFragment__StringFragment); -var render_DomFragment_Element_initialise_decorate__decorate = function (Decorator) { - - return function (descriptor, root, owner, contextStack) { - owner.decorator = new Decorator(descriptor, root, owner, contextStack); - if (owner.decorator.fn) { - root._deferred.decorators.push(owner.decorator); - } - }; - }(render_DomFragment_Element_initialise_decorate_Decorator); -var render_DomFragment_Element_initialise_addEventProxies_addEventProxy = function (warn, StringFragment) { - - var addEventProxy, MasterEventHandler, ProxyEvent, firePlainEvent, fireEventWithArgs, fireEventWithDynamicArgs, customHandlers, genericHandler, getCustomHandler; - addEventProxy = function (element, triggerEventName, proxyDescriptor, contextStack, indexRefs) { - var events, master; - events = element.node._ractive.events; - master = events[triggerEventName] || (events[triggerEventName] = new MasterEventHandler(element, triggerEventName, contextStack, indexRefs)); - master.add(proxyDescriptor); - }; - MasterEventHandler = function (element, eventName, contextStack) { - var definition; - this.element = element; - this.root = element.root; - this.node = element.node; - this.name = eventName; - this.contextStack = contextStack; - this.proxies = []; - if (definition = this.root.events[eventName]) { - this.custom = definition(this.node, getCustomHandler(eventName)); - } else { - if (!('on' + eventName in this.node)) { - warn('Missing "' + this.name + '" event. You may need to download a plugin via https://github.com/RactiveJS/Ractive/wiki/Plugins#events'); - } - this.node.addEventListener(eventName, genericHandler, false); - } - }; - MasterEventHandler.prototype = { - add: function (proxy) { - this.proxies[this.proxies.length] = new ProxyEvent(this.element, this.root, proxy, this.contextStack); - }, - teardown: function () { - var i; - if (this.custom) { - this.custom.teardown(); - } else { - this.node.removeEventListener(this.name, genericHandler, false); - } - i = this.proxies.length; - while (i--) { - this.proxies[i].teardown(); - } - }, - fire: function (event) { - var i = this.proxies.length; - while (i--) { - this.proxies[i].fire(event); - } - } - }; - ProxyEvent = function (element, ractive, descriptor, contextStack) { - var name; - this.root = ractive; - name = descriptor.n || descriptor; - if (typeof name === 'string') { - this.n = name; - } else { - this.n = new StringFragment({ - descriptor: descriptor.n, - root: this.root, - owner: element, - contextStack: contextStack - }); - } - if (descriptor.a) { - this.a = descriptor.a; - this.fire = fireEventWithArgs; - return; - } - if (descriptor.d) { - this.d = new StringFragment({ - descriptor: descriptor.d, - root: this.root, - owner: element, - contextStack: contextStack - }); - this.fire = fireEventWithDynamicArgs; - return; - } - this.fire = firePlainEvent; - }; - ProxyEvent.prototype = { - teardown: function () { - if (this.n.teardown) { - this.n.teardown(); - } - if (this.d) { - this.d.teardown(); - } - }, - bubble: function () { - } - }; - firePlainEvent = function (event) { - this.root.fire(this.n.toString(), event); - }; - fireEventWithArgs = function (event) { - this.root.fire.apply(this.root, [ - this.n.toString(), - event - ].concat(this.a)); - }; - fireEventWithDynamicArgs = function (event) { - var args = this.d.toArgsList(); - if (typeof args === 'string') { - args = args.substr(1, args.length - 2); - } - this.root.fire.apply(this.root, [ - this.n.toString(), - event - ].concat(args)); - }; - genericHandler = function (event) { - var storage = this._ractive; - storage.events[event.type].fire({ - node: this, - original: event, - index: storage.index, - keypath: storage.keypath, - context: storage.root.get(storage.keypath) - }); - }; - customHandlers = {}; - getCustomHandler = function (eventName) { - if (customHandlers[eventName]) { - return customHandlers[eventName]; - } - return customHandlers[eventName] = function (event) { - var storage = event.node._ractive; - event.index = storage.index; - event.keypath = storage.keypath; - event.context = storage.root.get(storage.keypath); - storage.events[eventName].fire(event); - }; - }; - return addEventProxy; - }(utils_warn, render_StringFragment__StringFragment); -var render_DomFragment_Element_initialise_addEventProxies__addEventProxies = function (addEventProxy) { - - return function (element, proxies) { - var i, eventName, eventNames; - for (eventName in proxies) { - if (proxies.hasOwnProperty(eventName)) { - eventNames = eventName.split('-'); - i = eventNames.length; - while (i--) { - addEventProxy(element, eventNames[i], proxies[eventName], element.parentFragment.contextStack); - } - } - } - }; - }(render_DomFragment_Element_initialise_addEventProxies_addEventProxy); -var render_DomFragment_Element_initialise_updateLiveQueries = function () { - - return function (element) { - var ractive, liveQueries, i, selector, query; - ractive = element.root; - liveQueries = ractive._liveQueries; - i = liveQueries.length; - while (i--) { - selector = liveQueries[i]; - query = liveQueries[selector]; - if (query._test(element)) { - (element.liveQueries || (element.liveQueries = [])).push(selector); - element.liveQueries[selector] = [element.node]; - } - } - }; - }(); -var utils_camelCase = function () { - - return function (hyphenatedStr) { - return hyphenatedStr.replace(/-([a-zA-Z])/g, function (match, $1) { - return $1.toUpperCase(); - }); - }; - }(); -var utils_fillGaps = function () { - - return function (target, source) { - var key; - for (key in source) { - if (source.hasOwnProperty(key) && !target.hasOwnProperty(key)) { - target[key] = source[key]; - } - } - return target; - }; - }(); -var render_DomFragment_Element_shared_executeTransition_Transition = function (isClient, createElement, warn, isNumeric, isArray, camelCase, fillGaps, StringFragment) { - - var Transition, testStyle, vendors, vendorPattern, unprefixPattern, prefixCache, CSS_TRANSITIONS_ENABLED, TRANSITION, TRANSITION_DURATION, TRANSITION_PROPERTY, TRANSITION_TIMING_FUNCTION, TRANSITIONEND; - if (!isClient) { - return; - } - testStyle = createElement('div').style; - (function () { - if (testStyle.transition !== undefined) { - TRANSITION = 'transition'; - TRANSITIONEND = 'transitionend'; - CSS_TRANSITIONS_ENABLED = true; - } else if (testStyle.webkitTransition !== undefined) { - TRANSITION = 'webkitTransition'; - TRANSITIONEND = 'webkitTransitionEnd'; - CSS_TRANSITIONS_ENABLED = true; - } else { - CSS_TRANSITIONS_ENABLED = false; - } - }()); - if (TRANSITION) { - TRANSITION_DURATION = TRANSITION + 'Duration'; - TRANSITION_PROPERTY = TRANSITION + 'Property'; - TRANSITION_TIMING_FUNCTION = TRANSITION + 'TimingFunction'; - } - Transition = function (descriptor, root, owner, contextStack, isIntro) { - var t = this, name, fragment, errorMessage; - this.root = root; - this.node = owner.node; - this.isIntro = isIntro; - this.originalStyle = this.node.getAttribute('style'); - this.complete = function (noReset) { - if (!noReset && t.isIntro) { - t.resetStyle(); - } - t._manager.pop(t.node); - t.node._ractive.transition = null; - }; - name = descriptor.n || descriptor; - if (typeof name !== 'string') { - fragment = new StringFragment({ - descriptor: name, - root: this.root, - owner: owner, - contextStack: contextStack - }); - name = fragment.toString(); - fragment.teardown(); - } - this.name = name; - if (descriptor.a) { - this.params = descriptor.a; - } else if (descriptor.d) { - fragment = new StringFragment({ - descriptor: descriptor.d, - root: this.root, - owner: owner, - contextStack: contextStack - }); - this.params = fragment.toArgsList(); - fragment.teardown(); - } - this._fn = root.transitions[name]; - if (!this._fn) { - errorMessage = 'Missing "' + name + '" transition. You may need to download a plugin via https://github.com/RactiveJS/Ractive/wiki/Plugins#transitions'; - if (root.debug) { - throw new Error(errorMessage); - } else { - warn(errorMessage); - } - return; - } - }; - Transition.prototype = { - init: function () { - if (this._inited) { - throw new Error('Cannot initialize a transition more than once'); - } - this._inited = true; - this._fn.apply(this.root, [this].concat(this.params)); - }, - getStyle: function (props) { - var computedStyle, styles, i, prop, value; - computedStyle = window.getComputedStyle(this.node); - if (typeof props === 'string') { - value = computedStyle[prefix(props)]; - if (value === '0px') { - value = 0; - } - return value; - } - if (!isArray(props)) { - throw new Error('Transition#getStyle must be passed a string, or an array of strings representing CSS properties'); - } - styles = {}; - i = props.length; - while (i--) { - prop = props[i]; - value = computedStyle[prefix(prop)]; - if (value === '0px') { - value = 0; - } - styles[prop] = value; - } - return styles; - }, - setStyle: function (style, value) { - var prop; - if (typeof style === 'string') { - this.node.style[prefix(style)] = value; - } else { - for (prop in style) { - if (style.hasOwnProperty(prop)) { - this.node.style[prefix(prop)] = style[prop]; - } - } - } - return this; - }, - animateStyle: function (style, value, options, complete) { - var t = this, propertyNames, changedProperties, computedStyle, current, to, from, transitionEndHandler, i, prop; - if (typeof style === 'string') { - to = {}; - to[style] = value; - } else { - to = style; - complete = options; - options = value; - } - if (!options) { - warn('The "' + t.name + '" transition does not supply an options object to `t.animateStyle()`. This will break in a future version of Ractive. For more info see https://github.com/RactiveJS/Ractive/issues/340'); - options = t; - complete = t.complete; - } - if (!options.duration) { - t.setStyle(to); - if (complete) { - complete(); - } - } - propertyNames = Object.keys(to); - changedProperties = []; - computedStyle = window.getComputedStyle(t.node); - from = {}; - i = propertyNames.length; - while (i--) { - prop = propertyNames[i]; - current = computedStyle[prefix(prop)]; - if (current === '0px') { - current = 0; - } - if (current != to[prop]) { - changedProperties[changedProperties.length] = prop; - t.node.style[prefix(prop)] = current; - } - } - if (!changedProperties.length) { - if (complete) { - complete(); - } - return; - } - setTimeout(function () { - t.node.style[TRANSITION_PROPERTY] = propertyNames.map(prefix).map(hyphenate).join(','); - t.node.style[TRANSITION_TIMING_FUNCTION] = hyphenate(options.easing || 'linear'); - t.node.style[TRANSITION_DURATION] = options.duration / 1000 + 's'; - transitionEndHandler = function (event) { - var index; - index = changedProperties.indexOf(camelCase(unprefix(event.propertyName))); - if (index !== -1) { - changedProperties.splice(index, 1); - } - if (changedProperties.length) { - return; - } - t.root.fire(t.name + ':end'); - t.node.removeEventListener(TRANSITIONEND, transitionEndHandler, false); - if (complete) { - complete(); - } - }; - t.node.addEventListener(TRANSITIONEND, transitionEndHandler, false); - setTimeout(function () { - var i = changedProperties.length; - while (i--) { - prop = changedProperties[i]; - t.node.style[prefix(prop)] = to[prop]; - } - }, 0); - }, options.delay || 0); - }, - resetStyle: function () { - if (this.originalStyle) { - this.node.setAttribute('style', this.originalStyle); - } else { - this.node.getAttribute('style'); - this.node.removeAttribute('style'); - } - }, - processParams: function (params, defaults) { - if (typeof params === 'number') { - params = { duration: params }; - } else if (typeof params === 'string') { - if (params === 'slow') { - params = { duration: 600 }; - } else if (params === 'fast') { - params = { duration: 200 }; - } else { - params = { duration: 400 }; - } - } else if (!params) { - params = {}; - } - return fillGaps(params, defaults); - } - }; - vendors = [ - 'o', - 'ms', - 'moz', - 'webkit' - ]; - vendorPattern = new RegExp('^(?:' + vendors.join('|') + ')([A-Z])'); - unprefixPattern = new RegExp('^-(?:' + vendors.join('|') + ')-'); - prefixCache = {}; - function prefix(prop) { - var i, vendor, capped; - if (!prefixCache[prop]) { - if (testStyle[prop] !== undefined) { - prefixCache[prop] = prop; - } else { - capped = prop.charAt(0).toUpperCase() + prop.substring(1); - i = vendors.length; - while (i--) { - vendor = vendors[i]; - if (testStyle[vendor + capped] !== undefined) { - prefixCache[prop] = vendor + capped; - break; - } - } - } - } - return prefixCache[prop]; - } - function unprefix(prop) { - return prop.replace(unprefixPattern, ''); - } - function hyphenate(str) { - var hyphenated; - if (vendorPattern.test(str)) { - str = '-' + str; - } - hyphenated = str.replace(/[A-Z]/g, function (match) { - return '-' + match.toLowerCase(); - }); - return hyphenated; - } - return Transition; - }(config_isClient, utils_createElement, utils_warn, utils_isNumeric, utils_isArray, utils_camelCase, utils_fillGaps, render_StringFragment__StringFragment); -var render_DomFragment_Element_shared_executeTransition__executeTransition = function (warn, Transition) { - - return function (descriptor, root, owner, contextStack, isIntro) { - var transition, node, oldTransition; - if (!root.transitionsEnabled || root._parent && !root._parent.transitionsEnabled) { - return; - } - transition = new Transition(descriptor, root, owner, contextStack, isIntro); - if (transition._fn) { - node = transition.node; - transition._manager = root._transitionManager; - if (oldTransition = node._ractive.transition) { - oldTransition.complete(); - } - node._ractive.transition = transition; - transition._manager.push(node); - if (isIntro) { - root._deferred.transitions.push(transition); - } else { - transition.init(); - } - } - }; - }(utils_warn, render_DomFragment_Element_shared_executeTransition_Transition); -var render_DomFragment_Element_initialise__initialise = function (types, namespaces, create, defineProperty, matches, warn, createElement, getElementNamespace, createElementAttributes, appendElementChildren, decorate, addEventProxies, updateLiveQueries, executeTransition, enforceCase) { - - return function (element, options, docFrag) { - var parentFragment, pNode, contextStack, descriptor, namespace, name, attributes, width, height, loadHandler, root, selectBinding, errorMessage; - element.type = types.ELEMENT; - parentFragment = element.parentFragment = options.parentFragment; - pNode = parentFragment.pNode; - contextStack = parentFragment.contextStack; - descriptor = element.descriptor = options.descriptor; - element.root = root = parentFragment.root; - element.index = options.index; - element.lcName = descriptor.e.toLowerCase(); - element.eventListeners = []; - element.customEventListeners = []; - if (pNode) { - namespace = element.namespace = getElementNamespace(descriptor, pNode); - name = namespace !== namespaces.html ? enforceCase(descriptor.e) : descriptor.e; - element.node = createElement(name, namespace); - defineProperty(element.node, '_ractive', { - value: { - proxy: element, - keypath: contextStack.length ? contextStack[contextStack.length - 1] : '', - index: parentFragment.indexRefs, - events: create(null), - root: root - } - }); - } - attributes = createElementAttributes(element, descriptor.a); - if (descriptor.f) { - if (element.node && element.node.getAttribute('contenteditable')) { - if (element.node.innerHTML) { - errorMessage = 'A pre-populated contenteditable element should not have children'; - if (root.debug) { - throw new Error(errorMessage); - } else { - warn(errorMessage); - } - } - } - appendElementChildren(element, element.node, descriptor, docFrag); - } - if (docFrag && descriptor.v) { - addEventProxies(element, descriptor.v); - } - if (docFrag) { - if (root.twoway) { - element.bind(); - if (element.node.getAttribute('contenteditable') && element.node._ractive.binding) { - element.node._ractive.binding.update(); - } - } - if (attributes.name && !attributes.name.twoway) { - attributes.name.update(); - } - if (element.node.tagName === 'IMG' && ((width = element.attributes.width) || (height = element.attributes.height))) { - element.node.addEventListener('load', loadHandler = function () { - if (width) { - element.node.width = width.value; - } - if (height) { - element.node.height = height.value; - } - element.node.removeEventListener('load', loadHandler, false); - }, false); - } - docFrag.appendChild(element.node); - if (descriptor.o) { - decorate(descriptor.o, root, element, contextStack); - } - if (descriptor.t1) { - executeTransition(descriptor.t1, root, element, contextStack, true); - } - if (element.node.tagName === 'OPTION') { - if (pNode.tagName === 'SELECT' && (selectBinding = pNode._ractive.binding)) { - selectBinding.deferUpdate(); - } - if (element.node._ractive.value == pNode._ractive.value) { - element.node.selected = true; - } - } - if (element.node.autofocus) { - root._deferred.focusable = element.node; - } - } - updateLiveQueries(element); - }; - }(config_types, config_namespaces, utils_create, utils_defineProperty, utils_matches, utils_warn, utils_createElement, render_DomFragment_Element_initialise_getElementNamespace, render_DomFragment_Element_initialise_createElementAttributes, render_DomFragment_Element_initialise_appendElementChildren, render_DomFragment_Element_initialise_decorate__decorate, render_DomFragment_Element_initialise_addEventProxies__addEventProxies, render_DomFragment_Element_initialise_updateLiveQueries, render_DomFragment_Element_shared_executeTransition__executeTransition, render_DomFragment_shared_enforceCase); -var render_DomFragment_Element_prototype_teardown = function (executeTransition) { - - return function (destroy) { - var eventName, binding, bindings, i, liveQueries, selector, query, nodesToRemove, j; - if (this.fragment) { - this.fragment.teardown(false); - } - while (this.attributes.length) { - this.attributes.pop().teardown(); - } - if (this.node) { - for (eventName in this.node._ractive.events) { - this.node._ractive.events[eventName].teardown(); - } - if (binding = this.node._ractive.binding) { - binding.teardown(); - bindings = this.root._twowayBindings[binding.attr.keypath]; - bindings.splice(bindings.indexOf(binding), 1); - } - } - if (this.decorator) { - this.decorator.teardown(); - } - if (this.descriptor.t2) { - executeTransition(this.descriptor.t2, this.root, this, this.parentFragment.contextStack, false); - } - if (destroy) { - this.root._transitionManager.detachWhenReady(this); - } - if (liveQueries = this.liveQueries) { - i = liveQueries.length; - while (i--) { - selector = liveQueries[i]; - if (nodesToRemove = this.liveQueries[selector]) { - j = nodesToRemove.length; - query = this.root._liveQueries[selector]; - while (j--) { - query._remove(nodesToRemove[j]); - } - } - } - } - }; - }(render_DomFragment_Element_shared_executeTransition__executeTransition); -var config_voidElementNames = function () { - - return 'area base br col command doctype embed hr img input keygen link meta param source track wbr'.split(' '); - }(); -var render_DomFragment_Element_prototype_toString = function (voidElementNames) { - - return function () { - var str, i, len; - str = '<' + (this.descriptor.y ? '!doctype' : this.descriptor.e); - len = this.attributes.length; - for (i = 0; i < len; i += 1) { - str += ' ' + this.attributes[i].toString(); - } - str += '>'; - if (this.html) { - str += this.html; - } else if (this.fragment) { - str += this.fragment.toString(); - } - if (voidElementNames.indexOf(this.descriptor.e) === -1) { - str += ''; - } - return str; - }; - }(config_voidElementNames); -var render_DomFragment_Element_prototype_find = function (matches) { - - return function (selector) { - var queryResult; - if (matches(this.node, selector)) { - return this.node; - } - if (this.html && (queryResult = this.node.querySelector(selector))) { - return queryResult; - } - if (this.fragment && this.fragment.find) { - return this.fragment.find(selector); - } - }; - }(utils_matches); -var render_DomFragment_Element_prototype_findAll = function () { - - return function (selector, query) { - var queryAllResult, i, numNodes, node, registeredNodes; - if (query._test(this, true) && query.live) { - (this.liveQueries || (this.liveQueries = [])).push(selector); - this.liveQueries[selector] = [this.node]; - } - if (this.html && (queryAllResult = this.node.querySelectorAll(selector)) && (numNodes = queryAllResult.length)) { - if (query.live) { - if (!this.liveQueries[selector]) { - (this.liveQueries || (this.liveQueries = [])).push(selector); - this.liveQueries[selector] = []; - } - registeredNodes = this.liveQueries[selector]; - } - for (i = 0; i < numNodes; i += 1) { - node = queryAllResult[i]; - query.push(node); - if (query.live) { - registeredNodes.push(node); - } - } - } - if (this.fragment) { - this.fragment.findAll(selector, query); - } - }; - }(); -var render_DomFragment_Element_prototype_findComponent = function () { - - return function (selector) { - if (this.fragment) { - return this.fragment.findComponent(selector); - } - }; - }(); -var render_DomFragment_Element_prototype_findAllComponents = function () { - - return function (selector, query) { - if (this.fragment) { - this.fragment.findAllComponents(selector, query); - } - }; - }(); -var render_DomFragment_Element_prototype_bind = function () { - - return function () { - var attributes = this.attributes; - if (!this.node) { - return; - } - if (this.binding) { - this.binding.teardown(); - this.binding = null; - } - if (this.node.getAttribute('contenteditable') && attributes.value && attributes.value.bind()) { - return; - } - switch (this.descriptor.e) { - case 'select': - case 'textarea': - if (attributes.value) { - attributes.value.bind(); - } - return; - case 'input': - if (this.node.type === 'radio' || this.node.type === 'checkbox') { - if (attributes.name && attributes.name.bind()) { - return; - } - if (attributes.checked && attributes.checked.bind()) { - return; - } - } - if (attributes.value && attributes.value.bind()) { - return; - } - } - }; - }(); -var render_DomFragment_Element__Element = function (initialise, teardown, toString, find, findAll, findComponent, findAllComponents, bind) { - - var DomElement = function (options, docFrag) { - initialise(this, options, docFrag); - }; - DomElement.prototype = { - detach: function () { - if (this.node) { - if (this.node.parentNode) { - this.node.parentNode.removeChild(this.node); - } - return this.node; - } - }, - teardown: teardown, - firstNode: function () { - return this.node; - }, - findNextNode: function () { - return null; - }, - bubble: function () { - }, - toString: toString, - find: find, - findAll: findAll, - findComponent: findComponent, - findAllComponents: findAllComponents, - bind: bind - }; - return DomElement; - }(render_DomFragment_Element_initialise__initialise, render_DomFragment_Element_prototype_teardown, render_DomFragment_Element_prototype_toString, render_DomFragment_Element_prototype_find, render_DomFragment_Element_prototype_findAll, render_DomFragment_Element_prototype_findComponent, render_DomFragment_Element_prototype_findAllComponents, render_DomFragment_Element_prototype_bind); -var config_errors = { missingParser: 'Missing Ractive.parse - cannot parse template. Either preparse or use the version that includes the parser' }; -var registries_partials = {}; -var parse_utils_stripHtmlComments = function () { - - return function (html) { - var commentStart, commentEnd, processed; - processed = ''; - while (html.length) { - commentStart = html.indexOf(''); - if (commentStart === -1 && commentEnd === -1) { - processed += html; - break; - } - if (commentStart !== -1 && commentEnd === -1) { - throw 'Illegal HTML - expected closing comment sequence (\'-->\')'; - } - if (commentEnd !== -1 && commentStart === -1 || commentEnd < commentStart) { - throw 'Illegal HTML - unexpected closing comment sequence (\'-->\')'; - } - processed += html.substr(0, commentStart); - html = html.substring(commentEnd + 3); - } - return processed; - }; - }(); -var parse_utils_stripStandalones = function (types) { - - return function (tokens) { - var i, current, backOne, backTwo, leadingLinebreak, trailingLinebreak; - leadingLinebreak = /^\s*\r?\n/; - trailingLinebreak = /\r?\n\s*$/; - for (i = 2; i < tokens.length; i += 1) { - current = tokens[i]; - backOne = tokens[i - 1]; - backTwo = tokens[i - 2]; - if (current.type === types.TEXT && backOne.type === types.MUSTACHE && backTwo.type === types.TEXT) { - if (trailingLinebreak.test(backTwo.value) && leadingLinebreak.test(current.value)) { - if (backOne.mustacheType !== types.INTERPOLATOR && backOne.mustacheType !== types.TRIPLE) { - backTwo.value = backTwo.value.replace(trailingLinebreak, '\n'); - } - current.value = current.value.replace(leadingLinebreak, ''); - if (current.value === '') { - tokens.splice(i--, 1); - } - } - } - } - return tokens; - }; - }(config_types); -var parse_utils_stripCommentTokens = function (types) { - - return function (tokens) { - var i, current, previous, next; - for (i = 0; i < tokens.length; i += 1) { - current = tokens[i]; - previous = tokens[i - 1]; - next = tokens[i + 1]; - if (current.mustacheType === types.COMMENT || current.mustacheType === types.DELIMCHANGE) { - tokens.splice(i, 1); - if (previous && next) { - if (previous.type === types.TEXT && next.type === types.TEXT) { - previous.value += next.value; - tokens.splice(i, 1); - } - } - i -= 1; - } - } - return tokens; - }; - }(config_types); -var parse_Tokenizer_getMustache_getDelimiterChange = function (makeRegexMatcher) { - - var getDelimiter = makeRegexMatcher(/^[^\s=]+/); - return function (tokenizer) { - var start, opening, closing; - if (!tokenizer.getStringMatch('=')) { - return null; - } - start = tokenizer.pos; - tokenizer.allowWhitespace(); - opening = getDelimiter(tokenizer); - if (!opening) { - tokenizer.pos = start; - return null; - } - tokenizer.allowWhitespace(); - closing = getDelimiter(tokenizer); - if (!closing) { - tokenizer.pos = start; - return null; - } - tokenizer.allowWhitespace(); - if (!tokenizer.getStringMatch('=')) { - tokenizer.pos = start; - return null; - } - return [ - opening, - closing - ]; - }; - }(parse_Tokenizer_utils_makeRegexMatcher); -var parse_Tokenizer_getMustache_getMustacheType = function (types) { - - var mustacheTypes = { - '#': types.SECTION, - '^': types.INVERTED, - '/': types.CLOSING, - '>': types.PARTIAL, - '!': types.COMMENT, - '&': types.TRIPLE - }; - return function (tokenizer) { - var type = mustacheTypes[tokenizer.str.charAt(tokenizer.pos)]; - if (!type) { - return null; - } - tokenizer.pos += 1; - return type; - }; - }(config_types); -var parse_Tokenizer_getMustache_getMustacheContent = function (types, makeRegexMatcher, getMustacheType) { - - var getIndexRef = makeRegexMatcher(/^\s*:\s*([a-zA-Z_$][a-zA-Z_$0-9]*)/), arrayMember = /^[0-9][1-9]*$/; - return function (tokenizer, isTriple) { - var start, mustache, type, expr, i, remaining, index; - start = tokenizer.pos; - mustache = { type: isTriple ? types.TRIPLE : types.MUSTACHE }; - if (!isTriple) { - if (expr = tokenizer.getExpression()) { - mustache.mustacheType = types.INTERPOLATOR; - tokenizer.allowWhitespace(); - if (tokenizer.getStringMatch(tokenizer.delimiters[1])) { - tokenizer.pos -= tokenizer.delimiters[1].length; - } else { - tokenizer.pos = start; - expr = null; - } - } - if (!expr) { - type = getMustacheType(tokenizer); - if (type === types.TRIPLE) { - mustache = { type: types.TRIPLE }; - } else { - mustache.mustacheType = type || types.INTERPOLATOR; - } - if (type === types.COMMENT || type === types.CLOSING) { - remaining = tokenizer.remaining(); - index = remaining.indexOf(tokenizer.delimiters[1]); - if (index !== -1) { - mustache.ref = remaining.substr(0, index); - tokenizer.pos += index; - return mustache; - } - } - } - } - if (!expr) { - tokenizer.allowWhitespace(); - expr = tokenizer.getExpression(); - } - while (expr.t === types.BRACKETED && expr.x) { - expr = expr.x; - } - if (expr.t === types.REFERENCE) { - mustache.ref = expr.n; - } else if (expr.t === types.NUMBER_LITERAL && arrayMember.test(expr.v)) { - mustache.ref = expr.v; - } else { - mustache.expression = expr; - } - i = getIndexRef(tokenizer); - if (i !== null) { - mustache.indexRef = i; - } - return mustache; - }; - }(config_types, parse_Tokenizer_utils_makeRegexMatcher, parse_Tokenizer_getMustache_getMustacheType); -var parse_Tokenizer_getMustache__getMustache = function (types, getDelimiterChange, getMustacheContent) { - - return function () { - var seekTripleFirst = this.tripleDelimiters[0].length > this.delimiters[0].length; - return getMustache(this, seekTripleFirst) || getMustache(this, !seekTripleFirst); - }; - function getMustache(tokenizer, seekTriple) { - var start = tokenizer.pos, content, delimiters; - delimiters = seekTriple ? tokenizer.tripleDelimiters : tokenizer.delimiters; - if (!tokenizer.getStringMatch(delimiters[0])) { - return null; - } - content = getDelimiterChange(tokenizer); - if (content) { - if (!tokenizer.getStringMatch(delimiters[1])) { - tokenizer.pos = start; - return null; - } - tokenizer[seekTriple ? 'tripleDelimiters' : 'delimiters'] = content; - return { - type: types.MUSTACHE, - mustacheType: types.DELIMCHANGE - }; - } - tokenizer.allowWhitespace(); - content = getMustacheContent(tokenizer, seekTriple); - if (content === null) { - tokenizer.pos = start; - return null; - } - tokenizer.allowWhitespace(); - if (!tokenizer.getStringMatch(delimiters[1])) { - tokenizer.pos = start; - return null; - } - return content; - } - }(config_types, parse_Tokenizer_getMustache_getDelimiterChange, parse_Tokenizer_getMustache_getMustacheContent); -var parse_Tokenizer_getComment_getComment = function (types) { - - return function () { - var content, remaining, endIndex; - if (!this.getStringMatch(''); - if (endIndex === -1) { - throw new Error('Unexpected end of input (expected "-->" to close comment)'); - } - content = remaining.substr(0, endIndex); - this.pos += endIndex + 3; - return { - type: types.COMMENT, - content: content - }; - }; - }(config_types); -var parse_Tokenizer_utils_getLowestIndex = function () { - - return function (haystack, needles) { - var i, index, lowest; - i = needles.length; - while (i--) { - index = haystack.indexOf(needles[i]); - if (!index) { - return 0; - } - if (index === -1) { - continue; - } - if (!lowest || index < lowest) { - lowest = index; - } - } - return lowest || -1; - }; - }(); -var parse_Tokenizer_getTag__getTag = function (types, makeRegexMatcher, getLowestIndex) { - - var getTag, getOpeningTag, getClosingTag, getTagName, getAttributes, getAttribute, getAttributeName, getAttributeValue, getUnquotedAttributeValue, getUnquotedAttributeValueToken, getUnquotedAttributeValueText, getQuotedStringToken, getQuotedAttributeValue; - getTag = function () { - return getOpeningTag(this) || getClosingTag(this); - }; - getOpeningTag = function (tokenizer) { - var start, tag, attrs, lowerCaseName; - start = tokenizer.pos; - if (tokenizer.inside) { - return null; - } - if (!tokenizer.getStringMatch('<')) { - return null; - } - tag = { type: types.TAG }; - if (tokenizer.getStringMatch('!')) { - tag.doctype = true; - } - tag.name = getTagName(tokenizer); - if (!tag.name) { - tokenizer.pos = start; - return null; - } - attrs = getAttributes(tokenizer); - if (attrs) { - tag.attrs = attrs; - } - tokenizer.allowWhitespace(); - if (tokenizer.getStringMatch('/')) { - tag.selfClosing = true; - } - if (!tokenizer.getStringMatch('>')) { - tokenizer.pos = start; - return null; - } - lowerCaseName = tag.name.toLowerCase(); - if (lowerCaseName === 'script' || lowerCaseName === 'style') { - tokenizer.inside = lowerCaseName; - } - return tag; - }; - getClosingTag = function (tokenizer) { - var start, tag, expected; - start = tokenizer.pos; - expected = function (str) { - throw new Error('Unexpected character ' + tokenizer.remaining().charAt(0) + ' (expected ' + str + ')'); - }; - if (!tokenizer.getStringMatch('<')) { - return null; - } - tag = { - type: types.TAG, - closing: true - }; - if (!tokenizer.getStringMatch('/')) { - expected('"/"'); - } - tag.name = getTagName(tokenizer); - if (!tag.name) { - expected('tag name'); - } - if (!tokenizer.getStringMatch('>')) { - expected('">"'); - } - if (tokenizer.inside) { - if (tag.name.toLowerCase() !== tokenizer.inside) { - tokenizer.pos = start; - return null; - } - tokenizer.inside = null; - } - return tag; - }; - getTagName = makeRegexMatcher(/^[a-zA-Z]{1,}:?[a-zA-Z0-9\-]*/); - getAttributes = function (tokenizer) { - var start, attrs, attr; - start = tokenizer.pos; - tokenizer.allowWhitespace(); - attr = getAttribute(tokenizer); - if (!attr) { - tokenizer.pos = start; - return null; - } - attrs = []; - while (attr !== null) { - attrs[attrs.length] = attr; - tokenizer.allowWhitespace(); - attr = getAttribute(tokenizer); - } - return attrs; - }; - getAttribute = function (tokenizer) { - var attr, name, value; - name = getAttributeName(tokenizer); - if (!name) { - return null; - } - attr = { name: name }; - value = getAttributeValue(tokenizer); - if (value) { - attr.value = value; - } - return attr; - }; - getAttributeName = makeRegexMatcher(/^[^\s"'>\/=]+/); - getAttributeValue = function (tokenizer) { - var start, value; - start = tokenizer.pos; - tokenizer.allowWhitespace(); - if (!tokenizer.getStringMatch('=')) { - tokenizer.pos = start; - return null; - } - tokenizer.allowWhitespace(); - value = getQuotedAttributeValue(tokenizer, '\'') || getQuotedAttributeValue(tokenizer, '"') || getUnquotedAttributeValue(tokenizer); - if (value === null) { - tokenizer.pos = start; - return null; - } - return value; - }; - getUnquotedAttributeValueText = makeRegexMatcher(/^[^\s"'=<>`]+/); - getUnquotedAttributeValueToken = function (tokenizer) { - var start, text, index; - start = tokenizer.pos; - text = getUnquotedAttributeValueText(tokenizer); - if (!text) { - return null; - } - if ((index = text.indexOf(tokenizer.delimiters[0])) !== -1) { - text = text.substr(0, index); - tokenizer.pos = start + text.length; - } - return { - type: types.TEXT, - value: text - }; - }; - getUnquotedAttributeValue = function (tokenizer) { - var tokens, token; - tokens = []; - token = tokenizer.getMustache() || getUnquotedAttributeValueToken(tokenizer); - while (token !== null) { - tokens[tokens.length] = token; - token = tokenizer.getMustache() || getUnquotedAttributeValueToken(tokenizer); - } - if (!tokens.length) { - return null; - } - return tokens; - }; - getQuotedAttributeValue = function (tokenizer, quoteMark) { - var start, tokens, token; - start = tokenizer.pos; - if (!tokenizer.getStringMatch(quoteMark)) { - return null; - } - tokens = []; - token = tokenizer.getMustache() || getQuotedStringToken(tokenizer, quoteMark); - while (token !== null) { - tokens[tokens.length] = token; - token = tokenizer.getMustache() || getQuotedStringToken(tokenizer, quoteMark); - } - if (!tokenizer.getStringMatch(quoteMark)) { - tokenizer.pos = start; - return null; - } - return tokens; - }; - getQuotedStringToken = function (tokenizer, quoteMark) { - var start, index, remaining; - start = tokenizer.pos; - remaining = tokenizer.remaining(); - index = getLowestIndex(remaining, [ - quoteMark, - tokenizer.delimiters[0], - tokenizer.delimiters[1] - ]); - if (index === -1) { - throw new Error('Quoted attribute value must have a closing quote'); - } - if (!index) { - return null; - } - tokenizer.pos += index; - return { - type: types.TEXT, - value: remaining.substr(0, index) - }; - }; - return getTag; - }(config_types, parse_Tokenizer_utils_makeRegexMatcher, parse_Tokenizer_utils_getLowestIndex); -var parse_Tokenizer_getText__getText = function (types, getLowestIndex) { - - return function () { - var index, remaining, barrier; - remaining = this.remaining(); - barrier = this.inside ? '> >>> < <= > >= in instanceof == != === !== & ^ | && ||'.split(' '); - fallthrough = getTypeOf; - for (i = 0, len = infixOperators.length; i < len; i += 1) { - matcher = makeInfixSequenceMatcher(infixOperators[i], fallthrough); - fallthrough = matcher; - } - getLogicalOr = fallthrough; - }()); - return getLogicalOr; - }(config_types, parse_Tokenizer_getExpression_getTypeOf); -var parse_Tokenizer_getExpression_getConditional = function (types, getLogicalOr) { - - return function (tokenizer) { - var start, expression, ifTrue, ifFalse; - expression = getLogicalOr(tokenizer); - if (!expression) { - return null; - } - start = tokenizer.pos; - tokenizer.allowWhitespace(); - if (!tokenizer.getStringMatch('?')) { - tokenizer.pos = start; - return expression; - } - tokenizer.allowWhitespace(); - ifTrue = tokenizer.getExpression(); - if (!ifTrue) { - tokenizer.pos = start; - return expression; - } - tokenizer.allowWhitespace(); - if (!tokenizer.getStringMatch(':')) { - tokenizer.pos = start; - return expression; - } - tokenizer.allowWhitespace(); - ifFalse = tokenizer.getExpression(); - if (!ifFalse) { - tokenizer.pos = start; - return expression; - } - return { - t: types.CONDITIONAL, - o: [ - expression, - ifTrue, - ifFalse - ] - }; - }; - }(config_types, parse_Tokenizer_getExpression_getLogicalOr); -var parse_Tokenizer_getExpression__getExpression = function (getConditional) { - - return function () { - return getConditional(this); - }; - }(parse_Tokenizer_getExpression_getConditional); -var parse_Tokenizer__Tokenizer = function (getMustache, getComment, getTag, getText, getExpression, allowWhitespace, getStringMatch) { - - var Tokenizer; - Tokenizer = function (str, options) { - var token; - this.str = str; - this.pos = 0; - this.delimiters = options.delimiters; - this.tripleDelimiters = options.tripleDelimiters; - this.tokens = []; - while (this.pos < this.str.length) { - token = this.getToken(); - if (token === null && this.remaining()) { - this.fail(); - } - this.tokens.push(token); - } - }; - Tokenizer.prototype = { - getToken: function () { - var token = this.getMustache() || this.getComment() || this.getTag() || this.getText(); - return token; - }, - getMustache: getMustache, - getComment: getComment, - getTag: getTag, - getText: getText, - getExpression: getExpression, - allowWhitespace: allowWhitespace, - getStringMatch: getStringMatch, - remaining: function () { - return this.str.substring(this.pos); - }, - fail: function () { - var last20, next20; - last20 = this.str.substr(0, this.pos).substr(-20); - if (last20.length === 20) { - last20 = '...' + last20; - } - next20 = this.remaining().substr(0, 20); - if (next20.length === 20) { - next20 = next20 + '...'; - } - throw new Error('Could not parse template: ' + (last20 ? last20 + '<- ' : '') + 'failed at character ' + this.pos + ' ->' + next20); - }, - expected: function (thing) { - var remaining = this.remaining().substr(0, 40); - if (remaining.length === 40) { - remaining += '...'; - } - throw new Error('Tokenizer failed: unexpected string "' + remaining + '" (expected ' + thing + ')'); - } - }; - return Tokenizer; - }(parse_Tokenizer_getMustache__getMustache, parse_Tokenizer_getComment_getComment, parse_Tokenizer_getTag__getTag, parse_Tokenizer_getText__getText, parse_Tokenizer_getExpression__getExpression, parse_Tokenizer_utils_allowWhitespace, parse_Tokenizer_utils_getStringMatch); -var parse_tokenize = function (stripHtmlComments, stripStandalones, stripCommentTokens, Tokenizer, circular) { - - var tokenize, Ractive; - circular.push(function () { - Ractive = circular.Ractive; - }); - tokenize = function (template, options) { - var tokenizer, tokens; - options = options || {}; - if (options.stripComments !== false) { - template = stripHtmlComments(template); - } - tokenizer = new Tokenizer(template, { - delimiters: options.delimiters || (Ractive ? Ractive.delimiters : [ - '{{', - '}}' - ]), - tripleDelimiters: options.tripleDelimiters || (Ractive ? Ractive.tripleDelimiters : [ - '{{{', - '}}}' - ]) - }); - tokens = tokenizer.tokens; - stripStandalones(tokens); - stripCommentTokens(tokens); - return tokens; - }; - return tokenize; - }(parse_utils_stripHtmlComments, parse_utils_stripStandalones, parse_utils_stripCommentTokens, parse_Tokenizer__Tokenizer, circular); -var parse_Parser_getText_TextStub__TextStub = function (types) { - - var TextStub, htmlEntities, controlCharacters, namedEntityPattern, hexEntityPattern, decimalEntityPattern, validateCode, decodeCharacterReferences, whitespace; - TextStub = function (token, preserveWhitespace) { - this.text = preserveWhitespace ? token.value : token.value.replace(whitespace, ' '); - }; - TextStub.prototype = { - type: types.TEXT, - toJSON: function () { - return this.decoded || (this.decoded = decodeCharacterReferences(this.text)); - }, - toString: function () { - return this.text; - } - }; - htmlEntities = { - quot: 34, - amp: 38, - apos: 39, - lt: 60, - gt: 62, - nbsp: 160, - iexcl: 161, - cent: 162, - pound: 163, - curren: 164, - yen: 165, - brvbar: 166, - sect: 167, - uml: 168, - copy: 169, - ordf: 170, - laquo: 171, - not: 172, - shy: 173, - reg: 174, - macr: 175, - deg: 176, - plusmn: 177, - sup2: 178, - sup3: 179, - acute: 180, - micro: 181, - para: 182, - middot: 183, - cedil: 184, - sup1: 185, - ordm: 186, - raquo: 187, - frac14: 188, - frac12: 189, - frac34: 190, - iquest: 191, - Agrave: 192, - Aacute: 193, - Acirc: 194, - Atilde: 195, - Auml: 196, - Aring: 197, - AElig: 198, - Ccedil: 199, - Egrave: 200, - Eacute: 201, - Ecirc: 202, - Euml: 203, - Igrave: 204, - Iacute: 205, - Icirc: 206, - Iuml: 207, - ETH: 208, - Ntilde: 209, - Ograve: 210, - Oacute: 211, - Ocirc: 212, - Otilde: 213, - Ouml: 214, - times: 215, - Oslash: 216, - Ugrave: 217, - Uacute: 218, - Ucirc: 219, - Uuml: 220, - Yacute: 221, - THORN: 222, - szlig: 223, - agrave: 224, - aacute: 225, - acirc: 226, - atilde: 227, - auml: 228, - aring: 229, - aelig: 230, - ccedil: 231, - egrave: 232, - eacute: 233, - ecirc: 234, - euml: 235, - igrave: 236, - iacute: 237, - icirc: 238, - iuml: 239, - eth: 240, - ntilde: 241, - ograve: 242, - oacute: 243, - ocirc: 244, - otilde: 245, - ouml: 246, - divide: 247, - oslash: 248, - ugrave: 249, - uacute: 250, - ucirc: 251, - uuml: 252, - yacute: 253, - thorn: 254, - yuml: 255, - OElig: 338, - oelig: 339, - Scaron: 352, - scaron: 353, - Yuml: 376, - fnof: 402, - circ: 710, - tilde: 732, - Alpha: 913, - Beta: 914, - Gamma: 915, - Delta: 916, - Epsilon: 917, - Zeta: 918, - Eta: 919, - Theta: 920, - Iota: 921, - Kappa: 922, - Lambda: 923, - Mu: 924, - Nu: 925, - Xi: 926, - Omicron: 927, - Pi: 928, - Rho: 929, - Sigma: 931, - Tau: 932, - Upsilon: 933, - Phi: 934, - Chi: 935, - Psi: 936, - Omega: 937, - alpha: 945, - beta: 946, - gamma: 947, - delta: 948, - epsilon: 949, - zeta: 950, - eta: 951, - theta: 952, - iota: 953, - kappa: 954, - lambda: 955, - mu: 956, - nu: 957, - xi: 958, - omicron: 959, - pi: 960, - rho: 961, - sigmaf: 962, - sigma: 963, - tau: 964, - upsilon: 965, - phi: 966, - chi: 967, - psi: 968, - omega: 969, - thetasym: 977, - upsih: 978, - piv: 982, - ensp: 8194, - emsp: 8195, - thinsp: 8201, - zwnj: 8204, - zwj: 8205, - lrm: 8206, - rlm: 8207, - ndash: 8211, - mdash: 8212, - lsquo: 8216, - rsquo: 8217, - sbquo: 8218, - ldquo: 8220, - rdquo: 8221, - bdquo: 8222, - dagger: 8224, - Dagger: 8225, - bull: 8226, - hellip: 8230, - permil: 8240, - prime: 8242, - Prime: 8243, - lsaquo: 8249, - rsaquo: 8250, - oline: 8254, - frasl: 8260, - euro: 8364, - image: 8465, - weierp: 8472, - real: 8476, - trade: 8482, - alefsym: 8501, - larr: 8592, - uarr: 8593, - rarr: 8594, - darr: 8595, - harr: 8596, - crarr: 8629, - lArr: 8656, - uArr: 8657, - rArr: 8658, - dArr: 8659, - hArr: 8660, - forall: 8704, - part: 8706, - exist: 8707, - empty: 8709, - nabla: 8711, - isin: 8712, - notin: 8713, - ni: 8715, - prod: 8719, - sum: 8721, - minus: 8722, - lowast: 8727, - radic: 8730, - prop: 8733, - infin: 8734, - ang: 8736, - and: 8743, - or: 8744, - cap: 8745, - cup: 8746, - 'int': 8747, - there4: 8756, - sim: 8764, - cong: 8773, - asymp: 8776, - ne: 8800, - equiv: 8801, - le: 8804, - ge: 8805, - sub: 8834, - sup: 8835, - nsub: 8836, - sube: 8838, - supe: 8839, - oplus: 8853, - otimes: 8855, - perp: 8869, - sdot: 8901, - lceil: 8968, - rceil: 8969, - lfloor: 8970, - rfloor: 8971, - lang: 9001, - rang: 9002, - loz: 9674, - spades: 9824, - clubs: 9827, - hearts: 9829, - diams: 9830 - }; - controlCharacters = [ - 8364, - 129, - 8218, - 402, - 8222, - 8230, - 8224, - 8225, - 710, - 8240, - 352, - 8249, - 338, - 141, - 381, - 143, - 144, - 8216, - 8217, - 8220, - 8221, - 8226, - 8211, - 8212, - 732, - 8482, - 353, - 8250, - 339, - 157, - 382, - 376 - ]; - namedEntityPattern = new RegExp('&(' + Object.keys(htmlEntities).join('|') + ');?', 'g'); - hexEntityPattern = /&#x([0-9]+);?/g; - decimalEntityPattern = /&#([0-9]+);?/g; - validateCode = function (code) { - if (!code) { - return 65533; - } - if (code === 10) { - return 32; - } - if (code < 128) { - return code; - } - if (code <= 159) { - return controlCharacters[code - 128]; - } - if (code < 55296) { - return code; - } - if (code <= 57343) { - return 65533; - } - if (code <= 65535) { - return code; - } - return 65533; - }; - decodeCharacterReferences = function (html) { - var result; - result = html.replace(namedEntityPattern, function (match, name) { - if (htmlEntities[name]) { - return String.fromCharCode(htmlEntities[name]); - } - return match; - }); - result = result.replace(hexEntityPattern, function (match, hex) { - return String.fromCharCode(validateCode(parseInt(hex, 16))); - }); - result = result.replace(decimalEntityPattern, function (match, charCode) { - return String.fromCharCode(validateCode(charCode)); - }); - return result; - }; - whitespace = /\s+/g; - return TextStub; - }(config_types); -var parse_Parser_getText__getText = function (types, TextStub) { - - return function (token) { - if (token.type === types.TEXT) { - this.pos += 1; - return new TextStub(token, this.preserveWhitespace); - } - return null; - }; - }(config_types, parse_Parser_getText_TextStub__TextStub); -var parse_Parser_getComment_CommentStub__CommentStub = function (types) { - - var CommentStub; - CommentStub = function (token) { - this.content = token.content; - }; - CommentStub.prototype = { - toJSON: function () { - return { - t: types.COMMENT, - f: this.content - }; - }, - toString: function () { - return ''; - } - }; - return CommentStub; - }(config_types); -var parse_Parser_getComment__getComment = function (types, CommentStub) { - - return function (token) { - if (token.type === types.COMMENT) { - this.pos += 1; - return new CommentStub(token, this.preserveWhitespace); - } - return null; - }; - }(config_types, parse_Parser_getComment_CommentStub__CommentStub); -var parse_Parser_getMustache_ExpressionStub__ExpressionStub = function (types, isObject) { - - var ExpressionStub, getRefs, stringify; - ExpressionStub = function (token) { - this.refs = []; - getRefs(token, this.refs); - this.str = stringify(token, this.refs); - }; - ExpressionStub.prototype = { - toJSON: function () { - if (this.json) { - return this.json; - } - this.json = { - r: this.refs, - s: this.str - }; - return this.json; - } - }; - getRefs = function (token, refs) { - var i, list; - if (token.t === types.REFERENCE) { - if (refs.indexOf(token.n) === -1) { - refs.unshift(token.n); - } - } - list = token.o || token.m; - if (list) { - if (isObject(list)) { - getRefs(list, refs); - } else { - i = list.length; - while (i--) { - getRefs(list[i], refs); - } - } - } - if (token.x) { - getRefs(token.x, refs); - } - if (token.r) { - getRefs(token.r, refs); - } - if (token.v) { - getRefs(token.v, refs); - } - }; - stringify = function (token, refs) { - var map = function (item) { - return stringify(item, refs); - }; - switch (token.t) { - case types.BOOLEAN_LITERAL: - case types.GLOBAL: - case types.NUMBER_LITERAL: - return token.v; - case types.STRING_LITERAL: - return '\'' + token.v.replace(/'/g, '\\\'') + '\''; - case types.ARRAY_LITERAL: - return '[' + (token.m ? token.m.map(map).join(',') : '') + ']'; - case types.OBJECT_LITERAL: - return '{' + (token.m ? token.m.map(map).join(',') : '') + '}'; - case types.KEY_VALUE_PAIR: - return token.k + ':' + stringify(token.v, refs); - case types.PREFIX_OPERATOR: - return (token.s === 'typeof' ? 'typeof ' : token.s) + stringify(token.o, refs); - case types.INFIX_OPERATOR: - return stringify(token.o[0], refs) + (token.s.substr(0, 2) === 'in' ? ' ' + token.s + ' ' : token.s) + stringify(token.o[1], refs); - case types.INVOCATION: - return stringify(token.x, refs) + '(' + (token.o ? token.o.map(map).join(',') : '') + ')'; - case types.BRACKETED: - return '(' + stringify(token.x, refs) + ')'; - case types.MEMBER: - return stringify(token.x, refs) + stringify(token.r, refs); - case types.REFINEMENT: - return token.n ? '.' + token.n : '[' + stringify(token.x, refs) + ']'; - case types.CONDITIONAL: - return stringify(token.o[0], refs) + '?' + stringify(token.o[1], refs) + ':' + stringify(token.o[2], refs); - case types.REFERENCE: - return '${' + refs.indexOf(token.n) + '}'; - default: - throw new Error('Could not stringify expression token. This error is unexpected'); - } - }; - return ExpressionStub; - }(config_types, utils_isObject); -var parse_Parser_getMustache_MustacheStub__MustacheStub = function (types, ExpressionStub) { - - var MustacheStub = function (token, parser) { - this.type = token.type === types.TRIPLE ? types.TRIPLE : token.mustacheType; - if (token.ref) { - this.ref = token.ref; - } - if (token.expression) { - this.expr = new ExpressionStub(token.expression); - } - parser.pos += 1; - }; - MustacheStub.prototype = { - toJSON: function () { - var json; - if (this.json) { - return this.json; - } - json = { t: this.type }; - if (this.ref) { - json.r = this.ref; - } - if (this.expr) { - json.x = this.expr.toJSON(); - } - this.json = json; - return json; - }, - toString: function () { - return false; - } - }; - return MustacheStub; - }(config_types, parse_Parser_getMustache_ExpressionStub__ExpressionStub); -var parse_Parser_utils_stringifyStubs = function () { - - return function (items) { - var str = '', itemStr, i, len; - if (!items) { - return ''; - } - for (i = 0, len = items.length; i < len; i += 1) { - itemStr = items[i].toString(); - if (itemStr === false) { - return false; - } - str += itemStr; - } - return str; - }; - }(); -var parse_Parser_utils_jsonifyStubs = function (stringifyStubs) { - - return function (items, noStringify) { - var str, json; - if (!noStringify) { - str = stringifyStubs(items); - if (str !== false) { - return str; - } - } - json = items.map(function (item) { - return item.toJSON(noStringify); - }); - return json; - }; - }(parse_Parser_utils_stringifyStubs); -var parse_Parser_getMustache_SectionStub__SectionStub = function (types, jsonifyStubs, ExpressionStub) { - - var SectionStub = function (firstToken, parser) { - var next; - this.ref = firstToken.ref; - this.indexRef = firstToken.indexRef; - this.inverted = firstToken.mustacheType === types.INVERTED; - if (firstToken.expression) { - this.expr = new ExpressionStub(firstToken.expression); - } - parser.pos += 1; - this.items = []; - next = parser.next(); - while (next) { - if (next.mustacheType === types.CLOSING) { - if (next.ref.trim() === this.ref || this.expr) { - parser.pos += 1; - break; - } else { - throw new Error('Could not parse template: Illegal closing section'); - } - } - this.items[this.items.length] = parser.getStub(); - next = parser.next(); - } - }; - SectionStub.prototype = { - toJSON: function (noStringify) { - var json; - if (this.json) { - return this.json; - } - json = { t: types.SECTION }; - if (this.ref) { - json.r = this.ref; - } - if (this.indexRef) { - json.i = this.indexRef; - } - if (this.inverted) { - json.n = true; - } - if (this.expr) { - json.x = this.expr.toJSON(); - } - if (this.items.length) { - json.f = jsonifyStubs(this.items, noStringify); - } - this.json = json; - return json; - }, - toString: function () { - return false; - } - }; - return SectionStub; - }(config_types, parse_Parser_utils_jsonifyStubs, parse_Parser_getMustache_ExpressionStub__ExpressionStub); -var parse_Parser_getMustache__getMustache = function (types, MustacheStub, SectionStub) { - - return function (token) { - if (token.type === types.MUSTACHE || token.type === types.TRIPLE) { - if (token.mustacheType === types.SECTION || token.mustacheType === types.INVERTED) { - return new SectionStub(token, this); - } - return new MustacheStub(token, this); - } - }; - }(config_types, parse_Parser_getMustache_MustacheStub__MustacheStub, parse_Parser_getMustache_SectionStub__SectionStub); -var parse_Parser_getElement_ElementStub_utils_siblingsByTagName = function () { - - return { - li: ['li'], - dt: [ - 'dt', - 'dd' - ], - dd: [ - 'dt', - 'dd' - ], - p: 'address article aside blockquote dir div dl fieldset footer form h1 h2 h3 h4 h5 h6 header hgroup hr menu nav ol p pre section table ul'.split(' '), - rt: [ - 'rt', - 'rp' - ], - rp: [ - 'rp', - 'rt' - ], - optgroup: ['optgroup'], - option: [ - 'option', - 'optgroup' - ], - thead: [ - 'tbody', - 'tfoot' - ], - tbody: [ - 'tbody', - 'tfoot' - ], - tr: ['tr'], - td: [ - 'td', - 'th' - ], - th: [ - 'td', - 'th' - ] - }; - }(); -var parse_Parser_getElement_ElementStub_utils_filterAttributes = function (isArray) { - - return function (items) { - var attrs, proxies, filtered, i, len, item; - filtered = {}; - attrs = []; - proxies = []; - len = items.length; - for (i = 0; i < len; i += 1) { - item = items[i]; - if (item.name === 'intro') { - if (filtered.intro) { - throw new Error('An element can only have one intro transition'); - } - filtered.intro = item; - } else if (item.name === 'outro') { - if (filtered.outro) { - throw new Error('An element can only have one outro transition'); - } - filtered.outro = item; - } else if (item.name === 'intro-outro') { - if (filtered.intro || filtered.outro) { - throw new Error('An element can only have one intro and one outro transition'); - } - filtered.intro = item; - filtered.outro = deepClone(item); - } else if (item.name.substr(0, 6) === 'proxy-') { - item.name = item.name.substring(6); - proxies[proxies.length] = item; - } else if (item.name.substr(0, 3) === 'on-') { - item.name = item.name.substring(3); - proxies[proxies.length] = item; - } else if (item.name === 'decorator') { - filtered.decorator = item; - } else { - attrs[attrs.length] = item; - } - } - filtered.attrs = attrs; - filtered.proxies = proxies; - return filtered; - }; - function deepClone(obj) { - var result, key; - if (typeof obj !== 'object') { - return obj; - } - if (isArray(obj)) { - return obj.map(deepClone); - } - result = {}; - for (key in obj) { - if (obj.hasOwnProperty(key)) { - result[key] = deepClone(obj[key]); - } - } - return result; - } - }(utils_isArray); -var parse_Parser_getElement_ElementStub_utils_processDirective = function (types, parseJSON) { - - return function (directive) { - var processed, tokens, token, colonIndex, throwError, directiveName, directiveArgs, parsed; - throwError = function () { - throw new Error('Illegal directive'); - }; - if (!directive.name || !directive.value) { - throwError(); - } - processed = { directiveType: directive.name }; - tokens = directive.value; - directiveName = []; - directiveArgs = []; - while (tokens.length) { - token = tokens.shift(); - if (token.type === types.TEXT) { - colonIndex = token.value.indexOf(':'); - if (colonIndex === -1) { - directiveName[directiveName.length] = token; - } else { - if (colonIndex) { - directiveName[directiveName.length] = { - type: types.TEXT, - value: token.value.substr(0, colonIndex) - }; - } - if (token.value.length > colonIndex + 1) { - directiveArgs[0] = { - type: types.TEXT, - value: token.value.substring(colonIndex + 1) - }; - } - break; - } - } else { - directiveName[directiveName.length] = token; - } - } - directiveArgs = directiveArgs.concat(tokens); - if (directiveName.length === 1 && directiveName[0].type === types.TEXT) { - processed.name = directiveName[0].value; - } else { - processed.name = directiveName; - } - if (directiveArgs.length) { - if (directiveArgs.length === 1 && directiveArgs[0].type === types.TEXT) { - parsed = parseJSON('[' + directiveArgs[0].value + ']'); - processed.args = parsed ? parsed.value : directiveArgs[0].value; - } else { - processed.dynamicArgs = directiveArgs; - } - } - return processed; - }; - }(config_types, utils_parseJSON); -var parse_Parser_StringStub_StringParser = function (getText, getMustache) { - - var StringParser; - StringParser = function (tokens, options) { - var stub; - this.tokens = tokens || []; - this.pos = 0; - this.options = options; - this.result = []; - while (stub = this.getStub()) { - this.result.push(stub); - } - }; - StringParser.prototype = { - getStub: function () { - var token = this.next(); - if (!token) { - return null; - } - return this.getText(token) || this.getMustache(token); - }, - getText: getText, - getMustache: getMustache, - next: function () { - return this.tokens[this.pos]; - } - }; - return StringParser; - }(parse_Parser_getText__getText, parse_Parser_getMustache__getMustache); -var parse_Parser_StringStub__StringStub = function (StringParser, stringifyStubs, jsonifyStubs) { - - var StringStub; - StringStub = function (tokens) { - var parser = new StringParser(tokens); - this.stubs = parser.result; - }; - StringStub.prototype = { - toJSON: function (noStringify) { - var json; - if (this['json_' + noStringify]) { - return this['json_' + noStringify]; - } - json = this['json_' + noStringify] = jsonifyStubs(this.stubs, noStringify); - return json; - }, - toString: function () { - if (this.str !== undefined) { - return this.str; - } - this.str = stringifyStubs(this.stubs); - return this.str; - } - }; - return StringStub; - }(parse_Parser_StringStub_StringParser, parse_Parser_utils_stringifyStubs, parse_Parser_utils_jsonifyStubs); -var parse_Parser_getElement_ElementStub_utils_jsonifyDirective = function (StringStub) { - - return function (directive) { - var result, name; - if (typeof directive.name === 'string') { - if (!directive.args && !directive.dynamicArgs) { - return directive.name; - } - name = directive.name; - } else { - name = new StringStub(directive.name).toJSON(); - } - result = { n: name }; - if (directive.args) { - result.a = directive.args; - return result; - } - if (directive.dynamicArgs) { - result.d = new StringStub(directive.dynamicArgs).toJSON(); - } - return result; - }; - }(parse_Parser_StringStub__StringStub); -var parse_Parser_getElement_ElementStub_toJSON = function (types, jsonifyStubs, jsonifyDirective) { - - return function (noStringify) { - var json, name, value, proxy, i, len, attribute; - if (this['json_' + noStringify]) { - return this['json_' + noStringify]; - } - if (this.component) { - json = { - t: types.COMPONENT, - e: this.component - }; - } else { - json = { - t: types.ELEMENT, - e: this.tag - }; - } - if (this.doctype) { - json.y = 1; - } - if (this.attributes && this.attributes.length) { - json.a = {}; - len = this.attributes.length; - for (i = 0; i < len; i += 1) { - attribute = this.attributes[i]; - name = attribute.name; - if (json.a[name]) { - throw new Error('You cannot have multiple attributes with the same name'); - } - if (attribute.value === null) { - value = null; - } else { - value = attribute.value.toJSON(noStringify); - } - json.a[name] = value; - } - } - if (this.items && this.items.length) { - json.f = jsonifyStubs(this.items, noStringify); - } - if (this.proxies && this.proxies.length) { - json.v = {}; - len = this.proxies.length; - for (i = 0; i < len; i += 1) { - proxy = this.proxies[i]; - json.v[proxy.directiveType] = jsonifyDirective(proxy); - } - } - if (this.intro) { - json.t1 = jsonifyDirective(this.intro); - } - if (this.outro) { - json.t2 = jsonifyDirective(this.outro); - } - if (this.decorator) { - json.o = jsonifyDirective(this.decorator); - } - this['json_' + noStringify] = json; - return json; - }; - }(config_types, parse_Parser_utils_jsonifyStubs, parse_Parser_getElement_ElementStub_utils_jsonifyDirective); -var parse_Parser_getElement_ElementStub_toString = function (stringifyStubs, voidElementNames) { - - var htmlElements; - htmlElements = 'a abbr acronym address applet area b base basefont bdo big blockquote body br button caption center cite code col colgroup dd del dfn dir div dl dt em fieldset font form frame frameset h1 h2 h3 h4 h5 h6 head hr html i iframe img input ins isindex kbd label legend li link map menu meta noframes noscript object ol p param pre q s samp script select small span strike strong style sub sup textarea title tt u ul var article aside audio bdi canvas command data datagrid datalist details embed eventsource figcaption figure footer header hgroup keygen mark meter nav output progress ruby rp rt section source summary time track video wbr'.split(' '); - return function () { - var str, i, len, attrStr, name, attrValueStr, fragStr, isVoid; - if (this.str !== undefined) { - return this.str; - } - if (this.component) { - return this.str = false; - } - if (htmlElements.indexOf(this.tag.toLowerCase()) === -1) { - return this.str = false; - } - if (this.proxies || this.intro || this.outro || this.decorator) { - return this.str = false; - } - fragStr = stringifyStubs(this.items); - if (fragStr === false) { - return this.str = false; - } - isVoid = voidElementNames.indexOf(this.tag.toLowerCase()) !== -1; - str = '<' + this.tag; - if (this.attributes) { - for (i = 0, len = this.attributes.length; i < len; i += 1) { - name = this.attributes[i].name; - if (name.indexOf(':') !== -1) { - return this.str = false; - } - if (name === 'id' || name === 'intro' || name === 'outro') { - return this.str = false; - } - attrStr = ' ' + name; - if (this.attributes[i].value !== null) { - attrValueStr = this.attributes[i].value.toString(); - if (attrValueStr === false) { - return this.str = false; - } - if (attrValueStr !== '') { - attrStr += '='; - if (/[\s"'=<>`]/.test(attrValueStr)) { - attrStr += '"' + attrValueStr.replace(/"/g, '"') + '"'; - } else { - attrStr += attrValueStr; - } - } - } - str += attrStr; - } - } - if (this.selfClosing && !isVoid) { - str += '/>'; - return this.str = str; - } - str += '>'; - if (isVoid) { - return this.str = str; - } - str += fragStr; - str += ''; - return this.str = str; - }; - }(parse_Parser_utils_stringifyStubs, config_voidElementNames); -var parse_Parser_getElement_ElementStub__ElementStub = function (types, voidElementNames, warn, camelCase, stringifyStubs, siblingsByTagName, filterAttributes, processDirective, toJSON, toString, StringStub) { - - var ElementStub, allElementNames, closedByParentClose, onPattern, sanitize, leadingWhitespace = /^\s+/, trailingWhitespace = /\s+$/; - ElementStub = function (firstToken, parser, preserveWhitespace) { - var next, attrs, filtered, proxies, item, getFrag, lowerCaseTag; - parser.pos += 1; - getFrag = function (attr) { - return { - name: attr.name, - value: attr.value ? new StringStub(attr.value) : null - }; - }; - this.tag = firstToken.name; - lowerCaseTag = firstToken.name.toLowerCase(); - if (lowerCaseTag.substr(0, 3) === 'rv-') { - warn('The "rv-" prefix for components has been deprecated. Support will be removed in a future version'); - this.tag = this.tag.substring(3); - } - preserveWhitespace = preserveWhitespace || lowerCaseTag === 'pre'; - if (firstToken.attrs) { - filtered = filterAttributes(firstToken.attrs); - attrs = filtered.attrs; - proxies = filtered.proxies; - if (parser.options.sanitize && parser.options.sanitize.eventAttributes) { - attrs = attrs.filter(sanitize); - } - if (attrs.length) { - this.attributes = attrs.map(getFrag); - } - if (proxies.length) { - this.proxies = proxies.map(processDirective); - } - if (filtered.intro) { - this.intro = processDirective(filtered.intro); - } - if (filtered.outro) { - this.outro = processDirective(filtered.outro); - } - if (filtered.decorator) { - this.decorator = processDirective(filtered.decorator); - } - } - if (firstToken.doctype) { - this.doctype = true; - } - if (firstToken.selfClosing) { - this.selfClosing = true; - } - if (voidElementNames.indexOf(lowerCaseTag) !== -1) { - this.isVoid = true; - } - if (this.selfClosing || this.isVoid) { - return; - } - this.siblings = siblingsByTagName[lowerCaseTag]; - this.items = []; - next = parser.next(); - while (next) { - if (next.mustacheType === types.CLOSING) { - break; - } - if (next.type === types.TAG) { - if (next.closing) { - if (next.name.toLowerCase() === lowerCaseTag) { - parser.pos += 1; - } - break; - } else if (this.siblings && this.siblings.indexOf(next.name.toLowerCase()) !== -1) { - break; - } - } - this.items[this.items.length] = parser.getStub(); - next = parser.next(); - } - if (!preserveWhitespace) { - item = this.items[0]; - if (item && item.type === types.TEXT) { - item.text = item.text.replace(leadingWhitespace, ''); - if (!item.text) { - this.items.shift(); - } - } - item = this.items[this.items.length - 1]; - if (item && item.type === types.TEXT) { - item.text = item.text.replace(trailingWhitespace, ''); - if (!item.text) { - this.items.pop(); - } - } - } - }; - ElementStub.prototype = { - toJSON: toJSON, - toString: toString - }; - allElementNames = 'a abbr acronym address applet area b base basefont bdo big blockquote body br button caption center cite code col colgroup dd del dfn dir div dl dt em fieldset font form frame frameset h1 h2 h3 h4 h5 h6 head hr html i iframe img input ins isindex kbd label legend li link map menu meta noframes noscript object ol p param pre q s samp script select small span strike strong style sub sup textarea title tt u ul var article aside audio bdi canvas command data datagrid datalist details embed eventsource figcaption figure footer header hgroup keygen mark meter nav output progress ruby rp rt section source summary time track video wbr'.split(' '); - closedByParentClose = 'li dd rt rp optgroup option tbody tfoot tr td th'.split(' '); - onPattern = /^on[a-zA-Z]/; - sanitize = function (attr) { - var valid = !onPattern.test(attr.name); - return valid; - }; - return ElementStub; - }(config_types, config_voidElementNames, utils_warn, utils_camelCase, parse_Parser_utils_stringifyStubs, parse_Parser_getElement_ElementStub_utils_siblingsByTagName, parse_Parser_getElement_ElementStub_utils_filterAttributes, parse_Parser_getElement_ElementStub_utils_processDirective, parse_Parser_getElement_ElementStub_toJSON, parse_Parser_getElement_ElementStub_toString, parse_Parser_StringStub__StringStub); -var parse_Parser_getElement__getElement = function (types, ElementStub) { - - return function (token) { - if (this.options.sanitize && this.options.sanitize.elements) { - if (this.options.sanitize.elements.indexOf(token.name.toLowerCase()) !== -1) { - return null; - } - } - return new ElementStub(token, this); - }; - }(config_types, parse_Parser_getElement_ElementStub__ElementStub); -var parse_Parser__Parser = function (getText, getComment, getMustache, getElement, jsonifyStubs) { - - var Parser; - Parser = function (tokens, options) { - var stub, stubs; - this.tokens = tokens || []; - this.pos = 0; - this.options = options; - this.preserveWhitespace = options.preserveWhitespace; - stubs = []; - while (stub = this.getStub()) { - stubs.push(stub); - } - this.result = jsonifyStubs(stubs); - }; - Parser.prototype = { - getStub: function () { - var token = this.next(); - if (!token) { - return null; - } - return this.getText(token) || this.getComment(token) || this.getMustache(token) || this.getElement(token); - }, - getText: getText, - getComment: getComment, - getMustache: getMustache, - getElement: getElement, - next: function () { - return this.tokens[this.pos]; - } - }; - return Parser; - }(parse_Parser_getText__getText, parse_Parser_getComment__getComment, parse_Parser_getMustache__getMustache, parse_Parser_getElement__getElement, parse_Parser_utils_jsonifyStubs); -var parse__parse = function (tokenize, types, Parser) { - - var parse, onlyWhitespace, inlinePartialStart, inlinePartialEnd, parseCompoundTemplate; - onlyWhitespace = /^\s*$/; - inlinePartialStart = //; - inlinePartialEnd = //; - parse = function (template, options) { - var tokens, json, token; - options = options || {}; - if (inlinePartialStart.test(template)) { - return parseCompoundTemplate(template, options); - } - if (options.sanitize === true) { - options.sanitize = { - elements: 'applet base basefont body frame frameset head html isindex link meta noframes noscript object param script style title'.split(' '), - eventAttributes: true - }; - } - tokens = tokenize(template, options); - if (!options.preserveWhitespace) { - token = tokens[0]; - if (token && token.type === types.TEXT && onlyWhitespace.test(token.value)) { - tokens.shift(); - } - token = tokens[tokens.length - 1]; - if (token && token.type === types.TEXT && onlyWhitespace.test(token.value)) { - tokens.pop(); - } - } - json = new Parser(tokens, options).result; - if (typeof json === 'string') { - return [json]; - } - return json; - }; - parseCompoundTemplate = function (template, options) { - var mainTemplate, remaining, partials, name, startMatch, endMatch; - partials = {}; - mainTemplate = ''; - remaining = template; - while (startMatch = inlinePartialStart.exec(remaining)) { - name = startMatch[1]; - mainTemplate += remaining.substr(0, startMatch.index); - remaining = remaining.substring(startMatch.index + startMatch[0].length); - endMatch = inlinePartialEnd.exec(remaining); - if (!endMatch || endMatch[1] !== name) { - throw new Error('Inline partials must have a closing delimiter, and cannot be nested'); - } - partials[name] = parse(remaining.substr(0, endMatch.index), options); - remaining = remaining.substring(endMatch.index + endMatch[0].length); - } - return { - main: parse(mainTemplate, options), - partials: partials - }; - }; - return parse; - }(parse_tokenize, config_types, parse_Parser__Parser); -var render_DomFragment_Partial_getPartialDescriptor = function (errors, isClient, warn, isObject, partials, parse) { - - var getPartialDescriptor, registerPartial, getPartialFromRegistry, unpack; - getPartialDescriptor = function (root, name) { - var el, partial, errorMessage; - if (partial = getPartialFromRegistry(root, name)) { - return partial; - } - if (isClient) { - el = document.getElementById(name); - if (el && el.tagName === 'SCRIPT') { - if (!parse) { - throw new Error(errors.missingParser); - } - registerPartial(parse(el.innerHTML), name, partials); - } - } - partial = partials[name]; - if (!partial) { - errorMessage = 'Could not find descriptor for partial "' + name + '"'; - if (root.debug) { - throw new Error(errorMessage); - } else { - warn(errorMessage); - } - return []; - } - return unpack(partial); - }; - getPartialFromRegistry = function (registryOwner, name) { - var partial; - if (registryOwner.partials[name]) { - if (typeof registryOwner.partials[name] === 'string') { - if (!parse) { - throw new Error(errors.missingParser); - } - partial = parse(registryOwner.partials[name], registryOwner.parseOptions); - registerPartial(partial, name, registryOwner.partials); - } - return unpack(registryOwner.partials[name]); - } - }; - registerPartial = function (partial, name, registry) { - var key; - if (isObject(partial)) { - registry[name] = partial.main; - for (key in partial.partials) { - if (partial.partials.hasOwnProperty(key)) { - registry[key] = partial.partials[key]; - } - } - } else { - registry[name] = partial; - } - }; - unpack = function (partial) { - if (partial.length === 1 && typeof partial[0] === 'string') { - return partial[0]; - } - return partial; - }; - return getPartialDescriptor; - }(config_errors, config_isClient, utils_warn, utils_isObject, registries_partials, parse__parse); -var render_DomFragment_Partial__Partial = function (types, getPartialDescriptor, circular) { - - var DomPartial, DomFragment; - circular.push(function () { - DomFragment = circular.DomFragment; - }); - DomPartial = function (options, docFrag) { - var parentFragment = this.parentFragment = options.parentFragment, descriptor; - this.type = types.PARTIAL; - this.name = options.descriptor.r; - this.index = options.index; - if (!options.descriptor.r) { - throw new Error('Partials must have a static reference (no expressions). This may change in a future version of Ractive.'); - } - descriptor = getPartialDescriptor(parentFragment.root, options.descriptor.r); - this.fragment = new DomFragment({ - descriptor: descriptor, - root: parentFragment.root, - pNode: parentFragment.pNode, - contextStack: parentFragment.contextStack, - owner: this - }); - if (docFrag) { - docFrag.appendChild(this.fragment.docFrag); - } - }; - DomPartial.prototype = { - firstNode: function () { - return this.fragment.firstNode(); - }, - findNextNode: function () { - return this.parentFragment.findNextNode(this); - }, - detach: function () { - return this.fragment.detach(); - }, - teardown: function (destroy) { - this.fragment.teardown(destroy); - }, - toString: function () { - return this.fragment.toString(); - }, - find: function (selector) { - return this.fragment.find(selector); - }, - findAll: function (selector, query) { - return this.fragment.findAll(selector, query); - }, - findComponent: function (selector) { - return this.fragment.findComponent(selector); - }, - findAllComponents: function (selector, query) { - return this.fragment.findAllComponents(selector, query); - } - }; - return DomPartial; - }(config_types, render_DomFragment_Partial_getPartialDescriptor, circular); -var render_DomFragment_Component_initialise_createModel_ComponentParameter = function (StringFragment) { - - var ComponentParameter = function (component, key, value) { - this.parentFragment = component.parentFragment; - this.component = component; - this.key = key; - this.fragment = new StringFragment({ - descriptor: value, - root: component.root, - owner: this, - contextStack: component.parentFragment.contextStack - }); - this.selfUpdating = this.fragment.isSimple(); - this.value = this.fragment.getValue(); - }; - ComponentParameter.prototype = { - bubble: function () { - if (this.selfUpdating) { - this.update(); - } else if (!this.deferred && this.ready) { - this.root._deferred.attrs.push(this); - this.deferred = true; - } - }, - update: function () { - var value = this.fragment.getValue(); - this.component.instance.set(this.key, value); - this.value = value; - }, - teardown: function () { - this.fragment.teardown(); - } - }; - return ComponentParameter; - }(render_StringFragment__StringFragment); -var render_DomFragment_Component_initialise_createModel__createModel = function (types, parseJSON, resolveRef, ComponentParameter) { - - return function (component, attributes, toBind) { - var data, key, value; - data = {}; - component.complexParameters = []; - for (key in attributes) { - if (attributes.hasOwnProperty(key)) { - value = getValue(component, key, attributes[key], toBind); - if (value !== undefined) { - data[key] = value; - } - } - } - return data; - }; - function getValue(component, key, descriptor, toBind) { - var parameter, parsed, root, parentFragment, keypath; - root = component.root; - parentFragment = component.parentFragment; - if (typeof descriptor === 'string') { - parsed = parseJSON(descriptor); - return parsed ? parsed.value : descriptor; - } - if (descriptor === null) { - return true; - } - if (descriptor.length === 1 && descriptor[0].t === types.INTERPOLATOR && descriptor[0].r) { - if (parentFragment.indexRefs && parentFragment.indexRefs[descriptor[0].r] !== undefined) { - return parentFragment.indexRefs[descriptor[0].r]; - } - keypath = resolveRef(root, descriptor[0].r, parentFragment.contextStack) || descriptor[0].r; - toBind.push({ - childKeypath: key, - parentKeypath: keypath - }); - return root.get(keypath); - } - parameter = new ComponentParameter(component, key, descriptor); - component.complexParameters.push(parameter); - return parameter.value; - } - }(config_types, utils_parseJSON, shared_resolveRef, render_DomFragment_Component_initialise_createModel_ComponentParameter); -var render_DomFragment_Component_initialise_createInstance = function () { - - return function (component, Component, data, docFrag, contentDescriptor) { - var instance, parentFragment, partials, root; - parentFragment = component.parentFragment; - root = component.root; - partials = { content: contentDescriptor || [] }; - instance = new Component({ - el: parentFragment.pNode.cloneNode(false), - data: data, - partials: partials, - _parent: root, - adaptors: root.adaptors - }); - instance.component = component; - component.instance = instance; - instance.insert(docFrag); - instance.fragment.pNode = parentFragment.pNode; - return instance; - }; - }(); -var render_DomFragment_Component_initialise_createObservers = function () { - - var observeOptions = { - init: false, - debug: true - }; - return function (component, toBind) { - var pair, i; - component.observers = []; - i = toBind.length; - while (i--) { - pair = toBind[i]; - bind(component, pair.parentKeypath, pair.childKeypath); - } - }; - function bind(component, parentKeypath, childKeypath) { - var parentInstance, childInstance, settingParent, settingChild, observers, observer, value; - parentInstance = component.root; - childInstance = component.instance; - observers = component.observers; - observer = parentInstance.observe(parentKeypath, function (value) { - if (!settingParent && !parentInstance._wrapped[parentKeypath]) { - settingChild = true; - childInstance.set(childKeypath, value); - settingChild = false; - } - }, observeOptions); - observers.push(observer); - if (childInstance.twoway) { - observer = childInstance.observe(childKeypath, function (value) { - if (!settingChild) { - settingParent = true; - parentInstance.set(parentKeypath, value); - settingParent = false; - } - }, observeOptions); - observers.push(observer); - value = childInstance.get(childKeypath); - if (value !== undefined) { - parentInstance.set(parentKeypath, value); - } - } - } - }(); -var render_DomFragment_Component_initialise_propagateEvents = function (warn) { - - var errorMessage = 'Components currently only support simple events - you cannot include arguments. Sorry!'; - return function (component, eventsDescriptor) { - var eventName; - for (eventName in eventsDescriptor) { - if (eventsDescriptor.hasOwnProperty(eventName)) { - propagateEvent(component.instance, component.root, eventName, eventsDescriptor[eventName]); - } - } - }; - function propagateEvent(childInstance, parentInstance, eventName, proxyEventName) { - if (typeof proxyEventName !== 'string') { - if (parentInstance.debug) { - throw new Error(errorMessage); - } else { - warn(errorMessage); - return; - } - } - childInstance.on(eventName, function () { - var args = Array.prototype.slice.call(arguments); - args.unshift(proxyEventName); - parentInstance.fire.apply(parentInstance, args); - }); - } - }(utils_warn); -var render_DomFragment_Component_initialise_updateLiveQueries = function () { - - return function (component) { - var ancestor, query; - ancestor = component.root; - while (ancestor) { - if (query = ancestor._liveComponentQueries[component.name]) { - query.push(component.instance); - } - ancestor = ancestor._parent; - } - }; - }(); -var render_DomFragment_Component_initialise__initialise = function (types, warn, createModel, createInstance, createObservers, propagateEvents, updateLiveQueries) { - - return function (component, options, docFrag) { - var parentFragment, root, Component, data, toBind; - parentFragment = component.parentFragment = options.parentFragment; - root = parentFragment.root; - component.root = root; - component.type = types.COMPONENT; - component.name = options.descriptor.e; - component.index = options.index; - component.observers = []; - Component = root.components[options.descriptor.e]; - if (!Component) { - throw new Error('Component "' + options.descriptor.e + '" not found'); - } - toBind = []; - data = createModel(component, options.descriptor.a, toBind); - createInstance(component, Component, data, docFrag, options.descriptor.f); - createObservers(component, toBind); - propagateEvents(component, options.descriptor.v); - if (options.descriptor.t1 || options.descriptor.t2 || options.descriptor.o) { - warn('The "intro", "outro" and "decorator" directives have no effect on components'); - } - updateLiveQueries(component); - }; - }(config_types, utils_warn, render_DomFragment_Component_initialise_createModel__createModel, render_DomFragment_Component_initialise_createInstance, render_DomFragment_Component_initialise_createObservers, render_DomFragment_Component_initialise_propagateEvents, render_DomFragment_Component_initialise_updateLiveQueries); -var render_DomFragment_Component__Component = function (initialise) { - - var DomComponent = function (options, docFrag) { - initialise(this, options, docFrag); - }; - DomComponent.prototype = { - firstNode: function () { - return this.instance.fragment.firstNode(); - }, - findNextNode: function () { - return this.parentFragment.findNextNode(this); - }, - detach: function () { - return this.instance.fragment.detach(); - }, - teardown: function () { - var query; - while (this.complexParameters.length) { - this.complexParameters.pop().teardown(); - } - while (this.observers.length) { - this.observers.pop().cancel(); - } - if (query = this.root._liveComponentQueries[this.name]) { - query._remove(this); - } - this.instance.teardown(); - }, - toString: function () { - return this.instance.fragment.toString(); - }, - find: function (selector) { - return this.instance.fragment.find(selector); - }, - findAll: function (selector, query) { - return this.instance.fragment.findAll(selector, query); - }, - findComponent: function (selector) { - if (!selector || selector === this.name) { - return this.instance; - } - return null; - }, - findAllComponents: function (selector, query) { - query._test(this, true); - if (this.instance.fragment) { - this.instance.fragment.findAllComponents(selector, query); - } - } - }; - return DomComponent; - }(render_DomFragment_Component_initialise__initialise); -var render_DomFragment_Comment = function (types) { - - var DomComment = function (options, docFrag) { - this.type = types.COMMENT; - this.descriptor = options.descriptor; - if (docFrag) { - this.node = document.createComment(options.descriptor.f); - docFrag.appendChild(this.node); - } - }; - DomComment.prototype = { - detach: function () { - this.node.parentNode.removeChild(this.node); - return this.node; - }, - teardown: function (destroy) { - if (destroy) { - this.detach(); - } - }, - firstNode: function () { - return this.node; - }, - toString: function () { - return ''; - } - }; - return DomComment; - }(config_types); -var render_DomFragment__DomFragment = function (types, matches, initFragment, insertHtml, Text, Interpolator, Section, Triple, Element, Partial, Component, Comment, circular) { - - var DomFragment = function (options) { - if (options.pNode) { - this.docFrag = document.createDocumentFragment(); - } - if (typeof options.descriptor === 'string') { - this.html = options.descriptor; - if (this.docFrag) { - this.nodes = insertHtml(this.html, options.pNode.tagName, this.docFrag); - } - } else { - initFragment(this, options); - } - }; - DomFragment.prototype = { - detach: function () { - var len, i; - if (this.nodes) { - i = this.nodes.length; - while (i--) { - this.docFrag.appendChild(this.nodes[i]); - } - } else if (this.items) { - len = this.items.length; - for (i = 0; i < len; i += 1) { - this.docFrag.appendChild(this.items[i].detach()); - } - } - return this.docFrag; - }, - createItem: function (options) { - if (typeof options.descriptor === 'string') { - return new Text(options, this.docFrag); - } - switch (options.descriptor.t) { - case types.INTERPOLATOR: - return new Interpolator(options, this.docFrag); - case types.SECTION: - return new Section(options, this.docFrag); - case types.TRIPLE: - return new Triple(options, this.docFrag); - case types.ELEMENT: - if (this.root.components[options.descriptor.e]) { - return new Component(options, this.docFrag); - } - return new Element(options, this.docFrag); - case types.PARTIAL: - return new Partial(options, this.docFrag); - case types.COMMENT: - return new Comment(options, this.docFrag); - default: - throw new Error('Something very strange happened. Please file an issue at https://github.com/RactiveJS/Ractive/issues. Thanks!'); - } - }, - teardown: function (destroy) { - var node; - if (this.nodes && destroy) { - while (node = this.nodes.pop()) { - node.parentNode.removeChild(node); - } - } else if (this.items) { - while (this.items.length) { - this.items.pop().teardown(destroy); - } - } - this.nodes = this.items = this.docFrag = null; - }, - firstNode: function () { - if (this.items && this.items[0]) { - return this.items[0].firstNode(); - } else if (this.nodes) { - return this.nodes[0] || null; - } - return null; - }, - findNextNode: function (item) { - var index = item.index; - if (this.items[index + 1]) { - return this.items[index + 1].firstNode(); - } - if (this.owner === this.root) { - if (!this.owner.component) { - return null; - } - return this.owner.component.findNextNode(); - } - return this.owner.findNextNode(this); - }, - toString: function () { - var html, i, len, item; - if (this.html) { - return this.html; - } - html = ''; - if (!this.items) { - return html; - } - len = this.items.length; - for (i = 0; i < len; i += 1) { - item = this.items[i]; - html += item.toString(); - } - return html; - }, - find: function (selector) { - var i, len, item, node, queryResult; - if (this.nodes) { - len = this.nodes.length; - for (i = 0; i < len; i += 1) { - node = this.nodes[i]; - if (node.nodeType !== 1) { - continue; - } - if (matches(node, selector)) { - return node; - } - if (queryResult = node.querySelector(selector)) { - return queryResult; - } - } - return null; - } - if (this.items) { - len = this.items.length; - for (i = 0; i < len; i += 1) { - item = this.items[i]; - if (item.find && (queryResult = item.find(selector))) { - return queryResult; - } - } - return null; - } - }, - findAll: function (selector, query) { - var i, len, item, node, queryAllResult, numNodes, j; - if (this.nodes) { - len = this.nodes.length; - for (i = 0; i < len; i += 1) { - node = this.nodes[i]; - if (node.nodeType !== 1) { - continue; - } - if (matches(node, selector)) { - query.push(node); - } - if (queryAllResult = node.querySelectorAll(selector)) { - numNodes = queryAllResult.length; - for (j = 0; j < numNodes; j += 1) { - query.push(queryAllResult[j]); - } - } - } - } else if (this.items) { - len = this.items.length; - for (i = 0; i < len; i += 1) { - item = this.items[i]; - if (item.findAll) { - item.findAll(selector, query); - } - } - } - return query; - }, - findComponent: function (selector) { - var len, i, item, queryResult; - if (this.items) { - len = this.items.length; - for (i = 0; i < len; i += 1) { - item = this.items[i]; - if (item.findComponent && (queryResult = item.findComponent(selector))) { - return queryResult; - } - } - return null; - } - }, - findAllComponents: function (selector, query) { - var i, len, item; - if (this.items) { - len = this.items.length; - for (i = 0; i < len; i += 1) { - item = this.items[i]; - if (item.findAllComponents) { - item.findAllComponents(selector, query); - } - } - } - return query; - } - }; - circular.DomFragment = DomFragment; - return DomFragment; - }(config_types, utils_matches, render_shared_initFragment, render_DomFragment_shared_insertHtml, render_DomFragment_Text, render_DomFragment_Interpolator, render_DomFragment_Section__Section, render_DomFragment_Triple, render_DomFragment_Element__Element, render_DomFragment_Partial__Partial, render_DomFragment_Component__Component, render_DomFragment_Comment, circular); -var Ractive_prototype_render = function (getElement, makeTransitionManager, preDomUpdate, postDomUpdate, DomFragment) { - - return function (target, complete) { - var transitionManager; - if (!this._initing) { - throw new Error('You cannot call ractive.render() directly!'); - } - this._transitionManager = transitionManager = makeTransitionManager(this, complete); - this.fragment = new DomFragment({ - descriptor: this.template, - root: this, - owner: this, - pNode: target - }); - preDomUpdate(this); - if (target) { - target.appendChild(this.fragment.docFrag); - } - postDomUpdate(this); - this._transitionManager = null; - transitionManager.ready(); - this.rendered = true; - }; - }(utils_getElement, shared_makeTransitionManager, shared_preDomUpdate, shared_postDomUpdate, render_DomFragment__DomFragment); -var Ractive_prototype_renderHTML = function (warn) { - - return function () { - warn('renderHTML() has been deprecated and will be removed in a future version. Please use toHTML() instead'); - return this.toHTML(); - }; - }(utils_warn); -var Ractive_prototype_toHTML = function () { - - return function () { - return this.fragment.toString(); - }; - }(); -var Ractive_prototype_teardown = function (makeTransitionManager, clearCache) { - - return function (complete) { - var keypath, transitionManager, previousTransitionManager; - this.fire('teardown'); - previousTransitionManager = this._transitionManager; - this._transitionManager = transitionManager = makeTransitionManager(this, complete); - this.fragment.teardown(true); - while (this._animations[0]) { - this._animations[0].stop(); - } - for (keypath in this._cache) { - clearCache(this, keypath); - } - this._transitionManager = previousTransitionManager; - transitionManager.ready(); - }; - }(shared_makeTransitionManager, shared_clearCache); -var Ractive_prototype_shared_add = function (isNumeric) { - - return function (root, keypath, d) { - var value; - if (typeof keypath !== 'string' || !isNumeric(d)) { - if (root.debug) { - throw new Error('Bad arguments'); - } - return; - } - value = root.get(keypath); - if (value === undefined) { - value = 0; - } - if (!isNumeric(value)) { - if (root.debug) { - throw new Error('Cannot add to a non-numeric value'); - } - return; - } - root.set(keypath, value + d); - }; - }(utils_isNumeric); -var Ractive_prototype_add = function (add) { - - return function (keypath, d) { - add(this, keypath, d === undefined ? 1 : d); - }; - }(Ractive_prototype_shared_add); -var Ractive_prototype_subtract = function (add) { - - return function (keypath, d) { - add(this, keypath, d === undefined ? -1 : -d); - }; - }(Ractive_prototype_shared_add); -var Ractive_prototype_toggle = function () { - - return function (keypath) { - var value; - if (typeof keypath !== 'string') { - if (this.debug) { - throw new Error('Bad arguments'); - } - return; - } - value = this.get(keypath); - this.set(keypath, !value); - }; - }(); -var Ractive_prototype_merge_mapOldToNewIndex = function () { - - return function (oldArray, newArray) { - var usedIndices, mapper, firstUnusedIndex, newIndices, changed; - usedIndices = {}; - firstUnusedIndex = 0; - mapper = function (item, i) { - var index, start, len; - start = firstUnusedIndex; - len = newArray.length; - do { - index = newArray.indexOf(item, start); - if (index === -1) { - changed = true; - return -1; - } - start = index + 1; - } while (usedIndices[index] && start < len); - if (index === firstUnusedIndex) { - firstUnusedIndex += 1; - } - if (index !== i) { - changed = true; - } - usedIndices[index] = true; - return index; - }; - newIndices = oldArray.map(mapper); - newIndices.unchanged = !changed; - return newIndices; - }; - }(); -var Ractive_prototype_merge_queueDependants = function (types) { - - return function queueDependants(keypath, deps, mergeQueue, updateQueue) { - var i, dependant; - i = deps.length; - while (i--) { - dependant = deps[i]; - if (dependant.type === types.REFERENCE) { - dependant.update(); - } else if (dependant.keypath === keypath && dependant.type === types.SECTION && !dependant.inverted && dependant.docFrag) { - mergeQueue[mergeQueue.length] = dependant; - } else { - updateQueue[updateQueue.length] = dependant; - } - } - }; - }(config_types); -var Ractive_prototype_merge__merge = function (warn, isArray, clearCache, preDomUpdate, processDeferredUpdates, makeTransitionManager, notifyDependants, replaceData, mapOldToNewIndex, queueDependants) { - - var identifiers = {}; - return function (keypath, array, options) { - var currentArray, oldArray, newArray, identifier, lengthUnchanged, i, newIndices, mergeQueue, updateQueue, depsByKeypath, deps, transitionManager, previousTransitionManager, upstreamQueue, keys; - currentArray = this.get(keypath); - if (!isArray(currentArray) || !isArray(array)) { - return this.set(keypath, array, options && options.complete); - } - lengthUnchanged = currentArray.length === array.length; - if (options && options.compare) { - if (options.compare === true) { - identifier = stringify; - } else if (typeof options.compare === 'string') { - identifier = getIdentifier(options.compare); - } else if (typeof options.compare == 'function') { - identifier = options.compare; - } else { - throw new Error('The `compare` option must be a function, or a string representing an identifying field (or `true` to use JSON.stringify)'); - } - try { - oldArray = currentArray.map(identifier); - newArray = array.map(identifier); - } catch (err) { - if (this.debug) { - throw err; - } else { - warn('Merge operation: comparison failed. Falling back to identity checking'); - } - oldArray = currentArray; - newArray = array; - } - } else { - oldArray = currentArray; - newArray = array; - } - newIndices = mapOldToNewIndex(oldArray, newArray); - clearCache(this, keypath); - replaceData(this, keypath, array); - if (newIndices.unchanged && lengthUnchanged) { - return; - } - previousTransitionManager = this._transitionManager; - this._transitionManager = transitionManager = makeTransitionManager(this, options && options.complete); - mergeQueue = []; - updateQueue = []; - for (i = 0; i < this._deps.length; i += 1) { - depsByKeypath = this._deps[i]; - if (!depsByKeypath) { - continue; - } - deps = depsByKeypath[keypath]; - if (deps) { - queueDependants(keypath, deps, mergeQueue, updateQueue); - preDomUpdate(this); - while (mergeQueue.length) { - mergeQueue.pop().merge(newIndices); - } - while (updateQueue.length) { - updateQueue.pop().update(); - } - } - } - processDeferredUpdates(this); - upstreamQueue = []; - keys = keypath.split('.'); - while (keys.length) { - keys.pop(); - upstreamQueue[upstreamQueue.length] = keys.join('.'); - } - notifyDependants.multiple(this, upstreamQueue, true); - if (oldArray.length !== newArray.length) { - notifyDependants(this, keypath + '.length', true); - } - this._transitionManager = previousTransitionManager; - transitionManager.ready(); - }; - function stringify(item) { - return JSON.stringify(item); - } - function getIdentifier(str) { - if (!identifiers[str]) { - identifiers[str] = function (item) { - return item[str]; - }; - } - return identifiers[str]; - } - }(utils_warn, utils_isArray, shared_clearCache, shared_preDomUpdate, shared_processDeferredUpdates, shared_makeTransitionManager, shared_notifyDependants, Ractive_prototype_shared_replaceData, Ractive_prototype_merge_mapOldToNewIndex, Ractive_prototype_merge_queueDependants); -var Ractive_prototype_detach = function () { - - return function () { - return this.fragment.detach(); - }; - }(); -var Ractive_prototype_insert = function (getElement) { - - return function (target, anchor) { - target = getElement(target); - anchor = getElement(anchor) || null; - if (!target) { - throw new Error('You must specify a valid target to insert into'); - } - target.insertBefore(this.detach(), anchor); - this.fragment.pNode = target; - }; - }(utils_getElement); -var Ractive_prototype__prototype = function (get, set, update, updateModel, animate, on, off, observe, fire, find, findAll, findComponent, findAllComponents, render, renderHTML, toHTML, teardown, add, subtract, toggle, merge, detach, insert) { - - return { - get: get, - set: set, - update: update, - updateModel: updateModel, - animate: animate, - on: on, - off: off, - observe: observe, - fire: fire, - find: find, - findAll: findAll, - findComponent: findComponent, - findAllComponents: findAllComponents, - renderHTML: renderHTML, - toHTML: toHTML, - render: render, - teardown: teardown, - add: add, - subtract: subtract, - toggle: toggle, - merge: merge, - detach: detach, - insert: insert - }; - }(Ractive_prototype_get__get, Ractive_prototype_set, Ractive_prototype_update, Ractive_prototype_updateModel, Ractive_prototype_animate__animate, Ractive_prototype_on, Ractive_prototype_off, Ractive_prototype_observe__observe, Ractive_prototype_fire, Ractive_prototype_find, Ractive_prototype_findAll, Ractive_prototype_findComponent, Ractive_prototype_findAllComponents, Ractive_prototype_render, Ractive_prototype_renderHTML, Ractive_prototype_toHTML, Ractive_prototype_teardown, Ractive_prototype_add, Ractive_prototype_subtract, Ractive_prototype_toggle, Ractive_prototype_merge__merge, Ractive_prototype_detach, Ractive_prototype_insert); -var extend_registries = function () { - - return [ - 'partials', - 'transitions', - 'events', - 'components', - 'decorators', - 'data' - ]; - }(); -var extend_initOptions = function () { - - return [ - 'el', - 'template', - 'complete', - 'modifyArrays', - 'magic', - 'twoway', - 'lazy', - 'append', - 'preserveWhitespace', - 'sanitize', - 'stripComments', - 'noIntro', - 'transitionsEnabled', - 'adaptors' - ]; - }(); -var extend_inheritFromParent = function (registries, initOptions, create) { - - return function (Child, Parent) { - registries.forEach(function (property) { - if (Parent[property]) { - Child[property] = create(Parent[property]); - } - }); - initOptions.forEach(function (property) { - Child[property] = Parent[property]; - }); - }; - }(extend_registries, extend_initOptions, utils_create); -var extend_wrapMethod = function () { - - return function (method, superMethod) { - if (/_super/.test(method)) { - return function () { - var _super = this._super, result; - this._super = superMethod; - result = method.apply(this, arguments); - this._super = _super; - return result; - }; - } else { - return method; - } - }; - }(); -var extend_utils_augment = function () { - - return function (target, source) { - var key; - for (key in source) { - if (source.hasOwnProperty(key)) { - target[key] = source[key]; - } - } - return target; - }; - }(); -var extend_inheritFromChildProps = function (registries, initOptions, wrapMethod, augment) { - - var blacklist, blacklisted; - blacklist = registries.concat(initOptions); - blacklisted = {}; - blacklist.forEach(function (property) { - blacklisted[property] = true; - }); - return function (Child, childProps) { - var key, member; - registries.forEach(function (property) { - var value = childProps[property]; - if (value) { - if (Child[property]) { - augment(Child[property], value); - } else { - Child[property] = value; - } - } - }); - initOptions.forEach(function (property) { - var value = childProps[property]; - if (value !== undefined) { - if (typeof value === 'function' && typeof Child[property] === 'function') { - Child[property] = wrapMethod(value, Child[property]); - } else { - Child[property] = childProps[property]; - } - } - }); - for (key in childProps) { - if (childProps.hasOwnProperty(key) && !blacklisted[key]) { - member = childProps[key]; - if (typeof member === 'function' && typeof Child.prototype[key] === 'function') { - Child.prototype[key] = wrapMethod(member, Child.prototype[key]); - } else { - Child.prototype[key] = member; - } - } - } - }; - }(extend_registries, extend_initOptions, extend_wrapMethod, extend_utils_augment); -var extend_extractInlinePartials = function (isObject, augment) { - - return function (Child, childProps) { - if (isObject(Child.template)) { - if (!Child.partials) { - Child.partials = {}; - } - augment(Child.partials, Child.template.partials); - if (childProps.partials) { - augment(Child.partials, childProps.partials); - } - Child.template = Child.template.main; - } - }; - }(utils_isObject, extend_utils_augment); -var extend_conditionallyParseTemplate = function (errors, isClient, parse) { - - return function (Child) { - var templateEl; - if (typeof Child.template === 'string') { - if (!parse) { - throw new Error(errors.missingParser); - } - if (Child.template.charAt(0) === '#' && isClient) { - templateEl = document.getElementById(Child.template.substring(1)); - if (templateEl && templateEl.tagName === 'SCRIPT') { - Child.template = parse(templateEl.innerHTML, Child); - } else { - throw new Error('Could not find template element (' + Child.template + ')'); - } - } else { - Child.template = parse(Child.template, Child); - } - } - }; - }(config_errors, config_isClient, parse__parse); -var extend_conditionallyParsePartials = function (errors, parse) { - - return function (Child) { - var key; - if (Child.partials) { - for (key in Child.partials) { - if (Child.partials.hasOwnProperty(key) && typeof Child.partials[key] === 'string') { - if (!parse) { - throw new Error(errors.missingParser); - } - Child.partials[key] = parse(Child.partials[key], Child); - } - } - } - }; - }(config_errors, parse__parse); -var extend_utils_clone = function () { - - return function (source) { - var target = {}, key; - for (key in source) { - if (source.hasOwnProperty(key)) { - target[key] = source[key]; - } - } - return target; - }; - }(); -var utils_extend = function () { - - return function (target) { - var prop, source, sources = Array.prototype.slice.call(arguments, 1); - while (source = sources.shift()) { - for (prop in source) { - if (source.hasOwnProperty(prop)) { - target[prop] = source[prop]; - } - } - } - return target; - }; - }(); -var Ractive_initialise = function (isClient, errors, warn, create, extend, defineProperty, defineProperties, getElement, isObject, magicAdaptor, parse) { - - var getObject, getArray, defaultOptions, registries; - getObject = function () { - return {}; - }; - getArray = function () { - return []; - }; - defaultOptions = create(null); - defineProperties(defaultOptions, { - preserveWhitespace: { - enumerable: true, - value: false - }, - append: { - enumerable: true, - value: false - }, - twoway: { - enumerable: true, - value: true - }, - modifyArrays: { - enumerable: true, - value: true - }, - data: { - enumerable: true, - value: getObject - }, - lazy: { - enumerable: true, - value: false - }, - debug: { - enumerable: true, - value: false - }, - transitions: { - enumerable: true, - value: getObject - }, - decorators: { - enumerable: true, - value: getObject - }, - events: { - enumerable: true, - value: getObject - }, - noIntro: { - enumerable: true, - value: false - }, - transitionsEnabled: { - enumerable: true, - value: true - }, - magic: { - enumerable: true, - value: false - }, - adaptors: { - enumerable: true, - value: getArray - } - }); - registries = [ - 'components', - 'decorators', - 'events', - 'partials', - 'transitions', - 'data' - ]; - return function (ractive, options) { - var key, template, templateEl, parsedTemplate; - for (key in defaultOptions) { - if (options[key] === undefined) { - options[key] = typeof defaultOptions[key] === 'function' ? defaultOptions[key]() : defaultOptions[key]; - } - } - defineProperties(ractive, { - _initing: { - value: true, - writable: true - }, - _guid: { - value: 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { - var r, v; - r = Math.random() * 16 | 0; - v = c == 'x' ? r : r & 3 | 8; - return v.toString(16); - }) - }, - _subs: { - value: create(null), - configurable: true - }, - _cache: { value: {} }, - _cacheMap: { value: create(null) }, - _deps: { value: [] }, - _depsMap: { value: create(null) }, - _patternObservers: { value: [] }, - _pendingResolution: { value: [] }, - _deferred: { value: {} }, - _evaluators: { value: create(null) }, - _twowayBindings: { value: {} }, - _transitionManager: { - value: null, - writable: true - }, - _animations: { value: [] }, - nodes: { value: {} }, - _wrapped: { value: create(null) }, - _liveQueries: { value: [] }, - _liveComponentQueries: { value: [] } - }); - defineProperties(ractive._deferred, { - attrs: { value: [] }, - evals: { value: [] }, - selectValues: { value: [] }, - checkboxes: { value: [] }, - radios: { value: [] }, - observers: { value: [] }, - transitions: { value: [] }, - liveQueries: { value: [] }, - decorators: { value: [] }, - focusable: { - value: null, - writable: true - } - }); - ractive.adaptors = options.adaptors; - ractive.modifyArrays = options.modifyArrays; - ractive.magic = options.magic; - ractive.twoway = options.twoway; - ractive.lazy = options.lazy; - ractive.debug = options.debug; - if (ractive.magic && !magicAdaptor) { - throw new Error('Getters and setters (magic mode) are not supported in this browser'); - } - if (options._parent) { - defineProperty(ractive, '_parent', { value: options._parent }); - } - if (options.el) { - ractive.el = getElement(options.el); - if (!ractive.el && ractive.debug) { - throw new Error('Could not find container element'); - } - } - if (options.eventDefinitions) { - warn('ractive.eventDefinitions has been deprecated in favour of ractive.events. Support will be removed in future versions'); - options.events = options.eventDefinitions; - } - registries.forEach(function (registry) { - if (ractive.constructor[registry]) { - ractive[registry] = extend(create(ractive.constructor[registry] || {}), options[registry]); - } else if (options[registry]) { - ractive[registry] = options[registry]; - } - }); - template = options.template; - if (typeof template === 'string') { - if (!parse) { - throw new Error(errors.missingParser); - } - if (template.charAt(0) === '#' && isClient) { - templateEl = document.getElementById(template.substring(1)); - if (templateEl) { - parsedTemplate = parse(templateEl.innerHTML, options); - } else { - throw new Error('Could not find template element (' + template + ')'); - } - } else { - parsedTemplate = parse(template, options); - } - } else { - parsedTemplate = template; - } - if (isObject(parsedTemplate)) { - extend(ractive.partials, parsedTemplate.partials); - parsedTemplate = parsedTemplate.main; - } - if (parsedTemplate && parsedTemplate.length === 1 && typeof parsedTemplate[0] === 'string') { - parsedTemplate = parsedTemplate[0]; - } - ractive.template = parsedTemplate; - extend(ractive.partials, options.partials); - ractive.parseOptions = { - preserveWhitespace: options.preserveWhitespace, - sanitize: options.sanitize, - stripComments: options.stripComments - }; - ractive.transitionsEnabled = options.noIntro ? false : options.transitionsEnabled; - if (isClient && !ractive.el) { - ractive.el = document.createDocumentFragment(); - } - if (ractive.el && !options.append) { - ractive.el.innerHTML = ''; - } - ractive.render(ractive.el, options.complete); - ractive.transitionsEnabled = options.transitionsEnabled; - ractive._initing = false; - }; - }(config_isClient, config_errors, utils_warn, utils_create, utils_extend, utils_defineProperty, utils_defineProperties, utils_getElement, utils_isObject, Ractive_prototype_get_magicAdaptor, parse__parse); -var extend_initChildInstance = function (fillGaps, initOptions, clone, wrapMethod, initialise) { - - return function (child, Child, options) { - initOptions.forEach(function (property) { - var value = options[property], defaultValue = Child[property]; - if (typeof value === 'function' && typeof defaultValue === 'function') { - options[property] = wrapMethod(value, defaultValue); - } else if (value === undefined && defaultValue !== undefined) { - options[property] = defaultValue; - } - }); - if (child.beforeInit) { - child.beforeInit(options); - } - initialise(child, options); - if (child.init) { - child.init(options); - } - }; - }(utils_fillGaps, extend_initOptions, extend_utils_clone, extend_wrapMethod, Ractive_initialise); -var extend__extend = function (create, inheritFromParent, inheritFromChildProps, extractInlinePartials, conditionallyParseTemplate, conditionallyParsePartials, initChildInstance, circular) { - - var Ractive; - circular.push(function () { - Ractive = circular.Ractive; - }); - return function (childProps) { - var Parent = this, Child; - Child = function (options) { - initChildInstance(this, Child, options || {}); - }; - Child.prototype = create(Parent.prototype); - Child.prototype.constructor = Child; - inheritFromParent(Child, Parent); - inheritFromChildProps(Child, childProps); - conditionallyParseTemplate(Child); - extractInlinePartials(Child, childProps); - conditionallyParsePartials(Child); - Child.extend = Parent.extend; - return Child; - }; - }(utils_create, extend_inheritFromParent, extend_inheritFromChildProps, extend_extractInlinePartials, extend_conditionallyParseTemplate, extend_conditionallyParsePartials, extend_initChildInstance, circular); -var Ractive__Ractive = function (svg, create, defineProperties, prototype, partialRegistry, adaptorRegistry, easingRegistry, Ractive_extend, parse, initialise, circular) { - - var Ractive = function (options) { - initialise(this, options); - }; - defineProperties(Ractive, { - prototype: { value: prototype }, - partials: { value: partialRegistry }, - adaptors: { value: adaptorRegistry }, - easing: { value: easingRegistry }, - transitions: { value: {} }, - events: { value: {} }, - components: { value: {} }, - decorators: { value: {} }, - svg: { value: svg }, - VERSION: { value: '0.3.9' } - }); - Ractive.eventDefinitions = Ractive.events; - Ractive.prototype.constructor = Ractive; - Ractive.delimiters = [ - '{{', - '}}' - ]; - Ractive.tripleDelimiters = [ - '{{{', - '}}}' - ]; - Ractive.extend = Ractive_extend; - Ractive.parse = parse; - circular.Ractive = Ractive; - return Ractive; - }(config_svg, utils_create, utils_defineProperties, Ractive_prototype__prototype, registries_partials, registries_adaptors, registries_easing, extend__extend, parse__parse, Ractive_initialise, circular); -var Ractive = function (Ractive, circular) { - - if (typeof window !== 'undefined' && window.Node && !window.Node.prototype.contains && window.HTMLElement && window.HTMLElement.prototype.contains) { - window.Node.prototype.contains = window.HTMLElement.prototype.contains; - } - while (circular.length) { - circular.pop()(); - } - return Ractive; - }(Ractive__Ractive, circular); -// export as Common JS module... -if ( typeof module !== "undefined" && module.exports ) { - module.exports = Ractive; -} - -// ... or as AMD module -else if ( typeof define === "function" && define.amd ) { - define( function () { - return Ractive; - }); -} - -// ... or as browser global -else { - global.Ractive = Ractive; -} - -}( typeof window !== 'undefined' ? window : this )); \ No newline at end of file diff --git a/build/Ractive.min.js b/build/Ractive.min.js deleted file mode 100644 index 3b52eaafc5..0000000000 --- a/build/Ractive.min.js +++ /dev/null @@ -1,4 +0,0 @@ -!function(a){var b=function(){return"undefined"!=typeof document?document&&document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1"):void 0}(),c=function(){var a;try{Object.create(null),a=Object.create}catch(b){a=function(){var a=function(){};return function(b,c){var d;return null===b?{}:(a.prototype=b,d=new a,c&&Object.defineProperties(d,c),d)}}()}return a}(),d={html:"http://www.w3.org/1999/xhtml",mathml:"http://www.w3.org/1998/Math/MathML",svg:"http://www.w3.org/2000/svg",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"},e=function(a,b){return a?function(a,b){return b?document.createElementNS(b,a):document.createElement(a)}:function(a,c){if(c&&c!==b.html)throw"This browser does not support namespaces other than http://www.w3.org/1999/xhtml. The most likely cause of this error is that you're trying to render SVG in an older browser. See https://github.com/RactiveJS/Ractive/wiki/SVG-and-older-browsers for more information";return document.createElement(a)}}(b,d),f=function(){return"object"==typeof document?!0:!1}(),g=function(a){try{return Object.defineProperty({},"test",{value:0}),a&&Object.defineProperty(document.createElement("div"),"test",{value:0}),Object.defineProperty}catch(b){return function(a,b,c){a[b]=c.value}}}(f),h=function(a,b,c){try{try{Object.defineProperties({},{test:{value:0}})}catch(d){throw d}return c&&Object.defineProperties(a("div"),{test:{value:0}}),Object.defineProperties}catch(d){return function(a,c){var d;for(d in c)c.hasOwnProperty(d)&&b(a,d,c[d])}}}(e,g,f),i=function(){var a=/\[\s*(\*|[0-9]|[1-9][0-9]+)\s*\]/g;return function(b){return(b||"").replace(a,".$1")}}(),j={},k={TEXT:1,INTERPOLATOR:2,TRIPLE:3,SECTION:4,INVERTED:5,CLOSING:6,ELEMENT:7,PARTIAL:8,COMMENT:9,DELIMCHANGE:10,MUSTACHE:11,TAG:12,ATTRIBUTE:13,COMPONENT:15,NUMBER_LITERAL:20,STRING_LITERAL:21,ARRAY_LITERAL:22,OBJECT_LITERAL:23,BOOLEAN_LITERAL:24,GLOBAL:26,KEY_VALUE_PAIR:27,REFERENCE:30,REFINEMENT:31,MEMBER:32,PREFIX_OPERATOR:33,BRACKETED:34,CONDITIONAL:35,INFIX_OPERATOR:36,INVOCATION:40},l=function(){var a=Object.prototype.toString;return function(b){return"[object Array]"===a.call(b)}}(),m=function(){return function a(b,c){var d,e;if((e=b._wrapped[c])&&e.teardown()!==!1&&(b._wrapped[c]=null),b._cache[c]=void 0,d=b._cacheMap[c])for(;d.length;)a(b,d.pop())}}(),n=function(){return function(a,b){var c,d,e,f,g,h;for(c=[],h=a.rendered?a.el:a.fragment.docFrag,d=h.querySelectorAll('input[type="checkbox"][name="{{'+b+'}}"]'),f=d.length,g=0;f>g;g+=1)e=d[g],(e.hasAttribute("checked")||e.checked)&&(c[c.length]=e._ractive.value);return c}}(),o=function(a){return function(b){var c,d,e,f,g,h;for(c=b._deferred;d=c.evals.pop();)d.update().deferred=!1;for(;e=c.selectValues.pop();)e.deferredUpdate();for(;f=c.attrs.pop();)f.update().deferred=!1;for(;g=c.checkboxes.pop();)b.set(g,a(b,g));for(;h=c.radios.pop();)h.update()}}(n),p=function(){return function(a){var b,c,d,e,f,g;for(b=a._deferred,(c=b.focusable)&&(c.focus(),b.focusable=null);d=b.liveQueries.pop();)d._sort();for(;e=b.decorators.pop();)e.init();for(;f=b.transitions.pop();)f.init();for(;g=b.observers.pop();)g.update()}}(),q=function(){var a=function(a,b){var c,d,e,f;return a._parent&&a._parent._transitionManager?a._parent._transitionManager:(d=[],e=function(){var a,b;for(a=d.length;a--;)b=d[a],f(b.node)&&(b.detach(),d.splice(a,1))},f=function(a){var b,d;for(b=c.active.length;b--;)if(d=c.active[b],a.contains(d))return!1;return!0},c={active:[],push:function(a){c.active[c.active.length]=a},pop:function(a){var b;b=c.active.indexOf(a),-1!==b&&(c.active.splice(b,1),e(),!c.active.length&&c._ready&&c.complete())},complete:function(){b&&b.call(a)},ready:function(){e(),c._ready=!0,c.active.length||c.complete()},detachWhenReady:function(a){d[d.length]=a}})};return a}(),r=function(){function a(a,d,e,f){var g=a._deps[e];g&&(b(g[d]),f||c(a._depsMap[d],a,e))}function b(a){var b,c;if(a)for(c=a.length,b=0;c>b;b+=1)a[b].update()}function c(b,c,d,e){var f;if(b)for(f=b.length;f--;)a(c,b[f],d,e)}function d(a,b,c,f,g){var i,j,k,l,m,n,o,p;for(i=a._patternObservers.length;i--;)j=a._patternObservers[i],j.regex.test(c)&&j.update(c);f||(p=function(b){if(k=a._depsMap[b])for(i=k.length;i--;)l=k[i],m=h.exec(l)[0],n=c+"."+m,d(a,l,n)},g?(o=e(c),o.forEach(p)):p(b))}function e(a){var b,c,d,e,g,h;for(b=a.split("."),c=f(b.length),g=[],d=function(a,c){return a?"*":b[c]},e=c.length;e--;)h=c[e].map(d).join("."),g[h]||(g[g.length]=h,g[h]=!0);return g}function f(a){var b,c,d,e,f,g="";if(!i[a]){for(d=[];g.length=f;f+=1){for(c=f.toString(2);c.length2&&f[1])for(q=Math.min(f[1],f.length-2),r=f[0],s=r+q,f[1]===f.length-2&&(u=!0),p=r;s>p;p+=1)t=g+"."+p,h(a,t);for(e(a),m=[],l=g.split(".");l.length;)l.pop(),m[m.length]=l.join(".");h.multiple(a,m,!0),u||h(a,g+".length",!0)},i=function(b,c,d,e){var f,g;for(f=c.length;f--;)g=c[f],g.type===a.REFERENCE?g.update():g.keypath===b&&g.type===a.SECTION&&!g.inverted&&g.docFrag?d[d.length]=g:e[e.length]=g},j=b._ractive.wrappers,l=j.length;l--;)k=j[l],g(k.root,k.keypath)},n=[],p=["pop","push","reverse","shift","sort","splice","unshift"],q=function(){},p.forEach(function(a){var c=function(){var b,c,d,h,i={},k={};for(b=Array.prototype[a].apply(this,arguments),c=this._ractive.instances,h=c.length;h--;)d=c[h],i[d._guid]=d._transitionManager,d._transitionManager=k[d._guid]=g(d,q);for(this._ractive.setting=!0,j(this,a,arguments),this._ractive.setting=!1,h=c.length;h--;)d=c[h],d._transitionManager=i[d._guid],k[d._guid].ready(),e(d),f(d);return b};b(n,a,{value:c})}),o={},o.__proto__?(l=function(a){a.__proto__=n},m=function(a){a.__proto__=Array.prototype}):(l=function(a){var c,d;for(c=p.length;c--;)d=p[c],b(a,d,{value:n[d],configurable:!0})},m=function(a){var b;for(b=p.length;b--;)delete a[p[b]]}),r="Something went wrong in a rather interesting way",i}(k,g,l,m,o,p,q,r),t=function(){var a,b;try{Object.defineProperty({},"test",{value:0})}catch(c){return!1}return a={filter:function(a,b){return!!b},wrap:function(a,c,d){return new b(a,c,d)}},b=function(a,b,c){var d,e,f,g,h,i,j,k,l,m=this;if(this.ractive=a,this.keypath=c,d=c.split("."),this.prop=d.pop(),f=d.join("."),this.obj=f?a.get(f):a.data,g=this.originalDescriptor=Object.getOwnPropertyDescriptor(this.obj,this.prop),g&&g.set&&(h=g.set._ractiveWrappers))return-1===h.indexOf(this)&&h.push(this),void 0;if(g&&!g.configurable)throw new Error('Cannot use magic mode with property "'+e+'" - object is not configurable');g&&(this.value=g.value,i=g.get,j=g.set),k=i||function(){return m.value},l=function(a){var b,c,d;for(j&&j(a),b=l._ractiveWrappers,d=b.length;d--;)c=b[d],c.resetting||c.ractive.set(c.keypath,a)},l._ractiveWrappers=[this],Object.defineProperty(this.obj,this.prop,{get:k,set:l,enumerable:!0,configurable:!0})},b.prototype={get:function(){return this.value},reset:function(a){this.resetting=!0,this.value=a,this.resetting=!1},teardown:function(){var a,b,c,d;a=Object.getOwnPropertyDescriptor(this.obj,this.prop),b=a.set,d=b._ractiveWrappers,d.splice(d.indexOf(this),1),d.length||(c=this.obj[this.prop],Object.defineProperty(this.obj,this.prop,this.originalDescriptor||{writable:!0,enumerable:!0,configrable:!0}),this.obj[this.prop]=c)}},a}(),u=function(a,b,c){function d(a,b){var c,d={};if(!b)return a;b+=".";for(c in a)a.hasOwnProperty(c)&&(d[b+c]=a[c]);return d}function e(a){var b;return f[a]||(b=a?a+".":"",f[a]=function(c,e){var f;return"string"==typeof c?(f={},f[b+c]=e,f):"object"==typeof c?b?d(c,a):c:void 0}),f[a]}var f={};return function(d,f,g,h){var i,j,k,l;for(i=d.adaptors.length,j=0;i>j;j+=1){if(k=d.adaptors[j],"string"==typeof k){if(!a[k])throw new Error('Missing adaptor "'+k+'"');k=d.adaptors[j]=a[k]}if(k.filter(g,f,d))return l=d._wrapped[f]=k.wrap(d,g,f,e(f)),l.value=g,void 0}h||(d.magic&&c.filter(g,f,d)?d._wrapped[f]=c.wrap(d,g,f):d.modifyArrays&&b.filter(g,f,d)&&(d._wrapped[f]=b.wrap(d,g,f)))}}(j,s,t),v=function(a,b,c){var d,e,f;return d=function(a){return this._captured&&!this._captured[a]&&(this._captured.push(a),this._captured[a]=!0),e(this,a)},e=function(b,d){var e,g,h,i,j;return d=a(d),e=b._cache,void 0!==(g=e[d])?g:((i=b._wrapped[d])?h=i.value:d?h=(j=b._evaluators[d])?j.value:f(b,d):(c(b,"",b.data),h=b.data),e[d]=h,h)},f=function(a,b){var d,f,g,h,i,j,k;return d=b.split("."),f=d.pop(),g=d.join("."),h=e(a,g),(k=a._wrapped[g])&&(h=k.get()),null!==h&&void 0!==h?((i=a._cacheMap[g])?-1===i.indexOf(b)&&(i[i.length]=b):a._cacheMap[g]=[b],j=h[f],c(a,b,j),a._cache[b]=j,j):void 0},d}(i,j,u),w=function(){var a=Object.prototype.toString;return function(b){return"object"==typeof b&&"[object Object]"===a.call(b)}}(),x=function(){return function(a,b){return null===a&&null===b?!0:"object"==typeof a||"object"==typeof b?!1:a===b}}(),y=function(){var a;return a=function(a,b,c){var d,e,f,g,h,i,j,k,l,m,n;if(n='Could not resolve reference - too many "../" prefixes',"."===b){if(!c.length)return"";d=c[c.length-1]}else if("."===b.charAt(0))if(m=c[c.length-1],g=m?m.split("."):[],"../"===b.substr(0,3)){for(;"../"===b.substr(0,3);){if(!g.length)throw new Error(n);g.pop(),b=b.substring(3)}g.push(b),d=g.join(".")}else d=m?m+b:b.substring(1);else{for(e=b.split("."),f=e.pop(),i=e.length?"."+e.join("."):"",c=c.concat();c.length;)if(h=c.pop(),j=h+i,k=a.get(j),(l=a._wrapped[j])&&(k=l.get()),"object"==typeof k&&null!==k&&k.hasOwnProperty(f)){d=h+"."+b;break}d||void 0===a.get(b)||(d=b)}return d?d.replace(/^\./,""):d}}(),z=function(a){var b=Array.prototype.push;return function(c){for(var d,e,f;d=c._pendingResolution.pop();)e=a(c,d.ref,d.contextStack),void 0!==e?d.resolve(e):(f||(f=[])).push(d);f&&b.apply(c._pendingResolution,f)}}(y),A=function(a,b){return function(c){a(c),b(c)}}(o,p),B=function(){return function(a,b,c){var d,e,f,g,h,i,j;for(d=b.split("."),e=[],(f=a._wrapped[""])?(f.set&&f.set(d.join("."),c),g=f.get()):g=a.data;d.length>1;)h=e[e.length]=d.shift(),i=e.join("."),(f=a._wrapped[i])?(f.set&&f.set(d.join("."),c),g=f.get()):(g.hasOwnProperty(h)||(j||(j=i),g[h]=/^\s*[0-9]+\s*$/.test(d[0])?[]:{}),g=g[h]);return h=d[0],g[h]=c,j}}(),C=function(a,b,c,d,e,f,g,h,i){var j,k,l,m;return j=function(b,d,i){var j,m,n,o,p,q,r;if(m=[],a(b)&&(j=b,i=d),j)for(b in j)j.hasOwnProperty(b)&&(d=j[b],b=c(b),k(this,b,d,m));else b=c(b),k(this,b,d,m);if(m.length){if(o=this._transitionManager,this._transitionManager=p=g(this,i),n=l(m),n.length&&e.multiple(this,n,!0),e.multiple(this,m),this._pendingResolution.length&&f(this),h(this),this._transitionManager=o,p.ready(),!this.firingChangeEvent){for(this.firingChangeEvent=!0,r={},q=m.length;q--;)r[m[q]]=this.get(m[q]);this.fire("change",r),this.firingChangeEvent=!1}return this}},k=function(a,b,c,e){var f,g,h,j,k;if(!(h=a._wrapped[b])||!h.reset||m(a,b,c,h,e)===!1){if((k=a._evaluators[b])&&(k.value=c),f=a._cache[b],g=a.get(b),g===c||k){if(c===f&&"object"!=typeof c)return}else j=i(a,b,c);d(a,j||b),e[e.length]=b}},l=function(a){var b,c,d,e,f=[""];for(b=a.length;b--;)for(c=a[b],d=c.split(".");d.length>1;)d.pop(),e=d.join("."),f[e]||(f[f.length]=e,f[e]=!0);return f},m=function(a,c,e,f,g){var h,i,j,k;if(h=f.get(),!b(h,e)&&f.reset(e)===!1)return!1;if(e=f.get(),i=a._cache[c],!b(i,e)){if(a._cache[c]=e,j=a._cacheMap[c])for(k=j.length;k--;)d(a,j[k]);g[g.length]=c}},j}(w,x,i,m,r,z,q,A,B),D=function(a,b,c,d,e){return function(f,g){var h,i;return"function"==typeof f&&(g=f,f=""),i=this._transitionManager,this._transitionManager=h=a(this,g),b(this),c(this,f||""),d(this,f||""),e(this),this._transitionManager=i,h.ready(),"string"==typeof f?this.fire("update",f):this.fire("update"),this}}(q,z,m,r,A),E=function(a){return function(b,c){var d;if(!a(b)||!a(c))return!1;if(b.length!==c.length)return!1;for(d=b.length;d--;)if(b[d]!==c[d])return!1;return!0}}(l),F=function(a,b,c){function d(a,e,f,g,h){var i,j,k,l,m,n;if(i=a._twowayBindings[e])for(k=i.length;k--;)l=i[k],(!l.radioName||l.node.checked)&&(l.checkboxName?l.changed()&&!g[e]&&(g[e]=!0,g[g.length]=e):(m=l.attr.value,n=l.value(),b(m,n)||c(m,n)||(f[e]=n)));if(h&&(j=a._depsMap[e]))for(k=j.length;k--;)d(a,j[k],f,g,h)}return function(b,c){var e,f,g;if("string"!=typeof b&&(b="",c=!0),d(this,b,e={},f=[],c),g=f.length)for(;g--;)b=f[g],e[b]=a(this,b);this.set(e)}}(n,E,x),G=function(){return"undefined"!=typeof window?(function(a,b,c){var d,e;if(!c.requestAnimationFrame){for(d=0;d=this.duration?(null!==g&&this.root.set(g,this.to),this.step&&this.step(1,this.to),this.complete&&this.complete(1,this.to),f=this.root._animations.indexOf(this),-1===f&&a("Animation was not found"),this.root._animations.splice(f,1),this.running=!1,!1):(c=this.easing?this.easing(b/this.duration):b/this.duration,null!==g&&(d=this.interpolator(c),this.root.set(g,d)),this.step&&this.step(c,d),!0)):!1},stop:function(){var b;this.running=!1,b=this.root._animations.indexOf(this),-1===b&&a("Animation was not found"),this.root._animations.splice(b,1)}},c}(I,K),M=function(){return{linear:function(a){return a},easeIn:function(a){return Math.pow(a,3)},easeOut:function(a){return Math.pow(a-1,3)+1},easeInOut:function(a){return(a/=.5)<1?.5*Math.pow(a,3):.5*(Math.pow(a-2,3)+2)}}}(),N=function(a,b,c,d){function e(e,g,h,i){var j,k,l,m;return null!==g&&(m=e.get(g)),b.abort(g,e),a(m,h)?(i.complete&&i.complete(1,i.to),f):(i.easing&&(j="function"==typeof i.easing?i.easing:e.easing&&e.easing[i.easing]?e.easing[i.easing]:d[i.easing],"function"!=typeof j&&(j=null)),k=void 0===i.duration?400:i.duration,l=new c({keypath:g,from:m,to:h,root:e,duration:k,easing:j,step:i.step,complete:i.complete}),b.add(l),e._animations[e._animations.length]=l,l)}var f={stop:function(){}};return function(a,b,c){var d,f,g,h,i,j,k,l,m,n,o,p;if("object"==typeof a){c=b||{},h=c.easing,i=c.duration,g=[],j=c.step,k=c.complete,(j||k)&&(m={},c.step=null,c.complete=null,l=function(a){return function(b,c){m[a]=c}});for(d in a)a.hasOwnProperty(d)&&((j||k)&&(n=l(d),c={easing:h,duration:i},j&&(c.step=n),k&&(c.complete=n)),g[g.length]=e(this,d,a[d],c));return(j||k)&&(p={easing:h,duration:i},j&&(p.step=function(a){j(a,m)}),k&&(p.complete=function(a){k(a,m)}),g[g.length]=o=e(this,null,null,p)),{stop:function(){for(;g.length;)g.pop().stop();o&&o.stop()}}}return c=c||{},f=e(this,a,b,c),{stop:function(){f.stop()}}}}(x,H,L,M),O=function(){return function(a,b){var c,d,e=this;if("object"==typeof a){c=[];for(d in a)a.hasOwnProperty(d)&&(c[c.length]=this.on(d,a[d]));return{cancel:function(){for(;c.length;)c.pop().cancel()}}}return this._subs[a]?this._subs[a].push(b):this._subs[a]=[b],{cancel:function(){e.off(a,b)}}}}(),P=function(){return function(a,b){var c,d;if(!b)if(a)this._subs[a]=[];else for(a in this._subs)delete this._subs[a];c=this._subs[a],c&&(d=c.indexOf(b),-1!==d&&c.splice(d,1))}}(),Q=function(){return function(a){var b,c,d,e,f,g,h,i;if(g=a.root,h=a.keypath,i=a.priority,b=g._deps[i]||(g._deps[i]={}),c=b[h]||(b[h]=[]),c[c.length]=a,a.registered=!0,h)for(d=h.split(".");d.length;)d.pop(),e=d.join("."),f=g._depsMap[e]||(g._depsMap[e]=[]),void 0===f[h]&&(f[h]=0,f[f.length]=h),f[h]+=1,h=e}}(),R=function(){return function(a){var b,c,d,e,f,g,h,i;if(g=a.root,h=a.keypath,i=a.priority,b=g._deps[i][h],c=b.indexOf(a),-1===c||!a.registered)throw new Error("Attempted to remove a dependant that was no longer registered! This should not happen. If you are seeing this bug in development please raise an issue at https://github.com/RactiveJS/Ractive/issues - thanks");if(b.splice(c,1),a.registered=!1,h)for(d=h.split(".");d.length;)d.pop(),e=d.join("."),f=g._depsMap[e],f[h]-=1,f[h]||(f.splice(f.indexOf(h),1),f[h]=void 0),h=e}}(),S=function(a){var b=function(a,b,c,d){var e=this;this.root=a,this.keypath=b,this.callback=c,this.defer=d.defer,this.debug=d.debug,this.proxy={update:function(){e.reallyUpdate()}},this.priority=0,this.context=d&&d.context?d.context:a};return b.prototype={init:function(a){a!==!1?this.update():this.value=this.root.get(this.keypath)},update:function(){return this.defer&&this.ready?(this.root._deferred.observers.push(this.proxy),void 0):(this.reallyUpdate(),void 0)},reallyUpdate:function(){var b,c;if(b=this.value,c=this.root.get(this.keypath),this.value=c,!this.updating){if(this.updating=!0,!a(c,b)||!this.ready)try{this.callback.call(this.context,c,b,this.keypath)}catch(d){if(this.debug||this.root.debug)throw d}this.updating=!1}}},b}(x),T=function(){return function(a,b){var c,d,e,f,g,h,i;for(c=b.split("."),f=[],h=function(b){var c,d;c=a._wrapped[b]?a._wrapped[b].get():a.get(b);for(d in c)g.push(b+"."+d)},i=function(a){return a+"."+d};d=c.shift();)"*"===d?(g=[],f.forEach(h),f=g):f[0]?f=f.map(i):f[0]=d;return e={},f.forEach(function(b){e[b]=a.get(b)}),e}}(),U=function(a,b){var c,d=/\*/;return c=function(a,b,c,d){this.root=a,this.callback=c,this.defer=d.defer,this.debug=d.debug,this.keypath=b,this.regex=new RegExp("^"+b.replace(/\./g,"\\.").replace(/\*/g,"[^\\.]+")+"$"),this.values={},this.defer&&(this.proxies=[]),this.priority="pattern",this.context=d&&d.context?d.context:a},c.prototype={init:function(a){var c,d;if(c=b(this.root,this.keypath),a!==!1)for(d in c)c.hasOwnProperty(d)&&this.update(d);else this.values=c},update:function(a){var c;{if(!d.test(a))return this.defer&&this.ready?(this.root._deferred.observers.push(this.getProxy(a)),void 0):(this.reallyUpdate(a),void 0);c=b(this.root,a);for(a in c)c.hasOwnProperty(a)&&this.update(a)}},reallyUpdate:function(b){var c=this.root.get(b);if(this.updating)return this.values[b]=c,void 0;if(this.updating=!0,!a(c,this.values[b])||!this.ready){try{this.callback.call(this.context,c,this.values[b],b)}catch(d){if(this.debug||this.root.debug)throw d}this.values[b]=c}this.updating=!1},getProxy:function(a){var b=this;return this.proxies[a]||(this.proxies[a]={update:function(){b.reallyUpdate(a)}}),this.proxies[a]}},c}(x,T),V=function(a,b,c,d,e){var f=/\*/,g={};return function(h,i,j,k){var l,m;return i=a(i),k=k||g,f.test(i)?(l=new e(h,i,j,k),h._patternObservers.push(l),m=!0):l=new d(h,i,j,k),b(l),l.init(k.init),l.ready=!0,{cancel:function(){var a;m&&(a=h._patternObservers.indexOf(l),-1!==a&&h._patternObservers.splice(a,1)),c(l)}}}}(i,Q,R,S,U),W=function(a,b){return function(c,d,e){var f,g=[];if(a(c)){e=d;for(f in c)c.hasOwnProperty(f)&&(d=c[f],g[g.length]=b(this,f,d,e));return{cancel:function(){for(;g.length;)g.pop().cancel()}}}return b(this,c,d,e)}}(w,V),X=function(){return function(a){var b,c,d,e=this._subs[a];if(e)for(b=Array.prototype.slice.call(arguments,1),c=0,d=e.length;d>c;c+=1)e[c].apply(this,b)}}(),Y=function(){return function(a){return this.el?this.fragment.find(a):null}}(),Z=function(a,b){var c,d,e,f,g,h,i,j;if(a){for(c=b("div"),d=["matches","matchesSelector"],g=["o","ms","moz","webkit"],j=function(a){return function(b,c){return b[a](c)}},h=d.length;h--;){if(e=d[h],c[e])return j(e);for(i=g.length;i--;)if(f=g[h]+e.substr(0,1).toUpperCase()+e.substring(1),c[f])return j(f)}return function(a,b){var c,d;for(c=(a.parentNode||a.document).querySelectorAll(b),d=c.length;d--;)if(c[d]===a)return!0;return!1}}}(f,e),$=function(a){return function(b,c){var d=this._isComponentQuery?!this.selector||b.name===this.selector:a(b.node,this.selector);return d?(this.push(b.node||b.instance),c||this._makeDirty(),!0):void 0}}(Z),_=function(){return function(){var a,b,c;a=this._root[this._isComponentQuery?"liveComponentQueries":"liveQueries"],b=this.selector,c=a.indexOf(b),-1!==c&&(a.splice(c,1),a[b]=null)}}(),ab=function(){function a(a){var b;return(b=a.parentFragment)?b.owner:a.component&&(b=a.component.parentFragment)?b.owner:void 0}function b(b){var c,d;for(c=[b],d=a(b);d;)c.push(d),d=a(d);return c}return function(a,c){var d,e,f,g,h,i,j,k,l,m;for(d=b(a.component||a._ractive.proxy),e=b(c.component||c._ractive.proxy),f=d[d.length-1],g=e[e.length-1];f&&f===g;)d.pop(),e.pop(),h=f,f=d[d.length-1],g=e[e.length-1];if(f=f.component||f,g=g.component||g,l=f.parentFragment,m=g.parentFragment,l===m)return i=l.items.indexOf(f),j=m.items.indexOf(g),i-j||d.length-e.length;if(k=h.fragments)return i=k.indexOf(l),j=k.indexOf(m),i-j||d.length-e.length;throw new Error("An unexpected condition was met while comparing the position of two components. Please file an issue at https://github.com/RactiveJS/Ractive/issues - thanks!")}}(),bb=function(a){return function(b,c){var d;return b.compareDocumentPosition?(d=b.compareDocumentPosition(c),2&d?1:-1):a(b,c)}}(ab),cb=function(a,b){return function(){this.sort(this._isComponentQuery?b:a),this._dirty=!1}}(bb,ab),db=function(){return function(){this._dirty||(this._root._deferred.liveQueries.push(this),this._dirty=!0)}}(),eb=function(){return function(a){var b=this.indexOf(this._isComponentQuery?a.instance:a.node);-1!==b&&this.splice(b,1)}}(),fb=function(a,b,c,d,e,f){return function(g,h,i,j){var k;return k=[],a(k,{selector:{value:h},live:{value:i},_isComponentQuery:{value:j},_test:{value:b}}),i?(a(k,{cancel:{value:c},_root:{value:g},_sort:{value:d},_makeDirty:{value:e},_remove:{value:f},_dirty:{value:!1,writable:!0}}),k):k}}(h,$,_,cb,db,eb),gb=function(a,b,c,d){return function(a,b){var c,e;return this.el?(b=b||{},c=this._liveQueries,(e=c[a])?b&&b.live?e:e.slice():(e=d(this,a,!!b.live,!1),e.live&&(c.push(a),c[a]=e),this.fragment.findAll(a,e),e)):[]}}(I,Z,h,fb),hb=function(){return function(a){return this.fragment.findComponent(a)}}(),ib=function(a,b,c,d){return function(a,b){var c,e;return b=b||{},c=this._liveComponentQueries,(e=c[a])?b&&b.live?e:e.slice():(e=d(this,a,!!b.live,!0),e.live&&(c.push(a),c[a]=e),this.fragment.findAllComponents(a,e),e)}}(I,Z,h,fb),jb=function(){return function(a){var b;return"undefined"!=typeof window&&document&&a?a.nodeType?a:"string"==typeof a&&(b=document.getElementById(a),!b&&document.querySelector&&(b=document.querySelector(a)),b&&b.nodeType)?b:a[0]&&a[0].nodeType?a[0]:null:null}}(),kb=function(a,b){return function(c,d){var e,f,g,h,i;if(c.owner=d.owner,g=c.owner.parentFragment,c.root=d.root,c.pNode=d.pNode,c.contextStack=d.contextStack||[],c.owner.type===a.SECTION&&(c.index=d.index),g&&(h=g.indexRefs)){c.indexRefs=b(null);for(i in h)c.indexRefs[i]=h[i]}for(c.priority=g?g.priority+1:1,d.indexRef&&(c.indexRefs||(c.indexRefs={}),c.indexRefs[d.indexRef]=d.index),c.items=[],e=d.descriptor?d.descriptor.length:0,f=0;e>f;f+=1)c.items[c.items.length]=c.createItem({parentFragment:c,descriptor:d.descriptor[f],index:f})}}(k,c),lb=function(a){var b={};return function(c,d,e){var f,g=[];if(c)for(f=b[d]||(b[d]=a(d)),f.innerHTML=c;f.firstChild;)g[g.length]=f.firstChild,e.appendChild(f.firstChild);return g}}(e),mb=function(a){var b,c,d;return c=//g,b=function(b,c){this.type=a.TEXT,this.descriptor=b.descriptor,c&&(this.node=document.createTextNode(b.descriptor),c.appendChild(this.node))},b.prototype={detach:function(){return this.node.parentNode.removeChild(this.node),this.node},teardown:function(a){a&&this.detach()},firstNode:function(){return this.node},toString:function(){return(""+this.descriptor).replace(c,"<").replace(d,">")}},b}(k),nb=function(a){return function(b){if(b.keypath)a(b);else{var c=b.root._pendingResolution.indexOf(b);-1!==c&&b.root._pendingResolution.splice(c,1)}}}(R),ob=function(a,b,c,d,e){function f(a,b,d){var e,f,g;if(!h.test(a.toString()))return c(a,"_nowrap",{value:!0}),a;if(!a["_"+b._guid]){c(a,"_"+b._guid,{value:function(){var c,d,e,g;if(c=b._captured,c||(b._captured=[]),d=a.apply(b,arguments),b._captured.length)for(e=f.length;e--;)g=f[e],g.updateSoftDependencies(b._captured);return b._captured=c,d},writable:!0});for(e in a)a.hasOwnProperty(e)&&(a["_"+b._guid][e]=a[e]);a["_"+b._guid+"_evaluators"]=[]}return f=a["_"+b._guid+"_evaluators"],g=f.indexOf(d),-1===g&&f.push(d),a["_"+b._guid]}var g,h;return h=/this/,g=function(b,c,e,g,h){var i;this.evaluator=e,this.keypath=c,this.root=b,this.argNum=g,this.type=a.REFERENCE,this.priority=h,i=b.get(c),"function"==typeof i&&(i=f(i,b,e)),this.value=e.values[g]=i,d(this)},g.prototype={update:function(){var a=this.root.get(this.keypath);"function"!=typeof a||a._nowrap||(a=f(a,this.root,this.evaluator)),b(a,this.value)||(this.evaluator.values[this.argNum]=a,this.evaluator.bubble(),this.value=a)},teardown:function(){e(this)}},g}(k,x,g,Q,R),pb=function(a,b,c){var d=function(a,c,d){this.root=a,this.keypath=c,this.priority=d.priority,this.evaluator=d,b(this)};return d.prototype={update:function(){var b=this.root.get(this.keypath);a(b,this.value)||(this.evaluator.bubble(),this.value=b)},teardown:function(){c(this)}},d}(x,Q,R),qb=function(a,b,c,d,e,f,g,h,i){function j(a,b){var c,d;if(a=a.replace(/\$\{([0-9]+)\}/g,"_$1"),l[a])return l[a];for(d=[];b--;)d[b]="_"+b;return c=new Function(d.join(","),"return("+a+")"),l[a]=c,c}var k,l={};return k=function(a,b,c,d,e){var f,g;for(this.root=a,this.keypath=b,this.priority=e,this.fn=j(c,d.length),this.values=[],this.refs=[],f=d.length;f--;)(g=d[f])?g[0]?this.values[f]=g[1]:this.refs[this.refs.length]=new h(a,g[1],this,f,e):this.values[f]=void 0;this.selfUpdating=this.refs.length<=1,this.update()},k.prototype={bubble:function(){this.selfUpdating?this.update():this.deferred||(this.root._deferred.evals.push(this),this.deferred=!0)},update:function(){var b;if(this.evaluating)return this;this.evaluating=!0;try{b=this.fn.apply(null,this.values)}catch(e){if(this.root.debug)throw e;b=void 0}return a(b,this.value)||(c(this.root,this.keypath),this.root._cache[this.keypath]=b,g(this.root,this.keypath,b,!0),this.value=b,d(this.root,this.keypath)),this.evaluating=!1,this},teardown:function(){for(;this.refs.length;)this.refs.pop().teardown();c(this.root,this.keypath),this.root._evaluators[this.keypath]=null},refresh:function(){this.selfUpdating||(this.deferred=!0);for(var a=this.refs.length;a--;)this.refs[a].update();this.deferred&&(this.update(),this.deferred=!1)},updateSoftDependencies:function(a){var b,c,d;for(this.softRefs||(this.softRefs=[]),b=this.softRefs.length;b--;)d=this.softRefs[b],a[d.keypath]||(this.softRefs.splice(b,1),this.softRefs[d.keypath]=!1,d.teardown());for(b=a.length;b--;)c=a[b],this.softRefs[c]||(d=new i(this.root,c,this),this.softRefs[this.softRefs.length]=d,this.softRefs[c]=!0);this.selfUpdating=this.refs.length+this.softRefs.length<=1}},k}(x,g,m,r,Q,R,u,ob,pb),rb=function(a,b){var c=function(b,c,d,e){var f,g;g=this.root=b.root,f=a(g,c,d),void 0!==f?b.resolveRef(e,!1,f):(this.ref=c,this.argNum=e,this.resolver=b,this.contextStack=d,g._pendingResolution[g._pendingResolution.length]=this)};return c.prototype={resolve:function(a){this.keypath=a,this.resolver.resolveRef(this.argNum,!1,a)},teardown:function(){this.keypath||b(this)}},c}(y,nb),sb=function(){var a=/^(?:(?:[a-zA-Z$_][a-zA-Z$_0-9]*)|(?:[0-9]|[1-9][0-9]+))$/;return function(b){var c,d,e;for(c=b.split("."),e=c.length;e--;)if(d=c[e],"undefined"===d||!a.test(d))return!1;return!0}}(),tb=function(a,b){return function(c,d){var e,f;return e=c.replace(/\$\{([0-9]+)\}/g,function(a,b){return d[b]?d[b][1]:"undefined"}),f=a(e),b(f)?f:"${"+e.replace(/[\.\[\]]/g,"-")+"}"}}(i,sb),ub=function(a,b){function c(a,b,c){var e,f;if(e=a._depsMap[b])for(f=e.length;f--;)d(a,e[f],c)}function d(a,b,d){var e,f,g,h;for(e=a._deps.length;e--;)if(f=a._deps[e],f&&(g=f[b]))for(h=g.length;h--;)d.push(g[h]);c(a,b,d)}return function(c,e,f){var g,h,i;for(g=[],d(c,e,g),h=g.length;h--;)i=g[h],b(i),i.keypath=i.keypath.replace(e,f),a(i),i.update()}}(Q,R),vb=function(a,b,c,d){var e=function(a){var c,d,e,f,g;if(this.root=a.root,this.mustache=a,this.args=[],this.scouts=[],c=a.descriptor.x,g=a.parentFragment.indexRefs,this.str=c.s,e=this.unresolved=this.args.length=c.r?c.r.length:0,!e)return this.resolved=this.ready=!0,this.bubble(),void 0;for(d=0;e>d;d+=1)f=c.r[d],g&&void 0!==g[f]?this.resolveRef(d,!0,g[f]):this.scouts[this.scouts.length]=new b(this,f,a.contextStack,d);this.ready=!0,this.bubble()};return e.prototype={bubble:function(){var a;this.ready&&(a=this.keypath,this.keypath=c(this.str,this.args),"${"===this.keypath.substr(0,2)&&this.createEvaluator(),a?d(this.root,a,this.keypath):this.mustache.resolve(this.keypath))},teardown:function(){for(;this.scouts.length;)this.scouts.pop().teardown()},resolveRef:function(a,b,c){this.args[a]=[b,c],this.bubble(),this.resolved=!--this.unresolved},createEvaluator:function(){this.root._evaluators[this.keypath]?this.root._evaluators[this.keypath].refresh():this.root._evaluators[this.keypath]=new a(this.root,this.keypath,this.str,this.args,this.mustache.priority)}},e}(qb,rb,tb,ub),wb=function(a,b){return function(c,d){var e,f,g;g=c.parentFragment=d.parentFragment,c.root=g.root,c.contextStack=g.contextStack,c.descriptor=d.descriptor,c.index=d.index||0,c.priority=g.priority,c.type=d.descriptor.t,d.descriptor.r&&(g.indexRefs&&void 0!==g.indexRefs[d.descriptor.r]?(f=g.indexRefs[d.descriptor.r],c.indexRef=d.descriptor.r,c.value=f,c.render(c.value)):(e=a(c.root,d.descriptor.r,c.contextStack),void 0!==e?c.resolve(e):(c.ref=d.descriptor.r,c.root._pendingResolution[c.root._pendingResolution.length]=c))),d.descriptor.x&&(c.expressionResolver=new b(c)),c.descriptor.n&&!c.hasOwnProperty("value")&&c.render(void 0) -}}(y,vb),xb=function(a,b,c){return function(d){d!==this.keypath&&(this.registered&&c(this),this.keypath=d,b(this),this.update(),this.root.twoway&&this.parentFragment.owner.type===a.ATTRIBUTE&&this.parentFragment.owner.element.bind(),this.expressionResolver&&this.expressionResolver.resolved&&(this.expressionResolver=null))}}(k,Q,R),yb=function(a){return function(){var b,c;c=this.root.get(this.keypath),(b=this.root._wrapped[this.keypath])&&(c=b.get()),a(c,this.value)||(this.render(c),this.value=c)}}(x),zb=function(a,b,c,d,e){var f,g,h;return g=//g,f=function(b,d){this.type=a.INTERPOLATOR,d&&(this.node=document.createTextNode(""),d.appendChild(this.node)),c(this,b)},f.prototype={update:e,resolve:d,detach:function(){return this.node.parentNode.removeChild(this.node),this.node},teardown:function(a){a&&this.detach(),b(this)},render:function(a){this.node&&(this.node.data=void 0==a?"":a)},firstNode:function(){return this.node},toString:function(){var a=void 0!=this.value?""+this.value:"";return a.replace(g,"<").replace(h,">")}},f}(k,nb,wb,xb,yb),Ab=function(a,b,c){function d(a,b,c){var d,e,f;if(e=b.length,ea.length)for(d=a.length;e>d;d+=1)c.contextStack=a.contextStack.concat(a.keypath+"."+d),c.index=d,a.descriptor.i&&(c.indexRef=a.descriptor.i),a.fragments[d]=a.createFragment(c);a.length=e}function e(a,b,d){var e,f;f=a.fragmentsById||(a.fragmentsById=c(null));for(e in f)void 0===b[e]&&f[e]&&(f[e].teardown(!0),f[e]=null);for(e in b)void 0===b[e]||f[e]||(d.contextStack=a.contextStack.concat(a.keypath+"."+e),d.index=e,a.descriptor.i&&(d.indexRef=a.descriptor.i),f[e]=a.createFragment(d))}function f(a,b){a.length||(b.contextStack=a.contextStack.concat(a.keypath),b.index=0,a.fragments[0]=a.createFragment(b),a.length=1)}function g(b,c,d,e){var f,g,h,i;if(g=a(c)&&0===c.length,f=d?g||!c:c&&!g){if(b.length||(e.contextStack=b.contextStack,e.index=0,b.fragments[0]=b.createFragment(e),b.length=1),b.length>1)for(h=b.fragments.splice(1);i=h.pop();)i.teardown(!0)}else b.length&&(b.teardownFragments(!0),b.length=0)}return function(c,h){var i;return i={descriptor:c.descriptor.f,root:c.root,pNode:c.parentFragment.pNode,owner:c},c.descriptor.n?(g(c,h,!0,i),void 0):(a(h)?d(c,h,i):b(h)?c.descriptor.i?e(c,h,i):f(c,i):g(c,h,!1,i),void 0)}}(l,w,c),Bb=function(a,b,c){function d(b,c,g,h,i,j,k){var l,m,n,o;if(!b.html){for(b.indexRefs&&void 0!==b.indexRefs[c]&&(b.indexRefs[c]=h),l=b.contextStack.length;l--;)n=b.contextStack[l],n.substr(0,j.length)===j&&(b.contextStack[l]=n.replace(j,k));for(l=b.items.length;l--;)switch(m=b.items[l],m.type){case a.ELEMENT:e(m,c,g,h,i,j,k);break;case a.PARTIAL:d(m.fragment,c,g,h,i,j,k);break;case a.COMPONENT:d(m.instance.fragment,c,g,h,i,j,k),(o=b.root._liveComponentQueries[m.name])&&o._makeDirty();break;case a.SECTION:case a.INTERPOLATOR:case a.TRIPLE:f(m,c,g,h,i,j,k)}}}function e(a,b,c,e,f,g,h){var i,j,k,l,m,n,o,p,q,r;for(i=a.attributes.length;i--;)j=a.attributes[i],j.fragment&&(d(j.fragment,b,c,e,f,g,h),j.twoway&&j.updateBindings());if(k=a.node._ractive){k.keypath.substr(0,g.length)===g&&(k.keypath=k.keypath.replace(g,h)),void 0!==b&&(k.index[b]=e);for(l in k.events)for(m=k.events[l].proxies,i=m.length;i--;)n=m[i],"object"==typeof n.n&&d(n.a,b,c,e,f,g,h),n.d&&d(n.d,b,c,e,f,g,h);(o=k.binding)&&o.keypath.substr(0,g.length)===g&&(p=k.root._twowayBindings[o.keypath],p.splice(p.indexOf(o),1),o.keypath=o.keypath.replace(g,h),p=k.root._twowayBindings[o.keypath]||(k.root._twowayBindings[o.keypath]=[]),p.push(o))}if(a.fragment&&d(a.fragment,b,c,e,f,g,h),q=a.liveQueries)for(r=a.root,i=q.length;i--;)r._liveQueries[q[i]]._makeDirty()}function f(a,b,e,f,g,h,i){var j;if(a.descriptor.x&&(a.expressionResolver&&a.expressionResolver.teardown(),a.expressionResolver=new c(a)),a.keypath?a.keypath.substr(0,h.length)===h&&a.resolve(a.keypath.replace(h,i)):a.indexRef===b&&(a.value=f,a.render(f)),a.fragments)for(j=a.fragments.length;j--;)d(a.fragments[j],b,e,f,g,h,i)}return d}(k,R,vb),Cb=function(a,b,c){return function(a,d,e,f,g){var h,i,j,k,l,m,n;for(j=d.descriptor.i,h=e;f>h;h+=1)i=d.fragments[h],k=h-g,l=h,m=d.keypath+"."+(h-g),n=d.keypath+"."+h,i.index+=g,b(i,j,k,l,g,m,n);c(a)}}(k,Bb,o),Db=function(a){return function(b){var c,d,e,f,g,h,i,j,k,l,m=this;if(c=this.parentFragment,h=[],b.forEach(function(b,c){var f,g,j;return b===c?(h[b]=m.fragments[c],void 0):(void 0===d&&(d=c),-1===b?((i||(i=[])).push(m.fragments[c]),void 0):(f=b-c,g=m.keypath+"."+c,j=m.keypath+"."+b,a(m.fragments[c],m.descriptor.i,c,b,f,g,j),h[b]=m.fragments[c],e=!0,void 0))}),i)for(;k=i.pop();)k.teardown(!0);if(void 0===d&&(d=this.length),g=this.root.get(this.keypath).length,g!==d){for(j={descriptor:this.descriptor.f,root:this.root,pNode:c.pNode,owner:this},this.descriptor.i&&(j.indexRef=this.descriptor.i),f=d;g>f;f+=1)(k=h[f])?this.docFrag.appendChild(k.detach(!1)):(j.contextStack=this.contextStack.concat(this.keypath+"."+f),j.index=f,k=this.createFragment(j)),this.fragments[f]=k;l=c.findNextNode(this),c.pNode.insertBefore(this.docFrag,l),this.length=g}}}(Bb),Eb=function(){return[]}(),Fb=function(a,b,c,d,e,f,g,h,i,j,k){var l,m;return k.push(function(){m=k.DomFragment}),l=function(b,d){this.type=a.SECTION,this.inverted=!!b.descriptor.n,this.fragments=[],this.length=0,d&&(this.docFrag=document.createDocumentFragment()),this.initialising=!0,c(this,b),d&&d.appendChild(this.docFrag),this.initialising=!1},l.prototype={update:d,resolve:e,smartUpdate:function(a,b){var c;("push"===a||"unshift"===a||"splice"===a)&&(c={descriptor:this.descriptor.f,root:this.root,pNode:this.parentFragment.pNode,owner:this},this.descriptor.i&&(c.indexRef=this.descriptor.i)),this[a]&&(this.rendering=!0,this[a](c,b),this.rendering=!1)},pop:function(){this.length&&(this.fragments.pop().teardown(!0),this.length-=1)},push:function(a,b){var c,d,e;for(c=this.length,d=c+b.length,e=c;d>e;e+=1)a.contextStack=this.contextStack.concat(this.keypath+"."+e),a.index=e,this.fragments[e]=this.createFragment(a);this.length+=b.length,this.parentFragment.pNode.insertBefore(this.docFrag,this.parentFragment.findNextNode(this))},shift:function(){this.splice(null,[0,1])},unshift:function(a,b){this.splice(a,[0,0].concat(new Array(b.length)))},splice:function(a,b){var c,d,e,f,g,i,j,k,l;if(b.length&&(i=+(b[0]<0?this.length+b[0]:b[0]),d=Math.max(0,b.length-2),e=void 0!==b[1]?b[1]:this.length-i,e=Math.min(e,this.length-i),f=d-e)){if(0>f){for(j=i-f,g=i;j>g;g+=1)this.fragments[g].teardown(!0);this.fragments.splice(i,-f)}else{for(j=i+f,c=this.fragments[i]?this.fragments[i].firstNode():this.parentFragment.findNextNode(this),k=[i,0].concat(new Array(f)),this.fragments.splice.apply(this.fragments,k),g=i;j>g;g+=1)a.contextStack=this.contextStack.concat(this.keypath+"."+g),a.index=g,this.fragments[g]=this.createFragment(a);this.parentFragment.pNode.insertBefore(this.docFrag,c)}this.length+=f,l=i+d,h(this.root,this,l,this.length,f)}},merge:i,detach:function(){var a,b;for(b=this.fragments.length,a=0;b>a;a+=1)this.docFrag.appendChild(this.fragments[a].detach());return this.docFrag},teardown:function(a){this.teardownFragments(a),j(this)},firstNode:function(){return this.fragments[0]?this.fragments[0].firstNode():this.parentFragment.findNextNode(this)},findNextNode:function(a){return this.fragments[a.index+1]?this.fragments[a.index+1].firstNode():this.parentFragment.findNextNode(this)},teardownFragments:function(a){for(var b,c;c=this.fragments.shift();)c.teardown(a);if(this.fragmentsById)for(b in this.fragmentsById)this.fragments[b]&&(this.fragmentsById[b].teardown(a),this.fragmentsById[b]=null)},render:function(a){var c,d;(d=this.root._wrapped[this.keypath])&&(a=d.get()),this.rendering||(this.rendering=!0,f(this,a),this.rendering=!1,(!this.docFrag||this.docFrag.childNodes.length)&&!this.initialising&&b&&(c=this.parentFragment.findNextNode(this),c&&c.parentNode===this.parentFragment.pNode?this.parentFragment.pNode.insertBefore(this.docFrag,c):this.parentFragment.pNode.appendChild(this.docFrag)))},createFragment:function(a){var b=new m(a);return this.docFrag&&this.docFrag.appendChild(b.docFrag),b},toString:function(){var a,b,c,d;for(a="",b=0,d=this.length,b=0;d>b;b+=1)a+=this.fragments[b].toString();if(this.fragmentsById)for(c in this.fragmentsById)this.fragmentsById[c]&&(a+=this.fragmentsById[c].toString());return a},find:function(a){var b,c,d;for(c=this.fragments.length,b=0;c>b;b+=1)if(d=this.fragments[b].find(a))return d;return null},findAll:function(a,b){var c,d;for(d=this.fragments.length,c=0;d>c;c+=1)this.fragments[c].findAll(a,b)},findComponent:function(a){var b,c,d;for(c=this.fragments.length,b=0;c>b;b+=1)if(d=this.fragments[b].findComponent(a))return d;return null},findAllComponents:function(a,b){var c,d;for(d=this.fragments.length,c=0;d>c;c+=1)this.fragments[c].findAllComponents(a,b)}},l}(k,f,wb,yb,xb,Ab,Bb,Cb,Db,nb,Eb),Gb=function(a,b,c,d,e,f,g){var h=function(b,d){this.type=a.TRIPLE,d&&(this.nodes=[],this.docFrag=document.createDocumentFragment()),this.initialising=!0,c(this,b),d&&d.appendChild(this.docFrag),this.initialising=!1};return h.prototype={update:d,resolve:e,detach:function(){for(var a=this.nodes.length;a--;)this.docFrag.appendChild(this.nodes[a]);return this.docFrag},teardown:function(a){a&&(this.detach(),this.docFrag=this.nodes=null),g(this)},firstNode:function(){return this.nodes[0]?this.nodes[0]:this.parentFragment.findNextNode(this)},render:function(a){var b,c;if(this.nodes){for(;this.nodes.length;)b=this.nodes.pop(),b.parentNode.removeChild(b);if(!a)return this.nodes=[],void 0;c=this.parentFragment.pNode,this.nodes=f(a,c.tagName,this.docFrag),this.initialising||c.insertBefore(this.docFrag,this.parentFragment.findNextNode(this))}},toString:function(){return void 0!=this.value?this.value:""},find:function(a){var c,d,e,f;for(d=this.nodes.length,c=0;d>c;c+=1)if(e=this.nodes[c],1===e.nodeType){if(b(e,a))return e;if(f=e.querySelector(a))return f}return null},findAll:function(a,c){var d,e,f,g,h,i;for(e=this.nodes.length,d=0;e>d;d+=1)if(f=this.nodes[d],1===f.nodeType&&(b(f,a)&&c.push(f),g=f.querySelectorAll(a)))for(h=g.length,i=0;h>i;i+=1)c.push(g[i])}},h}(k,Z,wb,yb,xb,lb,nb),Hb=function(a){return function(b,c){return b.a&&b.a.xmlns?b.a.xmlns:"svg"===b.e?a.svg:c.namespaceURI||a.html}}(d),Ib=function(){var a,b,c,d;return a="altGlyph altGlyphDef altGlyphItem animateColor animateMotion animateTransform clipPath feBlend feColorMatrix feComponentTransfer feComposite feConvolveMatrix feDiffuseLighting feDisplacementMap feDistantLight feFlood feFuncA feFuncB feFuncG feFuncR feGaussianBlur feImage feMerge feMergeNode feMorphology feOffset fePointLight feSpecularLighting feSpotLight feTile feTurbulence foreignObject glyphRef linearGradient radialGradient textPath vkern".split(" "),b="attributeName attributeType baseFrequency baseProfile calcMode clipPathUnits contentScriptType contentStyleType diffuseConstant edgeMode externalResourcesRequired filterRes filterUnits glyphRef gradientTransform gradientUnits kernelMatrix kernelUnitLength keyPoints keySplines keyTimes lengthAdjust limitingConeAngle markerHeight markerUnits markerWidth maskContentUnits maskUnits numOctaves pathLength patternContentUnits patternTransform patternUnits pointsAtX pointsAtY pointsAtZ preserveAlpha preserveAspectRatio primitiveUnits refX refY repeatCount repeatDur requiredExtensions requiredFeatures specularConstant specularExponent spreadMethod startOffset stdDeviation stitchTiles surfaceScale systemLanguage tableValues targetX targetY textLength viewBox viewTarget xChannelSelector yChannelSelector zoomAndPan".split(" "),c=function(a){for(var b={},c=a.length;c--;)b[a[c].toLowerCase()]=a[c];return b},d=c(a.concat(b)),function(a){var b=a.toLowerCase();return d[b]||b}}(),Jb=function(a,b){return function(c,d){var e,f;if(e=d.indexOf(":"),-1===e||(f=d.substr(0,e),"xmlns"===f))c.name=c.element.namespace!==a.html?b(d):d,c.lcName=c.name.toLowerCase();else if(d=d.substring(e+1),c.name=b(d),c.lcName=c.name.toLowerCase(),c.namespace=a[f.toLowerCase()],!c.namespace)throw'Unknown namespace ("'+f+'")'}}(d,Ib),Kb=function(a){return function(b,c){var d,e=null===c.value?"":c.value;(d=c.pNode)&&(b.namespace?d.setAttributeNS(b.namespace,c.name,e):"style"===c.name&&d.style.setAttribute?d.style.setAttribute("cssText",e):"class"!==c.name||d.namespaceURI&&d.namespaceURI!==a.html?d.setAttribute(c.name,e):d.className=e,"id"===b.name&&(c.root.nodes[c.value]=d),"value"===b.name&&(d._ractive.value=c.value)),b.value=c.value}}(d),Lb=function(a){var b={"accept-charset":"acceptCharset",accesskey:"accessKey",bgcolor:"bgColor","class":"className",codebase:"codeBase",colspan:"colSpan",contenteditable:"contentEditable",datetime:"dateTime",dirname:"dirName","for":"htmlFor","http-equiv":"httpEquiv",ismap:"isMap",maxlength:"maxLength",novalidate:"noValidate",pubdate:"pubDate",readonly:"readOnly",rowspan:"rowSpan",tabindex:"tabIndex",usemap:"useMap"};return function(c,d){var e;!c.pNode||c.namespace||d.pNode.namespaceURI&&d.pNode.namespaceURI!==a.html||(e=b[c.name]||c.name,void 0!==d.pNode[e]&&(c.propertyName=e),("boolean"==typeof d.pNode[e]||"value"===e)&&(c.useProperty=!0))}}(d),Mb=function(a,b,c,d){var e,f,g,h,i,j,k,l,m,n,o,p,q,r;return e=function(){var a,b,c,d=this.pNode;return this.fragment?(a=f(this))?(this.interpolator=a,this.keypath=a.keypath||a.descriptor.r,(b=i(this))?(d._ractive.binding=this.element.binding=b,this.twoway=!0,c=this.root._twowayBindings[this.keypath]||(this.root._twowayBindings[this.keypath]=[]),c[c.length]=b,!0):!1):!1:!1},g=function(){this._ractive.binding.update()},h=function(){var a=this._ractive.root.get(this._ractive.binding.keypath);this.value=void 0==a?"":a},f=function(c){var d,e;return 1!==c.fragment.items.length?null:(d=c.fragment.items[0],d.type!==a.INTERPOLATOR?null:d.keypath||d.ref?d.keypath&&"${"===d.keypath.substr(0,2)?(e="You cannot set up two-way binding against an expression "+d.keypath,c.root.debug&&b(e),null):d:null)},i=function(a){var c=a.pNode;if("SELECT"===c.tagName)return c.multiple?new k(a,c):new l(a,c);if("checkbox"===c.type||"radio"===c.type){if("name"===a.propertyName){if("checkbox"===c.type)return new n(a,c);if("radio"===c.type)return new m(a,c)}return"checked"===a.propertyName?new o(a,c):null}return"value"!==a.lcName&&b("This is... odd"),"file"===c.type?new p(a,c):c.getAttribute("contenteditable")?new q(a,c):new r(a,c)},k=function(a,b){var c;j(this,a,b),b.addEventListener("change",g,!1),c=this.root.get(this.keypath),void 0===c&&this.update()},k.prototype={value:function(){var a,b,c,d;for(a=[],b=this.node.options,d=b.length,c=0;d>c;c+=1)b[c].selected&&(a[a.length]=b[c]._ractive.value);return a},update:function(){var a,b,d;return a=this.attr,b=a.value,d=this.value(),void 0!==b&&c(d,b)||(a.receiving=!0,a.value=d,this.root.set(this.keypath,d),a.receiving=!1),this},deferUpdate:function(){this.deferred!==!0&&(this.root._deferred.attrs.push(this),this.deferred=!0)},teardown:function(){this.node.removeEventListener("change",g,!1)}},l=function(a,b){var c;j(this,a,b),b.addEventListener("change",g,!1),c=this.root.get(this.keypath),void 0===c&&this.update()},l.prototype={value:function(){var a,b,c;for(a=this.node.options,c=a.length,b=0;c>b;b+=1)if(a[b].selected)return a[b]._ractive.value},update:function(){var a=this.value();return this.attr.receiving=!0,this.attr.value=a,this.root.set(this.keypath,a),this.attr.receiving=!1,this},deferUpdate:function(){this.deferred!==!0&&(this.root._deferred.attrs.push(this),this.deferred=!0)},teardown:function(){this.node.removeEventListener("change",g,!1)}},m=function(a,b){var c;this.radioName=!0,j(this,a,b),b.name="{{"+a.keypath+"}}",b.addEventListener("change",g,!1),b.attachEvent&&b.addEventListener("click",g,!1),c=this.root.get(this.keypath),void 0!==c?b.checked=c==b._ractive.value:this.root._deferred.radios.push(this)},m.prototype={value:function(){return this.node._ractive?this.node._ractive.value:this.node.value},update:function(){var a=this.node;a.checked&&(this.attr.receiving=!0,this.root.set(this.keypath,this.value()),this.attr.receiving=!1)},teardown:function(){this.node.removeEventListener("change",g,!1),this.node.removeEventListener("click",g,!1)}},n=function(a,b){var c,d;this.checkboxName=!0,j(this,a,b),b.name="{{"+this.keypath+"}}",b.addEventListener("change",g,!1),b.attachEvent&&b.addEventListener("click",g,!1),c=this.root.get(this.keypath),void 0!==c?(d=-1!==c.indexOf(b._ractive.value),b.checked=d):-1===this.root._deferred.checkboxes.indexOf(this.keypath)&&this.root._deferred.checkboxes.push(this.keypath)},n.prototype={changed:function(){return this.node.checked!==!!this.checked},update:function(){this.checked=this.node.checked,this.attr.receiving=!0,this.root.set(this.keypath,d(this.root,this.keypath)),this.attr.receiving=!1},teardown:function(){this.node.removeEventListener("change",g,!1),this.node.removeEventListener("click",g,!1)}},o=function(a,b){j(this,a,b),b.addEventListener("change",g,!1),b.attachEvent&&b.addEventListener("click",g,!1)},o.prototype={value:function(){return this.node.checked},update:function(){this.attr.receiving=!0,this.root.set(this.keypath,this.value()),this.attr.receiving=!1},teardown:function(){this.node.removeEventListener("change",g,!1),this.node.removeEventListener("click",g,!1)}},p=function(a,b){j(this,a,b),b.addEventListener("change",g,!1)},p.prototype={value:function(){return this.attr.pNode.files},update:function(){this.attr.root.set(this.attr.keypath,this.value())},teardown:function(){this.node.removeEventListener("change",g,!1)}},q=function(a,b){j(this,a,b),b.addEventListener("change",g,!1),this.root.lazy||(b.addEventListener("input",g,!1),b.attachEvent&&b.addEventListener("keyup",g,!1))},q.prototype={update:function(){this.attr.receiving=!0,this.root.set(this.keypath,this.node.innerHTML),this.attr.receiving=!1},teardown:function(){this.node.removeEventListener("change",g,!1),this.node.removeEventListener("input",g,!1),this.node.removeEventListener("keyup",g,!1)}},r=function(a,b){j(this,a,b),b.addEventListener("change",g,!1),this.root.lazy||(b.addEventListener("input",g,!1),b.attachEvent&&b.addEventListener("keyup",g,!1)),this.node.addEventListener("blur",h,!1)},r.prototype={value:function(){var a=this.attr.pNode.value;return+a+""===a&&-1===a.indexOf("e")&&(a=+a),a},update:function(){var a=this.attr,b=this.value();a.receiving=!0,a.root.set(a.keypath,b),a.receiving=!1},teardown:function(){this.node.removeEventListener("change",g,!1),this.node.removeEventListener("input",g,!1),this.node.removeEventListener("keyup",g,!1),this.node.removeEventListener("blur",h,!1)}},j=function(a,b,c){a.attr=b,a.node=c,a.root=b.root,a.keypath=b.keypath},e}(k,I,E,n),Nb=function(a,b){var c,d,e,f,g,h,i,j,k,l,m,n;return c=function(){var a;if(!this.ready)return this;if(a=this.pNode,"SELECT"===a.tagName&&"value"===this.lcName)return this.update=e,this.deferredUpdate=f,this.update();if(this.isFileInputValue)return this.update=d,this;if(this.twoway&&"name"===this.lcName){if("radio"===a.type)return this.update=i,this.update();if("checkbox"===a.type)return this.update=j,this.update()}return"style"===this.lcName&&a.style.setAttribute?(this.update=k,this.update()):"class"!==this.lcName||a.namespaceURI&&a.namespaceURI!==b.html?a.getAttribute("contenteditable")&&"value"===this.lcName?(this.update=m,this.update()):(this.update=n,this.update()):(this.update=l,this.update())},d=function(){return this},f=function(){this.deferredUpdate=this.pNode.multiple?h:g,this.deferredUpdate()},e=function(){return this.root._deferred.selectValues.push(this),this},g=function(){var a,b,c,d=this.fragment.getValue();for(this.value=this.pNode._ractive.value=d,a=this.pNode.options,c=a.length;c--;)if(b=a[c],b._ractive.value==d)return b.selected=!0,this;return this},h=function(){var b,c,d=this.fragment.getValue();for(a(d)||(d=[d]),b=this.pNode.options,c=b.length;c--;)b[c].selected=-1!==d.indexOf(b[c]._ractive.value);return this.value=d,this},i=function(){var a,b;return a=this.pNode,b=this.fragment.getValue(),a.checked=b==a._ractive.value,this},j=function(){var b,c;return b=this.pNode,c=this.fragment.getValue(),a(c)?(b.checked=-1!==c.indexOf(b._ractive.value),this):(b.checked=c==b._ractive.value,this)},k=function(){var a,b;return a=this.pNode,b=this.fragment.getValue(),void 0===b&&(b=""),b!==this.value&&(a.style.setAttribute("cssText",b),this.value=b),this},l=function(){var a,b;return a=this.pNode,b=this.fragment.getValue(),void 0===b&&(b=""),b!==this.value&&(a.className=b,this.value=b),this},m=function(){var a,b;return a=this.pNode,b=this.fragment.getValue(),void 0===b&&(b=""),b!==this.value&&(this.receiving||(a.innerHTML=b),this.value=b),this},n=function(){var a,b;if(a=this.pNode,b=this.fragment.getValue(),this.isValueAttribute&&(a._ractive.value=b),void 0===b&&(b=""),b!==this.value){if(this.useProperty)return this.receiving||(a[this.propertyName]=b),this.value=b,this;if(this.namespace)return a.setAttributeNS(this.namespace,this.name,b),this.value=b,this;"id"===this.lcName&&(void 0!==this.value&&(this.root.nodes[this.value]=void 0),this.root.nodes[b]=a),a.setAttribute(this.name,b),this.value=b}return this},c}(l,d),Ob=function(){return function(a){var b;return b=this.str.substr(this.pos,a.length),b===a?(this.pos+=a.length,a):null}}(),Pb=function(){var a=/^\s+/;return function(){var b=a.exec(this.remaining());return b?(this.pos+=b[0].length,b[0]):null}}(),Qb=function(){return function(a){return function(b){var c=a.exec(b.str.substring(b.pos));return c?(b.pos+=c[0].length,c[1]||c[0]):null}}}(),Rb=function(){function a(a){var b;return a.getStringMatch("\\")?(b=a.str.charAt(a.pos),a.pos+=1,b):null}return function(b){var c,d="";for(c=a(b);c;)d+=c,c=a(b);return d||null}}(),Sb=function(a,b){var c=a(/^[^\\"]+/),d=a(/^[^\\']+/);return function e(a,f){var g,h,i,j,k,l;if(g=a.pos,h="",l=f?d:c,i=b(a),i&&(h+=i),j=l(a),j&&(h+=j),!h)return"";for(k=e(a,f);""!==k;)h+=k;return h}}(Qb,Rb),Tb=function(a,b){return function(c){var d,e;return d=c.pos,c.getStringMatch('"')?(e=b(c,!1),c.getStringMatch('"')?{t:a.STRING_LITERAL,v:e}:(c.pos=d,null)):c.getStringMatch("'")?(e=b(c,!0),c.getStringMatch("'")?{t:a.STRING_LITERAL,v:e}:(c.pos=d,null)):null}}(k,Sb),Ub=function(a,b){var c=b(/^(?:[+-]?)(?:(?:(?:0|[1-9]\d*)?\.\d+)|(?:(?:0|[1-9]\d*)\.)|(?:0|[1-9]\d*))(?:[eE][+-]?\d+)?/);return function(b){var d;return(d=c(b))?{t:a.NUMBER_LITERAL,v:d}:null}}(k,Qb),Vb=function(a){return a(/^[a-zA-Z_$][a-zA-Z_$0-9]*/)}(Qb),Wb=function(a,b,c){var d=/^[a-zA-Z_$][a-zA-Z_$0-9]*$/;return function(e){var f;return(f=a(e))?d.test(f.v)?f.v:'"'+f.v.replace(/"/g,'\\"')+'"':(f=b(e))?f.v:(f=c(e))?f:void 0}}(Tb,Ub,Vb),Xb=function(a,b,c,d){function e(a){var b,c,e;return a.allowWhitespace(),(b=d(a))?(e={key:b},a.allowWhitespace(),a.getStringMatch(":")?(a.allowWhitespace(),(c=a.getToken())?(e.value=c.v,e):null):null):null}var f,g,h,i,j,k;return g={"true":!0,"false":!1,undefined:void 0,"null":null},h=new RegExp("^(?:"+Object.keys(g).join("|")+")"),i=/^(?:[+-]?)(?:(?:(?:0|[1-9]\d*)?\.\d+)|(?:(?:0|[1-9]\d*)\.)|(?:0|[1-9]\d*))(?:[eE][+-]?\d+)?/,j=/\$\{([^\}]+)\}/g,k=/^\$\{([^\}]+)\}/,f=function(a,b){this.str=a,this.values=b,this.pos=0,this.result=this.getToken()},f.prototype={remaining:function(){return this.str.substring(this.pos)},getStringMatch:a,getToken:function(){return this.allowWhitespace(),this.getPlaceholder()||this.getSpecial()||this.getNumber()||this.getString()||this.getObject()||this.getArray()},getPlaceholder:function(){var a;return this.values?(a=k.exec(this.remaining()))&&this.values.hasOwnProperty(a[1])?(this.pos+=a[0].length,{v:this.values[a[1]]}):void 0:null},getSpecial:function(){var a;return(a=h.exec(this.remaining()))?(this.pos+=a[0].length,{v:g[a[0]]}):void 0},getNumber:function(){var a;return(a=i.exec(this.remaining()))?(this.pos+=a[0].length,{v:+a[0]}):void 0},getString:function(){var a,b=c(this);return b&&(a=this.values)?{v:b.v.replace(j,function(b,c){return a[c]||c})}:b},getObject:function(){var a,b;if(!this.getStringMatch("{"))return null;for(a={};b=e(this);){if(a[b.key]=b.value,this.allowWhitespace(),this.getStringMatch("}"))return{v:a};if(!this.getStringMatch(","))return null}return null},getArray:function(){var a,b;if(!this.getStringMatch("["))return null;for(a=[];b=this.getToken();){if(a.push(b.v),this.getStringMatch("]"))return{v:a};if(!this.getStringMatch(","))return null}return null},allowWhitespace:b},function(a,b){var c=new f(a,b);return c.result?{value:c.result.v,remaining:c.remaining()}:null}}(Ob,Pb,Tb,Wb),Yb=function(a,b,c,d,e){function f(a){return"string"==typeof a?a:JSON.stringify(a)}var g=function(b){this.type=a.INTERPOLATOR,c(this,b)};return g.prototype={update:d,resolve:e,render:function(a){this.value=a,this.parentFragment.bubble()},teardown:function(){b(this)},toString:function(){return void 0==this.value?"":f(this.value)}},g}(k,nb,wb,yb,xb),Zb=function(a,b,c,d,e,f,g){var h,i;return g.push(function(){i=g.StringFragment}),h=function(c){this.type=a.SECTION,this.fragments=[],this.length=0,b(this,c)},h.prototype={update:c,resolve:d,teardown:function(){this.teardownFragments(),f(this)},teardownFragments:function(){for(;this.fragments.length;)this.fragments.shift().teardown();this.length=0},bubble:function(){this.value=this.fragments.join(""),this.parentFragment.bubble()},render:function(a){var b;(b=this.root._wrapped[this.keypath])&&(a=b.get()),e(this,a),this.parentFragment.bubble()},createFragment:function(a){return new i(a)},toString:function(){return this.fragments.join("")}},h}(k,wb,yb,xb,Ab,nb,Eb),$b=function(a){var b=function(b){this.type=a.TEXT,this.text=b};return b.prototype={toString:function(){return this.text},teardown:function(){}},b}(k),_b=function(a,b){return function(){var c,d,e,f,g,h,i;if(!this.argsList||this.dirty){if(c={},d=0,f=this.root._guid,i=function(a){return a.map(function(a){var b,e,g;return a.text?a.text:a.fragments?a.fragments.map(function(a){return i(a.items)}).join(""):(b=f+"-"+d++,g=(e=a.root._wrapped[a.keypath])?e.value:a.value,c[b]=g,"${"+b+"}")}).join("")},e=i(this.items),h=b("["+e+"]",c))this.argsList=h.value;else{if(g="Could not parse directive arguments ("+this.toString()+"). If you think this is a bug, please file an issue at http://github.com/RactiveJS/Ractive/issues",this.root.debug)throw new Error(g);a(g),this.argsList=[e]}this.dirty=!1}return this.argsList}}(I,Xb),ac=function(a,b,c,d,e,f,g,h){var i=function(a){c(this,a)};return i.prototype={createItem:function(b){if("string"==typeof b.descriptor)return new f(b.descriptor);switch(b.descriptor.t){case a.INTERPOLATOR:return new d(b);case a.TRIPLE:return new d(b);case a.SECTION:return new e(b);default:throw"Something went wrong in a rather interesting way"}},bubble:function(){this.dirty=!0,this.owner.bubble()},teardown:function(){var a,b;for(a=this.items.length,b=0;a>b;b+=1)this.items[b].teardown()},getValue:function(){var b;return 1===this.items.length&&this.items[0].type===a.INTERPOLATOR&&(b=this.items[0].value,void 0!==b)?b:this.toString()},isSimple:function(){var b,c,d;if(void 0!==this.simple)return this.simple;for(b=this.items.length;b--;)if(c=this.items[b],c.type!==a.TEXT){if(c.type!==a.INTERPOLATOR)return this.simple=!1;if(d)return!1;d=!0}return this.simple=!0},toString:function(){return this.items.join("")},toJSON:function(){var a,c=this.getValue();return"string"==typeof c&&(a=b(c),c=a?a.value:c),c},toArgsList:g},h.StringFragment=i,i}(k,Xb,kb,Yb,Zb,$b,_b,Eb),bc=function(a,b,c,d,e,f,g){var h=function(e){return this.type=a.ATTRIBUTE,this.element=e.element,b(this,e.name),null===e.value||"string"==typeof e.value?(c(this,e),void 0):(this.root=e.root,this.pNode=e.pNode,this.parentFragment=this.element.parentFragment,this.fragment=new g({descriptor:e.value,root:this.root,owner:this,contextStack:e.contextStack}),this.pNode&&("value"===this.name&&(this.isValueAttribute=!0,"INPUT"===this.pNode.tagName&&"file"===this.pNode.type&&(this.isFileInputValue=!0)),d(this,e),this.selfUpdating=this.fragment.isSimple(),this.ready=!0),void 0)};return h.prototype={bind:e,update:f,updateBindings:function(){this.keypath=this.interpolator.keypath||this.interpolator.ref,"name"===this.propertyName&&(this.pNode.name="{{"+this.keypath+"}}")},teardown:function(){var a;if(this.boundEvents)for(a=this.boundEvents.length;a--;)this.pNode.removeEventListener(this.boundEvents[a],this.updateModel,!1);this.fragment&&this.fragment.teardown()},bubble:function(){this.selfUpdating?this.update():!this.deferred&&this.ready&&(this.root._deferred.attrs.push(this),this.deferred=!0)},toString:function(){var a;return null===this.value?this.name:this.fragment?(a=this.fragment.toString(),this.name+"="+JSON.stringify(a)):this.name+"="+JSON.stringify(this.value)}},h}(k,Jb,Kb,Lb,Mb,Nb,ac),cc=function(a){return function(b,c){var d,e,f;b.attributes=[];for(d in c)c.hasOwnProperty(d)&&(e=c[d],f=new a({element:b,name:d,value:e,root:b.root,pNode:b.node,contextStack:b.parentFragment.contextStack}),b.attributes[b.attributes.length]=b.attributes[d]=f,"name"!==d&&f.update());return b.attributes}}(bc),dc=function(a,b,c,d){var e,f,g;return d.push(function(){e=d.DomFragment}),f=function(){var a=this.node,b=this.fragment.toString();a.styleSheet&&(a.styleSheet.cssText=b),a.innerHTML=b},g=function(){this.node.type&&"text/javascript"!==this.node.type||a("Script tag was updated. This does not cause the code to be re-evaluated!"),this.node.innerHTML=this.fragment.toString()},function(a,d,h,i){var j,k,l,m,n;if("script"===a.lcName||"style"===a.lcName)return a.fragment=new c({descriptor:h.f,root:a.root,contextStack:a.parentFragment.contextStack,owner:a}),i&&("script"===a.lcName?(a.bubble=g,a.node.innerHTML=a.fragment.toString()):(a.bubble=f,a.bubble())),void 0;if("string"!=typeof h.f||d&&d.namespaceURI&&d.namespaceURI!==b.html)a.fragment=new e({descriptor:h.f,root:a.root,pNode:d,contextStack:a.parentFragment.contextStack,owner:a}),i&&d.appendChild(a.fragment.docFrag);else if(a.html=h.f,i)for(d.innerHTML=a.html,j=a.root._liveQueries,k=j.length;k--;)if(l=j[k],(m=d.querySelectorAll(l))&&(n=m.length))for((a.liveQueries||(a.liveQueries=[])).push(l),a.liveQueries[l]=[];n--;)a.liveQueries[l][n]=m[n]}}(I,d,ac,Eb),ec=function(a,b){var c=function(c,d,e,f){var g,h,i;if(this.root=d,this.node=e.node,g=c.n||c,"string"!=typeof g&&(h=new b({descriptor:g,root:this.root,owner:e,contextStack:f}),g=h.toString(),h.teardown()),c.a?this.params=c.a:c.d&&(h=new b({descriptor:c.d,root:this.root,owner:e,contextStack:f}),this.params=h.toArgsList(),h.teardown()),this.fn=d.decorators[g],!this.fn){if(i='Missing "'+g+'" decorator. You may need to download a plugin via https://github.com/RactiveJS/Ractive/wiki/Plugins#decorators',d.debug)throw new Error(i);a(i)}};return c.prototype={init:function(){var a,b;if(this.params?(b=[this.node].concat(this.params),a=this.fn.apply(this.root,b)):a=this.fn.call(this.root,this.node),!a||!a.teardown)throw new Error("Decorator definition must return an object with a teardown method");this.teardown=a.teardown}},c}(I,ac),fc=function(a){return function(b,c,d,e){d.decorator=new a(b,c,d,e),d.decorator.fn&&c._deferred.decorators.push(d.decorator)}}(ec),gc=function(a,b){var c,d,e,f,g,h,i,j,k;return c=function(a,b,c,e,f){var g,h;g=a.node._ractive.events,h=g[b]||(g[b]=new d(a,b,e,f)),h.add(c)},d=function(b,c,d){var e;this.element=b,this.root=b.root,this.node=b.node,this.name=c,this.contextStack=d,this.proxies=[],(e=this.root.events[c])?this.custom=e(this.node,k(c)):("on"+c in this.node||a('Missing "'+this.name+'" event. You may need to download a plugin via https://github.com/RactiveJS/Ractive/wiki/Plugins#events'),this.node.addEventListener(c,j,!1))},d.prototype={add:function(a){this.proxies[this.proxies.length]=new e(this.element,this.root,a,this.contextStack)},teardown:function(){var a;for(this.custom?this.custom.teardown():this.node.removeEventListener(this.name,j,!1),a=this.proxies.length;a--;)this.proxies[a].teardown()},fire:function(a){for(var b=this.proxies.length;b--;)this.proxies[b].fire(a)}},e=function(a,c,d,e){var i;return this.root=c,i=d.n||d,this.n="string"==typeof i?i:new b({descriptor:d.n,root:this.root,owner:a,contextStack:e}),d.a?(this.a=d.a,this.fire=g,void 0):d.d?(this.d=new b({descriptor:d.d,root:this.root,owner:a,contextStack:e}),this.fire=h,void 0):(this.fire=f,void 0) -},e.prototype={teardown:function(){this.n.teardown&&this.n.teardown(),this.d&&this.d.teardown()},bubble:function(){}},f=function(a){this.root.fire(this.n.toString(),a)},g=function(a){this.root.fire.apply(this.root,[this.n.toString(),a].concat(this.a))},h=function(a){var b=this.d.toArgsList();"string"==typeof b&&(b=b.substr(1,b.length-2)),this.root.fire.apply(this.root,[this.n.toString(),a].concat(b))},j=function(a){var b=this._ractive;b.events[a.type].fire({node:this,original:a,index:b.index,keypath:b.keypath,context:b.root.get(b.keypath)})},i={},k=function(a){return i[a]?i[a]:i[a]=function(b){var c=b.node._ractive;b.index=c.index,b.keypath=c.keypath,b.context=c.root.get(c.keypath),c.events[a].fire(b)}},c}(I,ac),hc=function(a){return function(b,c){var d,e,f;for(e in c)if(c.hasOwnProperty(e))for(f=e.split("-"),d=f.length;d--;)a(b,f[d],c[e],b.parentFragment.contextStack)}}(gc),ic=function(){return function(a){var b,c,d,e,f;for(b=a.root,c=b._liveQueries,d=c.length;d--;)e=c[d],f=c[e],f._test(a)&&((a.liveQueries||(a.liveQueries=[])).push(e),a.liveQueries[e]=[a.node])}}(),jc=function(){return function(a){return a.replace(/-([a-zA-Z])/g,function(a,b){return b.toUpperCase()})}}(),kc=function(){return function(a,b){var c;for(c in b)b.hasOwnProperty(c)&&!a.hasOwnProperty(c)&&(a[c]=b[c]);return a}}(),lc=function(a,b,c,d,e,f,g,h){function i(a){var b,c,d;if(!q[a])if(void 0!==m[a])q[a]=a;else for(d=a.charAt(0).toUpperCase()+a.substring(1),b=n.length;b--;)if(c=n[b],void 0!==m[c+d]){q[a]=c+d;break}return q[a]}function j(a){return a.replace(p,"")}function k(a){var b;return o.test(a)&&(a="-"+a),b=a.replace(/[A-Z]/g,function(a){return"-"+a.toLowerCase()})}var l,m,n,o,p,q,r,s,t,u,v,w;if(a)return m=b("div").style,function(){void 0!==m.transition?(s="transition",w="transitionend",r=!0):void 0!==m.webkitTransition?(s="webkitTransition",w="webkitTransitionEnd",r=!0):r=!1}(),s&&(t=s+"Duration",u=s+"Property",v=s+"TimingFunction"),l=function(a,b,d,e,f){var g,i,j,k=this;if(this.root=b,this.node=d.node,this.isIntro=f,this.originalStyle=this.node.getAttribute("style"),this.complete=function(a){!a&&k.isIntro&&k.resetStyle(),k._manager.pop(k.node),k.node._ractive.transition=null},g=a.n||a,"string"!=typeof g&&(i=new h({descriptor:g,root:this.root,owner:d,contextStack:e}),g=i.toString(),i.teardown()),this.name=g,a.a?this.params=a.a:a.d&&(i=new h({descriptor:a.d,root:this.root,owner:d,contextStack:e}),this.params=i.toArgsList(),i.teardown()),this._fn=b.transitions[g],!this._fn){if(j='Missing "'+g+'" transition. You may need to download a plugin via https://github.com/RactiveJS/Ractive/wiki/Plugins#transitions',b.debug)throw new Error(j);return c(j),void 0}},l.prototype={init:function(){if(this._inited)throw new Error("Cannot initialize a transition more than once");this._inited=!0,this._fn.apply(this.root,[this].concat(this.params))},getStyle:function(a){var b,c,d,f,g;if(b=window.getComputedStyle(this.node),"string"==typeof a)return g=b[i(a)],"0px"===g&&(g=0),g;if(!e(a))throw new Error("Transition#getStyle must be passed a string, or an array of strings representing CSS properties");for(c={},d=a.length;d--;)f=a[d],g=b[i(f)],"0px"===g&&(g=0),c[f]=g;return c},setStyle:function(a,b){var c;if("string"==typeof a)this.node.style[i(a)]=b;else for(c in a)a.hasOwnProperty(c)&&(this.node.style[i(c)]=a[c]);return this},animateStyle:function(a,b,d,e){var g,h,l,m,n,o,p,q,r,s=this;for("string"==typeof a?(n={},n[a]=b):(n=a,e=d,d=b),d||(c('The "'+s.name+'" transition does not supply an options object to `t.animateStyle()`. This will break in a future version of Ractive. For more info see https://github.com/RactiveJS/Ractive/issues/340'),d=s,e=s.complete),d.duration||(s.setStyle(n),e&&e()),g=Object.keys(n),h=[],l=window.getComputedStyle(s.node),o={},q=g.length;q--;)r=g[q],m=l[i(r)],"0px"===m&&(m=0),m!=n[r]&&(h[h.length]=r,s.node.style[i(r)]=m);return h.length?(setTimeout(function(){s.node.style[u]=g.map(i).map(k).join(","),s.node.style[v]=k(d.easing||"linear"),s.node.style[t]=d.duration/1e3+"s",p=function(a){var b;b=h.indexOf(f(j(a.propertyName))),-1!==b&&h.splice(b,1),h.length||(s.root.fire(s.name+":end"),s.node.removeEventListener(w,p,!1),e&&e())},s.node.addEventListener(w,p,!1),setTimeout(function(){for(var a=h.length;a--;)r=h[a],s.node.style[i(r)]=n[r]},0)},d.delay||0),void 0):(e&&e(),void 0)},resetStyle:function(){this.originalStyle?this.node.setAttribute("style",this.originalStyle):(this.node.getAttribute("style"),this.node.removeAttribute("style"))},processParams:function(a,b){return"number"==typeof a?a={duration:a}:"string"==typeof a?a="slow"===a?{duration:600}:"fast"===a?{duration:200}:{duration:400}:a||(a={}),g(a,b)}},n=["o","ms","moz","webkit"],o=new RegExp("^(?:"+n.join("|")+")([A-Z])"),p=new RegExp("^-(?:"+n.join("|")+")-"),q={},l}(f,e,I,J,l,jc,kc,ac),mc=function(a,b){return function(a,c,d,e,f){var g,h,i;!c.transitionsEnabled||c._parent&&!c._parent.transitionsEnabled||(g=new b(a,c,d,e,f),g._fn&&(h=g.node,g._manager=c._transitionManager,(i=h._ractive.transition)&&i.complete(),h._ractive.transition=g,g._manager.push(h),f?c._deferred.transitions.push(g):g.init()))}}(I,lc),nc=function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){return function(e,p,q){var r,s,t,u,v,w,x,y,z,A,B,C,D;if(e.type=a.ELEMENT,r=e.parentFragment=p.parentFragment,s=r.pNode,t=r.contextStack,u=e.descriptor=p.descriptor,e.root=B=r.root,e.index=p.index,e.lcName=u.e.toLowerCase(),e.eventListeners=[],e.customEventListeners=[],s&&(v=e.namespace=h(u,s),w=v!==b.html?o(u.e):u.e,e.node=g(w,v),d(e.node,"_ractive",{value:{proxy:e,keypath:t.length?t[t.length-1]:"",index:r.indexRefs,events:c(null),root:B}})),x=i(e,u.a),u.f){if(e.node&&e.node.getAttribute("contenteditable")&&e.node.innerHTML){if(D="A pre-populated contenteditable element should not have children",B.debug)throw new Error(D);f(D)}j(e,e.node,u,q)}q&&u.v&&l(e,u.v),q&&(B.twoway&&(e.bind(),e.node.getAttribute("contenteditable")&&e.node._ractive.binding&&e.node._ractive.binding.update()),x.name&&!x.name.twoway&&x.name.update(),"IMG"===e.node.tagName&&((y=e.attributes.width)||(z=e.attributes.height))&&e.node.addEventListener("load",A=function(){y&&(e.node.width=y.value),z&&(e.node.height=z.value),e.node.removeEventListener("load",A,!1)},!1),q.appendChild(e.node),u.o&&k(u.o,B,e,t),u.t1&&n(u.t1,B,e,t,!0),"OPTION"===e.node.tagName&&("SELECT"===s.tagName&&(C=s._ractive.binding)&&C.deferUpdate(),e.node._ractive.value==s._ractive.value&&(e.node.selected=!0)),e.node.autofocus&&(B._deferred.focusable=e.node)),m(e)}}(k,d,c,g,Z,I,e,Hb,cc,dc,fc,hc,ic,mc,Ib),oc=function(a){return function(b){var c,d,e,f,g,h,i,j,k;for(this.fragment&&this.fragment.teardown(!1);this.attributes.length;)this.attributes.pop().teardown();if(this.node){for(c in this.node._ractive.events)this.node._ractive.events[c].teardown();(d=this.node._ractive.binding)&&(d.teardown(),e=this.root._twowayBindings[d.attr.keypath],e.splice(e.indexOf(d),1))}if(this.decorator&&this.decorator.teardown(),this.descriptor.t2&&a(this.descriptor.t2,this.root,this,this.parentFragment.contextStack,!1),b&&this.root._transitionManager.detachWhenReady(this),g=this.liveQueries)for(f=g.length;f--;)if(h=g[f],j=this.liveQueries[h])for(k=j.length,i=this.root._liveQueries[h];k--;)i._remove(j[k])}}(mc),pc=function(){return"area base br col command doctype embed hr img input keygen link meta param source track wbr".split(" ")}(),qc=function(a){return function(){var b,c,d;for(b="<"+(this.descriptor.y?"!doctype":this.descriptor.e),d=this.attributes.length,c=0;d>c;c+=1)b+=" "+this.attributes[c].toString();return b+=">",this.html?b+=this.html:this.fragment&&(b+=this.fragment.toString()),-1===a.indexOf(this.descriptor.e)&&(b+=""),b}}(pc),rc=function(a){return function(b){var c;return a(this.node,b)?this.node:this.html&&(c=this.node.querySelector(b))?c:this.fragment&&this.fragment.find?this.fragment.find(b):void 0}}(Z),sc=function(){return function(a,b){var c,d,e,f,g;if(b._test(this,!0)&&b.live&&((this.liveQueries||(this.liveQueries=[])).push(a),this.liveQueries[a]=[this.node]),this.html&&(c=this.node.querySelectorAll(a))&&(e=c.length))for(b.live&&(this.liveQueries[a]||((this.liveQueries||(this.liveQueries=[])).push(a),this.liveQueries[a]=[]),g=this.liveQueries[a]),d=0;e>d;d+=1)f=c[d],b.push(f),b.live&&g.push(f);this.fragment&&this.fragment.findAll(a,b)}}(),tc=function(){return function(a){return this.fragment?this.fragment.findComponent(a):void 0}}(),uc=function(){return function(a,b){this.fragment&&this.fragment.findAllComponents(a,b)}}(),vc=function(){return function(){var a=this.attributes;if(this.node&&(this.binding&&(this.binding.teardown(),this.binding=null),!(this.node.getAttribute("contenteditable")&&a.value&&a.value.bind())))switch(this.descriptor.e){case"select":case"textarea":return a.value&&a.value.bind(),void 0;case"input":if("radio"===this.node.type||"checkbox"===this.node.type){if(a.name&&a.name.bind())return;if(a.checked&&a.checked.bind())return}if(a.value&&a.value.bind())return}}}(),wc=function(a,b,c,d,e,f,g,h){var i=function(b,c){a(this,b,c)};return i.prototype={detach:function(){return this.node?(this.node.parentNode&&this.node.parentNode.removeChild(this.node),this.node):void 0},teardown:b,firstNode:function(){return this.node},findNextNode:function(){return null},bubble:function(){},toString:c,find:d,findAll:e,findComponent:f,findAllComponents:g,bind:h},i}(nc,oc,qc,rc,sc,tc,uc,vc),xc={missingParser:"Missing Ractive.parse - cannot parse template. Either preparse or use the version that includes the parser"},yc={},zc=function(){return function(a){var b,c,d;for(d="";a.length;){if(b=a.indexOf(""),-1===b&&-1===c){d+=a;break}if(-1!==b&&-1===c)throw"Illegal HTML - expected closing comment sequence ('-->')";if(-1!==c&&-1===b||b>c)throw"Illegal HTML - unexpected closing comment sequence ('-->')";d+=a.substr(0,b),a=a.substring(c+3)}return d}}(),Ac=function(a){return function(b){var c,d,e,f,g,h;for(g=/^\s*\r?\n/,h=/\r?\n\s*$/,c=2;c":a.PARTIAL,"!":a.COMMENT,"&":a.TRIPLE};return function(a){var c=b[a.str.charAt(a.pos)];return c?(a.pos+=1,c):null}}(k),Ec=function(a,b,c){var d=b(/^\s*:\s*([a-zA-Z_$][a-zA-Z_$0-9]*)/),e=/^[0-9][1-9]*$/;return function(b,f){var g,h,i,j,k,l,m;if(g=b.pos,h={type:f?a.TRIPLE:a.MUSTACHE},!(f||((j=b.getExpression())&&(h.mustacheType=a.INTERPOLATOR,b.allowWhitespace(),b.getStringMatch(b.delimiters[1])?b.pos-=b.delimiters[1].length:(b.pos=g,j=null)),j||(i=c(b),i===a.TRIPLE?h={type:a.TRIPLE}:h.mustacheType=i||a.INTERPOLATOR,i!==a.COMMENT&&i!==a.CLOSING||(l=b.remaining(),m=l.indexOf(b.delimiters[1]),-1===m)))))return h.ref=l.substr(0,m),b.pos+=m,h;for(j||(b.allowWhitespace(),j=b.getExpression());j.t===a.BRACKETED&&j.x;)j=j.x;return j.t===a.REFERENCE?h.ref=j.n:j.t===a.NUMBER_LITERAL&&e.test(j.v)?h.ref=j.v:h.expression=j,k=d(b),null!==k&&(h.indexRef=k),h}}(k,Qb,Dc),Fc=function(a,b,c){function d(d,e){var f,g,h=d.pos;return g=e?d.tripleDelimiters:d.delimiters,d.getStringMatch(g[0])?(f=b(d))?d.getStringMatch(g[1])?(d[e?"tripleDelimiters":"delimiters"]=f,{type:a.MUSTACHE,mustacheType:a.DELIMCHANGE}):(d.pos=h,null):(d.allowWhitespace(),f=c(d,e),null===f?(d.pos=h,null):(d.allowWhitespace(),d.getStringMatch(g[1])?f:(d.pos=h,null))):null}return function(){var a=this.tripleDelimiters[0].length>this.delimiters[0].length;return d(this,a)||d(this,!a)}}(k,Cc,Ec),Gc=function(a){return function(){var b,c,d;if(!this.getStringMatch(""),-1===d)throw new Error('Unexpected end of input (expected "-->" to close comment)');return b=c.substr(0,d),this.pos+=d+3,{type:a.COMMENT,content:b}}}(k),Hc=function(){return function(a,b){var c,d,e;for(c=b.length;c--;){if(d=a.indexOf(b[c]),!d)return 0;-1!==d&&(!e||e>d)&&(e=d)}return e||-1}}(),Ic=function(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p;return d=function(){return e(this)||f(this)},e=function(b){var c,d,e,f;return c=b.pos,b.inside?null:b.getStringMatch("<")?(d={type:a.TAG},b.getStringMatch("!")&&(d.doctype=!0),d.name=g(b),d.name?(e=h(b),e&&(d.attrs=e),b.allowWhitespace(),b.getStringMatch("/")&&(d.selfClosing=!0),b.getStringMatch(">")?(f=d.name.toLowerCase(),("script"===f||"style"===f)&&(b.inside=f),d):(b.pos=c,null)):(b.pos=c,null)):null},f=function(b){var c,d,e;if(c=b.pos,e=function(a){throw new Error("Unexpected character "+b.remaining().charAt(0)+" (expected "+a+")")},!b.getStringMatch("<"))return null;if(d={type:a.TAG,closing:!0},b.getStringMatch("/")||e('"/"'),d.name=g(b),d.name||e("tag name"),b.getStringMatch(">")||e('">"'),b.inside){if(d.name.toLowerCase()!==b.inside)return b.pos=c,null;b.inside=null}return d},g=b(/^[a-zA-Z]{1,}:?[a-zA-Z0-9\-]*/),h=function(a){var b,c,d;if(b=a.pos,a.allowWhitespace(),d=i(a),!d)return a.pos=b,null;for(c=[];null!==d;)c[c.length]=d,a.allowWhitespace(),d=i(a);return c},i=function(a){var b,c,d;return(c=j(a))?(b={name:c},d=k(a),d&&(b.value=d),b):null},j=b(/^[^\s"'>\/=]+/),k=function(a){var b,c;return b=a.pos,a.allowWhitespace(),a.getStringMatch("=")?(a.allowWhitespace(),c=p(a,"'")||p(a,'"')||l(a),null===c?(a.pos=b,null):c):(a.pos=b,null)},n=b(/^[^\s"'=<>`]+/),m=function(b){var c,d,e;return c=b.pos,(d=n(b))?(-1!==(e=d.indexOf(b.delimiters[0]))&&(d=d.substr(0,e),b.pos=c+d.length),{type:a.TEXT,value:d}):null},l=function(a){var b,c;for(b=[],c=a.getMustache()||m(a);null!==c;)b[b.length]=c,c=a.getMustache()||m(a);return b.length?b:null},p=function(a,b){var c,d,e;if(c=a.pos,!a.getStringMatch(b))return null;for(d=[],e=a.getMustache()||o(a,b);null!==e;)d[d.length]=e,e=a.getMustache()||o(a,b);return a.getStringMatch(b)?d:(a.pos=c,null)},o=function(b,d){var e,f,g;if(e=b.pos,g=b.remaining(),f=c(g,[d,b.delimiters[0],b.delimiters[1]]),-1===f)throw new Error("Quoted attribute value must have a closing quote");return f?(b.pos+=f,{type:a.TEXT,value:g.substr(0,f)}):null},d}(k,Qb,Hc),Jc=function(a,b){return function(){var c,d,e;return d=this.remaining(),e=this.inside?"a;a+=1)f=d(g[a],h),h=f;c=h}(),c}(k,Vc),Xc=function(a,b){var c,d;return d=function(b,c){return function(d){var e,f,g;return(f=c(d))?(e=d.pos,d.allowWhitespace(),d.getStringMatch(b)?"in"===b&&/[a-zA-Z_$0-9]/.test(d.remaining().charAt(0))?(d.pos=e,f):(d.allowWhitespace(),g=d.getExpression(),g?{t:a.INFIX_OPERATOR,s:b,o:[f,g]}:(d.pos=e,f)):(d.pos=e,f)):null}},function(){var a,e,f,g,h;for(g="* / % + - << >> >>> < <= > >= in instanceof == != === !== & ^ | && ||".split(" "),h=b,a=0,e=g.length;e>a;a+=1)f=d(g[a],h),h=f;c=h}(),c}(k,Wc),Yc=function(a,b){return function(c){var d,e,f,g;return(e=b(c))?(d=c.pos,c.allowWhitespace(),c.getStringMatch("?")?(c.allowWhitespace(),(f=c.getExpression())?(c.allowWhitespace(),c.getStringMatch(":")?(c.allowWhitespace(),g=c.getExpression(),g?{t:a.CONDITIONAL,o:[e,f,g]}:(c.pos=d,e)):(c.pos=d,e)):(c.pos=d,e)):(c.pos=d,e)):null}}(k,Xc),Zc=function(a){return function(){return a(this)}}(Yc),$c=function(a,b,c,d,e,f,g){var h;return h=function(a,b){var c;for(this.str=a,this.pos=0,this.delimiters=b.delimiters,this.tripleDelimiters=b.tripleDelimiters,this.tokens=[];this.pos"+b)},expected:function(a){var b=this.remaining().substr(0,40);throw 40===b.length&&(b+="..."),new Error('Tokenizer failed: unexpected string "'+b+'" (expected '+a+")")}},h}(Fc,Gc,Ic,Jc,Zc,Pb,Ob),_c=function(a,b,c,d,e){var f,g;return e.push(function(){g=e.Ractive}),f=function(e,f){var h,i;return f=f||{},f.stripComments!==!1&&(e=a(e)),h=new d(e,{delimiters:f.delimiters||(g?g.delimiters:["{{","}}"]),tripleDelimiters:f.tripleDelimiters||(g?g.tripleDelimiters:["{{{","}}}"])}),i=h.tokens,b(i),c(i),i}}(zc,Ac,Bc,$c,Eb),ad=function(a){var b,c,d,e,f,g,h,i,j;return b=function(a,b){this.text=b?a.value:a.value.replace(j," ")},b.prototype={type:a.TEXT,toJSON:function(){return this.decoded||(this.decoded=i(this.text))},toString:function(){return this.text}},c={quot:34,amp:38,apos:39,lt:60,gt:62,nbsp:160,iexcl:161,cent:162,pound:163,curren:164,yen:165,brvbar:166,sect:167,uml:168,copy:169,ordf:170,laquo:171,not:172,shy:173,reg:174,macr:175,deg:176,plusmn:177,sup2:178,sup3:179,acute:180,micro:181,para:182,middot:183,cedil:184,sup1:185,ordm:186,raquo:187,frac14:188,frac12:189,frac34:190,iquest:191,Agrave:192,Aacute:193,Acirc:194,Atilde:195,Auml:196,Aring:197,AElig:198,Ccedil:199,Egrave:200,Eacute:201,Ecirc:202,Euml:203,Igrave:204,Iacute:205,Icirc:206,Iuml:207,ETH:208,Ntilde:209,Ograve:210,Oacute:211,Ocirc:212,Otilde:213,Ouml:214,times:215,Oslash:216,Ugrave:217,Uacute:218,Ucirc:219,Uuml:220,Yacute:221,THORN:222,szlig:223,agrave:224,aacute:225,acirc:226,atilde:227,auml:228,aring:229,aelig:230,ccedil:231,egrave:232,eacute:233,ecirc:234,euml:235,igrave:236,iacute:237,icirc:238,iuml:239,eth:240,ntilde:241,ograve:242,oacute:243,ocirc:244,otilde:245,ouml:246,divide:247,oslash:248,ugrave:249,uacute:250,ucirc:251,uuml:252,yacute:253,thorn:254,yuml:255,OElig:338,oelig:339,Scaron:352,scaron:353,Yuml:376,fnof:402,circ:710,tilde:732,Alpha:913,Beta:914,Gamma:915,Delta:916,Epsilon:917,Zeta:918,Eta:919,Theta:920,Iota:921,Kappa:922,Lambda:923,Mu:924,Nu:925,Xi:926,Omicron:927,Pi:928,Rho:929,Sigma:931,Tau:932,Upsilon:933,Phi:934,Chi:935,Psi:936,Omega:937,alpha:945,beta:946,gamma:947,delta:948,epsilon:949,zeta:950,eta:951,theta:952,iota:953,kappa:954,lambda:955,mu:956,nu:957,xi:958,omicron:959,pi:960,rho:961,sigmaf:962,sigma:963,tau:964,upsilon:965,phi:966,chi:967,psi:968,omega:969,thetasym:977,upsih:978,piv:982,ensp:8194,emsp:8195,thinsp:8201,zwnj:8204,zwj:8205,lrm:8206,rlm:8207,ndash:8211,mdash:8212,lsquo:8216,rsquo:8217,sbquo:8218,ldquo:8220,rdquo:8221,bdquo:8222,dagger:8224,Dagger:8225,bull:8226,hellip:8230,permil:8240,prime:8242,Prime:8243,lsaquo:8249,rsaquo:8250,oline:8254,frasl:8260,euro:8364,image:8465,weierp:8472,real:8476,trade:8482,alefsym:8501,larr:8592,uarr:8593,rarr:8594,darr:8595,harr:8596,crarr:8629,lArr:8656,uArr:8657,rArr:8658,dArr:8659,hArr:8660,forall:8704,part:8706,exist:8707,empty:8709,nabla:8711,isin:8712,notin:8713,ni:8715,prod:8719,sum:8721,minus:8722,lowast:8727,radic:8730,prop:8733,infin:8734,ang:8736,and:8743,or:8744,cap:8745,cup:8746,"int":8747,there4:8756,sim:8764,cong:8773,asymp:8776,ne:8800,equiv:8801,le:8804,ge:8805,sub:8834,sup:8835,nsub:8836,sube:8838,supe:8839,oplus:8853,otimes:8855,perp:8869,sdot:8901,lceil:8968,rceil:8969,lfloor:8970,rfloor:8971,lang:9001,rang:9002,loz:9674,spades:9824,clubs:9827,hearts:9829,diams:9830},d=[8364,129,8218,402,8222,8230,8224,8225,710,8240,352,8249,338,141,381,143,144,8216,8217,8220,8221,8226,8211,8212,732,8482,353,8250,339,157,382,376],e=new RegExp("&("+Object.keys(c).join("|")+");?","g"),f=/&#x([0-9]+);?/g,g=/&#([0-9]+);?/g,h=function(a){return a?10===a?32:128>a?a:159>=a?d[a-128]:55296>a?a:57343>=a?65533:65535>=a?a:65533:65533},i=function(a){var b;return b=a.replace(e,function(a,b){return c[b]?String.fromCharCode(c[b]):a}),b=b.replace(f,function(a,b){return String.fromCharCode(h(parseInt(b,16)))}),b=b.replace(g,function(a,b){return String.fromCharCode(h(b))})},j=/\s+/g,b}(k),bd=function(a,b){return function(c){return c.type===a.TEXT?(this.pos+=1,new b(c,this.preserveWhitespace)):null}}(k,ad),cd=function(a){var b;return b=function(a){this.content=a.content},b.prototype={toJSON:function(){return{t:a.COMMENT,f:this.content}},toString:function(){return""}},b}(k),dd=function(a,b){return function(c){return c.type===a.COMMENT?(this.pos+=1,new b(c,this.preserveWhitespace)):null}}(k,cd),ed=function(a,b){var c,d,e;return c=function(a){this.refs=[],d(a,this.refs),this.str=e(a,this.refs)},c.prototype={toJSON:function(){return this.json?this.json:(this.json={r:this.refs,s:this.str},this.json)}},d=function(c,e){var f,g;if(c.t===a.REFERENCE&&-1===e.indexOf(c.n)&&e.unshift(c.n),g=c.o||c.m)if(b(g))d(g,e);else for(f=g.length;f--;)d(g[f],e);c.x&&d(c.x,e),c.r&&d(c.r,e),c.v&&d(c.v,e)},e=function(b,c){var d=function(a){return e(a,c)};switch(b.t){case a.BOOLEAN_LITERAL:case a.GLOBAL:case a.NUMBER_LITERAL:return b.v;case a.STRING_LITERAL:return"'"+b.v.replace(/'/g,"\\'")+"'";case a.ARRAY_LITERAL:return"["+(b.m?b.m.map(d).join(","):"")+"]";case a.OBJECT_LITERAL:return"{"+(b.m?b.m.map(d).join(","):"")+"}";case a.KEY_VALUE_PAIR:return b.k+":"+e(b.v,c);case a.PREFIX_OPERATOR:return("typeof"===b.s?"typeof ":b.s)+e(b.o,c);case a.INFIX_OPERATOR:return e(b.o[0],c)+("in"===b.s.substr(0,2)?" "+b.s+" ":b.s)+e(b.o[1],c);case a.INVOCATION:return e(b.x,c)+"("+(b.o?b.o.map(d).join(","):"")+")";case a.BRACKETED:return"("+e(b.x,c)+")";case a.MEMBER:return e(b.x,c)+e(b.r,c);case a.REFINEMENT:return b.n?"."+b.n:"["+e(b.x,c)+"]";case a.CONDITIONAL:return e(b.o[0],c)+"?"+e(b.o[1],c)+":"+e(b.o[2],c);case a.REFERENCE:return"${"+c.indexOf(b.n)+"}";default:throw new Error("Could not stringify expression token. This error is unexpected")}},c}(k,w),fd=function(a,b){var c=function(c,d){this.type=c.type===a.TRIPLE?a.TRIPLE:c.mustacheType,c.ref&&(this.ref=c.ref),c.expression&&(this.expr=new b(c.expression)),d.pos+=1};return c.prototype={toJSON:function(){var a;return this.json?this.json:(a={t:this.type},this.ref&&(a.r=this.ref),this.expr&&(a.x=this.expr.toJSON()),this.json=a,a)},toString:function(){return!1}},c}(k,ed),gd=function(){return function(a){var b,c,d,e="";if(!a)return"";for(c=0,d=a.length;d>c;c+=1){if(b=a[c].toString(),b===!1)return!1;e+=b}return e}}(),hd=function(a){return function(b,c){var d,e;return c||(d=a(b),d===!1)?e=b.map(function(a){return a.toJSON(c)}):d}}(gd),id=function(a,b,c){var d=function(b,d){var e;for(this.ref=b.ref,this.indexRef=b.indexRef,this.inverted=b.mustacheType===a.INVERTED,b.expression&&(this.expr=new c(b.expression)),d.pos+=1,this.items=[],e=d.next();e;){if(e.mustacheType===a.CLOSING){if(e.ref.trim()===this.ref||this.expr){d.pos+=1;break}throw new Error("Could not parse template: Illegal closing section")}this.items[this.items.length]=d.getStub(),e=d.next()}};return d.prototype={toJSON:function(c){var d;return this.json?this.json:(d={t:a.SECTION},this.ref&&(d.r=this.ref),this.indexRef&&(d.i=this.indexRef),this.inverted&&(d.n=!0),this.expr&&(d.x=this.expr.toJSON()),this.items.length&&(d.f=b(this.items,c)),this.json=d,d)},toString:function(){return!1}},d}(k,hd,ed),jd=function(a,b,c){return function(d){return d.type===a.MUSTACHE||d.type===a.TRIPLE?d.mustacheType===a.SECTION||d.mustacheType===a.INVERTED?new c(d,this):new b(d,this):void 0}}(k,fd,id),kd=function(){return{li:["li"],dt:["dt","dd"],dd:["dt","dd"],p:"address article aside blockquote dir div dl fieldset footer form h1 h2 h3 h4 h5 h6 header hgroup hr menu nav ol p pre section table ul".split(" "),rt:["rt","rp"],rp:["rp","rt"],optgroup:["optgroup"],option:["option","optgroup"],thead:["tbody","tfoot"],tbody:["tbody","tfoot"],tr:["tr"],td:["td","th"],th:["td","th"]}}(),ld=function(a){function b(c){var d,e;if("object"!=typeof c)return c;if(a(c))return c.map(b);d={};for(e in c)c.hasOwnProperty(e)&&(d[e]=b(c[e]));return d}return function(a){var c,d,e,f,g,h;for(e={},c=[],d=[],g=a.length,f=0;g>f;f+=1)if(h=a[f],"intro"===h.name){if(e.intro)throw new Error("An element can only have one intro transition");e.intro=h}else if("outro"===h.name){if(e.outro)throw new Error("An element can only have one outro transition");e.outro=h}else if("intro-outro"===h.name){if(e.intro||e.outro)throw new Error("An element can only have one intro and one outro transition");e.intro=h,e.outro=b(h)}else"proxy-"===h.name.substr(0,6)?(h.name=h.name.substring(6),d[d.length]=h):"on-"===h.name.substr(0,3)?(h.name=h.name.substring(3),d[d.length]=h):"decorator"===h.name?e.decorator=h:c[c.length]=h;return e.attrs=c,e.proxies=d,e}}(l),md=function(a,b){return function(c){var d,e,f,g,h,i,j,k;for(h=function(){throw new Error("Illegal directive")},c.name&&c.value||h(),d={directiveType:c.name},e=c.value,i=[],j=[];e.length;)if(f=e.shift(),f.type===a.TEXT){if(g=f.value.indexOf(":"),-1!==g){g&&(i[i.length]={type:a.TEXT,value:f.value.substr(0,g)}),f.value.length>g+1&&(j[0]={type:a.TEXT,value:f.value.substring(g+1)});break}i[i.length]=f}else i[i.length]=f;return j=j.concat(e),d.name=1===i.length&&i[0].type===a.TEXT?i[0].value:i,j.length&&(1===j.length&&j[0].type===a.TEXT?(k=b("["+j[0].value+"]"),d.args=k?k.value:j[0].value):d.dynamicArgs=j),d}}(k,Xb),nd=function(a,b){var c;return c=function(a,b){var c;for(this.tokens=a||[],this.pos=0,this.options=b,this.result=[];c=this.getStub();)this.result.push(c)},c.prototype={getStub:function(){var a=this.next();return a?this.getText(a)||this.getMustache(a):null},getText:a,getMustache:b,next:function(){return this.tokens[this.pos]}},c}(bd,jd),od=function(a,b,c){var d;return d=function(b){var c=new a(b);this.stubs=c.result},d.prototype={toJSON:function(a){var b;return this["json_"+a]?this["json_"+a]:b=this["json_"+a]=c(this.stubs,a)},toString:function(){return void 0!==this.str?this.str:(this.str=b(this.stubs),this.str)}},d}(nd,gd,hd),pd=function(a){return function(b){var c,d;if("string"==typeof b.name){if(!b.args&&!b.dynamicArgs)return b.name;d=b.name}else d=new a(b.name).toJSON();return c={n:d},b.args?(c.a=b.args,c):(b.dynamicArgs&&(c.d=new a(b.dynamicArgs).toJSON()),c)}}(od),qd=function(a,b,c){return function(d){var e,f,g,h,i,j,k;if(this["json_"+d])return this["json_"+d];if(e=this.component?{t:a.COMPONENT,e:this.component}:{t:a.ELEMENT,e:this.tag},this.doctype&&(e.y=1),this.attributes&&this.attributes.length)for(e.a={},j=this.attributes.length,i=0;j>i;i+=1){if(k=this.attributes[i],f=k.name,e.a[f])throw new Error("You cannot have multiple attributes with the same name");g=null===k.value?null:k.value.toJSON(d),e.a[f]=g}if(this.items&&this.items.length&&(e.f=b(this.items,d)),this.proxies&&this.proxies.length)for(e.v={},j=this.proxies.length,i=0;j>i;i+=1)h=this.proxies[i],e.v[h.directiveType]=c(h);return this.intro&&(e.t1=c(this.intro)),this.outro&&(e.t2=c(this.outro)),this.decorator&&(e.o=c(this.decorator)),this["json_"+d]=e,e}}(k,hd,pd),rd=function(a,b){var c;return c="a abbr acronym address applet area b base basefont bdo big blockquote body br button caption center cite code col colgroup dd del dfn dir div dl dt em fieldset font form frame frameset h1 h2 h3 h4 h5 h6 head hr html i iframe img input ins isindex kbd label legend li link map menu meta noframes noscript object ol p param pre q s samp script select small span strike strong style sub sup textarea title tt u ul var article aside audio bdi canvas command data datagrid datalist details embed eventsource figcaption figure footer header hgroup keygen mark meter nav output progress ruby rp rt section source summary time track video wbr".split(" "),function(){var d,e,f,g,h,i,j,k;if(void 0!==this.str)return this.str;if(this.component)return this.str=!1;if(-1===c.indexOf(this.tag.toLowerCase()))return this.str=!1;if(this.proxies||this.intro||this.outro||this.decorator)return this.str=!1;if(j=a(this.items),j===!1)return this.str=!1;if(k=-1!==b.indexOf(this.tag.toLowerCase()),d="<"+this.tag,this.attributes)for(e=0,f=this.attributes.length;f>e;e+=1){if(h=this.attributes[e].name,-1!==h.indexOf(":"))return this.str=!1;if("id"===h||"intro"===h||"outro"===h)return this.str=!1;if(g=" "+h,null!==this.attributes[e].value){if(i=this.attributes[e].value.toString(),i===!1)return this.str=!1; -""!==i&&(g+="=",g+=/[\s"'=<>`]/.test(i)?'"'+i.replace(/"/g,""")+'"':i)}d+=g}return this.selfClosing&&!k?(d+="/>",this.str=d):(d+=">",k?this.str=d:(d+=j,d+="",this.str=d))}}(gd,pc),sd=function(a,b,c,d,e,f,g,h,i,j,k){var l,m,n,o,p,q=/^\s+/,r=/\s+$/;return l=function(d,e,i){var j,l,m,n,o,s,t;if(e.pos+=1,s=function(a){return{name:a.name,value:a.value?new k(a.value):null}},this.tag=d.name,t=d.name.toLowerCase(),"rv-"===t.substr(0,3)&&(c('The "rv-" prefix for components has been deprecated. Support will be removed in a future version'),this.tag=this.tag.substring(3)),i=i||"pre"===t,d.attrs&&(m=g(d.attrs),l=m.attrs,n=m.proxies,e.options.sanitize&&e.options.sanitize.eventAttributes&&(l=l.filter(p)),l.length&&(this.attributes=l.map(s)),n.length&&(this.proxies=n.map(h)),m.intro&&(this.intro=h(m.intro)),m.outro&&(this.outro=h(m.outro)),m.decorator&&(this.decorator=h(m.decorator))),d.doctype&&(this.doctype=!0),d.selfClosing&&(this.selfClosing=!0),-1!==b.indexOf(t)&&(this.isVoid=!0),!this.selfClosing&&!this.isVoid){for(this.siblings=f[t],this.items=[],j=e.next();j&&j.mustacheType!==a.CLOSING;){if(j.type===a.TAG){if(j.closing){j.name.toLowerCase()===t&&(e.pos+=1);break}if(this.siblings&&-1!==this.siblings.indexOf(j.name.toLowerCase()))break}this.items[this.items.length]=e.getStub(),j=e.next()}i||(o=this.items[0],o&&o.type===a.TEXT&&(o.text=o.text.replace(q,""),o.text||this.items.shift()),o=this.items[this.items.length-1],o&&o.type===a.TEXT&&(o.text=o.text.replace(r,""),o.text||this.items.pop()))}},l.prototype={toJSON:i,toString:j},m="a abbr acronym address applet area b base basefont bdo big blockquote body br button caption center cite code col colgroup dd del dfn dir div dl dt em fieldset font form frame frameset h1 h2 h3 h4 h5 h6 head hr html i iframe img input ins isindex kbd label legend li link map menu meta noframes noscript object ol p param pre q s samp script select small span strike strong style sub sup textarea title tt u ul var article aside audio bdi canvas command data datagrid datalist details embed eventsource figcaption figure footer header hgroup keygen mark meter nav output progress ruby rp rt section source summary time track video wbr".split(" "),n="li dd rt rp optgroup option tbody tfoot tr td th".split(" "),o=/^on[a-zA-Z]/,p=function(a){var b=!o.test(a.name);return b},l}(k,pc,I,jc,gd,kd,ld,md,qd,rd,od),td=function(a,b){return function(a){return this.options.sanitize&&this.options.sanitize.elements&&-1!==this.options.sanitize.elements.indexOf(a.name.toLowerCase())?null:new b(a,this)}}(k,sd),ud=function(a,b,c,d,e){var f;return f=function(a,b){var c,d;for(this.tokens=a||[],this.pos=0,this.options=b,this.preserveWhitespace=b.preserveWhitespace,d=[];c=this.getStub();)d.push(c);this.result=e(d)},f.prototype={getStub:function(){var a=this.next();return a?this.getText(a)||this.getComment(a)||this.getMustache(a)||this.getElement(a):null},getText:a,getComment:b,getMustache:c,getElement:d,next:function(){return this.tokens[this.pos]}},f}(bd,dd,jd,td,hd),vd=function(a,b,c){var d,e,f,g,h;return e=/^\s*$/,f=//,g=//,d=function(d,g){var i,j,k;return g=g||{},f.test(d)?h(d,g):(g.sanitize===!0&&(g.sanitize={elements:"applet base basefont body frame frameset head html isindex link meta noframes noscript object param script style title".split(" "),eventAttributes:!0}),i=a(d,g),g.preserveWhitespace||(k=i[0],k&&k.type===b.TEXT&&e.test(k.value)&&i.shift(),k=i[i.length-1],k&&k.type===b.TEXT&&e.test(k.value)&&i.pop()),j=new c(i,g).result,"string"==typeof j?[j]:j)},h=function(a,b){var c,e,h,i,j,k;for(h={},c="",e=a;j=f.exec(e);){if(i=j[1],c+=e.substr(0,j.index),e=e.substring(j.index+j[0].length),k=g.exec(e),!k||k[1]!==i)throw new Error("Inline partials must have a closing delimiter, and cannot be nested");h[i]=d(e.substr(0,k.index),b),e=e.substring(k.index+k[0].length)}return{main:d(c,b),partials:h}},d}(_c,k,ud),wd=function(a,b,c,d,e,f){var g,h,i,j;return g=function(d,g){var k,l,m;if(l=i(d,g))return l;if(b&&(k=document.getElementById(g),k&&"SCRIPT"===k.tagName)){if(!f)throw new Error(a.missingParser);h(f(k.innerHTML),g,e)}if(l=e[g],!l){if(m='Could not find descriptor for partial "'+g+'"',d.debug)throw new Error(m);return c(m),[]}return j(l)},i=function(b,c){var d;if(b.partials[c]){if("string"==typeof b.partials[c]){if(!f)throw new Error(a.missingParser);d=f(b.partials[c],b.parseOptions),h(d,c,b.partials)}return j(b.partials[c])}},h=function(a,b,c){var e;if(d(a)){c[b]=a.main;for(e in a.partials)a.partials.hasOwnProperty(e)&&(c[e]=a.partials[e])}else c[b]=a},j=function(a){return 1===a.length&&"string"==typeof a[0]?a[0]:a},g}(xc,f,I,w,yc,vd),xd=function(a,b,c){var d,e;return c.push(function(){e=c.DomFragment}),d=function(c,d){var f,g=this.parentFragment=c.parentFragment;if(this.type=a.PARTIAL,this.name=c.descriptor.r,this.index=c.index,!c.descriptor.r)throw new Error("Partials must have a static reference (no expressions). This may change in a future version of Ractive.");f=b(g.root,c.descriptor.r),this.fragment=new e({descriptor:f,root:g.root,pNode:g.pNode,contextStack:g.contextStack,owner:this}),d&&d.appendChild(this.fragment.docFrag)},d.prototype={firstNode:function(){return this.fragment.firstNode()},findNextNode:function(){return this.parentFragment.findNextNode(this)},detach:function(){return this.fragment.detach()},teardown:function(a){this.fragment.teardown(a)},toString:function(){return this.fragment.toString()},find:function(a){return this.fragment.find(a)},findAll:function(a,b){return this.fragment.findAll(a,b)},findComponent:function(a){return this.fragment.findComponent(a)},findAllComponents:function(a,b){return this.fragment.findAllComponents(a,b)}},d}(k,wd,Eb),yd=function(a){var b=function(b,c,d){this.parentFragment=b.parentFragment,this.component=b,this.key=c,this.fragment=new a({descriptor:d,root:b.root,owner:this,contextStack:b.parentFragment.contextStack}),this.selfUpdating=this.fragment.isSimple(),this.value=this.fragment.getValue()};return b.prototype={bubble:function(){this.selfUpdating?this.update():!this.deferred&&this.ready&&(this.root._deferred.attrs.push(this),this.deferred=!0)},update:function(){var a=this.fragment.getValue();this.component.instance.set(this.key,a),this.value=a},teardown:function(){this.fragment.teardown()}},b}(ac),zd=function(a,b,c,d){function e(e,f,g,h){var i,j,k,l,m;return k=e.root,l=e.parentFragment,"string"==typeof g?(j=b(g),j?j.value:g):null===g?!0:1===g.length&&g[0].t===a.INTERPOLATOR&&g[0].r?l.indexRefs&&void 0!==l.indexRefs[g[0].r]?l.indexRefs[g[0].r]:(m=c(k,g[0].r,l.contextStack)||g[0].r,h.push({childKeypath:f,parentKeypath:m}),k.get(m)):(i=new d(e,f,g),e.complexParameters.push(i),i.value)}return function(a,b,c){var d,f,g;d={},a.complexParameters=[];for(f in b)b.hasOwnProperty(f)&&(g=e(a,f,b[f],c),void 0!==g&&(d[f]=g));return d}}(k,Xb,y,yd),Ad=function(){return function(a,b,c,d,e){var f,g,h,i;return g=a.parentFragment,i=a.root,h={content:e||[]},f=new b({el:g.pNode.cloneNode(!1),data:c,partials:h,_parent:i,adaptors:i.adaptors}),f.component=a,a.instance=f,f.insert(d),f.fragment.pNode=g.pNode,f}}(),Bd=function(){function a(a,c,d){var e,f,g,h,i,j,k;e=a.root,f=a.instance,i=a.observers,j=e.observe(c,function(a){g||e._wrapped[c]||(h=!0,f.set(d,a),h=!1)},b),i.push(j),f.twoway&&(j=f.observe(d,function(a){h||(g=!0,e.set(c,a),g=!1)},b),i.push(j),k=f.get(d),void 0!==k&&e.set(c,k))}var b={init:!1,debug:!0};return function(b,c){var d,e;for(b.observers=[],e=c.length;e--;)d=c[e],a(b,d.parentKeypath,d.childKeypath)}}(),Cd=function(a){function b(b,d,e,f){if("string"!=typeof f){if(d.debug)throw new Error(c);return a(c),void 0}b.on(e,function(){var a=Array.prototype.slice.call(arguments);a.unshift(f),d.fire.apply(d,a)})}var c="Components currently only support simple events - you cannot include arguments. Sorry!";return function(a,c){var d;for(d in c)c.hasOwnProperty(d)&&b(a.instance,a.root,d,c[d])}}(I),Dd=function(){return function(a){var b,c;for(b=a.root;b;)(c=b._liveComponentQueries[a.name])&&c.push(a.instance),b=b._parent}}(),Ed=function(a,b,c,d,e,f,g){return function(h,i,j){var k,l,m,n,o;if(k=h.parentFragment=i.parentFragment,l=k.root,h.root=l,h.type=a.COMPONENT,h.name=i.descriptor.e,h.index=i.index,h.observers=[],m=l.components[i.descriptor.e],!m)throw new Error('Component "'+i.descriptor.e+'" not found');o=[],n=c(h,i.descriptor.a,o),d(h,m,n,j,i.descriptor.f),e(h,o),f(h,i.descriptor.v),(i.descriptor.t1||i.descriptor.t2||i.descriptor.o)&&b('The "intro", "outro" and "decorator" directives have no effect on components'),g(h)}}(k,I,zd,Ad,Bd,Cd,Dd),Fd=function(a){var b=function(b,c){a(this,b,c)};return b.prototype={firstNode:function(){return this.instance.fragment.firstNode()},findNextNode:function(){return this.parentFragment.findNextNode(this)},detach:function(){return this.instance.fragment.detach()},teardown:function(){for(var a;this.complexParameters.length;)this.complexParameters.pop().teardown();for(;this.observers.length;)this.observers.pop().cancel();(a=this.root._liveComponentQueries[this.name])&&a._remove(this),this.instance.teardown()},toString:function(){return this.instance.fragment.toString()},find:function(a){return this.instance.fragment.find(a)},findAll:function(a,b){return this.instance.fragment.findAll(a,b)},findComponent:function(a){return a&&a!==this.name?null:this.instance},findAllComponents:function(a,b){b._test(this,!0),this.instance.fragment&&this.instance.fragment.findAllComponents(a,b)}},b}(Ed),Gd=function(a){var b=function(b,c){this.type=a.COMMENT,this.descriptor=b.descriptor,c&&(this.node=document.createComment(b.descriptor.f),c.appendChild(this.node))};return b.prototype={detach:function(){return this.node.parentNode.removeChild(this.node),this.node},teardown:function(a){a&&this.detach()},firstNode:function(){return this.node},toString:function(){return""}},b}(k),Hd=function(a,b,c,d,e,f,g,h,i,j,k,l,m){var n=function(a){a.pNode&&(this.docFrag=document.createDocumentFragment()),"string"==typeof a.descriptor?(this.html=a.descriptor,this.docFrag&&(this.nodes=d(this.html,a.pNode.tagName,this.docFrag))):c(this,a)};return n.prototype={detach:function(){var a,b;if(this.nodes)for(b=this.nodes.length;b--;)this.docFrag.appendChild(this.nodes[b]);else if(this.items)for(a=this.items.length,b=0;a>b;b+=1)this.docFrag.appendChild(this.items[b].detach());return this.docFrag},createItem:function(b){if("string"==typeof b.descriptor)return new e(b,this.docFrag);switch(b.descriptor.t){case a.INTERPOLATOR:return new f(b,this.docFrag);case a.SECTION:return new g(b,this.docFrag);case a.TRIPLE:return new h(b,this.docFrag);case a.ELEMENT:return this.root.components[b.descriptor.e]?new k(b,this.docFrag):new i(b,this.docFrag);case a.PARTIAL:return new j(b,this.docFrag);case a.COMMENT:return new l(b,this.docFrag);default:throw new Error("Something very strange happened. Please file an issue at https://github.com/RactiveJS/Ractive/issues. Thanks!")}},teardown:function(a){var b;if(this.nodes&&a)for(;b=this.nodes.pop();)b.parentNode.removeChild(b);else if(this.items)for(;this.items.length;)this.items.pop().teardown(a);this.nodes=this.items=this.docFrag=null},firstNode:function(){return this.items&&this.items[0]?this.items[0].firstNode():this.nodes?this.nodes[0]||null:null},findNextNode:function(a){var b=a.index;return this.items[b+1]?this.items[b+1].firstNode():this.owner===this.root?this.owner.component?this.owner.component.findNextNode():null:this.owner.findNextNode(this)},toString:function(){var a,b,c,d;if(this.html)return this.html;if(a="",!this.items)return a;for(c=this.items.length,b=0;c>b;b+=1)d=this.items[b],a+=d.toString();return a},find:function(a){var c,d,e,f,g;if(this.nodes){for(d=this.nodes.length,c=0;d>c;c+=1)if(f=this.nodes[c],1===f.nodeType){if(b(f,a))return f;if(g=f.querySelector(a))return g}return null}if(this.items){for(d=this.items.length,c=0;d>c;c+=1)if(e=this.items[c],e.find&&(g=e.find(a)))return g;return null}},findAll:function(a,c){var d,e,f,g,h,i,j;if(this.nodes){for(e=this.nodes.length,d=0;e>d;d+=1)if(g=this.nodes[d],1===g.nodeType&&(b(g,a)&&c.push(g),h=g.querySelectorAll(a)))for(i=h.length,j=0;i>j;j+=1)c.push(h[j])}else if(this.items)for(e=this.items.length,d=0;e>d;d+=1)f=this.items[d],f.findAll&&f.findAll(a,c);return c},findComponent:function(a){var b,c,d,e;if(this.items){for(b=this.items.length,c=0;b>c;c+=1)if(d=this.items[c],d.findComponent&&(e=d.findComponent(a)))return e;return null}},findAllComponents:function(a,b){var c,d,e;if(this.items)for(d=this.items.length,c=0;d>c;c+=1)e=this.items[c],e.findAllComponents&&e.findAllComponents(a,b);return b}},m.DomFragment=n,n}(k,Z,kb,lb,mb,zb,Fb,Gb,wc,xd,Fd,Gd,Eb),Id=function(a,b,c,d,e){return function(a,f){var g;if(!this._initing)throw new Error("You cannot call ractive.render() directly!");this._transitionManager=g=b(this,f),this.fragment=new e({descriptor:this.template,root:this,owner:this,pNode:a}),c(this),a&&a.appendChild(this.fragment.docFrag),d(this),this._transitionManager=null,g.ready(),this.rendered=!0}}(jb,q,o,p,Hd),Jd=function(a){return function(){return a("renderHTML() has been deprecated and will be removed in a future version. Please use toHTML() instead"),this.toHTML()}}(I),Kd=function(){return function(){return this.fragment.toString()}}(),Ld=function(a,b){return function(c){var d,e,f;for(this.fire("teardown"),f=this._transitionManager,this._transitionManager=e=a(this,c),this.fragment.teardown(!0);this._animations[0];)this._animations[0].stop();for(d in this._cache)b(this,d);this._transitionManager=f,e.ready()}}(q,m),Md=function(a){return function(b,c,d){var e;if("string"==typeof c&&a(d)){if(e=b.get(c),void 0===e&&(e=0),a(e))b.set(c,e+d);else if(b.debug)throw new Error("Cannot add to a non-numeric value")}else if(b.debug)throw new Error("Bad arguments")}}(J),Nd=function(a){return function(b,c){a(this,b,void 0===c?1:c)}}(Md),Od=function(a){return function(b,c){a(this,b,void 0===c?-1:-c)}}(Md),Pd=function(){return function(a){var b;if("string"==typeof a)b=this.get(a),this.set(a,!b);else if(this.debug)throw new Error("Bad arguments")}}(),Qd=function(){return function(a,b){var c,d,e,f,g;return c={},e=0,d=function(a,d){var f,h,i;h=e,i=b.length;do{if(f=b.indexOf(a,h),-1===f)return g=!0,-1;h=f+1}while(c[f]&&i>h);return f===e&&(e+=1),f!==d&&(g=!0),c[f]=!0,f},f=a.map(d),f.unchanged=!g,f}}(),Rd=function(a){return function(b,c,d,e){var f,g;for(f=c.length;f--;)g=c[f],g.type===a.REFERENCE?g.update():g.keypath===b&&g.type===a.SECTION&&!g.inverted&&g.docFrag?d[d.length]=g:e[e.length]=g}}(k),Sd=function(a,b,c,d,e,f,g,h,i,j){function k(a){return JSON.stringify(a)}function l(a){return m[a]||(m[a]=function(b){return b[a]}),m[a]}var m={};return function(m,n,o){var p,q,r,s,t,u,v,w,x,y,z,A,B,C,D;if(p=this.get(m),!b(p)||!b(n))return this.set(m,n,o&&o.complete);if(t=p.length===n.length,o&&o.compare){if(o.compare===!0)s=k;else if("string"==typeof o.compare)s=l(o.compare);else{if("function"!=typeof o.compare)throw new Error("The `compare` option must be a function, or a string representing an identifying field (or `true` to use JSON.stringify)");s=o.compare}try{q=p.map(s),r=n.map(s)}catch(E){if(this.debug)throw E;a("Merge operation: comparison failed. Falling back to identity checking"),q=p,r=n}}else q=p,r=n;if(v=i(q,r),c(this,m),h(this,m,n),!v.unchanged||!t){for(B=this._transitionManager,this._transitionManager=A=f(this,o&&o.complete),w=[],x=[],u=0;u 2 && args[1]) { - changed = Math.min(args[1], args.length - 2); - start = args[0]; - end = start + changed; - if (args[1] === args.length - 2) { - lengthUnchanged = true; - } - for (i = start; i < end; i += 1) { - childKeypath = keypath + '.' + i; - notifyDependants(root, childKeypath); - } - } - preDomUpdate(root); - upstreamQueue = []; - keys = keypath.split('.'); - while (keys.length) { - keys.pop(); - upstreamQueue[upstreamQueue.length] = keys.join('.'); - } - notifyDependants.multiple(root, upstreamQueue, true); - if (!lengthUnchanged) { - notifyDependants(root, keypath + '.length', true); - } - }; - queueDependants = function (keypath, deps, smartUpdateQueue, dumbUpdateQueue) { - var k, dependant; - k = deps.length; - while (k--) { - dependant = deps[k]; - if (dependant.type === types.REFERENCE) { - dependant.update(); - } else if (dependant.keypath === keypath && dependant.type === types.SECTION && !dependant.inverted && dependant.docFrag) { - smartUpdateQueue[smartUpdateQueue.length] = dependant; - } else { - dumbUpdateQueue[dumbUpdateQueue.length] = dependant; - } - } - }; - wrappers = array._ractive.wrappers; - i = wrappers.length; - while (i--) { - wrapper = wrappers[i]; - notifyKeypathDependants(wrapper.root, wrapper.keypath); - } - }; - patchedArrayProto = []; - mutatorMethods = [ - 'pop', - 'push', - 'reverse', - 'shift', - 'sort', - 'splice', - 'unshift' - ]; - noop = function () { - }; - mutatorMethods.forEach(function (methodName) { - var method = function () { - var result, instances, instance, i, previousTransitionManagers = {}, transitionManagers = {}; - result = Array.prototype[methodName].apply(this, arguments); - instances = this._ractive.instances; - i = instances.length; - while (i--) { - instance = instances[i]; - previousTransitionManagers[instance._guid] = instance._transitionManager; - instance._transitionManager = transitionManagers[instance._guid] = makeTransitionManager(instance, noop); - } - this._ractive.setting = true; - notifyArrayDependants(this, methodName, arguments); - this._ractive.setting = false; - i = instances.length; - while (i--) { - instance = instances[i]; - instance._transitionManager = previousTransitionManagers[instance._guid]; - transitionManagers[instance._guid].ready(); - preDomUpdate(instance); - postDomUpdate(instance); - } - return result; - }; - defineProperty(patchedArrayProto, methodName, { value: method }); - }); - testObj = {}; - if (testObj.__proto__) { - patchArrayMethods = function (array) { - array.__proto__ = patchedArrayProto; - }; - unpatchArrayMethods = function (array) { - array.__proto__ = Array.prototype; - }; - } else { - patchArrayMethods = function (array) { - var i, methodName; - i = mutatorMethods.length; - while (i--) { - methodName = mutatorMethods[i]; - defineProperty(array, methodName, { - value: patchedArrayProto[methodName], - configurable: true - }); - } - }; - unpatchArrayMethods = function (array) { - var i; - i = mutatorMethods.length; - while (i--) { - delete array[mutatorMethods[i]]; - } - }; - } - errorMessage = 'Something went wrong in a rather interesting way'; - return arrayAdaptor; - }(config_types, utils_defineProperty, utils_isArray, shared_clearCache, shared_preDomUpdate, shared_postDomUpdate, shared_makeTransitionManager, shared_notifyDependants); -var Ractive_prototype_get_magicAdaptor = function () { - - var magicAdaptor, MagicWrapper; - try { - Object.defineProperty({}, 'test', { value: 0 }); - } catch (err) { - return false; - } - magicAdaptor = { - filter: function (object, keypath) { - return !!keypath; - }, - wrap: function (ractive, object, keypath) { - return new MagicWrapper(ractive, object, keypath); - } - }; - MagicWrapper = function (ractive, object, keypath) { - var wrapper = this, keys, prop, objKeypath, descriptor, wrappers, oldGet, oldSet, get, set; - this.ractive = ractive; - this.keypath = keypath; - keys = keypath.split('.'); - this.prop = keys.pop(); - objKeypath = keys.join('.'); - this.obj = objKeypath ? ractive.get(objKeypath) : ractive.data; - descriptor = this.originalDescriptor = Object.getOwnPropertyDescriptor(this.obj, this.prop); - if (descriptor && descriptor.set && (wrappers = descriptor.set._ractiveWrappers)) { - if (wrappers.indexOf(this) === -1) { - wrappers.push(this); - } - return; - } - if (descriptor && !descriptor.configurable) { - throw new Error('Cannot use magic mode with property "' + prop + '" - object is not configurable'); - } - if (descriptor) { - this.value = descriptor.value; - oldGet = descriptor.get; - oldSet = descriptor.set; - } - get = oldGet || function () { - return wrapper.value; - }; - set = function (value) { - var wrappers, wrapper, i; - if (oldSet) { - oldSet(value); - } - wrappers = set._ractiveWrappers; - i = wrappers.length; - while (i--) { - wrapper = wrappers[i]; - if (!wrapper.resetting) { - wrapper.ractive.set(wrapper.keypath, value); - } - } - }; - set._ractiveWrappers = [this]; - Object.defineProperty(this.obj, this.prop, { - get: get, - set: set, - enumerable: true, - configurable: true - }); - }; - MagicWrapper.prototype = { - get: function () { - return this.value; - }, - reset: function (value) { - this.resetting = true; - this.value = value; - this.resetting = false; - }, - teardown: function () { - var descriptor, set, value, wrappers; - descriptor = Object.getOwnPropertyDescriptor(this.obj, this.prop); - set = descriptor.set; - wrappers = set._ractiveWrappers; - wrappers.splice(wrappers.indexOf(this), 1); - if (!wrappers.length) { - value = this.obj[this.prop]; - Object.defineProperty(this.obj, this.prop, this.originalDescriptor || { - writable: true, - enumerable: true, - configrable: true - }); - this.obj[this.prop] = value; - } - } - }; - return magicAdaptor; - }(); -var shared_adaptIfNecessary = function (adaptorRegistry, arrayAdaptor, magicAdaptor) { - - var prefixers = {}; - return function (ractive, keypath, value, isExpressionResult) { - var len, i, adaptor, wrapped; - len = ractive.adaptors.length; - for (i = 0; i < len; i += 1) { - adaptor = ractive.adaptors[i]; - if (typeof adaptor === 'string') { - if (!adaptorRegistry[adaptor]) { - throw new Error('Missing adaptor "' + adaptor + '"'); - } - adaptor = ractive.adaptors[i] = adaptorRegistry[adaptor]; - } - if (adaptor.filter(value, keypath, ractive)) { - wrapped = ractive._wrapped[keypath] = adaptor.wrap(ractive, value, keypath, getPrefixer(keypath)); - wrapped.value = value; - return; - } - } - if (!isExpressionResult) { - if (ractive.magic && magicAdaptor.filter(value, keypath, ractive)) { - ractive._wrapped[keypath] = magicAdaptor.wrap(ractive, value, keypath); - } else if (ractive.modifyArrays && arrayAdaptor.filter(value, keypath, ractive)) { - ractive._wrapped[keypath] = arrayAdaptor.wrap(ractive, value, keypath); - } - } - }; - function prefixKeypath(obj, prefix) { - var prefixed = {}, key; - if (!prefix) { - return obj; - } - prefix += '.'; - for (key in obj) { - if (obj.hasOwnProperty(key)) { - prefixed[prefix + key] = obj[key]; - } - } - return prefixed; - } - function getPrefixer(rootKeypath) { - var rootDot; - if (!prefixers[rootKeypath]) { - rootDot = rootKeypath ? rootKeypath + '.' : ''; - prefixers[rootKeypath] = function (relativeKeypath, value) { - var obj; - if (typeof relativeKeypath === 'string') { - obj = {}; - obj[rootDot + relativeKeypath] = value; - return obj; - } - if (typeof relativeKeypath === 'object') { - return rootDot ? prefixKeypath(relativeKeypath, rootKeypath) : relativeKeypath; - } - }; - } - return prefixers[rootKeypath]; - } - }(registries_adaptors, Ractive_prototype_get_arrayAdaptor, Ractive_prototype_get_magicAdaptor); -var Ractive_prototype_get__get = function (normaliseKeypath, adaptorRegistry, adaptIfNecessary) { - - var get, _get, retrieve; - get = function (keypath) { - if (this._captured && !this._captured[keypath]) { - this._captured.push(keypath); - this._captured[keypath] = true; - } - return _get(this, keypath); - }; - _get = function (ractive, keypath) { - var cache, cached, value, wrapped, evaluator; - keypath = normaliseKeypath(keypath); - cache = ractive._cache; - if ((cached = cache[keypath]) !== undefined) { - return cached; - } - if (wrapped = ractive._wrapped[keypath]) { - value = wrapped.value; - } else if (!keypath) { - adaptIfNecessary(ractive, '', ractive.data); - value = ractive.data; - } else if (evaluator = ractive._evaluators[keypath]) { - value = evaluator.value; - } else { - value = retrieve(ractive, keypath); - } - cache[keypath] = value; - return value; - }; - retrieve = function (ractive, keypath) { - var keys, key, parentKeypath, parentValue, cacheMap, value, wrapped; - keys = keypath.split('.'); - key = keys.pop(); - parentKeypath = keys.join('.'); - parentValue = _get(ractive, parentKeypath); - if (wrapped = ractive._wrapped[parentKeypath]) { - parentValue = wrapped.get(); - } - if (parentValue === null || parentValue === undefined) { - return; - } - if (!(cacheMap = ractive._cacheMap[parentKeypath])) { - ractive._cacheMap[parentKeypath] = [keypath]; - } else { - if (cacheMap.indexOf(keypath) === -1) { - cacheMap[cacheMap.length] = keypath; - } - } - value = parentValue[key]; - adaptIfNecessary(ractive, keypath, value); - ractive._cache[keypath] = value; - return value; - }; - return get; - }(utils_normaliseKeypath, registries_adaptors, shared_adaptIfNecessary); -var utils_isObject = function () { - - var toString = Object.prototype.toString; - return function (thing) { - return typeof thing === 'object' && toString.call(thing) === '[object Object]'; - }; - }(); -var utils_isEqual = function () { - - return function (a, b) { - if (a === null && b === null) { - return true; - } - if (typeof a === 'object' || typeof b === 'object') { - return false; - } - return a === b; - }; - }(); -var shared_resolveRef = function () { - - var resolveRef; - resolveRef = function (ractive, ref, contextStack) { - var keypath, keys, lastKey, contextKeys, innerMostContext, postfix, parentKeypath, parentValue, wrapped, context, ancestorErrorMessage; - ancestorErrorMessage = 'Could not resolve reference - too many "../" prefixes'; - if (ref === '.') { - if (!contextStack.length) { - return ''; - } - keypath = contextStack[contextStack.length - 1]; - } else if (ref.charAt(0) === '.') { - context = contextStack[contextStack.length - 1]; - contextKeys = context ? context.split('.') : []; - if (ref.substr(0, 3) === '../') { - while (ref.substr(0, 3) === '../') { - if (!contextKeys.length) { - throw new Error(ancestorErrorMessage); - } - contextKeys.pop(); - ref = ref.substring(3); - } - contextKeys.push(ref); - keypath = contextKeys.join('.'); - } else if (!context) { - keypath = ref.substring(1); - } else { - keypath = context + ref; - } - } else { - keys = ref.split('.'); - lastKey = keys.pop(); - postfix = keys.length ? '.' + keys.join('.') : ''; - contextStack = contextStack.concat(); - while (contextStack.length) { - innerMostContext = contextStack.pop(); - parentKeypath = innerMostContext + postfix; - parentValue = ractive.get(parentKeypath); - if (wrapped = ractive._wrapped[parentKeypath]) { - parentValue = wrapped.get(); - } - if (typeof parentValue === 'object' && parentValue !== null && parentValue.hasOwnProperty(lastKey)) { - keypath = innerMostContext + '.' + ref; - break; - } - } - if (!keypath && ractive.get(ref) !== undefined) { - keypath = ref; - } - } - return keypath ? keypath.replace(/^\./, '') : keypath; - }; - return resolveRef; - }(); -var shared_attemptKeypathResolution = function (resolveRef) { - - var push = Array.prototype.push; - return function (ractive) { - var unresolved, keypath, leftover; - while (unresolved = ractive._pendingResolution.pop()) { - keypath = resolveRef(ractive, unresolved.ref, unresolved.contextStack); - if (keypath !== undefined) { - unresolved.resolve(keypath); - } else { - (leftover || (leftover = [])).push(unresolved); - } - } - if (leftover) { - push.apply(ractive._pendingResolution, leftover); - } - }; - }(shared_resolveRef); -var shared_processDeferredUpdates = function (preDomUpdate, postDomUpdate) { - - return function (ractive) { - preDomUpdate(ractive); - postDomUpdate(ractive); - }; - }(shared_preDomUpdate, shared_postDomUpdate); -var Ractive_prototype_shared_replaceData = function () { - - return function (ractive, keypath, value) { - var keys, accumulated, wrapped, obj, key, currentKeypath, keypathToClear; - keys = keypath.split('.'); - accumulated = []; - if (wrapped = ractive._wrapped['']) { - if (wrapped.set) { - wrapped.set(keys.join('.'), value); - } - obj = wrapped.get(); - } else { - obj = ractive.data; - } - while (keys.length > 1) { - key = accumulated[accumulated.length] = keys.shift(); - currentKeypath = accumulated.join('.'); - if (wrapped = ractive._wrapped[currentKeypath]) { - if (wrapped.set) { - wrapped.set(keys.join('.'), value); - } - obj = wrapped.get(); - } else { - if (!obj.hasOwnProperty(key)) { - if (!keypathToClear) { - keypathToClear = currentKeypath; - } - obj[key] = /^\s*[0-9]+\s*$/.test(keys[0]) ? [] : {}; - } - obj = obj[key]; - } - } - key = keys[0]; - obj[key] = value; - return keypathToClear; - }; - }(); -var Ractive_prototype_set = function (isObject, isEqual, normaliseKeypath, clearCache, notifyDependants, attemptKeypathResolution, makeTransitionManager, processDeferredUpdates, replaceData) { - - var set, updateModel, getUpstreamChanges, resetWrapped; - set = function (keypath, value, complete) { - var map, changes, upstreamChanges, previousTransitionManager, transitionManager, i, changeHash; - changes = []; - if (isObject(keypath)) { - map = keypath; - complete = value; - } - if (map) { - for (keypath in map) { - if (map.hasOwnProperty(keypath)) { - value = map[keypath]; - keypath = normaliseKeypath(keypath); - updateModel(this, keypath, value, changes); - } - } - } else { - keypath = normaliseKeypath(keypath); - updateModel(this, keypath, value, changes); - } - if (!changes.length) { - return; - } - previousTransitionManager = this._transitionManager; - this._transitionManager = transitionManager = makeTransitionManager(this, complete); - upstreamChanges = getUpstreamChanges(changes); - if (upstreamChanges.length) { - notifyDependants.multiple(this, upstreamChanges, true); - } - notifyDependants.multiple(this, changes); - if (this._pendingResolution.length) { - attemptKeypathResolution(this); - } - processDeferredUpdates(this); - this._transitionManager = previousTransitionManager; - transitionManager.ready(); - if (!this.firingChangeEvent) { - this.firingChangeEvent = true; - changeHash = {}; - i = changes.length; - while (i--) { - changeHash[changes[i]] = this.get(changes[i]); - } - this.fire('change', changeHash); - this.firingChangeEvent = false; - } - return this; - }; - updateModel = function (ractive, keypath, value, changes) { - var cached, previous, wrapped, keypathToClear, evaluator; - if ((wrapped = ractive._wrapped[keypath]) && wrapped.reset) { - if (resetWrapped(ractive, keypath, value, wrapped, changes) !== false) { - return; - } - } - if (evaluator = ractive._evaluators[keypath]) { - evaluator.value = value; - } - cached = ractive._cache[keypath]; - previous = ractive.get(keypath); - if (previous !== value && !evaluator) { - keypathToClear = replaceData(ractive, keypath, value); - } else { - if (value === cached && typeof value !== 'object') { - return; - } - } - clearCache(ractive, keypathToClear || keypath); - changes[changes.length] = keypath; - }; - getUpstreamChanges = function (changes) { - var upstreamChanges = [''], i, keypath, keys, upstreamKeypath; - i = changes.length; - while (i--) { - keypath = changes[i]; - keys = keypath.split('.'); - while (keys.length > 1) { - keys.pop(); - upstreamKeypath = keys.join('.'); - if (!upstreamChanges[upstreamKeypath]) { - upstreamChanges[upstreamChanges.length] = upstreamKeypath; - upstreamChanges[upstreamKeypath] = true; - } - } - } - return upstreamChanges; - }; - resetWrapped = function (ractive, keypath, value, wrapped, changes) { - var previous, cached, cacheMap, i; - previous = wrapped.get(); - if (!isEqual(previous, value)) { - if (wrapped.reset(value) === false) { - return false; - } - } - value = wrapped.get(); - cached = ractive._cache[keypath]; - if (!isEqual(cached, value)) { - ractive._cache[keypath] = value; - cacheMap = ractive._cacheMap[keypath]; - if (cacheMap) { - i = cacheMap.length; - while (i--) { - clearCache(ractive, cacheMap[i]); - } - } - changes[changes.length] = keypath; - } - }; - return set; - }(utils_isObject, utils_isEqual, utils_normaliseKeypath, shared_clearCache, shared_notifyDependants, shared_attemptKeypathResolution, shared_makeTransitionManager, shared_processDeferredUpdates, Ractive_prototype_shared_replaceData); -var Ractive_prototype_update = function (makeTransitionManager, attemptKeypathResolution, clearCache, notifyDependants, processDeferredUpdates) { - - return function (keypath, complete) { - var transitionManager, previousTransitionManager; - if (typeof keypath === 'function') { - complete = keypath; - keypath = ''; - } - previousTransitionManager = this._transitionManager; - this._transitionManager = transitionManager = makeTransitionManager(this, complete); - attemptKeypathResolution(this); - clearCache(this, keypath || ''); - notifyDependants(this, keypath || ''); - processDeferredUpdates(this); - this._transitionManager = previousTransitionManager; - transitionManager.ready(); - if (typeof keypath === 'string') { - this.fire('update', keypath); - } else { - this.fire('update'); - } - return this; - }; - }(shared_makeTransitionManager, shared_attemptKeypathResolution, shared_clearCache, shared_notifyDependants, shared_processDeferredUpdates); -var utils_arrayContentsMatch = function (isArray) { - - return function (a, b) { - var i; - if (!isArray(a) || !isArray(b)) { - return false; - } - if (a.length !== b.length) { - return false; - } - i = a.length; - while (i--) { - if (a[i] !== b[i]) { - return false; - } - } - return true; - }; - }(utils_isArray); -var Ractive_prototype_updateModel = function (getValueFromCheckboxes, arrayContentsMatch, isEqual) { - - return function (keypath, cascade) { - var values, deferredCheckboxes, i; - if (typeof keypath !== 'string') { - keypath = ''; - cascade = true; - } - consolidateChangedValues(this, keypath, values = {}, deferredCheckboxes = [], cascade); - if (i = deferredCheckboxes.length) { - while (i--) { - keypath = deferredCheckboxes[i]; - values[keypath] = getValueFromCheckboxes(this, keypath); - } - } - this.set(values); - }; - function consolidateChangedValues(ractive, keypath, values, deferredCheckboxes, cascade) { - var bindings, childDeps, i, binding, oldValue, newValue; - bindings = ractive._twowayBindings[keypath]; - if (bindings) { - i = bindings.length; - while (i--) { - binding = bindings[i]; - if (binding.radioName && !binding.node.checked) { - continue; - } - if (binding.checkboxName) { - if (binding.changed() && !deferredCheckboxes[keypath]) { - deferredCheckboxes[keypath] = true; - deferredCheckboxes[deferredCheckboxes.length] = keypath; - } - continue; - } - oldValue = binding.attr.value; - newValue = binding.value(); - if (arrayContentsMatch(oldValue, newValue)) { - continue; - } - if (!isEqual(oldValue, newValue)) { - values[keypath] = newValue; - } - } - } - if (!cascade) { - return; - } - childDeps = ractive._depsMap[keypath]; - if (childDeps) { - i = childDeps.length; - while (i--) { - consolidateChangedValues(ractive, childDeps[i], values, deferredCheckboxes, cascade); - } - } - } - }(shared_getValueFromCheckboxes, utils_arrayContentsMatch, utils_isEqual); -var Ractive_prototype_animate_requestAnimationFrame = function () { - - if (typeof window === 'undefined') { - return; - } - (function (vendors, lastTime, window) { - var x, setTimeout; - if (window.requestAnimationFrame) { - return; - } - for (x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { - window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame']; - } - if (!window.requestAnimationFrame) { - setTimeout = window.setTimeout; - window.requestAnimationFrame = function (callback) { - var currTime, timeToCall, id; - currTime = Date.now(); - timeToCall = Math.max(0, 16 - (currTime - lastTime)); - id = setTimeout(function () { - callback(currTime + timeToCall); - }, timeToCall); - lastTime = currTime + timeToCall; - return id; - }; - } - }([ - 'ms', - 'moz', - 'webkit', - 'o' - ], 0, window)); - return window.requestAnimationFrame; - }(); -var Ractive_prototype_animate_animations = function (rAF) { - - var queue = []; - var animations = { - tick: function () { - var i, animation; - for (i = 0; i < queue.length; i += 1) { - animation = queue[i]; - if (!animation.tick()) { - queue.splice(i--, 1); - } - } - if (queue.length) { - rAF(animations.tick); - } else { - animations.running = false; - } - }, - add: function (animation) { - queue[queue.length] = animation; - if (!animations.running) { - animations.running = true; - animations.tick(); - } - }, - abort: function (keypath, root) { - var i = queue.length, animation; - while (i--) { - animation = queue[i]; - if (animation.root === root && animation.keypath === keypath) { - animation.stop(); - } - } - } - }; - return animations; - }(Ractive_prototype_animate_requestAnimationFrame); -var utils_warn = function () { - - if (typeof console !== 'undefined' && typeof console.warn === 'function' && typeof console.warn.apply === 'function') { - return function () { - console.warn.apply(console, arguments); - }; - } - return function () { - }; - }(); -var utils_isNumeric = function () { - - return function (thing) { - return !isNaN(parseFloat(thing)) && isFinite(thing); - }; - }(); -var shared_interpolate = function (isArray, isObject, isNumeric) { - - var interpolate = function (from, to) { - if (isNumeric(from) && isNumeric(to)) { - return makeNumberInterpolator(+from, +to); - } - if (isArray(from) && isArray(to)) { - return makeArrayInterpolator(from, to); - } - if (isObject(from) && isObject(to)) { - return makeObjectInterpolator(from, to); - } - return function () { - return to; - }; - }; - return interpolate; - function makeNumberInterpolator(from, to) { - var delta = to - from; - if (!delta) { - return function () { - return from; - }; - } - return function (t) { - return from + t * delta; - }; - } - function makeArrayInterpolator(from, to) { - var intermediate, interpolators, len, i; - intermediate = []; - interpolators = []; - i = len = Math.min(from.length, to.length); - while (i--) { - interpolators[i] = interpolate(from[i], to[i]); - } - for (i = len; i < from.length; i += 1) { - intermediate[i] = from[i]; - } - for (i = len; i < to.length; i += 1) { - intermediate[i] = to[i]; - } - return function (t) { - var i = len; - while (i--) { - intermediate[i] = interpolators[i](t); - } - return intermediate; - }; - } - function makeObjectInterpolator(from, to) { - var properties = [], len, interpolators, intermediate, prop; - intermediate = {}; - interpolators = {}; - for (prop in from) { - if (from.hasOwnProperty(prop)) { - if (to.hasOwnProperty(prop)) { - properties[properties.length] = prop; - interpolators[prop] = interpolate(from[prop], to[prop]); - } else { - intermediate[prop] = from[prop]; - } - } - } - for (prop in to) { - if (to.hasOwnProperty(prop) && !from.hasOwnProperty(prop)) { - intermediate[prop] = to[prop]; - } - } - len = properties.length; - return function (t) { - var i = len, prop; - while (i--) { - prop = properties[i]; - intermediate[prop] = interpolators[prop](t); - } - return intermediate; - }; - } - }(utils_isArray, utils_isObject, utils_isNumeric); -var Ractive_prototype_animate_Animation = function (warn, interpolate) { - - var Animation = function (options) { - var key; - this.startTime = Date.now(); - for (key in options) { - if (options.hasOwnProperty(key)) { - this[key] = options[key]; - } - } - this.interpolator = interpolate(this.from, this.to); - this.running = true; - }; - Animation.prototype = { - tick: function () { - var elapsed, t, value, timeNow, index, keypath; - keypath = this.keypath; - if (this.running) { - timeNow = Date.now(); - elapsed = timeNow - this.startTime; - if (elapsed >= this.duration) { - if (keypath !== null) { - this.root.set(keypath, this.to); - } - if (this.step) { - this.step(1, this.to); - } - if (this.complete) { - this.complete(1, this.to); - } - index = this.root._animations.indexOf(this); - if (index === -1) { - warn('Animation was not found'); - } - this.root._animations.splice(index, 1); - this.running = false; - return false; - } - t = this.easing ? this.easing(elapsed / this.duration) : elapsed / this.duration; - if (keypath !== null) { - value = this.interpolator(t); - this.root.set(keypath, value); - } - if (this.step) { - this.step(t, value); - } - return true; - } - return false; - }, - stop: function () { - var index; - this.running = false; - index = this.root._animations.indexOf(this); - if (index === -1) { - warn('Animation was not found'); - } - this.root._animations.splice(index, 1); - } - }; - return Animation; - }(utils_warn, shared_interpolate); -var registries_easing = function () { - - return { - linear: function (pos) { - return pos; - }, - easeIn: function (pos) { - return Math.pow(pos, 3); - }, - easeOut: function (pos) { - return Math.pow(pos - 1, 3) + 1; - }, - easeInOut: function (pos) { - if ((pos /= 0.5) < 1) { - return 0.5 * Math.pow(pos, 3); - } - return 0.5 * (Math.pow(pos - 2, 3) + 2); - } - }; - }(); -var Ractive_prototype_animate__animate = function (isEqual, animations, Animation, easingRegistry) { - - var noAnimation = { - stop: function () { - } - }; - return function (keypath, to, options) { - var k, animation, animations, easing, duration, step, complete, makeValueCollector, currentValues, collectValue, dummy, dummyOptions; - if (typeof keypath === 'object') { - options = to || {}; - easing = options.easing; - duration = options.duration; - animations = []; - step = options.step; - complete = options.complete; - if (step || complete) { - currentValues = {}; - options.step = null; - options.complete = null; - makeValueCollector = function (keypath) { - return function (t, value) { - currentValues[keypath] = value; - }; - }; - } - for (k in keypath) { - if (keypath.hasOwnProperty(k)) { - if (step || complete) { - collectValue = makeValueCollector(k); - options = { - easing: easing, - duration: duration - }; - if (step) { - options.step = collectValue; - } - if (complete) { - options.complete = collectValue; - } - } - animations[animations.length] = animate(this, k, keypath[k], options); - } - } - if (step || complete) { - dummyOptions = { - easing: easing, - duration: duration - }; - if (step) { - dummyOptions.step = function (t) { - step(t, currentValues); - }; - } - if (complete) { - dummyOptions.complete = function (t) { - complete(t, currentValues); - }; - } - animations[animations.length] = dummy = animate(this, null, null, dummyOptions); - } - return { - stop: function () { - while (animations.length) { - animations.pop().stop(); - } - if (dummy) { - dummy.stop(); - } - } - }; - } - options = options || {}; - animation = animate(this, keypath, to, options); - return { - stop: function () { - animation.stop(); - } - }; - }; - function animate(root, keypath, to, options) { - var easing, duration, animation, from; - if (keypath !== null) { - from = root.get(keypath); - } - animations.abort(keypath, root); - if (isEqual(from, to)) { - if (options.complete) { - options.complete(1, options.to); - } - return noAnimation; - } - if (options.easing) { - if (typeof options.easing === 'function') { - easing = options.easing; - } else { - if (root.easing && root.easing[options.easing]) { - easing = root.easing[options.easing]; - } else { - easing = easingRegistry[options.easing]; - } - } - if (typeof easing !== 'function') { - easing = null; - } - } - duration = options.duration === undefined ? 400 : options.duration; - animation = new Animation({ - keypath: keypath, - from: from, - to: to, - root: root, - duration: duration, - easing: easing, - step: options.step, - complete: options.complete - }); - animations.add(animation); - root._animations[root._animations.length] = animation; - return animation; - } - }(utils_isEqual, Ractive_prototype_animate_animations, Ractive_prototype_animate_Animation, registries_easing); -var Ractive_prototype_on = function () { - - return function (eventName, callback) { - var self = this, listeners, n; - if (typeof eventName === 'object') { - listeners = []; - for (n in eventName) { - if (eventName.hasOwnProperty(n)) { - listeners[listeners.length] = this.on(n, eventName[n]); - } - } - return { - cancel: function () { - while (listeners.length) { - listeners.pop().cancel(); - } - } - }; - } - if (!this._subs[eventName]) { - this._subs[eventName] = [callback]; - } else { - this._subs[eventName].push(callback); - } - return { - cancel: function () { - self.off(eventName, callback); - } - }; - }; - }(); -var Ractive_prototype_off = function () { - - return function (eventName, callback) { - var subscribers, index; - if (!callback) { - if (!eventName) { - for (eventName in this._subs) { - delete this._subs[eventName]; - } - } else { - this._subs[eventName] = []; - } - } - subscribers = this._subs[eventName]; - if (subscribers) { - index = subscribers.indexOf(callback); - if (index !== -1) { - subscribers.splice(index, 1); - } - } - }; - }(); -var shared_registerDependant = function () { - - return function (dependant) { - var depsByKeypath, deps, keys, parentKeypath, map, ractive, keypath, priority; - ractive = dependant.root; - keypath = dependant.keypath; - priority = dependant.priority; - depsByKeypath = ractive._deps[priority] || (ractive._deps[priority] = {}); - deps = depsByKeypath[keypath] || (depsByKeypath[keypath] = []); - deps[deps.length] = dependant; - dependant.registered = true; - if (!keypath) { - return; - } - keys = keypath.split('.'); - while (keys.length) { - keys.pop(); - parentKeypath = keys.join('.'); - map = ractive._depsMap[parentKeypath] || (ractive._depsMap[parentKeypath] = []); - if (map[keypath] === undefined) { - map[keypath] = 0; - map[map.length] = keypath; - } - map[keypath] += 1; - keypath = parentKeypath; - } - }; - }(); -var shared_unregisterDependant = function () { - - return function (dependant) { - var deps, index, keys, parentKeypath, map, ractive, keypath, priority; - ractive = dependant.root; - keypath = dependant.keypath; - priority = dependant.priority; - deps = ractive._deps[priority][keypath]; - index = deps.indexOf(dependant); - if (index === -1 || !dependant.registered) { - throw new Error('Attempted to remove a dependant that was no longer registered! This should not happen. If you are seeing this bug in development please raise an issue at https://github.com/RactiveJS/Ractive/issues - thanks'); - } - deps.splice(index, 1); - dependant.registered = false; - if (!keypath) { - return; - } - keys = keypath.split('.'); - while (keys.length) { - keys.pop(); - parentKeypath = keys.join('.'); - map = ractive._depsMap[parentKeypath]; - map[keypath] -= 1; - if (!map[keypath]) { - map.splice(map.indexOf(keypath), 1); - map[keypath] = undefined; - } - keypath = parentKeypath; - } - }; - }(); -var Ractive_prototype_observe_Observer = function (isEqual) { - - var Observer = function (ractive, keypath, callback, options) { - var self = this; - this.root = ractive; - this.keypath = keypath; - this.callback = callback; - this.defer = options.defer; - this.debug = options.debug; - this.proxy = { - update: function () { - self.reallyUpdate(); - } - }; - this.priority = 0; - this.context = options && options.context ? options.context : ractive; - }; - Observer.prototype = { - init: function (immediate) { - if (immediate !== false) { - this.update(); - } else { - this.value = this.root.get(this.keypath); - } - }, - update: function () { - if (this.defer && this.ready) { - this.root._deferred.observers.push(this.proxy); - return; - } - this.reallyUpdate(); - }, - reallyUpdate: function () { - var oldValue, newValue; - oldValue = this.value; - newValue = this.root.get(this.keypath); - this.value = newValue; - if (this.updating) { - return; - } - this.updating = true; - if (!isEqual(newValue, oldValue) || !this.ready) { - try { - this.callback.call(this.context, newValue, oldValue, this.keypath); - } catch (err) { - if (this.debug || this.root.debug) { - throw err; - } - } - } - this.updating = false; - } - }; - return Observer; - }(utils_isEqual); -var Ractive_prototype_observe_getPattern = function () { - - return function (ractive, pattern) { - var keys, key, values, toGet, newToGet, expand, concatenate; - keys = pattern.split('.'); - toGet = []; - expand = function (keypath) { - var value, key; - value = ractive._wrapped[keypath] ? ractive._wrapped[keypath].get() : ractive.get(keypath); - for (key in value) { - newToGet.push(keypath + '.' + key); - } - }; - concatenate = function (keypath) { - return keypath + '.' + key; - }; - while (key = keys.shift()) { - if (key === '*') { - newToGet = []; - toGet.forEach(expand); - toGet = newToGet; - } else { - if (!toGet[0]) { - toGet[0] = key; - } else { - toGet = toGet.map(concatenate); - } - } - } - values = {}; - toGet.forEach(function (keypath) { - values[keypath] = ractive.get(keypath); - }); - return values; - }; - }(); -var Ractive_prototype_observe_PatternObserver = function (isEqual, getPattern) { - - var PatternObserver, wildcard = /\*/; - PatternObserver = function (ractive, keypath, callback, options) { - this.root = ractive; - this.callback = callback; - this.defer = options.defer; - this.debug = options.debug; - this.keypath = keypath; - this.regex = new RegExp('^' + keypath.replace(/\./g, '\\.').replace(/\*/g, '[^\\.]+') + '$'); - this.values = {}; - if (this.defer) { - this.proxies = []; - } - this.priority = 'pattern'; - this.context = options && options.context ? options.context : ractive; - }; - PatternObserver.prototype = { - init: function (immediate) { - var values, keypath; - values = getPattern(this.root, this.keypath); - if (immediate !== false) { - for (keypath in values) { - if (values.hasOwnProperty(keypath)) { - this.update(keypath); - } - } - } else { - this.values = values; - } - }, - update: function (keypath) { - var values; - if (wildcard.test(keypath)) { - values = getPattern(this.root, keypath); - for (keypath in values) { - if (values.hasOwnProperty(keypath)) { - this.update(keypath); - } - } - return; - } - if (this.defer && this.ready) { - this.root._deferred.observers.push(this.getProxy(keypath)); - return; - } - this.reallyUpdate(keypath); - }, - reallyUpdate: function (keypath) { - var value = this.root.get(keypath); - if (this.updating) { - this.values[keypath] = value; - return; - } - this.updating = true; - if (!isEqual(value, this.values[keypath]) || !this.ready) { - try { - this.callback.call(this.context, value, this.values[keypath], keypath); - } catch (err) { - if (this.debug || this.root.debug) { - throw err; - } - } - this.values[keypath] = value; - } - this.updating = false; - }, - getProxy: function (keypath) { - var self = this; - if (!this.proxies[keypath]) { - this.proxies[keypath] = { - update: function () { - self.reallyUpdate(keypath); - } - }; - } - return this.proxies[keypath]; - } - }; - return PatternObserver; - }(utils_isEqual, Ractive_prototype_observe_getPattern); -var Ractive_prototype_observe_getObserverFacade = function (normaliseKeypath, registerDependant, unregisterDependant, Observer, PatternObserver) { - - var wildcard = /\*/, emptyObject = {}; - return function getObserverFacade(ractive, keypath, callback, options) { - var observer, isPatternObserver; - keypath = normaliseKeypath(keypath); - options = options || emptyObject; - if (wildcard.test(keypath)) { - observer = new PatternObserver(ractive, keypath, callback, options); - ractive._patternObservers.push(observer); - isPatternObserver = true; - } else { - observer = new Observer(ractive, keypath, callback, options); - } - registerDependant(observer); - observer.init(options.init); - observer.ready = true; - return { - cancel: function () { - var index; - if (isPatternObserver) { - index = ractive._patternObservers.indexOf(observer); - if (index !== -1) { - ractive._patternObservers.splice(index, 1); - } - } - unregisterDependant(observer); - } - }; - }; - }(utils_normaliseKeypath, shared_registerDependant, shared_unregisterDependant, Ractive_prototype_observe_Observer, Ractive_prototype_observe_PatternObserver); -var Ractive_prototype_observe__observe = function (isObject, getObserverFacade) { - - return function observe(keypath, callback, options) { - var observers = [], k; - if (isObject(keypath)) { - options = callback; - for (k in keypath) { - if (keypath.hasOwnProperty(k)) { - callback = keypath[k]; - observers[observers.length] = getObserverFacade(this, k, callback, options); - } - } - return { - cancel: function () { - while (observers.length) { - observers.pop().cancel(); - } - } - }; - } - return getObserverFacade(this, keypath, callback, options); - }; - }(utils_isObject, Ractive_prototype_observe_getObserverFacade); -var Ractive_prototype_fire = function () { - - return function (eventName) { - var args, i, len, subscribers = this._subs[eventName]; - if (!subscribers) { - return; - } - args = Array.prototype.slice.call(arguments, 1); - for (i = 0, len = subscribers.length; i < len; i += 1) { - subscribers[i].apply(this, args); - } - }; - }(); -var Ractive_prototype_find = function () { - - return function (selector) { - if (!this.el) { - return null; - } - return this.fragment.find(selector); - }; - }(); -var utils_matches = function (isClient, createElement) { - - var div, methodNames, unprefixed, prefixed, vendors, i, j, makeFunction; - if (!isClient) { - return; - } - div = createElement('div'); - methodNames = [ - 'matches', - 'matchesSelector' - ]; - vendors = [ - 'o', - 'ms', - 'moz', - 'webkit' - ]; - makeFunction = function (methodName) { - return function (node, selector) { - return node[methodName](selector); - }; - }; - i = methodNames.length; - while (i--) { - unprefixed = methodNames[i]; - if (div[unprefixed]) { - return makeFunction(unprefixed); - } - j = vendors.length; - while (j--) { - prefixed = vendors[i] + unprefixed.substr(0, 1).toUpperCase() + unprefixed.substring(1); - if (div[prefixed]) { - return makeFunction(prefixed); - } - } - } - return function (node, selector) { - var nodes, i; - nodes = (node.parentNode || node.document).querySelectorAll(selector); - i = nodes.length; - while (i--) { - if (nodes[i] === node) { - return true; - } - } - return false; - }; - }(config_isClient, utils_createElement); -var Ractive_prototype_shared_makeQuery_test = function (matches) { - - return function (item, noDirty) { - var itemMatches = this._isComponentQuery ? !this.selector || item.name === this.selector : matches(item.node, this.selector); - if (itemMatches) { - this.push(item.node || item.instance); - if (!noDirty) { - this._makeDirty(); - } - return true; - } - }; - }(utils_matches); -var Ractive_prototype_shared_makeQuery_cancel = function () { - - return function () { - var liveQueries, selector, index; - liveQueries = this._root[this._isComponentQuery ? 'liveComponentQueries' : 'liveQueries']; - selector = this.selector; - index = liveQueries.indexOf(selector); - if (index !== -1) { - liveQueries.splice(index, 1); - liveQueries[selector] = null; - } - }; - }(); -var Ractive_prototype_shared_makeQuery_sortByItemPosition = function () { - - return function (a, b) { - var ancestryA, ancestryB, oldestA, oldestB, mutualAncestor, indexA, indexB, fragments, fragmentA, fragmentB; - ancestryA = getAncestry(a.component || a._ractive.proxy); - ancestryB = getAncestry(b.component || b._ractive.proxy); - oldestA = ancestryA[ancestryA.length - 1]; - oldestB = ancestryB[ancestryB.length - 1]; - while (oldestA && oldestA === oldestB) { - ancestryA.pop(); - ancestryB.pop(); - mutualAncestor = oldestA; - oldestA = ancestryA[ancestryA.length - 1]; - oldestB = ancestryB[ancestryB.length - 1]; - } - oldestA = oldestA.component || oldestA; - oldestB = oldestB.component || oldestB; - fragmentA = oldestA.parentFragment; - fragmentB = oldestB.parentFragment; - if (fragmentA === fragmentB) { - indexA = fragmentA.items.indexOf(oldestA); - indexB = fragmentB.items.indexOf(oldestB); - return indexA - indexB || ancestryA.length - ancestryB.length; - } - if (fragments = mutualAncestor.fragments) { - indexA = fragments.indexOf(fragmentA); - indexB = fragments.indexOf(fragmentB); - return indexA - indexB || ancestryA.length - ancestryB.length; - } - throw new Error('An unexpected condition was met while comparing the position of two components. Please file an issue at https://github.com/RactiveJS/Ractive/issues - thanks!'); - }; - function getParent(item) { - var parentFragment; - if (parentFragment = item.parentFragment) { - return parentFragment.owner; - } - if (item.component && (parentFragment = item.component.parentFragment)) { - return parentFragment.owner; - } - } - function getAncestry(item) { - var ancestry, ancestor; - ancestry = [item]; - ancestor = getParent(item); - while (ancestor) { - ancestry.push(ancestor); - ancestor = getParent(ancestor); - } - return ancestry; - } - }(); -var Ractive_prototype_shared_makeQuery_sortByDocumentPosition = function (sortByItemPosition) { - - return function (node, otherNode) { - var bitmask; - if (node.compareDocumentPosition) { - bitmask = node.compareDocumentPosition(otherNode); - return bitmask & 2 ? 1 : -1; - } - return sortByItemPosition(node, otherNode); - }; - }(Ractive_prototype_shared_makeQuery_sortByItemPosition); -var Ractive_prototype_shared_makeQuery_sort = function (sortByDocumentPosition, sortByItemPosition) { - - return function () { - this.sort(this._isComponentQuery ? sortByItemPosition : sortByDocumentPosition); - this._dirty = false; - }; - }(Ractive_prototype_shared_makeQuery_sortByDocumentPosition, Ractive_prototype_shared_makeQuery_sortByItemPosition); -var Ractive_prototype_shared_makeQuery_dirty = function () { - - return function () { - if (!this._dirty) { - this._root._deferred.liveQueries.push(this); - this._dirty = true; - } - }; - }(); -var Ractive_prototype_shared_makeQuery_remove = function () { - - return function (item) { - var index = this.indexOf(this._isComponentQuery ? item.instance : item.node); - if (index !== -1) { - this.splice(index, 1); - } - }; - }(); -var Ractive_prototype_shared_makeQuery__makeQuery = function (defineProperties, test, cancel, sort, dirty, remove) { - - return function (ractive, selector, live, isComponentQuery) { - var query; - query = []; - defineProperties(query, { - selector: { value: selector }, - live: { value: live }, - _isComponentQuery: { value: isComponentQuery }, - _test: { value: test } - }); - if (!live) { - return query; - } - defineProperties(query, { - cancel: { value: cancel }, - _root: { value: ractive }, - _sort: { value: sort }, - _makeDirty: { value: dirty }, - _remove: { value: remove }, - _dirty: { - value: false, - writable: true - } - }); - return query; - }; - }(utils_defineProperties, Ractive_prototype_shared_makeQuery_test, Ractive_prototype_shared_makeQuery_cancel, Ractive_prototype_shared_makeQuery_sort, Ractive_prototype_shared_makeQuery_dirty, Ractive_prototype_shared_makeQuery_remove); -var Ractive_prototype_findAll = function (warn, matches, defineProperties, makeQuery) { - - return function (selector, options) { - var liveQueries, query; - if (!this.el) { - return []; - } - options = options || {}; - liveQueries = this._liveQueries; - if (query = liveQueries[selector]) { - return options && options.live ? query : query.slice(); - } - query = makeQuery(this, selector, !!options.live, false); - if (query.live) { - liveQueries.push(selector); - liveQueries[selector] = query; - } - this.fragment.findAll(selector, query); - return query; - }; - }(utils_warn, utils_matches, utils_defineProperties, Ractive_prototype_shared_makeQuery__makeQuery); -var Ractive_prototype_findComponent = function () { - - return function (selector) { - return this.fragment.findComponent(selector); - }; - }(); -var Ractive_prototype_findAllComponents = function (warn, matches, defineProperties, makeQuery) { - - return function (selector, options) { - var liveQueries, query; - options = options || {}; - liveQueries = this._liveComponentQueries; - if (query = liveQueries[selector]) { - return options && options.live ? query : query.slice(); - } - query = makeQuery(this, selector, !!options.live, true); - if (query.live) { - liveQueries.push(selector); - liveQueries[selector] = query; - } - this.fragment.findAllComponents(selector, query); - return query; - }; - }(utils_warn, utils_matches, utils_defineProperties, Ractive_prototype_shared_makeQuery__makeQuery); -var utils_getElement = function () { - - return function (input) { - var output; - if (typeof window === 'undefined' || !document || !input) { - return null; - } - if (input.nodeType) { - return input; - } - if (typeof input === 'string') { - output = document.getElementById(input); - if (!output && document.querySelector) { - output = document.querySelector(input); - } - if (output && output.nodeType) { - return output; - } - } - if (input[0] && input[0].nodeType) { - return input[0]; - } - return null; - }; - }(); -var render_shared_initFragment = function (types, create) { - - return function (fragment, options) { - var numItems, i, parentFragment, parentRefs, ref; - fragment.owner = options.owner; - parentFragment = fragment.owner.parentFragment; - fragment.root = options.root; - fragment.pNode = options.pNode; - fragment.contextStack = options.contextStack || []; - if (fragment.owner.type === types.SECTION) { - fragment.index = options.index; - } - if (parentFragment) { - parentRefs = parentFragment.indexRefs; - if (parentRefs) { - fragment.indexRefs = create(null); - for (ref in parentRefs) { - fragment.indexRefs[ref] = parentRefs[ref]; - } - } - } - fragment.priority = parentFragment ? parentFragment.priority + 1 : 1; - if (options.indexRef) { - if (!fragment.indexRefs) { - fragment.indexRefs = {}; - } - fragment.indexRefs[options.indexRef] = options.index; - } - fragment.items = []; - numItems = options.descriptor ? options.descriptor.length : 0; - for (i = 0; i < numItems; i += 1) { - fragment.items[fragment.items.length] = fragment.createItem({ - parentFragment: fragment, - descriptor: options.descriptor[i], - index: i - }); - } - }; - }(config_types, utils_create); -var render_DomFragment_shared_insertHtml = function (createElement) { - - var elementCache = {}; - return function (html, tagName, docFrag) { - var container, nodes = []; - if (html) { - container = elementCache[tagName] || (elementCache[tagName] = createElement(tagName)); - container.innerHTML = html; - while (container.firstChild) { - nodes[nodes.length] = container.firstChild; - docFrag.appendChild(container.firstChild); - } - } - return nodes; - }; - }(utils_createElement); -var render_DomFragment_Text = function (types) { - - var DomText, lessThan, greaterThan; - lessThan = //g; - DomText = function (options, docFrag) { - this.type = types.TEXT; - this.descriptor = options.descriptor; - if (docFrag) { - this.node = document.createTextNode(options.descriptor); - docFrag.appendChild(this.node); - } - }; - DomText.prototype = { - detach: function () { - this.node.parentNode.removeChild(this.node); - return this.node; - }, - teardown: function (destroy) { - if (destroy) { - this.detach(); - } - }, - firstNode: function () { - return this.node; - }, - toString: function () { - return ('' + this.descriptor).replace(lessThan, '<').replace(greaterThan, '>'); - } - }; - return DomText; - }(config_types); -var shared_teardown = function (unregisterDependant) { - - return function (thing) { - if (!thing.keypath) { - var index = thing.root._pendingResolution.indexOf(thing); - if (index !== -1) { - thing.root._pendingResolution.splice(index, 1); - } - } else { - unregisterDependant(thing); - } - }; - }(shared_unregisterDependant); -var render_shared_Evaluator_Reference = function (types, isEqual, defineProperty, registerDependant, unregisterDependant) { - - var Reference, thisPattern; - thisPattern = /this/; - Reference = function (root, keypath, evaluator, argNum, priority) { - var value; - this.evaluator = evaluator; - this.keypath = keypath; - this.root = root; - this.argNum = argNum; - this.type = types.REFERENCE; - this.priority = priority; - value = root.get(keypath); - if (typeof value === 'function') { - value = wrapFunction(value, root, evaluator); - } - this.value = evaluator.values[argNum] = value; - registerDependant(this); - }; - Reference.prototype = { - update: function () { - var value = this.root.get(this.keypath); - if (typeof value === 'function' && !value._nowrap) { - value = wrapFunction(value, this.root, this.evaluator); - } - if (!isEqual(value, this.value)) { - this.evaluator.values[this.argNum] = value; - this.evaluator.bubble(); - this.value = value; - } - }, - teardown: function () { - unregisterDependant(this); - } - }; - return Reference; - function wrapFunction(fn, ractive, evaluator) { - var prop, evaluators, index; - if (!thisPattern.test(fn.toString())) { - defineProperty(fn, '_nowrap', { value: true }); - return fn; - } - if (!fn['_' + ractive._guid]) { - defineProperty(fn, '_' + ractive._guid, { - value: function () { - var originalCaptured, result, i, evaluator; - originalCaptured = ractive._captured; - if (!originalCaptured) { - ractive._captured = []; - } - result = fn.apply(ractive, arguments); - if (ractive._captured.length) { - i = evaluators.length; - while (i--) { - evaluator = evaluators[i]; - evaluator.updateSoftDependencies(ractive._captured); - } - } - ractive._captured = originalCaptured; - return result; - }, - writable: true - }); - for (prop in fn) { - if (fn.hasOwnProperty(prop)) { - fn['_' + ractive._guid][prop] = fn[prop]; - } - } - fn['_' + ractive._guid + '_evaluators'] = []; - } - evaluators = fn['_' + ractive._guid + '_evaluators']; - index = evaluators.indexOf(evaluator); - if (index === -1) { - evaluators.push(evaluator); - } - return fn['_' + ractive._guid]; - } - }(config_types, utils_isEqual, utils_defineProperty, shared_registerDependant, shared_unregisterDependant); -var render_shared_Evaluator_SoftReference = function (isEqual, registerDependant, unregisterDependant) { - - var SoftReference = function (root, keypath, evaluator) { - this.root = root; - this.keypath = keypath; - this.priority = evaluator.priority; - this.evaluator = evaluator; - registerDependant(this); - }; - SoftReference.prototype = { - update: function () { - var value = this.root.get(this.keypath); - if (!isEqual(value, this.value)) { - this.evaluator.bubble(); - this.value = value; - } - }, - teardown: function () { - unregisterDependant(this); - } - }; - return SoftReference; - }(utils_isEqual, shared_registerDependant, shared_unregisterDependant); -var render_shared_Evaluator__Evaluator = function (isEqual, defineProperty, clearCache, notifyDependants, registerDependant, unregisterDependant, adaptIfNecessary, Reference, SoftReference) { - - var Evaluator, cache = {}; - Evaluator = function (root, keypath, functionStr, args, priority) { - var i, arg; - this.root = root; - this.keypath = keypath; - this.priority = priority; - this.fn = getFunctionFromString(functionStr, args.length); - this.values = []; - this.refs = []; - i = args.length; - while (i--) { - if (arg = args[i]) { - if (arg[0]) { - this.values[i] = arg[1]; - } else { - this.refs[this.refs.length] = new Reference(root, arg[1], this, i, priority); - } - } else { - this.values[i] = undefined; - } - } - this.selfUpdating = this.refs.length <= 1; - this.update(); - }; - Evaluator.prototype = { - bubble: function () { - if (this.selfUpdating) { - this.update(); - } else if (!this.deferred) { - this.root._deferred.evals.push(this); - this.deferred = true; - } - }, - update: function () { - var value; - if (this.evaluating) { - return this; - } - this.evaluating = true; - try { - value = this.fn.apply(null, this.values); - } catch (err) { - if (this.root.debug) { - throw err; - } else { - value = undefined; - } - } - if (!isEqual(value, this.value)) { - clearCache(this.root, this.keypath); - this.root._cache[this.keypath] = value; - adaptIfNecessary(this.root, this.keypath, value, true); - this.value = value; - notifyDependants(this.root, this.keypath); - } - this.evaluating = false; - return this; - }, - teardown: function () { - while (this.refs.length) { - this.refs.pop().teardown(); - } - clearCache(this.root, this.keypath); - this.root._evaluators[this.keypath] = null; - }, - refresh: function () { - if (!this.selfUpdating) { - this.deferred = true; - } - var i = this.refs.length; - while (i--) { - this.refs[i].update(); - } - if (this.deferred) { - this.update(); - this.deferred = false; - } - }, - updateSoftDependencies: function (softDeps) { - var i, keypath, ref; - if (!this.softRefs) { - this.softRefs = []; - } - i = this.softRefs.length; - while (i--) { - ref = this.softRefs[i]; - if (!softDeps[ref.keypath]) { - this.softRefs.splice(i, 1); - this.softRefs[ref.keypath] = false; - ref.teardown(); - } - } - i = softDeps.length; - while (i--) { - keypath = softDeps[i]; - if (!this.softRefs[keypath]) { - ref = new SoftReference(this.root, keypath, this); - this.softRefs[this.softRefs.length] = ref; - this.softRefs[keypath] = true; - } - } - this.selfUpdating = this.refs.length + this.softRefs.length <= 1; - } - }; - return Evaluator; - function getFunctionFromString(str, i) { - var fn, args; - str = str.replace(/\$\{([0-9]+)\}/g, '_$1'); - if (cache[str]) { - return cache[str]; - } - args = []; - while (i--) { - args[i] = '_' + i; - } - fn = new Function(args.join(','), 'return(' + str + ')'); - cache[str] = fn; - return fn; - } - }(utils_isEqual, utils_defineProperty, shared_clearCache, shared_notifyDependants, shared_registerDependant, shared_unregisterDependant, shared_adaptIfNecessary, render_shared_Evaluator_Reference, render_shared_Evaluator_SoftReference); -var render_shared_ExpressionResolver_ReferenceScout = function (resolveRef, teardown) { - - var ReferenceScout = function (resolver, ref, contextStack, argNum) { - var keypath, root; - root = this.root = resolver.root; - keypath = resolveRef(root, ref, contextStack); - if (keypath !== undefined) { - resolver.resolveRef(argNum, false, keypath); - } else { - this.ref = ref; - this.argNum = argNum; - this.resolver = resolver; - this.contextStack = contextStack; - root._pendingResolution[root._pendingResolution.length] = this; - } - }; - ReferenceScout.prototype = { - resolve: function (keypath) { - this.keypath = keypath; - this.resolver.resolveRef(this.argNum, false, keypath); - }, - teardown: function () { - if (!this.keypath) { - teardown(this); - } - } - }; - return ReferenceScout; - }(shared_resolveRef, shared_teardown); -var render_shared_ExpressionResolver_isRegularKeypath = function () { - - var keyPattern = /^(?:(?:[a-zA-Z$_][a-zA-Z$_0-9]*)|(?:[0-9]|[1-9][0-9]+))$/; - return function (keypath) { - var keys, key, i; - keys = keypath.split('.'); - i = keys.length; - while (i--) { - key = keys[i]; - if (key === 'undefined' || !keyPattern.test(key)) { - return false; - } - } - return true; - }; - }(); -var render_shared_ExpressionResolver_getKeypath = function (normaliseKeypath, isRegularKeypath) { - - return function (str, args) { - var unique, normalised; - unique = str.replace(/\$\{([0-9]+)\}/g, function (match, $1) { - return args[$1] ? args[$1][1] : 'undefined'; - }); - normalised = normaliseKeypath(unique); - if (isRegularKeypath(normalised)) { - return normalised; - } - return '${' + unique.replace(/[\.\[\]]/g, '-') + '}'; - }; - }(utils_normaliseKeypath, render_shared_ExpressionResolver_isRegularKeypath); -var render_shared_ExpressionResolver_reassignDependants = function (registerDependant, unregisterDependant) { - - return function (ractive, oldKeypath, newKeypath) { - var toReassign, i, dependant; - toReassign = []; - gatherDependants(ractive, oldKeypath, toReassign); - i = toReassign.length; - while (i--) { - dependant = toReassign[i]; - unregisterDependant(dependant); - dependant.keypath = dependant.keypath.replace(oldKeypath, newKeypath); - registerDependant(dependant); - dependant.update(); - } - }; - function cascade(ractive, oldKeypath, toReassign) { - var map, i; - map = ractive._depsMap[oldKeypath]; - if (!map) { - return; - } - i = map.length; - while (i--) { - gatherDependants(ractive, map[i], toReassign); - } - } - function gatherDependants(ractive, oldKeypath, toReassign) { - var priority, dependantsByKeypath, dependants, i; - priority = ractive._deps.length; - while (priority--) { - dependantsByKeypath = ractive._deps[priority]; - if (dependantsByKeypath) { - dependants = dependantsByKeypath[oldKeypath]; - if (dependants) { - i = dependants.length; - while (i--) { - toReassign.push(dependants[i]); - } - } - } - } - cascade(ractive, oldKeypath, toReassign); - } - }(shared_registerDependant, shared_unregisterDependant); -var render_shared_ExpressionResolver__ExpressionResolver = function (Evaluator, ReferenceScout, getKeypath, reassignDependants) { - - var ExpressionResolver = function (mustache) { - var expression, i, len, ref, indexRefs; - this.root = mustache.root; - this.mustache = mustache; - this.args = []; - this.scouts = []; - expression = mustache.descriptor.x; - indexRefs = mustache.parentFragment.indexRefs; - this.str = expression.s; - len = this.unresolved = this.args.length = expression.r ? expression.r.length : 0; - if (!len) { - this.resolved = this.ready = true; - this.bubble(); - return; - } - for (i = 0; i < len; i += 1) { - ref = expression.r[i]; - if (indexRefs && indexRefs[ref] !== undefined) { - this.resolveRef(i, true, indexRefs[ref]); - } else { - this.scouts[this.scouts.length] = new ReferenceScout(this, ref, mustache.contextStack, i); - } - } - this.ready = true; - this.bubble(); - }; - ExpressionResolver.prototype = { - bubble: function () { - var oldKeypath; - if (!this.ready) { - return; - } - oldKeypath = this.keypath; - this.keypath = getKeypath(this.str, this.args); - if (this.keypath.substr(0, 2) === '${') { - this.createEvaluator(); - } - if (oldKeypath) { - reassignDependants(this.root, oldKeypath, this.keypath); - } else { - this.mustache.resolve(this.keypath); - } - }, - teardown: function () { - while (this.scouts.length) { - this.scouts.pop().teardown(); - } - }, - resolveRef: function (argNum, isIndexRef, value) { - this.args[argNum] = [ - isIndexRef, - value - ]; - this.bubble(); - this.resolved = !--this.unresolved; - }, - createEvaluator: function () { - if (!this.root._evaluators[this.keypath]) { - this.root._evaluators[this.keypath] = new Evaluator(this.root, this.keypath, this.str, this.args, this.mustache.priority); - } else { - this.root._evaluators[this.keypath].refresh(); - } - } - }; - return ExpressionResolver; - }(render_shared_Evaluator__Evaluator, render_shared_ExpressionResolver_ReferenceScout, render_shared_ExpressionResolver_getKeypath, render_shared_ExpressionResolver_reassignDependants); -var render_shared_initMustache = function (resolveRef, ExpressionResolver) { - - return function (mustache, options) { - var keypath, indexRef, parentFragment; - parentFragment = mustache.parentFragment = options.parentFragment; - mustache.root = parentFragment.root; - mustache.contextStack = parentFragment.contextStack; - mustache.descriptor = options.descriptor; - mustache.index = options.index || 0; - mustache.priority = parentFragment.priority; - mustache.type = options.descriptor.t; - if (options.descriptor.r) { - if (parentFragment.indexRefs && parentFragment.indexRefs[options.descriptor.r] !== undefined) { - indexRef = parentFragment.indexRefs[options.descriptor.r]; - mustache.indexRef = options.descriptor.r; - mustache.value = indexRef; - mustache.render(mustache.value); - } else { - keypath = resolveRef(mustache.root, options.descriptor.r, mustache.contextStack); - if (keypath !== undefined) { - mustache.resolve(keypath); - } else { - mustache.ref = options.descriptor.r; - mustache.root._pendingResolution[mustache.root._pendingResolution.length] = mustache; - } - } - } - if (options.descriptor.x) { - mustache.expressionResolver = new ExpressionResolver(mustache); - } - if (mustache.descriptor.n && !mustache.hasOwnProperty('value')) { - mustache.render(undefined); - } - }; - }(shared_resolveRef, render_shared_ExpressionResolver__ExpressionResolver); -var render_shared_resolveMustache = function (types, registerDependant, unregisterDependant) { - - return function (keypath) { - if (keypath === this.keypath) { - return; - } - if (this.registered) { - unregisterDependant(this); - } - this.keypath = keypath; - registerDependant(this); - this.update(); - if (this.root.twoway && this.parentFragment.owner.type === types.ATTRIBUTE) { - this.parentFragment.owner.element.bind(); - } - if (this.expressionResolver && this.expressionResolver.resolved) { - this.expressionResolver = null; - } - }; - }(config_types, shared_registerDependant, shared_unregisterDependant); -var render_shared_updateMustache = function (isEqual) { - - return function () { - var wrapped, value; - value = this.root.get(this.keypath); - if (wrapped = this.root._wrapped[this.keypath]) { - value = wrapped.get(); - } - if (!isEqual(value, this.value)) { - this.render(value); - this.value = value; - } - }; - }(utils_isEqual); -var render_DomFragment_Interpolator = function (types, teardown, initMustache, resolveMustache, updateMustache) { - - var DomInterpolator, lessThan, greaterThan; - lessThan = //g; - DomInterpolator = function (options, docFrag) { - this.type = types.INTERPOLATOR; - if (docFrag) { - this.node = document.createTextNode(''); - docFrag.appendChild(this.node); - } - initMustache(this, options); - }; - DomInterpolator.prototype = { - update: updateMustache, - resolve: resolveMustache, - detach: function () { - this.node.parentNode.removeChild(this.node); - return this.node; - }, - teardown: function (destroy) { - if (destroy) { - this.detach(); - } - teardown(this); - }, - render: function (value) { - if (this.node) { - this.node.data = value == undefined ? '' : value; - } - }, - firstNode: function () { - return this.node; - }, - toString: function () { - var value = this.value != undefined ? '' + this.value : ''; - return value.replace(lessThan, '<').replace(greaterThan, '>'); - } - }; - return DomInterpolator; - }(config_types, shared_teardown, render_shared_initMustache, render_shared_resolveMustache, render_shared_updateMustache); -var render_shared_updateSection = function (isArray, isObject, create) { - - return function (section, value) { - var fragmentOptions; - fragmentOptions = { - descriptor: section.descriptor.f, - root: section.root, - pNode: section.parentFragment.pNode, - owner: section - }; - if (section.descriptor.n) { - updateConditionalSection(section, value, true, fragmentOptions); - return; - } - if (isArray(value)) { - updateListSection(section, value, fragmentOptions); - } else if (isObject(value)) { - if (section.descriptor.i) { - updateListObjectSection(section, value, fragmentOptions); - } else { - updateContextSection(section, fragmentOptions); - } - } else { - updateConditionalSection(section, value, false, fragmentOptions); - } - }; - function updateListSection(section, value, fragmentOptions) { - var i, length, fragmentsToRemove; - length = value.length; - if (length < section.length) { - fragmentsToRemove = section.fragments.splice(length, section.length - length); - while (fragmentsToRemove.length) { - fragmentsToRemove.pop().teardown(true); - } - } else { - if (length > section.length) { - for (i = section.length; i < length; i += 1) { - fragmentOptions.contextStack = section.contextStack.concat(section.keypath + '.' + i); - fragmentOptions.index = i; - if (section.descriptor.i) { - fragmentOptions.indexRef = section.descriptor.i; - } - section.fragments[i] = section.createFragment(fragmentOptions); - } - } - } - section.length = length; - } - function updateListObjectSection(section, value, fragmentOptions) { - var id, fragmentsById; - fragmentsById = section.fragmentsById || (section.fragmentsById = create(null)); - for (id in fragmentsById) { - if (value[id] === undefined && fragmentsById[id]) { - fragmentsById[id].teardown(true); - fragmentsById[id] = null; - } - } - for (id in value) { - if (value[id] !== undefined && !fragmentsById[id]) { - fragmentOptions.contextStack = section.contextStack.concat(section.keypath + '.' + id); - fragmentOptions.index = id; - if (section.descriptor.i) { - fragmentOptions.indexRef = section.descriptor.i; - } - fragmentsById[id] = section.createFragment(fragmentOptions); - } - } - } - function updateContextSection(section, fragmentOptions) { - if (!section.length) { - fragmentOptions.contextStack = section.contextStack.concat(section.keypath); - fragmentOptions.index = 0; - section.fragments[0] = section.createFragment(fragmentOptions); - section.length = 1; - } - } - function updateConditionalSection(section, value, inverted, fragmentOptions) { - var doRender, emptyArray, fragmentsToRemove, fragment; - emptyArray = isArray(value) && value.length === 0; - if (inverted) { - doRender = emptyArray || !value; - } else { - doRender = value && !emptyArray; - } - if (doRender) { - if (!section.length) { - fragmentOptions.contextStack = section.contextStack; - fragmentOptions.index = 0; - section.fragments[0] = section.createFragment(fragmentOptions); - section.length = 1; - } - if (section.length > 1) { - fragmentsToRemove = section.fragments.splice(1); - while (fragment = fragmentsToRemove.pop()) { - fragment.teardown(true); - } - } - } else if (section.length) { - section.teardownFragments(true); - section.length = 0; - } - } - }(utils_isArray, utils_isObject, utils_create); -var render_DomFragment_Section_reassignFragment = function (types, unregisterDependant, ExpressionResolver) { - - return reassignFragment; - function reassignFragment(fragment, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath) { - var i, item, context, query; - if (fragment.html) { - return; - } - if (fragment.indexRefs && fragment.indexRefs[indexRef] !== undefined) { - fragment.indexRefs[indexRef] = newIndex; - } - i = fragment.contextStack.length; - while (i--) { - context = fragment.contextStack[i]; - if (context.substr(0, oldKeypath.length) === oldKeypath) { - fragment.contextStack[i] = context.replace(oldKeypath, newKeypath); - } - } - i = fragment.items.length; - while (i--) { - item = fragment.items[i]; - switch (item.type) { - case types.ELEMENT: - reassignElement(item, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - break; - case types.PARTIAL: - reassignFragment(item.fragment, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - break; - case types.COMPONENT: - reassignFragment(item.instance.fragment, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - if (query = fragment.root._liveComponentQueries[item.name]) { - query._makeDirty(); - } - break; - case types.SECTION: - case types.INTERPOLATOR: - case types.TRIPLE: - reassignMustache(item, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - break; - } - } - } - function reassignElement(element, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath) { - var i, attribute, storage, masterEventName, proxies, proxy, binding, bindings, liveQueries, ractive; - i = element.attributes.length; - while (i--) { - attribute = element.attributes[i]; - if (attribute.fragment) { - reassignFragment(attribute.fragment, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - if (attribute.twoway) { - attribute.updateBindings(); - } - } - } - if (storage = element.node._ractive) { - if (storage.keypath.substr(0, oldKeypath.length) === oldKeypath) { - storage.keypath = storage.keypath.replace(oldKeypath, newKeypath); - } - if (indexRef !== undefined) { - storage.index[indexRef] = newIndex; - } - for (masterEventName in storage.events) { - proxies = storage.events[masterEventName].proxies; - i = proxies.length; - while (i--) { - proxy = proxies[i]; - if (typeof proxy.n === 'object') { - reassignFragment(proxy.a, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - } - if (proxy.d) { - reassignFragment(proxy.d, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - } - } - } - if (binding = storage.binding) { - if (binding.keypath.substr(0, oldKeypath.length) === oldKeypath) { - bindings = storage.root._twowayBindings[binding.keypath]; - bindings.splice(bindings.indexOf(binding), 1); - binding.keypath = binding.keypath.replace(oldKeypath, newKeypath); - bindings = storage.root._twowayBindings[binding.keypath] || (storage.root._twowayBindings[binding.keypath] = []); - bindings.push(binding); - } - } - } - if (element.fragment) { - reassignFragment(element.fragment, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - } - if (liveQueries = element.liveQueries) { - ractive = element.root; - i = liveQueries.length; - while (i--) { - ractive._liveQueries[liveQueries[i]]._makeDirty(); - } - } - } - function reassignMustache(mustache, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath) { - var i; - if (mustache.descriptor.x) { - if (mustache.expressionResolver) { - mustache.expressionResolver.teardown(); - } - mustache.expressionResolver = new ExpressionResolver(mustache); - } - if (mustache.keypath) { - if (mustache.keypath.substr(0, oldKeypath.length) === oldKeypath) { - mustache.resolve(mustache.keypath.replace(oldKeypath, newKeypath)); - } - } else if (mustache.indexRef === indexRef) { - mustache.value = newIndex; - mustache.render(newIndex); - } - if (mustache.fragments) { - i = mustache.fragments.length; - while (i--) { - reassignFragment(mustache.fragments[i], indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - } - } - } - }(config_types, shared_unregisterDependant, render_shared_ExpressionResolver__ExpressionResolver); -var render_DomFragment_Section_reassignFragments = function (types, reassignFragment, preDomUpdate) { - - return function (root, section, start, end, by) { - var i, fragment, indexRef, oldIndex, newIndex, oldKeypath, newKeypath; - indexRef = section.descriptor.i; - for (i = start; i < end; i += 1) { - fragment = section.fragments[i]; - oldIndex = i - by; - newIndex = i; - oldKeypath = section.keypath + '.' + (i - by); - newKeypath = section.keypath + '.' + i; - fragment.index += by; - reassignFragment(fragment, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath); - } - preDomUpdate(root); - }; - }(config_types, render_DomFragment_Section_reassignFragment, shared_preDomUpdate); -var render_DomFragment_Section_prototype_merge = function (reassignFragment) { - - return function (newIndices) { - var section = this, parentFragment, firstChange, changed, i, newLength, newFragments, toTeardown, fragmentOptions, fragment, nextNode; - parentFragment = this.parentFragment; - newFragments = []; - newIndices.forEach(function (newIndex, oldIndex) { - var by, oldKeypath, newKeypath; - if (newIndex === oldIndex) { - newFragments[newIndex] = section.fragments[oldIndex]; - return; - } - if (firstChange === undefined) { - firstChange = oldIndex; - } - if (newIndex === -1) { - (toTeardown || (toTeardown = [])).push(section.fragments[oldIndex]); - return; - } - by = newIndex - oldIndex; - oldKeypath = section.keypath + '.' + oldIndex; - newKeypath = section.keypath + '.' + newIndex; - reassignFragment(section.fragments[oldIndex], section.descriptor.i, oldIndex, newIndex, by, oldKeypath, newKeypath); - newFragments[newIndex] = section.fragments[oldIndex]; - changed = true; - }); - if (toTeardown) { - while (fragment = toTeardown.pop()) { - fragment.teardown(true); - } - } - if (firstChange === undefined) { - firstChange = this.length; - } - newLength = this.root.get(this.keypath).length; - if (newLength === firstChange) { - return; - } - fragmentOptions = { - descriptor: this.descriptor.f, - root: this.root, - pNode: parentFragment.pNode, - owner: this - }; - if (this.descriptor.i) { - fragmentOptions.indexRef = this.descriptor.i; - } - for (i = firstChange; i < newLength; i += 1) { - if (fragment = newFragments[i]) { - this.docFrag.appendChild(fragment.detach(false)); - } else { - fragmentOptions.contextStack = this.contextStack.concat(this.keypath + '.' + i); - fragmentOptions.index = i; - fragment = this.createFragment(fragmentOptions); - } - this.fragments[i] = fragment; - } - nextNode = parentFragment.findNextNode(this); - parentFragment.pNode.insertBefore(this.docFrag, nextNode); - this.length = newLength; - }; - }(render_DomFragment_Section_reassignFragment); -var circular = function () { - - return []; - }(); -var render_DomFragment_Section__Section = function (types, isClient, initMustache, updateMustache, resolveMustache, updateSection, reassignFragment, reassignFragments, merge, teardown, circular) { - - var DomSection, DomFragment; - circular.push(function () { - DomFragment = circular.DomFragment; - }); - DomSection = function (options, docFrag) { - this.type = types.SECTION; - this.inverted = !!options.descriptor.n; - this.fragments = []; - this.length = 0; - if (docFrag) { - this.docFrag = document.createDocumentFragment(); - } - this.initialising = true; - initMustache(this, options); - if (docFrag) { - docFrag.appendChild(this.docFrag); - } - this.initialising = false; - }; - DomSection.prototype = { - update: updateMustache, - resolve: resolveMustache, - smartUpdate: function (methodName, args) { - var fragmentOptions; - if (methodName === 'push' || methodName === 'unshift' || methodName === 'splice') { - fragmentOptions = { - descriptor: this.descriptor.f, - root: this.root, - pNode: this.parentFragment.pNode, - owner: this - }; - if (this.descriptor.i) { - fragmentOptions.indexRef = this.descriptor.i; - } - } - if (this[methodName]) { - this.rendering = true; - this[methodName](fragmentOptions, args); - this.rendering = false; - } - }, - pop: function () { - if (this.length) { - this.fragments.pop().teardown(true); - this.length -= 1; - } - }, - push: function (fragmentOptions, args) { - var start, end, i; - start = this.length; - end = start + args.length; - for (i = start; i < end; i += 1) { - fragmentOptions.contextStack = this.contextStack.concat(this.keypath + '.' + i); - fragmentOptions.index = i; - this.fragments[i] = this.createFragment(fragmentOptions); - } - this.length += args.length; - this.parentFragment.pNode.insertBefore(this.docFrag, this.parentFragment.findNextNode(this)); - }, - shift: function () { - this.splice(null, [ - 0, - 1 - ]); - }, - unshift: function (fragmentOptions, args) { - this.splice(fragmentOptions, [ - 0, - 0 - ].concat(new Array(args.length))); - }, - splice: function (fragmentOptions, args) { - var insertionPoint, addedItems, removedItems, balance, i, start, end, spliceArgs, reassignStart; - if (!args.length) { - return; - } - start = +(args[0] < 0 ? this.length + args[0] : args[0]); - addedItems = Math.max(0, args.length - 2); - removedItems = args[1] !== undefined ? args[1] : this.length - start; - removedItems = Math.min(removedItems, this.length - start); - balance = addedItems - removedItems; - if (!balance) { - return; - } - if (balance < 0) { - end = start - balance; - for (i = start; i < end; i += 1) { - this.fragments[i].teardown(true); - } - this.fragments.splice(start, -balance); - } else { - end = start + balance; - insertionPoint = this.fragments[start] ? this.fragments[start].firstNode() : this.parentFragment.findNextNode(this); - spliceArgs = [ - start, - 0 - ].concat(new Array(balance)); - this.fragments.splice.apply(this.fragments, spliceArgs); - for (i = start; i < end; i += 1) { - fragmentOptions.contextStack = this.contextStack.concat(this.keypath + '.' + i); - fragmentOptions.index = i; - this.fragments[i] = this.createFragment(fragmentOptions); - } - this.parentFragment.pNode.insertBefore(this.docFrag, insertionPoint); - } - this.length += balance; - reassignStart = start + addedItems; - reassignFragments(this.root, this, reassignStart, this.length, balance); - }, - merge: merge, - detach: function () { - var i, len; - len = this.fragments.length; - for (i = 0; i < len; i += 1) { - this.docFrag.appendChild(this.fragments[i].detach()); - } - return this.docFrag; - }, - teardown: function (destroy) { - this.teardownFragments(destroy); - teardown(this); - }, - firstNode: function () { - if (this.fragments[0]) { - return this.fragments[0].firstNode(); - } - return this.parentFragment.findNextNode(this); - }, - findNextNode: function (fragment) { - if (this.fragments[fragment.index + 1]) { - return this.fragments[fragment.index + 1].firstNode(); - } - return this.parentFragment.findNextNode(this); - }, - teardownFragments: function (destroy) { - var id, fragment; - while (fragment = this.fragments.shift()) { - fragment.teardown(destroy); - } - if (this.fragmentsById) { - for (id in this.fragmentsById) { - if (this.fragments[id]) { - this.fragmentsById[id].teardown(destroy); - this.fragmentsById[id] = null; - } - } - } - }, - render: function (value) { - var nextNode, wrapped; - if (wrapped = this.root._wrapped[this.keypath]) { - value = wrapped.get(); - } - if (this.rendering) { - return; - } - this.rendering = true; - updateSection(this, value); - this.rendering = false; - if (this.docFrag && !this.docFrag.childNodes.length) { - return; - } - if (!this.initialising && isClient) { - nextNode = this.parentFragment.findNextNode(this); - if (nextNode && nextNode.parentNode === this.parentFragment.pNode) { - this.parentFragment.pNode.insertBefore(this.docFrag, nextNode); - } else { - this.parentFragment.pNode.appendChild(this.docFrag); - } - } - }, - createFragment: function (options) { - var fragment = new DomFragment(options); - if (this.docFrag) { - this.docFrag.appendChild(fragment.docFrag); - } - return fragment; - }, - toString: function () { - var str, i, id, len; - str = ''; - i = 0; - len = this.length; - for (i = 0; i < len; i += 1) { - str += this.fragments[i].toString(); - } - if (this.fragmentsById) { - for (id in this.fragmentsById) { - if (this.fragmentsById[id]) { - str += this.fragmentsById[id].toString(); - } - } - } - return str; - }, - find: function (selector) { - var i, len, queryResult; - len = this.fragments.length; - for (i = 0; i < len; i += 1) { - if (queryResult = this.fragments[i].find(selector)) { - return queryResult; - } - } - return null; - }, - findAll: function (selector, query) { - var i, len; - len = this.fragments.length; - for (i = 0; i < len; i += 1) { - this.fragments[i].findAll(selector, query); - } - }, - findComponent: function (selector) { - var i, len, queryResult; - len = this.fragments.length; - for (i = 0; i < len; i += 1) { - if (queryResult = this.fragments[i].findComponent(selector)) { - return queryResult; - } - } - return null; - }, - findAllComponents: function (selector, query) { - var i, len; - len = this.fragments.length; - for (i = 0; i < len; i += 1) { - this.fragments[i].findAllComponents(selector, query); - } - } - }; - return DomSection; - }(config_types, config_isClient, render_shared_initMustache, render_shared_updateMustache, render_shared_resolveMustache, render_shared_updateSection, render_DomFragment_Section_reassignFragment, render_DomFragment_Section_reassignFragments, render_DomFragment_Section_prototype_merge, shared_teardown, circular); -var render_DomFragment_Triple = function (types, matches, initMustache, updateMustache, resolveMustache, insertHtml, teardown) { - - var DomTriple = function (options, docFrag) { - this.type = types.TRIPLE; - if (docFrag) { - this.nodes = []; - this.docFrag = document.createDocumentFragment(); - } - this.initialising = true; - initMustache(this, options); - if (docFrag) { - docFrag.appendChild(this.docFrag); - } - this.initialising = false; - }; - DomTriple.prototype = { - update: updateMustache, - resolve: resolveMustache, - detach: function () { - var i = this.nodes.length; - while (i--) { - this.docFrag.appendChild(this.nodes[i]); - } - return this.docFrag; - }, - teardown: function (destroy) { - if (destroy) { - this.detach(); - this.docFrag = this.nodes = null; - } - teardown(this); - }, - firstNode: function () { - if (this.nodes[0]) { - return this.nodes[0]; - } - return this.parentFragment.findNextNode(this); - }, - render: function (html) { - var node, pNode; - if (!this.nodes) { - return; - } - while (this.nodes.length) { - node = this.nodes.pop(); - node.parentNode.removeChild(node); - } - if (!html) { - this.nodes = []; - return; - } - pNode = this.parentFragment.pNode; - this.nodes = insertHtml(html, pNode.tagName, this.docFrag); - if (!this.initialising) { - pNode.insertBefore(this.docFrag, this.parentFragment.findNextNode(this)); - } - }, - toString: function () { - return this.value != undefined ? this.value : ''; - }, - find: function (selector) { - var i, len, node, queryResult; - len = this.nodes.length; - for (i = 0; i < len; i += 1) { - node = this.nodes[i]; - if (node.nodeType !== 1) { - continue; - } - if (matches(node, selector)) { - return node; - } - if (queryResult = node.querySelector(selector)) { - return queryResult; - } - } - return null; - }, - findAll: function (selector, queryResult) { - var i, len, node, queryAllResult, numNodes, j; - len = this.nodes.length; - for (i = 0; i < len; i += 1) { - node = this.nodes[i]; - if (node.nodeType !== 1) { - continue; - } - if (matches(node, selector)) { - queryResult.push(node); - } - if (queryAllResult = node.querySelectorAll(selector)) { - numNodes = queryAllResult.length; - for (j = 0; j < numNodes; j += 1) { - queryResult.push(queryAllResult[j]); - } - } - } - } - }; - return DomTriple; - }(config_types, utils_matches, render_shared_initMustache, render_shared_updateMustache, render_shared_resolveMustache, render_DomFragment_shared_insertHtml, shared_teardown); -var render_DomFragment_Element_initialise_getElementNamespace = function (namespaces) { - - return function (descriptor, parentNode) { - if (descriptor.a && descriptor.a.xmlns) { - return descriptor.a.xmlns; - } - return descriptor.e === 'svg' ? namespaces.svg : parentNode.namespaceURI || namespaces.html; - }; - }(config_namespaces); -var render_DomFragment_shared_enforceCase = function () { - - var svgCamelCaseElements, svgCamelCaseAttributes, createMap, map; - svgCamelCaseElements = 'altGlyph altGlyphDef altGlyphItem animateColor animateMotion animateTransform clipPath feBlend feColorMatrix feComponentTransfer feComposite feConvolveMatrix feDiffuseLighting feDisplacementMap feDistantLight feFlood feFuncA feFuncB feFuncG feFuncR feGaussianBlur feImage feMerge feMergeNode feMorphology feOffset fePointLight feSpecularLighting feSpotLight feTile feTurbulence foreignObject glyphRef linearGradient radialGradient textPath vkern'.split(' '); - svgCamelCaseAttributes = 'attributeName attributeType baseFrequency baseProfile calcMode clipPathUnits contentScriptType contentStyleType diffuseConstant edgeMode externalResourcesRequired filterRes filterUnits glyphRef gradientTransform gradientUnits kernelMatrix kernelUnitLength keyPoints keySplines keyTimes lengthAdjust limitingConeAngle markerHeight markerUnits markerWidth maskContentUnits maskUnits numOctaves pathLength patternContentUnits patternTransform patternUnits pointsAtX pointsAtY pointsAtZ preserveAlpha preserveAspectRatio primitiveUnits refX refY repeatCount repeatDur requiredExtensions requiredFeatures specularConstant specularExponent spreadMethod startOffset stdDeviation stitchTiles surfaceScale systemLanguage tableValues targetX targetY textLength viewBox viewTarget xChannelSelector yChannelSelector zoomAndPan'.split(' '); - createMap = function (items) { - var map = {}, i = items.length; - while (i--) { - map[items[i].toLowerCase()] = items[i]; - } - return map; - }; - map = createMap(svgCamelCaseElements.concat(svgCamelCaseAttributes)); - return function (elementName) { - var lowerCaseElementName = elementName.toLowerCase(); - return map[lowerCaseElementName] || lowerCaseElementName; - }; - }(); -var render_DomFragment_Attribute_helpers_determineNameAndNamespace = function (namespaces, enforceCase) { - - return function (attribute, name) { - var colonIndex, namespacePrefix; - colonIndex = name.indexOf(':'); - if (colonIndex !== -1) { - namespacePrefix = name.substr(0, colonIndex); - if (namespacePrefix !== 'xmlns') { - name = name.substring(colonIndex + 1); - attribute.name = enforceCase(name); - attribute.lcName = attribute.name.toLowerCase(); - attribute.namespace = namespaces[namespacePrefix.toLowerCase()]; - if (!attribute.namespace) { - throw 'Unknown namespace ("' + namespacePrefix + '")'; - } - return; - } - } - attribute.name = attribute.element.namespace !== namespaces.html ? enforceCase(name) : name; - attribute.lcName = attribute.name.toLowerCase(); - }; - }(config_namespaces, render_DomFragment_shared_enforceCase); -var render_DomFragment_Attribute_helpers_setStaticAttribute = function (namespaces) { - - return function (attribute, options) { - var node, value = options.value === null ? '' : options.value; - if (node = options.pNode) { - if (attribute.namespace) { - node.setAttributeNS(attribute.namespace, options.name, value); - } else { - if (options.name === 'style' && node.style.setAttribute) { - node.style.setAttribute('cssText', value); - } else if (options.name === 'class' && (!node.namespaceURI || node.namespaceURI === namespaces.html)) { - node.className = value; - } else { - node.setAttribute(options.name, value); - } - } - if (attribute.name === 'id') { - options.root.nodes[options.value] = node; - } - if (attribute.name === 'value') { - node._ractive.value = options.value; - } - } - attribute.value = options.value; - }; - }(config_namespaces); -var render_DomFragment_Attribute_helpers_determinePropertyName = function (namespaces) { - - var propertyNames = { - 'accept-charset': 'acceptCharset', - accesskey: 'accessKey', - bgcolor: 'bgColor', - 'class': 'className', - codebase: 'codeBase', - colspan: 'colSpan', - contenteditable: 'contentEditable', - datetime: 'dateTime', - dirname: 'dirName', - 'for': 'htmlFor', - 'http-equiv': 'httpEquiv', - ismap: 'isMap', - maxlength: 'maxLength', - novalidate: 'noValidate', - pubdate: 'pubDate', - readonly: 'readOnly', - rowspan: 'rowSpan', - tabindex: 'tabIndex', - usemap: 'useMap' - }; - return function (attribute, options) { - var propertyName; - if (attribute.pNode && !attribute.namespace && (!options.pNode.namespaceURI || options.pNode.namespaceURI === namespaces.html)) { - propertyName = propertyNames[attribute.name] || attribute.name; - if (options.pNode[propertyName] !== undefined) { - attribute.propertyName = propertyName; - } - if (typeof options.pNode[propertyName] === 'boolean' || propertyName === 'value') { - attribute.useProperty = true; - } - } - }; - }(config_namespaces); -var render_DomFragment_Attribute_prototype_bind = function (types, warn, arrayContentsMatch, getValueFromCheckboxes) { - - var bindAttribute, getInterpolator, updateModel, update, getBinding, inheritProperties, MultipleSelectBinding, SelectBinding, RadioNameBinding, CheckboxNameBinding, CheckedBinding, FileListBinding, ContentEditableBinding, GenericBinding; - bindAttribute = function () { - var node = this.pNode, interpolator, binding, bindings; - if (!this.fragment) { - return false; - } - interpolator = getInterpolator(this); - if (!interpolator) { - return false; - } - this.interpolator = interpolator; - this.keypath = interpolator.keypath || interpolator.descriptor.r; - binding = getBinding(this); - if (!binding) { - return false; - } - node._ractive.binding = this.element.binding = binding; - this.twoway = true; - bindings = this.root._twowayBindings[this.keypath] || (this.root._twowayBindings[this.keypath] = []); - bindings[bindings.length] = binding; - return true; - }; - updateModel = function () { - this._ractive.binding.update(); - }; - update = function () { - var value = this._ractive.root.get(this._ractive.binding.keypath); - this.value = value == undefined ? '' : value; - }; - getInterpolator = function (attribute) { - var item, errorMessage; - if (attribute.fragment.items.length !== 1) { - return null; - } - item = attribute.fragment.items[0]; - if (item.type !== types.INTERPOLATOR) { - return null; - } - if (!item.keypath && !item.ref) { - return null; - } - if (item.keypath && item.keypath.substr(0, 2) === '${') { - errorMessage = 'You cannot set up two-way binding against an expression ' + item.keypath; - if (attribute.root.debug) { - warn(errorMessage); - } - return null; - } - return item; - }; - getBinding = function (attribute) { - var node = attribute.pNode; - if (node.tagName === 'SELECT') { - return node.multiple ? new MultipleSelectBinding(attribute, node) : new SelectBinding(attribute, node); - } - if (node.type === 'checkbox' || node.type === 'radio') { - if (attribute.propertyName === 'name') { - if (node.type === 'checkbox') { - return new CheckboxNameBinding(attribute, node); - } - if (node.type === 'radio') { - return new RadioNameBinding(attribute, node); - } - } - if (attribute.propertyName === 'checked') { - return new CheckedBinding(attribute, node); - } - return null; - } - if (attribute.lcName !== 'value') { - warn('This is... odd'); - } - if (node.type === 'file') { - return new FileListBinding(attribute, node); - } - if (node.getAttribute('contenteditable')) { - return new ContentEditableBinding(attribute, node); - } - return new GenericBinding(attribute, node); - }; - MultipleSelectBinding = function (attribute, node) { - var valueFromModel; - inheritProperties(this, attribute, node); - node.addEventListener('change', updateModel, false); - valueFromModel = this.root.get(this.keypath); - if (valueFromModel === undefined) { - this.update(); - } - }; - MultipleSelectBinding.prototype = { - value: function () { - var value, options, i, len; - value = []; - options = this.node.options; - len = options.length; - for (i = 0; i < len; i += 1) { - if (options[i].selected) { - value[value.length] = options[i]._ractive.value; - } - } - return value; - }, - update: function () { - var attribute, previousValue, value; - attribute = this.attr; - previousValue = attribute.value; - value = this.value(); - if (previousValue === undefined || !arrayContentsMatch(value, previousValue)) { - attribute.receiving = true; - attribute.value = value; - this.root.set(this.keypath, value); - attribute.receiving = false; - } - return this; - }, - deferUpdate: function () { - if (this.deferred === true) { - return; - } - this.root._deferred.attrs.push(this); - this.deferred = true; - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - } - }; - SelectBinding = function (attribute, node) { - var valueFromModel; - inheritProperties(this, attribute, node); - node.addEventListener('change', updateModel, false); - valueFromModel = this.root.get(this.keypath); - if (valueFromModel === undefined) { - this.update(); - } - }; - SelectBinding.prototype = { - value: function () { - var options, i, len; - options = this.node.options; - len = options.length; - for (i = 0; i < len; i += 1) { - if (options[i].selected) { - return options[i]._ractive.value; - } - } - }, - update: function () { - var value = this.value(); - this.attr.receiving = true; - this.attr.value = value; - this.root.set(this.keypath, value); - this.attr.receiving = false; - return this; - }, - deferUpdate: function () { - if (this.deferred === true) { - return; - } - this.root._deferred.attrs.push(this); - this.deferred = true; - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - } - }; - RadioNameBinding = function (attribute, node) { - var valueFromModel; - this.radioName = true; - inheritProperties(this, attribute, node); - node.name = '{{' + attribute.keypath + '}}'; - node.addEventListener('change', updateModel, false); - if (node.attachEvent) { - node.addEventListener('click', updateModel, false); - } - valueFromModel = this.root.get(this.keypath); - if (valueFromModel !== undefined) { - node.checked = valueFromModel == node._ractive.value; - } else { - this.root._deferred.radios.push(this); - } - }; - RadioNameBinding.prototype = { - value: function () { - return this.node._ractive ? this.node._ractive.value : this.node.value; - }, - update: function () { - var node = this.node; - if (node.checked) { - this.attr.receiving = true; - this.root.set(this.keypath, this.value()); - this.attr.receiving = false; - } - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - this.node.removeEventListener('click', updateModel, false); - } - }; - CheckboxNameBinding = function (attribute, node) { - var valueFromModel, checked; - this.checkboxName = true; - inheritProperties(this, attribute, node); - node.name = '{{' + this.keypath + '}}'; - node.addEventListener('change', updateModel, false); - if (node.attachEvent) { - node.addEventListener('click', updateModel, false); - } - valueFromModel = this.root.get(this.keypath); - if (valueFromModel !== undefined) { - checked = valueFromModel.indexOf(node._ractive.value) !== -1; - node.checked = checked; - } else { - if (this.root._deferred.checkboxes.indexOf(this.keypath) === -1) { - this.root._deferred.checkboxes.push(this.keypath); - } - } - }; - CheckboxNameBinding.prototype = { - changed: function () { - return this.node.checked !== !!this.checked; - }, - update: function () { - this.checked = this.node.checked; - this.attr.receiving = true; - this.root.set(this.keypath, getValueFromCheckboxes(this.root, this.keypath)); - this.attr.receiving = false; - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - this.node.removeEventListener('click', updateModel, false); - } - }; - CheckedBinding = function (attribute, node) { - inheritProperties(this, attribute, node); - node.addEventListener('change', updateModel, false); - if (node.attachEvent) { - node.addEventListener('click', updateModel, false); - } - }; - CheckedBinding.prototype = { - value: function () { - return this.node.checked; - }, - update: function () { - this.attr.receiving = true; - this.root.set(this.keypath, this.value()); - this.attr.receiving = false; - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - this.node.removeEventListener('click', updateModel, false); - } - }; - FileListBinding = function (attribute, node) { - inheritProperties(this, attribute, node); - node.addEventListener('change', updateModel, false); - }; - FileListBinding.prototype = { - value: function () { - return this.attr.pNode.files; - }, - update: function () { - this.attr.root.set(this.attr.keypath, this.value()); - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - } - }; - ContentEditableBinding = function (attribute, node) { - inheritProperties(this, attribute, node); - node.addEventListener('change', updateModel, false); - if (!this.root.lazy) { - node.addEventListener('input', updateModel, false); - if (node.attachEvent) { - node.addEventListener('keyup', updateModel, false); - } - } - }; - ContentEditableBinding.prototype = { - update: function () { - this.attr.receiving = true; - this.root.set(this.keypath, this.node.innerHTML); - this.attr.receiving = false; - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - this.node.removeEventListener('input', updateModel, false); - this.node.removeEventListener('keyup', updateModel, false); - } - }; - GenericBinding = function (attribute, node) { - inheritProperties(this, attribute, node); - node.addEventListener('change', updateModel, false); - if (!this.root.lazy) { - node.addEventListener('input', updateModel, false); - if (node.attachEvent) { - node.addEventListener('keyup', updateModel, false); - } - } - this.node.addEventListener('blur', update, false); - }; - GenericBinding.prototype = { - value: function () { - var value = this.attr.pNode.value; - if (+value + '' === value && value.indexOf('e') === -1) { - value = +value; - } - return value; - }, - update: function () { - var attribute = this.attr, value = this.value(); - attribute.receiving = true; - attribute.root.set(attribute.keypath, value); - attribute.receiving = false; - }, - teardown: function () { - this.node.removeEventListener('change', updateModel, false); - this.node.removeEventListener('input', updateModel, false); - this.node.removeEventListener('keyup', updateModel, false); - this.node.removeEventListener('blur', update, false); - } - }; - inheritProperties = function (binding, attribute, node) { - binding.attr = attribute; - binding.node = node; - binding.root = attribute.root; - binding.keypath = attribute.keypath; - }; - return bindAttribute; - }(config_types, utils_warn, utils_arrayContentsMatch, shared_getValueFromCheckboxes); -var render_DomFragment_Attribute_prototype_update = function (isArray, namespaces) { - - var updateAttribute, updateFileInputValue, deferSelect, initSelect, updateSelect, updateMultipleSelect, updateRadioName, updateCheckboxName, updateIEStyleAttribute, updateClassName, updateContentEditableValue, updateEverythingElse; - updateAttribute = function () { - var node; - if (!this.ready) { - return this; - } - node = this.pNode; - if (node.tagName === 'SELECT' && this.lcName === 'value') { - this.update = deferSelect; - this.deferredUpdate = initSelect; - return this.update(); - } - if (this.isFileInputValue) { - this.update = updateFileInputValue; - return this; - } - if (this.twoway && this.lcName === 'name') { - if (node.type === 'radio') { - this.update = updateRadioName; - return this.update(); - } - if (node.type === 'checkbox') { - this.update = updateCheckboxName; - return this.update(); - } - } - if (this.lcName === 'style' && node.style.setAttribute) { - this.update = updateIEStyleAttribute; - return this.update(); - } - if (this.lcName === 'class' && (!node.namespaceURI || node.namespaceURI === namespaces.html)) { - this.update = updateClassName; - return this.update(); - } - if (node.getAttribute('contenteditable') && this.lcName === 'value') { - this.update = updateContentEditableValue; - return this.update(); - } - this.update = updateEverythingElse; - return this.update(); - }; - updateFileInputValue = function () { - return this; - }; - initSelect = function () { - this.deferredUpdate = this.pNode.multiple ? updateMultipleSelect : updateSelect; - this.deferredUpdate(); - }; - deferSelect = function () { - this.root._deferred.selectValues.push(this); - return this; - }; - updateSelect = function () { - var value = this.fragment.getValue(), options, option, i; - this.value = this.pNode._ractive.value = value; - options = this.pNode.options; - i = options.length; - while (i--) { - option = options[i]; - if (option._ractive.value == value) { - option.selected = true; - return this; - } - } - return this; - }; - updateMultipleSelect = function () { - var value = this.fragment.getValue(), options, i; - if (!isArray(value)) { - value = [value]; - } - options = this.pNode.options; - i = options.length; - while (i--) { - options[i].selected = value.indexOf(options[i]._ractive.value) !== -1; - } - this.value = value; - return this; - }; - updateRadioName = function () { - var node, value; - node = this.pNode; - value = this.fragment.getValue(); - node.checked = value == node._ractive.value; - return this; - }; - updateCheckboxName = function () { - var node, value; - node = this.pNode; - value = this.fragment.getValue(); - if (!isArray(value)) { - node.checked = value == node._ractive.value; - return this; - } - node.checked = value.indexOf(node._ractive.value) !== -1; - return this; - }; - updateIEStyleAttribute = function () { - var node, value; - node = this.pNode; - value = this.fragment.getValue(); - if (value === undefined) { - value = ''; - } - if (value !== this.value) { - node.style.setAttribute('cssText', value); - this.value = value; - } - return this; - }; - updateClassName = function () { - var node, value; - node = this.pNode; - value = this.fragment.getValue(); - if (value === undefined) { - value = ''; - } - if (value !== this.value) { - node.className = value; - this.value = value; - } - return this; - }; - updateContentEditableValue = function () { - var node, value; - node = this.pNode; - value = this.fragment.getValue(); - if (value === undefined) { - value = ''; - } - if (value !== this.value) { - if (!this.receiving) { - node.innerHTML = value; - } - this.value = value; - } - return this; - }; - updateEverythingElse = function () { - var node, value; - node = this.pNode; - value = this.fragment.getValue(); - if (this.isValueAttribute) { - node._ractive.value = value; - } - if (value === undefined) { - value = ''; - } - if (value !== this.value) { - if (this.useProperty) { - if (!this.receiving) { - node[this.propertyName] = value; - } - this.value = value; - return this; - } - if (this.namespace) { - node.setAttributeNS(this.namespace, this.name, value); - this.value = value; - return this; - } - if (this.lcName === 'id') { - if (this.value !== undefined) { - this.root.nodes[this.value] = undefined; - } - this.root.nodes[value] = node; - } - node.setAttribute(this.name, value); - this.value = value; - } - return this; - }; - return updateAttribute; - }(utils_isArray, config_namespaces); -var parse_Tokenizer_utils_getStringMatch = function () { - - return function (string) { - var substr; - substr = this.str.substr(this.pos, string.length); - if (substr === string) { - this.pos += string.length; - return string; - } - return null; - }; - }(); -var parse_Tokenizer_utils_allowWhitespace = function () { - - var leadingWhitespace = /^\s+/; - return function () { - var match = leadingWhitespace.exec(this.remaining()); - if (!match) { - return null; - } - this.pos += match[0].length; - return match[0]; - }; - }(); -var parse_Tokenizer_utils_makeRegexMatcher = function () { - - return function (regex) { - return function (tokenizer) { - var match = regex.exec(tokenizer.str.substring(tokenizer.pos)); - if (!match) { - return null; - } - tokenizer.pos += match[0].length; - return match[1] || match[0]; - }; - }; - }(); -var parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral_getEscapedChars = function () { - - return function (tokenizer) { - var chars = '', character; - character = getEscapedChar(tokenizer); - while (character) { - chars += character; - character = getEscapedChar(tokenizer); - } - return chars || null; - }; - function getEscapedChar(tokenizer) { - var character; - if (!tokenizer.getStringMatch('\\')) { - return null; - } - character = tokenizer.str.charAt(tokenizer.pos); - tokenizer.pos += 1; - return character; - } - }(); -var parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral_getQuotedString = function (makeRegexMatcher, getEscapedChars) { - - var getUnescapedDoubleQuotedChars = makeRegexMatcher(/^[^\\"]+/), getUnescapedSingleQuotedChars = makeRegexMatcher(/^[^\\']+/); - return function getQuotedString(tokenizer, singleQuotes) { - var start, string, escaped, unescaped, next, matcher; - start = tokenizer.pos; - string = ''; - matcher = singleQuotes ? getUnescapedSingleQuotedChars : getUnescapedDoubleQuotedChars; - escaped = getEscapedChars(tokenizer); - if (escaped) { - string += escaped; - } - unescaped = matcher(tokenizer); - if (unescaped) { - string += unescaped; - } - if (!string) { - return ''; - } - next = getQuotedString(tokenizer, singleQuotes); - while (next !== '') { - string += next; - } - return string; - }; - }(parse_Tokenizer_utils_makeRegexMatcher, parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral_getEscapedChars); -var parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral__getStringLiteral = function (types, getQuotedString) { - - return function (tokenizer) { - var start, string; - start = tokenizer.pos; - if (tokenizer.getStringMatch('"')) { - string = getQuotedString(tokenizer, false); - if (!tokenizer.getStringMatch('"')) { - tokenizer.pos = start; - return null; - } - return { - t: types.STRING_LITERAL, - v: string - }; - } - if (tokenizer.getStringMatch('\'')) { - string = getQuotedString(tokenizer, true); - if (!tokenizer.getStringMatch('\'')) { - tokenizer.pos = start; - return null; - } - return { - t: types.STRING_LITERAL, - v: string - }; - } - return null; - }; - }(config_types, parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral_getQuotedString); -var parse_Tokenizer_getExpression_getPrimary_getLiteral_getNumberLiteral = function (types, makeRegexMatcher) { - - var getNumber = makeRegexMatcher(/^(?:[+-]?)(?:(?:(?:0|[1-9]\d*)?\.\d+)|(?:(?:0|[1-9]\d*)\.)|(?:0|[1-9]\d*))(?:[eE][+-]?\d+)?/); - return function (tokenizer) { - var result; - if (result = getNumber(tokenizer)) { - return { - t: types.NUMBER_LITERAL, - v: result - }; - } - return null; - }; - }(config_types, parse_Tokenizer_utils_makeRegexMatcher); -var parse_Tokenizer_getExpression_shared_getName = function (makeRegexMatcher) { - - return makeRegexMatcher(/^[a-zA-Z_$][a-zA-Z_$0-9]*/); - }(parse_Tokenizer_utils_makeRegexMatcher); -var parse_Tokenizer_getExpression_shared_getKey = function (getStringLiteral, getNumberLiteral, getName) { - - var identifier = /^[a-zA-Z_$][a-zA-Z_$0-9]*$/; - return function (tokenizer) { - var token; - if (token = getStringLiteral(tokenizer)) { - return identifier.test(token.v) ? token.v : '"' + token.v.replace(/"/g, '\\"') + '"'; - } - if (token = getNumberLiteral(tokenizer)) { - return token.v; - } - if (token = getName(tokenizer)) { - return token; - } - }; - }(parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral__getStringLiteral, parse_Tokenizer_getExpression_getPrimary_getLiteral_getNumberLiteral, parse_Tokenizer_getExpression_shared_getName); -var utils_parseJSON = function (getStringMatch, allowWhitespace, getStringLiteral, getKey) { - - var Tokenizer, specials, specialsPattern, numberPattern, placeholderPattern, placeholderAtStartPattern; - specials = { - 'true': true, - 'false': false, - 'undefined': undefined, - 'null': null - }; - specialsPattern = new RegExp('^(?:' + Object.keys(specials).join('|') + ')'); - numberPattern = /^(?:[+-]?)(?:(?:(?:0|[1-9]\d*)?\.\d+)|(?:(?:0|[1-9]\d*)\.)|(?:0|[1-9]\d*))(?:[eE][+-]?\d+)?/; - placeholderPattern = /\$\{([^\}]+)\}/g; - placeholderAtStartPattern = /^\$\{([^\}]+)\}/; - Tokenizer = function (str, values) { - this.str = str; - this.values = values; - this.pos = 0; - this.result = this.getToken(); - }; - Tokenizer.prototype = { - remaining: function () { - return this.str.substring(this.pos); - }, - getStringMatch: getStringMatch, - getToken: function () { - this.allowWhitespace(); - return this.getPlaceholder() || this.getSpecial() || this.getNumber() || this.getString() || this.getObject() || this.getArray(); - }, - getPlaceholder: function () { - var match; - if (!this.values) { - return null; - } - if ((match = placeholderAtStartPattern.exec(this.remaining())) && this.values.hasOwnProperty(match[1])) { - this.pos += match[0].length; - return { v: this.values[match[1]] }; - } - }, - getSpecial: function () { - var match; - if (match = specialsPattern.exec(this.remaining())) { - this.pos += match[0].length; - return { v: specials[match[0]] }; - } - }, - getNumber: function () { - var match; - if (match = numberPattern.exec(this.remaining())) { - this.pos += match[0].length; - return { v: +match[0] }; - } - }, - getString: function () { - var stringLiteral = getStringLiteral(this), values; - if (stringLiteral && (values = this.values)) { - return { - v: stringLiteral.v.replace(placeholderPattern, function (match, $1) { - return values[$1] || $1; - }) - }; - } - return stringLiteral; - }, - getObject: function () { - var result, pair; - if (!this.getStringMatch('{')) { - return null; - } - result = {}; - while (pair = getKeyValuePair(this)) { - result[pair.key] = pair.value; - this.allowWhitespace(); - if (this.getStringMatch('}')) { - return { v: result }; - } - if (!this.getStringMatch(',')) { - return null; - } - } - return null; - }, - getArray: function () { - var result, valueToken; - if (!this.getStringMatch('[')) { - return null; - } - result = []; - while (valueToken = this.getToken()) { - result.push(valueToken.v); - if (this.getStringMatch(']')) { - return { v: result }; - } - if (!this.getStringMatch(',')) { - return null; - } - } - return null; - }, - allowWhitespace: allowWhitespace - }; - function getKeyValuePair(tokenizer) { - var key, valueToken, pair; - tokenizer.allowWhitespace(); - key = getKey(tokenizer); - if (!key) { - return null; - } - pair = { key: key }; - tokenizer.allowWhitespace(); - if (!tokenizer.getStringMatch(':')) { - return null; - } - tokenizer.allowWhitespace(); - valueToken = tokenizer.getToken(); - if (!valueToken) { - return null; - } - pair.value = valueToken.v; - return pair; - } - return function (str, values) { - var tokenizer = new Tokenizer(str, values); - if (tokenizer.result) { - return { - value: tokenizer.result.v, - remaining: tokenizer.remaining() - }; - } - return null; - }; - }(parse_Tokenizer_utils_getStringMatch, parse_Tokenizer_utils_allowWhitespace, parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral__getStringLiteral, parse_Tokenizer_getExpression_shared_getKey); -var render_StringFragment_Interpolator = function (types, teardown, initMustache, updateMustache, resolveMustache) { - - var StringInterpolator = function (options) { - this.type = types.INTERPOLATOR; - initMustache(this, options); - }; - StringInterpolator.prototype = { - update: updateMustache, - resolve: resolveMustache, - render: function (value) { - this.value = value; - this.parentFragment.bubble(); - }, - teardown: function () { - teardown(this); - }, - toString: function () { - if (this.value == undefined) { - return ''; - } - return stringify(this.value); - } - }; - return StringInterpolator; - function stringify(value) { - if (typeof value === 'string') { - return value; - } - return JSON.stringify(value); - } - }(config_types, shared_teardown, render_shared_initMustache, render_shared_updateMustache, render_shared_resolveMustache); -var render_StringFragment_Section = function (types, initMustache, updateMustache, resolveMustache, updateSection, teardown, circular) { - - var StringSection, StringFragment; - circular.push(function () { - StringFragment = circular.StringFragment; - }); - StringSection = function (options) { - this.type = types.SECTION; - this.fragments = []; - this.length = 0; - initMustache(this, options); - }; - StringSection.prototype = { - update: updateMustache, - resolve: resolveMustache, - teardown: function () { - this.teardownFragments(); - teardown(this); - }, - teardownFragments: function () { - while (this.fragments.length) { - this.fragments.shift().teardown(); - } - this.length = 0; - }, - bubble: function () { - this.value = this.fragments.join(''); - this.parentFragment.bubble(); - }, - render: function (value) { - var wrapped; - if (wrapped = this.root._wrapped[this.keypath]) { - value = wrapped.get(); - } - updateSection(this, value); - this.parentFragment.bubble(); - }, - createFragment: function (options) { - return new StringFragment(options); - }, - toString: function () { - return this.fragments.join(''); - } - }; - return StringSection; - }(config_types, render_shared_initMustache, render_shared_updateMustache, render_shared_resolveMustache, render_shared_updateSection, shared_teardown, circular); -var render_StringFragment_Text = function (types) { - - var StringText = function (text) { - this.type = types.TEXT; - this.text = text; - }; - StringText.prototype = { - toString: function () { - return this.text; - }, - teardown: function () { - } - }; - return StringText; - }(config_types); -var render_StringFragment_prototype_toArgsList = function (warn, parseJSON) { - - return function () { - var values, counter, jsonesque, guid, errorMessage, parsed, processItems; - if (!this.argsList || this.dirty) { - values = {}; - counter = 0; - guid = this.root._guid; - processItems = function (items) { - return items.map(function (item) { - var placeholderId, wrapped, value; - if (item.text) { - return item.text; - } - if (item.fragments) { - return item.fragments.map(function (fragment) { - return processItems(fragment.items); - }).join(''); - } - placeholderId = guid + '-' + counter++; - if (wrapped = item.root._wrapped[item.keypath]) { - value = wrapped.value; - } else { - value = item.value; - } - values[placeholderId] = value; - return '${' + placeholderId + '}'; - }).join(''); - }; - jsonesque = processItems(this.items); - parsed = parseJSON('[' + jsonesque + ']', values); - if (!parsed) { - errorMessage = 'Could not parse directive arguments (' + this.toString() + '). If you think this is a bug, please file an issue at http://github.com/RactiveJS/Ractive/issues'; - if (this.root.debug) { - throw new Error(errorMessage); - } else { - warn(errorMessage); - this.argsList = [jsonesque]; - } - } else { - this.argsList = parsed.value; - } - this.dirty = false; - } - return this.argsList; - }; - }(utils_warn, utils_parseJSON); -var render_StringFragment__StringFragment = function (types, parseJSON, initFragment, Interpolator, Section, Text, toArgsList, circular) { - - var StringFragment = function (options) { - initFragment(this, options); - }; - StringFragment.prototype = { - createItem: function (options) { - if (typeof options.descriptor === 'string') { - return new Text(options.descriptor); - } - switch (options.descriptor.t) { - case types.INTERPOLATOR: - return new Interpolator(options); - case types.TRIPLE: - return new Interpolator(options); - case types.SECTION: - return new Section(options); - default: - throw 'Something went wrong in a rather interesting way'; - } - }, - bubble: function () { - this.dirty = true; - this.owner.bubble(); - }, - teardown: function () { - var numItems, i; - numItems = this.items.length; - for (i = 0; i < numItems; i += 1) { - this.items[i].teardown(); - } - }, - getValue: function () { - var value; - if (this.items.length === 1 && this.items[0].type === types.INTERPOLATOR) { - value = this.items[0].value; - if (value !== undefined) { - return value; - } - } - return this.toString(); - }, - isSimple: function () { - var i, item, containsInterpolator; - if (this.simple !== undefined) { - return this.simple; - } - i = this.items.length; - while (i--) { - item = this.items[i]; - if (item.type === types.TEXT) { - continue; - } - if (item.type === types.INTERPOLATOR) { - if (containsInterpolator) { - return false; - } else { - containsInterpolator = true; - continue; - } - } - return this.simple = false; - } - return this.simple = true; - }, - toString: function () { - return this.items.join(''); - }, - toJSON: function () { - var value = this.getValue(), parsed; - if (typeof value === 'string') { - parsed = parseJSON(value); - value = parsed ? parsed.value : value; - } - return value; - }, - toArgsList: toArgsList - }; - circular.StringFragment = StringFragment; - return StringFragment; - }(config_types, utils_parseJSON, render_shared_initFragment, render_StringFragment_Interpolator, render_StringFragment_Section, render_StringFragment_Text, render_StringFragment_prototype_toArgsList, circular); -var render_DomFragment_Attribute__Attribute = function (types, determineNameAndNamespace, setStaticAttribute, determinePropertyName, bind, update, StringFragment) { - - var DomAttribute = function (options) { - this.type = types.ATTRIBUTE; - this.element = options.element; - determineNameAndNamespace(this, options.name); - if (options.value === null || typeof options.value === 'string') { - setStaticAttribute(this, options); - return; - } - this.root = options.root; - this.pNode = options.pNode; - this.parentFragment = this.element.parentFragment; - this.fragment = new StringFragment({ - descriptor: options.value, - root: this.root, - owner: this, - contextStack: options.contextStack - }); - if (!this.pNode) { - return; - } - if (this.name === 'value') { - this.isValueAttribute = true; - if (this.pNode.tagName === 'INPUT' && this.pNode.type === 'file') { - this.isFileInputValue = true; - } - } - determinePropertyName(this, options); - this.selfUpdating = this.fragment.isSimple(); - this.ready = true; - }; - DomAttribute.prototype = { - bind: bind, - update: update, - updateBindings: function () { - this.keypath = this.interpolator.keypath || this.interpolator.ref; - if (this.propertyName === 'name') { - this.pNode.name = '{{' + this.keypath + '}}'; - } - }, - teardown: function () { - var i; - if (this.boundEvents) { - i = this.boundEvents.length; - while (i--) { - this.pNode.removeEventListener(this.boundEvents[i], this.updateModel, false); - } - } - if (this.fragment) { - this.fragment.teardown(); - } - }, - bubble: function () { - if (this.selfUpdating) { - this.update(); - } else if (!this.deferred && this.ready) { - this.root._deferred.attrs.push(this); - this.deferred = true; - } - }, - toString: function () { - var str; - if (this.value === null) { - return this.name; - } - if (!this.fragment) { - return this.name + '=' + JSON.stringify(this.value); - } - str = this.fragment.toString(); - return this.name + '=' + JSON.stringify(str); - } - }; - return DomAttribute; - }(config_types, render_DomFragment_Attribute_helpers_determineNameAndNamespace, render_DomFragment_Attribute_helpers_setStaticAttribute, render_DomFragment_Attribute_helpers_determinePropertyName, render_DomFragment_Attribute_prototype_bind, render_DomFragment_Attribute_prototype_update, render_StringFragment__StringFragment); -var render_DomFragment_Element_initialise_createElementAttributes = function (DomAttribute) { - - return function (element, attributes) { - var attrName, attrValue, attr; - element.attributes = []; - for (attrName in attributes) { - if (attributes.hasOwnProperty(attrName)) { - attrValue = attributes[attrName]; - attr = new DomAttribute({ - element: element, - name: attrName, - value: attrValue, - root: element.root, - pNode: element.node, - contextStack: element.parentFragment.contextStack - }); - element.attributes[element.attributes.length] = element.attributes[attrName] = attr; - if (attrName !== 'name') { - attr.update(); - } - } - } - return element.attributes; - }; - }(render_DomFragment_Attribute__Attribute); -var render_DomFragment_Element_initialise_appendElementChildren = function (warn, namespaces, StringFragment, circular) { - - var DomFragment, updateCss, updateScript; - circular.push(function () { - DomFragment = circular.DomFragment; - }); - updateCss = function () { - var node = this.node, content = this.fragment.toString(); - if (node.styleSheet) { - node.styleSheet.cssText = content; - } - node.innerHTML = content; - }; - updateScript = function () { - if (!this.node.type || this.node.type === 'text/javascript') { - warn('Script tag was updated. This does not cause the code to be re-evaluated!'); - } - this.node.innerHTML = this.fragment.toString(); - }; - return function (element, node, descriptor, docFrag) { - var liveQueries, i, selector, queryAllResult, j; - if (element.lcName === 'script' || element.lcName === 'style') { - element.fragment = new StringFragment({ - descriptor: descriptor.f, - root: element.root, - contextStack: element.parentFragment.contextStack, - owner: element - }); - if (docFrag) { - if (element.lcName === 'script') { - element.bubble = updateScript; - element.node.innerHTML = element.fragment.toString(); - } else { - element.bubble = updateCss; - element.bubble(); - } - } - return; - } - if (typeof descriptor.f === 'string' && (!node || (!node.namespaceURI || node.namespaceURI === namespaces.html))) { - element.html = descriptor.f; - if (docFrag) { - node.innerHTML = element.html; - liveQueries = element.root._liveQueries; - i = liveQueries.length; - while (i--) { - selector = liveQueries[i]; - if ((queryAllResult = node.querySelectorAll(selector)) && (j = queryAllResult.length)) { - (element.liveQueries || (element.liveQueries = [])).push(selector); - element.liveQueries[selector] = []; - while (j--) { - element.liveQueries[selector][j] = queryAllResult[j]; - } - } - } - } - } else { - element.fragment = new DomFragment({ - descriptor: descriptor.f, - root: element.root, - pNode: node, - contextStack: element.parentFragment.contextStack, - owner: element - }); - if (docFrag) { - node.appendChild(element.fragment.docFrag); - } - } - }; - }(utils_warn, config_namespaces, render_StringFragment__StringFragment, circular); -var render_DomFragment_Element_initialise_decorate_Decorator = function (warn, StringFragment) { - - var Decorator = function (descriptor, root, owner, contextStack) { - var name, fragment, errorMessage; - this.root = root; - this.node = owner.node; - name = descriptor.n || descriptor; - if (typeof name !== 'string') { - fragment = new StringFragment({ - descriptor: name, - root: this.root, - owner: owner, - contextStack: contextStack - }); - name = fragment.toString(); - fragment.teardown(); - } - if (descriptor.a) { - this.params = descriptor.a; - } else if (descriptor.d) { - fragment = new StringFragment({ - descriptor: descriptor.d, - root: this.root, - owner: owner, - contextStack: contextStack - }); - this.params = fragment.toArgsList(); - fragment.teardown(); - } - this.fn = root.decorators[name]; - if (!this.fn) { - errorMessage = 'Missing "' + name + '" decorator. You may need to download a plugin via https://github.com/RactiveJS/Ractive/wiki/Plugins#decorators'; - if (root.debug) { - throw new Error(errorMessage); - } else { - warn(errorMessage); - } - } - }; - Decorator.prototype = { - init: function () { - var result, args; - if (this.params) { - args = [this.node].concat(this.params); - result = this.fn.apply(this.root, args); - } else { - result = this.fn.call(this.root, this.node); - } - if (!result || !result.teardown) { - throw new Error('Decorator definition must return an object with a teardown method'); - } - this.teardown = result.teardown; - } - }; - return Decorator; - }(utils_warn, render_StringFragment__StringFragment); -var render_DomFragment_Element_initialise_decorate__decorate = function (Decorator) { - - return function (descriptor, root, owner, contextStack) { - owner.decorator = new Decorator(descriptor, root, owner, contextStack); - if (owner.decorator.fn) { - root._deferred.decorators.push(owner.decorator); - } - }; - }(render_DomFragment_Element_initialise_decorate_Decorator); -var render_DomFragment_Element_initialise_addEventProxies_addEventProxy = function (warn, StringFragment) { - - var addEventProxy, MasterEventHandler, ProxyEvent, firePlainEvent, fireEventWithArgs, fireEventWithDynamicArgs, customHandlers, genericHandler, getCustomHandler; - addEventProxy = function (element, triggerEventName, proxyDescriptor, contextStack, indexRefs) { - var events, master; - events = element.node._ractive.events; - master = events[triggerEventName] || (events[triggerEventName] = new MasterEventHandler(element, triggerEventName, contextStack, indexRefs)); - master.add(proxyDescriptor); - }; - MasterEventHandler = function (element, eventName, contextStack) { - var definition; - this.element = element; - this.root = element.root; - this.node = element.node; - this.name = eventName; - this.contextStack = contextStack; - this.proxies = []; - if (definition = this.root.events[eventName]) { - this.custom = definition(this.node, getCustomHandler(eventName)); - } else { - if (!('on' + eventName in this.node)) { - warn('Missing "' + this.name + '" event. You may need to download a plugin via https://github.com/RactiveJS/Ractive/wiki/Plugins#events'); - } - this.node.addEventListener(eventName, genericHandler, false); - } - }; - MasterEventHandler.prototype = { - add: function (proxy) { - this.proxies[this.proxies.length] = new ProxyEvent(this.element, this.root, proxy, this.contextStack); - }, - teardown: function () { - var i; - if (this.custom) { - this.custom.teardown(); - } else { - this.node.removeEventListener(this.name, genericHandler, false); - } - i = this.proxies.length; - while (i--) { - this.proxies[i].teardown(); - } - }, - fire: function (event) { - var i = this.proxies.length; - while (i--) { - this.proxies[i].fire(event); - } - } - }; - ProxyEvent = function (element, ractive, descriptor, contextStack) { - var name; - this.root = ractive; - name = descriptor.n || descriptor; - if (typeof name === 'string') { - this.n = name; - } else { - this.n = new StringFragment({ - descriptor: descriptor.n, - root: this.root, - owner: element, - contextStack: contextStack - }); - } - if (descriptor.a) { - this.a = descriptor.a; - this.fire = fireEventWithArgs; - return; - } - if (descriptor.d) { - this.d = new StringFragment({ - descriptor: descriptor.d, - root: this.root, - owner: element, - contextStack: contextStack - }); - this.fire = fireEventWithDynamicArgs; - return; - } - this.fire = firePlainEvent; - }; - ProxyEvent.prototype = { - teardown: function () { - if (this.n.teardown) { - this.n.teardown(); - } - if (this.d) { - this.d.teardown(); - } - }, - bubble: function () { - } - }; - firePlainEvent = function (event) { - this.root.fire(this.n.toString(), event); - }; - fireEventWithArgs = function (event) { - this.root.fire.apply(this.root, [ - this.n.toString(), - event - ].concat(this.a)); - }; - fireEventWithDynamicArgs = function (event) { - var args = this.d.toArgsList(); - if (typeof args === 'string') { - args = args.substr(1, args.length - 2); - } - this.root.fire.apply(this.root, [ - this.n.toString(), - event - ].concat(args)); - }; - genericHandler = function (event) { - var storage = this._ractive; - storage.events[event.type].fire({ - node: this, - original: event, - index: storage.index, - keypath: storage.keypath, - context: storage.root.get(storage.keypath) - }); - }; - customHandlers = {}; - getCustomHandler = function (eventName) { - if (customHandlers[eventName]) { - return customHandlers[eventName]; - } - return customHandlers[eventName] = function (event) { - var storage = event.node._ractive; - event.index = storage.index; - event.keypath = storage.keypath; - event.context = storage.root.get(storage.keypath); - storage.events[eventName].fire(event); - }; - }; - return addEventProxy; - }(utils_warn, render_StringFragment__StringFragment); -var render_DomFragment_Element_initialise_addEventProxies__addEventProxies = function (addEventProxy) { - - return function (element, proxies) { - var i, eventName, eventNames; - for (eventName in proxies) { - if (proxies.hasOwnProperty(eventName)) { - eventNames = eventName.split('-'); - i = eventNames.length; - while (i--) { - addEventProxy(element, eventNames[i], proxies[eventName], element.parentFragment.contextStack); - } - } - } - }; - }(render_DomFragment_Element_initialise_addEventProxies_addEventProxy); -var render_DomFragment_Element_initialise_updateLiveQueries = function () { - - return function (element) { - var ractive, liveQueries, i, selector, query; - ractive = element.root; - liveQueries = ractive._liveQueries; - i = liveQueries.length; - while (i--) { - selector = liveQueries[i]; - query = liveQueries[selector]; - if (query._test(element)) { - (element.liveQueries || (element.liveQueries = [])).push(selector); - element.liveQueries[selector] = [element.node]; - } - } - }; - }(); -var utils_camelCase = function () { - - return function (hyphenatedStr) { - return hyphenatedStr.replace(/-([a-zA-Z])/g, function (match, $1) { - return $1.toUpperCase(); - }); - }; - }(); -var utils_fillGaps = function () { - - return function (target, source) { - var key; - for (key in source) { - if (source.hasOwnProperty(key) && !target.hasOwnProperty(key)) { - target[key] = source[key]; - } - } - return target; - }; - }(); -var render_DomFragment_Element_shared_executeTransition_Transition = function (isClient, createElement, warn, isNumeric, isArray, camelCase, fillGaps, StringFragment) { - - var Transition, testStyle, vendors, vendorPattern, unprefixPattern, prefixCache, CSS_TRANSITIONS_ENABLED, TRANSITION, TRANSITION_DURATION, TRANSITION_PROPERTY, TRANSITION_TIMING_FUNCTION, TRANSITIONEND; - if (!isClient) { - return; - } - testStyle = createElement('div').style; - (function () { - if (testStyle.transition !== undefined) { - TRANSITION = 'transition'; - TRANSITIONEND = 'transitionend'; - CSS_TRANSITIONS_ENABLED = true; - } else if (testStyle.webkitTransition !== undefined) { - TRANSITION = 'webkitTransition'; - TRANSITIONEND = 'webkitTransitionEnd'; - CSS_TRANSITIONS_ENABLED = true; - } else { - CSS_TRANSITIONS_ENABLED = false; - } - }()); - if (TRANSITION) { - TRANSITION_DURATION = TRANSITION + 'Duration'; - TRANSITION_PROPERTY = TRANSITION + 'Property'; - TRANSITION_TIMING_FUNCTION = TRANSITION + 'TimingFunction'; - } - Transition = function (descriptor, root, owner, contextStack, isIntro) { - var t = this, name, fragment, errorMessage; - this.root = root; - this.node = owner.node; - this.isIntro = isIntro; - this.originalStyle = this.node.getAttribute('style'); - this.complete = function (noReset) { - if (!noReset && t.isIntro) { - t.resetStyle(); - } - t._manager.pop(t.node); - t.node._ractive.transition = null; - }; - name = descriptor.n || descriptor; - if (typeof name !== 'string') { - fragment = new StringFragment({ - descriptor: name, - root: this.root, - owner: owner, - contextStack: contextStack - }); - name = fragment.toString(); - fragment.teardown(); - } - this.name = name; - if (descriptor.a) { - this.params = descriptor.a; - } else if (descriptor.d) { - fragment = new StringFragment({ - descriptor: descriptor.d, - root: this.root, - owner: owner, - contextStack: contextStack - }); - this.params = fragment.toArgsList(); - fragment.teardown(); - } - this._fn = root.transitions[name]; - if (!this._fn) { - errorMessage = 'Missing "' + name + '" transition. You may need to download a plugin via https://github.com/RactiveJS/Ractive/wiki/Plugins#transitions'; - if (root.debug) { - throw new Error(errorMessage); - } else { - warn(errorMessage); - } - return; - } - }; - Transition.prototype = { - init: function () { - if (this._inited) { - throw new Error('Cannot initialize a transition more than once'); - } - this._inited = true; - this._fn.apply(this.root, [this].concat(this.params)); - }, - getStyle: function (props) { - var computedStyle, styles, i, prop, value; - computedStyle = window.getComputedStyle(this.node); - if (typeof props === 'string') { - value = computedStyle[prefix(props)]; - if (value === '0px') { - value = 0; - } - return value; - } - if (!isArray(props)) { - throw new Error('Transition#getStyle must be passed a string, or an array of strings representing CSS properties'); - } - styles = {}; - i = props.length; - while (i--) { - prop = props[i]; - value = computedStyle[prefix(prop)]; - if (value === '0px') { - value = 0; - } - styles[prop] = value; - } - return styles; - }, - setStyle: function (style, value) { - var prop; - if (typeof style === 'string') { - this.node.style[prefix(style)] = value; - } else { - for (prop in style) { - if (style.hasOwnProperty(prop)) { - this.node.style[prefix(prop)] = style[prop]; - } - } - } - return this; - }, - animateStyle: function (style, value, options, complete) { - var t = this, propertyNames, changedProperties, computedStyle, current, to, from, transitionEndHandler, i, prop; - if (typeof style === 'string') { - to = {}; - to[style] = value; - } else { - to = style; - complete = options; - options = value; - } - if (!options) { - warn('The "' + t.name + '" transition does not supply an options object to `t.animateStyle()`. This will break in a future version of Ractive. For more info see https://github.com/RactiveJS/Ractive/issues/340'); - options = t; - complete = t.complete; - } - if (!options.duration) { - t.setStyle(to); - if (complete) { - complete(); - } - } - propertyNames = Object.keys(to); - changedProperties = []; - computedStyle = window.getComputedStyle(t.node); - from = {}; - i = propertyNames.length; - while (i--) { - prop = propertyNames[i]; - current = computedStyle[prefix(prop)]; - if (current === '0px') { - current = 0; - } - if (current != to[prop]) { - changedProperties[changedProperties.length] = prop; - t.node.style[prefix(prop)] = current; - } - } - if (!changedProperties.length) { - if (complete) { - complete(); - } - return; - } - setTimeout(function () { - t.node.style[TRANSITION_PROPERTY] = propertyNames.map(prefix).map(hyphenate).join(','); - t.node.style[TRANSITION_TIMING_FUNCTION] = hyphenate(options.easing || 'linear'); - t.node.style[TRANSITION_DURATION] = options.duration / 1000 + 's'; - transitionEndHandler = function (event) { - var index; - index = changedProperties.indexOf(camelCase(unprefix(event.propertyName))); - if (index !== -1) { - changedProperties.splice(index, 1); - } - if (changedProperties.length) { - return; - } - t.root.fire(t.name + ':end'); - t.node.removeEventListener(TRANSITIONEND, transitionEndHandler, false); - if (complete) { - complete(); - } - }; - t.node.addEventListener(TRANSITIONEND, transitionEndHandler, false); - setTimeout(function () { - var i = changedProperties.length; - while (i--) { - prop = changedProperties[i]; - t.node.style[prefix(prop)] = to[prop]; - } - }, 0); - }, options.delay || 0); - }, - resetStyle: function () { - if (this.originalStyle) { - this.node.setAttribute('style', this.originalStyle); - } else { - this.node.getAttribute('style'); - this.node.removeAttribute('style'); - } - }, - processParams: function (params, defaults) { - if (typeof params === 'number') { - params = { duration: params }; - } else if (typeof params === 'string') { - if (params === 'slow') { - params = { duration: 600 }; - } else if (params === 'fast') { - params = { duration: 200 }; - } else { - params = { duration: 400 }; - } - } else if (!params) { - params = {}; - } - return fillGaps(params, defaults); - } - }; - vendors = [ - 'o', - 'ms', - 'moz', - 'webkit' - ]; - vendorPattern = new RegExp('^(?:' + vendors.join('|') + ')([A-Z])'); - unprefixPattern = new RegExp('^-(?:' + vendors.join('|') + ')-'); - prefixCache = {}; - function prefix(prop) { - var i, vendor, capped; - if (!prefixCache[prop]) { - if (testStyle[prop] !== undefined) { - prefixCache[prop] = prop; - } else { - capped = prop.charAt(0).toUpperCase() + prop.substring(1); - i = vendors.length; - while (i--) { - vendor = vendors[i]; - if (testStyle[vendor + capped] !== undefined) { - prefixCache[prop] = vendor + capped; - break; - } - } - } - } - return prefixCache[prop]; - } - function unprefix(prop) { - return prop.replace(unprefixPattern, ''); - } - function hyphenate(str) { - var hyphenated; - if (vendorPattern.test(str)) { - str = '-' + str; - } - hyphenated = str.replace(/[A-Z]/g, function (match) { - return '-' + match.toLowerCase(); - }); - return hyphenated; - } - return Transition; - }(config_isClient, utils_createElement, utils_warn, utils_isNumeric, utils_isArray, utils_camelCase, utils_fillGaps, render_StringFragment__StringFragment); -var render_DomFragment_Element_shared_executeTransition__executeTransition = function (warn, Transition) { - - return function (descriptor, root, owner, contextStack, isIntro) { - var transition, node, oldTransition; - if (!root.transitionsEnabled || root._parent && !root._parent.transitionsEnabled) { - return; - } - transition = new Transition(descriptor, root, owner, contextStack, isIntro); - if (transition._fn) { - node = transition.node; - transition._manager = root._transitionManager; - if (oldTransition = node._ractive.transition) { - oldTransition.complete(); - } - node._ractive.transition = transition; - transition._manager.push(node); - if (isIntro) { - root._deferred.transitions.push(transition); - } else { - transition.init(); - } - } - }; - }(utils_warn, render_DomFragment_Element_shared_executeTransition_Transition); -var render_DomFragment_Element_initialise__initialise = function (types, namespaces, create, defineProperty, matches, warn, createElement, getElementNamespace, createElementAttributes, appendElementChildren, decorate, addEventProxies, updateLiveQueries, executeTransition, enforceCase) { - - return function (element, options, docFrag) { - var parentFragment, pNode, contextStack, descriptor, namespace, name, attributes, width, height, loadHandler, root, selectBinding, errorMessage; - element.type = types.ELEMENT; - parentFragment = element.parentFragment = options.parentFragment; - pNode = parentFragment.pNode; - contextStack = parentFragment.contextStack; - descriptor = element.descriptor = options.descriptor; - element.root = root = parentFragment.root; - element.index = options.index; - element.lcName = descriptor.e.toLowerCase(); - element.eventListeners = []; - element.customEventListeners = []; - if (pNode) { - namespace = element.namespace = getElementNamespace(descriptor, pNode); - name = namespace !== namespaces.html ? enforceCase(descriptor.e) : descriptor.e; - element.node = createElement(name, namespace); - defineProperty(element.node, '_ractive', { - value: { - proxy: element, - keypath: contextStack.length ? contextStack[contextStack.length - 1] : '', - index: parentFragment.indexRefs, - events: create(null), - root: root - } - }); - } - attributes = createElementAttributes(element, descriptor.a); - if (descriptor.f) { - if (element.node && element.node.getAttribute('contenteditable')) { - if (element.node.innerHTML) { - errorMessage = 'A pre-populated contenteditable element should not have children'; - if (root.debug) { - throw new Error(errorMessage); - } else { - warn(errorMessage); - } - } - } - appendElementChildren(element, element.node, descriptor, docFrag); - } - if (docFrag && descriptor.v) { - addEventProxies(element, descriptor.v); - } - if (docFrag) { - if (root.twoway) { - element.bind(); - if (element.node.getAttribute('contenteditable') && element.node._ractive.binding) { - element.node._ractive.binding.update(); - } - } - if (attributes.name && !attributes.name.twoway) { - attributes.name.update(); - } - if (element.node.tagName === 'IMG' && ((width = element.attributes.width) || (height = element.attributes.height))) { - element.node.addEventListener('load', loadHandler = function () { - if (width) { - element.node.width = width.value; - } - if (height) { - element.node.height = height.value; - } - element.node.removeEventListener('load', loadHandler, false); - }, false); - } - docFrag.appendChild(element.node); - if (descriptor.o) { - decorate(descriptor.o, root, element, contextStack); - } - if (descriptor.t1) { - executeTransition(descriptor.t1, root, element, contextStack, true); - } - if (element.node.tagName === 'OPTION') { - if (pNode.tagName === 'SELECT' && (selectBinding = pNode._ractive.binding)) { - selectBinding.deferUpdate(); - } - if (element.node._ractive.value == pNode._ractive.value) { - element.node.selected = true; - } - } - if (element.node.autofocus) { - root._deferred.focusable = element.node; - } - } - updateLiveQueries(element); - }; - }(config_types, config_namespaces, utils_create, utils_defineProperty, utils_matches, utils_warn, utils_createElement, render_DomFragment_Element_initialise_getElementNamespace, render_DomFragment_Element_initialise_createElementAttributes, render_DomFragment_Element_initialise_appendElementChildren, render_DomFragment_Element_initialise_decorate__decorate, render_DomFragment_Element_initialise_addEventProxies__addEventProxies, render_DomFragment_Element_initialise_updateLiveQueries, render_DomFragment_Element_shared_executeTransition__executeTransition, render_DomFragment_shared_enforceCase); -var render_DomFragment_Element_prototype_teardown = function (executeTransition) { - - return function (destroy) { - var eventName, binding, bindings, i, liveQueries, selector, query, nodesToRemove, j; - if (this.fragment) { - this.fragment.teardown(false); - } - while (this.attributes.length) { - this.attributes.pop().teardown(); - } - if (this.node) { - for (eventName in this.node._ractive.events) { - this.node._ractive.events[eventName].teardown(); - } - if (binding = this.node._ractive.binding) { - binding.teardown(); - bindings = this.root._twowayBindings[binding.attr.keypath]; - bindings.splice(bindings.indexOf(binding), 1); - } - } - if (this.decorator) { - this.decorator.teardown(); - } - if (this.descriptor.t2) { - executeTransition(this.descriptor.t2, this.root, this, this.parentFragment.contextStack, false); - } - if (destroy) { - this.root._transitionManager.detachWhenReady(this); - } - if (liveQueries = this.liveQueries) { - i = liveQueries.length; - while (i--) { - selector = liveQueries[i]; - if (nodesToRemove = this.liveQueries[selector]) { - j = nodesToRemove.length; - query = this.root._liveQueries[selector]; - while (j--) { - query._remove(nodesToRemove[j]); - } - } - } - } - }; - }(render_DomFragment_Element_shared_executeTransition__executeTransition); -var config_voidElementNames = function () { - - return 'area base br col command doctype embed hr img input keygen link meta param source track wbr'.split(' '); - }(); -var render_DomFragment_Element_prototype_toString = function (voidElementNames) { - - return function () { - var str, i, len; - str = '<' + (this.descriptor.y ? '!doctype' : this.descriptor.e); - len = this.attributes.length; - for (i = 0; i < len; i += 1) { - str += ' ' + this.attributes[i].toString(); - } - str += '>'; - if (this.html) { - str += this.html; - } else if (this.fragment) { - str += this.fragment.toString(); - } - if (voidElementNames.indexOf(this.descriptor.e) === -1) { - str += ''; - } - return str; - }; - }(config_voidElementNames); -var render_DomFragment_Element_prototype_find = function (matches) { - - return function (selector) { - var queryResult; - if (matches(this.node, selector)) { - return this.node; - } - if (this.html && (queryResult = this.node.querySelector(selector))) { - return queryResult; - } - if (this.fragment && this.fragment.find) { - return this.fragment.find(selector); - } - }; - }(utils_matches); -var render_DomFragment_Element_prototype_findAll = function () { - - return function (selector, query) { - var queryAllResult, i, numNodes, node, registeredNodes; - if (query._test(this, true) && query.live) { - (this.liveQueries || (this.liveQueries = [])).push(selector); - this.liveQueries[selector] = [this.node]; - } - if (this.html && (queryAllResult = this.node.querySelectorAll(selector)) && (numNodes = queryAllResult.length)) { - if (query.live) { - if (!this.liveQueries[selector]) { - (this.liveQueries || (this.liveQueries = [])).push(selector); - this.liveQueries[selector] = []; - } - registeredNodes = this.liveQueries[selector]; - } - for (i = 0; i < numNodes; i += 1) { - node = queryAllResult[i]; - query.push(node); - if (query.live) { - registeredNodes.push(node); - } - } - } - if (this.fragment) { - this.fragment.findAll(selector, query); - } - }; - }(); -var render_DomFragment_Element_prototype_findComponent = function () { - - return function (selector) { - if (this.fragment) { - return this.fragment.findComponent(selector); - } - }; - }(); -var render_DomFragment_Element_prototype_findAllComponents = function () { - - return function (selector, query) { - if (this.fragment) { - this.fragment.findAllComponents(selector, query); - } - }; - }(); -var render_DomFragment_Element_prototype_bind = function () { - - return function () { - var attributes = this.attributes; - if (!this.node) { - return; - } - if (this.binding) { - this.binding.teardown(); - this.binding = null; - } - if (this.node.getAttribute('contenteditable') && attributes.value && attributes.value.bind()) { - return; - } - switch (this.descriptor.e) { - case 'select': - case 'textarea': - if (attributes.value) { - attributes.value.bind(); - } - return; - case 'input': - if (this.node.type === 'radio' || this.node.type === 'checkbox') { - if (attributes.name && attributes.name.bind()) { - return; - } - if (attributes.checked && attributes.checked.bind()) { - return; - } - } - if (attributes.value && attributes.value.bind()) { - return; - } - } - }; - }(); -var render_DomFragment_Element__Element = function (initialise, teardown, toString, find, findAll, findComponent, findAllComponents, bind) { - - var DomElement = function (options, docFrag) { - initialise(this, options, docFrag); - }; - DomElement.prototype = { - detach: function () { - if (this.node) { - if (this.node.parentNode) { - this.node.parentNode.removeChild(this.node); - } - return this.node; - } - }, - teardown: teardown, - firstNode: function () { - return this.node; - }, - findNextNode: function () { - return null; - }, - bubble: function () { - }, - toString: toString, - find: find, - findAll: findAll, - findComponent: findComponent, - findAllComponents: findAllComponents, - bind: bind - }; - return DomElement; - }(render_DomFragment_Element_initialise__initialise, render_DomFragment_Element_prototype_teardown, render_DomFragment_Element_prototype_toString, render_DomFragment_Element_prototype_find, render_DomFragment_Element_prototype_findAll, render_DomFragment_Element_prototype_findComponent, render_DomFragment_Element_prototype_findAllComponents, render_DomFragment_Element_prototype_bind); -var config_errors = { missingParser: 'Missing Ractive.parse - cannot parse template. Either preparse or use the version that includes the parser' }; -var registries_partials = {}; -var render_DomFragment_Partial_getPartialDescriptor = function (errors, isClient, warn, isObject, partials, parse) { - - var getPartialDescriptor, registerPartial, getPartialFromRegistry, unpack; - getPartialDescriptor = function (root, name) { - var el, partial, errorMessage; - if (partial = getPartialFromRegistry(root, name)) { - return partial; - } - if (isClient) { - el = document.getElementById(name); - if (el && el.tagName === 'SCRIPT') { - if (!parse) { - throw new Error(errors.missingParser); - } - registerPartial(parse(el.innerHTML), name, partials); - } - } - partial = partials[name]; - if (!partial) { - errorMessage = 'Could not find descriptor for partial "' + name + '"'; - if (root.debug) { - throw new Error(errorMessage); - } else { - warn(errorMessage); - } - return []; - } - return unpack(partial); - }; - getPartialFromRegistry = function (registryOwner, name) { - var partial; - if (registryOwner.partials[name]) { - if (typeof registryOwner.partials[name] === 'string') { - if (!parse) { - throw new Error(errors.missingParser); - } - partial = parse(registryOwner.partials[name], registryOwner.parseOptions); - registerPartial(partial, name, registryOwner.partials); - } - return unpack(registryOwner.partials[name]); - } - }; - registerPartial = function (partial, name, registry) { - var key; - if (isObject(partial)) { - registry[name] = partial.main; - for (key in partial.partials) { - if (partial.partials.hasOwnProperty(key)) { - registry[key] = partial.partials[key]; - } - } - } else { - registry[name] = partial; - } - }; - unpack = function (partial) { - if (partial.length === 1 && typeof partial[0] === 'string') { - return partial[0]; - } - return partial; - }; - return getPartialDescriptor; - }(config_errors, config_isClient, utils_warn, utils_isObject, registries_partials, parse__parse); -var render_DomFragment_Partial__Partial = function (types, getPartialDescriptor, circular) { - - var DomPartial, DomFragment; - circular.push(function () { - DomFragment = circular.DomFragment; - }); - DomPartial = function (options, docFrag) { - var parentFragment = this.parentFragment = options.parentFragment, descriptor; - this.type = types.PARTIAL; - this.name = options.descriptor.r; - this.index = options.index; - if (!options.descriptor.r) { - throw new Error('Partials must have a static reference (no expressions). This may change in a future version of Ractive.'); - } - descriptor = getPartialDescriptor(parentFragment.root, options.descriptor.r); - this.fragment = new DomFragment({ - descriptor: descriptor, - root: parentFragment.root, - pNode: parentFragment.pNode, - contextStack: parentFragment.contextStack, - owner: this - }); - if (docFrag) { - docFrag.appendChild(this.fragment.docFrag); - } - }; - DomPartial.prototype = { - firstNode: function () { - return this.fragment.firstNode(); - }, - findNextNode: function () { - return this.parentFragment.findNextNode(this); - }, - detach: function () { - return this.fragment.detach(); - }, - teardown: function (destroy) { - this.fragment.teardown(destroy); - }, - toString: function () { - return this.fragment.toString(); - }, - find: function (selector) { - return this.fragment.find(selector); - }, - findAll: function (selector, query) { - return this.fragment.findAll(selector, query); - }, - findComponent: function (selector) { - return this.fragment.findComponent(selector); - }, - findAllComponents: function (selector, query) { - return this.fragment.findAllComponents(selector, query); - } - }; - return DomPartial; - }(config_types, render_DomFragment_Partial_getPartialDescriptor, circular); -var render_DomFragment_Component_initialise_createModel_ComponentParameter = function (StringFragment) { - - var ComponentParameter = function (component, key, value) { - this.parentFragment = component.parentFragment; - this.component = component; - this.key = key; - this.fragment = new StringFragment({ - descriptor: value, - root: component.root, - owner: this, - contextStack: component.parentFragment.contextStack - }); - this.selfUpdating = this.fragment.isSimple(); - this.value = this.fragment.getValue(); - }; - ComponentParameter.prototype = { - bubble: function () { - if (this.selfUpdating) { - this.update(); - } else if (!this.deferred && this.ready) { - this.root._deferred.attrs.push(this); - this.deferred = true; - } - }, - update: function () { - var value = this.fragment.getValue(); - this.component.instance.set(this.key, value); - this.value = value; - }, - teardown: function () { - this.fragment.teardown(); - } - }; - return ComponentParameter; - }(render_StringFragment__StringFragment); -var render_DomFragment_Component_initialise_createModel__createModel = function (types, parseJSON, resolveRef, ComponentParameter) { - - return function (component, attributes, toBind) { - var data, key, value; - data = {}; - component.complexParameters = []; - for (key in attributes) { - if (attributes.hasOwnProperty(key)) { - value = getValue(component, key, attributes[key], toBind); - if (value !== undefined) { - data[key] = value; - } - } - } - return data; - }; - function getValue(component, key, descriptor, toBind) { - var parameter, parsed, root, parentFragment, keypath; - root = component.root; - parentFragment = component.parentFragment; - if (typeof descriptor === 'string') { - parsed = parseJSON(descriptor); - return parsed ? parsed.value : descriptor; - } - if (descriptor === null) { - return true; - } - if (descriptor.length === 1 && descriptor[0].t === types.INTERPOLATOR && descriptor[0].r) { - if (parentFragment.indexRefs && parentFragment.indexRefs[descriptor[0].r] !== undefined) { - return parentFragment.indexRefs[descriptor[0].r]; - } - keypath = resolveRef(root, descriptor[0].r, parentFragment.contextStack) || descriptor[0].r; - toBind.push({ - childKeypath: key, - parentKeypath: keypath - }); - return root.get(keypath); - } - parameter = new ComponentParameter(component, key, descriptor); - component.complexParameters.push(parameter); - return parameter.value; - } - }(config_types, utils_parseJSON, shared_resolveRef, render_DomFragment_Component_initialise_createModel_ComponentParameter); -var render_DomFragment_Component_initialise_createInstance = function () { - - return function (component, Component, data, docFrag, contentDescriptor) { - var instance, parentFragment, partials, root; - parentFragment = component.parentFragment; - root = component.root; - partials = { content: contentDescriptor || [] }; - instance = new Component({ - el: parentFragment.pNode.cloneNode(false), - data: data, - partials: partials, - _parent: root, - adaptors: root.adaptors - }); - instance.component = component; - component.instance = instance; - instance.insert(docFrag); - instance.fragment.pNode = parentFragment.pNode; - return instance; - }; - }(); -var render_DomFragment_Component_initialise_createObservers = function () { - - var observeOptions = { - init: false, - debug: true - }; - return function (component, toBind) { - var pair, i; - component.observers = []; - i = toBind.length; - while (i--) { - pair = toBind[i]; - bind(component, pair.parentKeypath, pair.childKeypath); - } - }; - function bind(component, parentKeypath, childKeypath) { - var parentInstance, childInstance, settingParent, settingChild, observers, observer, value; - parentInstance = component.root; - childInstance = component.instance; - observers = component.observers; - observer = parentInstance.observe(parentKeypath, function (value) { - if (!settingParent && !parentInstance._wrapped[parentKeypath]) { - settingChild = true; - childInstance.set(childKeypath, value); - settingChild = false; - } - }, observeOptions); - observers.push(observer); - if (childInstance.twoway) { - observer = childInstance.observe(childKeypath, function (value) { - if (!settingChild) { - settingParent = true; - parentInstance.set(parentKeypath, value); - settingParent = false; - } - }, observeOptions); - observers.push(observer); - value = childInstance.get(childKeypath); - if (value !== undefined) { - parentInstance.set(parentKeypath, value); - } - } - } - }(); -var render_DomFragment_Component_initialise_propagateEvents = function (warn) { - - var errorMessage = 'Components currently only support simple events - you cannot include arguments. Sorry!'; - return function (component, eventsDescriptor) { - var eventName; - for (eventName in eventsDescriptor) { - if (eventsDescriptor.hasOwnProperty(eventName)) { - propagateEvent(component.instance, component.root, eventName, eventsDescriptor[eventName]); - } - } - }; - function propagateEvent(childInstance, parentInstance, eventName, proxyEventName) { - if (typeof proxyEventName !== 'string') { - if (parentInstance.debug) { - throw new Error(errorMessage); - } else { - warn(errorMessage); - return; - } - } - childInstance.on(eventName, function () { - var args = Array.prototype.slice.call(arguments); - args.unshift(proxyEventName); - parentInstance.fire.apply(parentInstance, args); - }); - } - }(utils_warn); -var render_DomFragment_Component_initialise_updateLiveQueries = function () { - - return function (component) { - var ancestor, query; - ancestor = component.root; - while (ancestor) { - if (query = ancestor._liveComponentQueries[component.name]) { - query.push(component.instance); - } - ancestor = ancestor._parent; - } - }; - }(); -var render_DomFragment_Component_initialise__initialise = function (types, warn, createModel, createInstance, createObservers, propagateEvents, updateLiveQueries) { - - return function (component, options, docFrag) { - var parentFragment, root, Component, data, toBind; - parentFragment = component.parentFragment = options.parentFragment; - root = parentFragment.root; - component.root = root; - component.type = types.COMPONENT; - component.name = options.descriptor.e; - component.index = options.index; - component.observers = []; - Component = root.components[options.descriptor.e]; - if (!Component) { - throw new Error('Component "' + options.descriptor.e + '" not found'); - } - toBind = []; - data = createModel(component, options.descriptor.a, toBind); - createInstance(component, Component, data, docFrag, options.descriptor.f); - createObservers(component, toBind); - propagateEvents(component, options.descriptor.v); - if (options.descriptor.t1 || options.descriptor.t2 || options.descriptor.o) { - warn('The "intro", "outro" and "decorator" directives have no effect on components'); - } - updateLiveQueries(component); - }; - }(config_types, utils_warn, render_DomFragment_Component_initialise_createModel__createModel, render_DomFragment_Component_initialise_createInstance, render_DomFragment_Component_initialise_createObservers, render_DomFragment_Component_initialise_propagateEvents, render_DomFragment_Component_initialise_updateLiveQueries); -var render_DomFragment_Component__Component = function (initialise) { - - var DomComponent = function (options, docFrag) { - initialise(this, options, docFrag); - }; - DomComponent.prototype = { - firstNode: function () { - return this.instance.fragment.firstNode(); - }, - findNextNode: function () { - return this.parentFragment.findNextNode(this); - }, - detach: function () { - return this.instance.fragment.detach(); - }, - teardown: function () { - var query; - while (this.complexParameters.length) { - this.complexParameters.pop().teardown(); - } - while (this.observers.length) { - this.observers.pop().cancel(); - } - if (query = this.root._liveComponentQueries[this.name]) { - query._remove(this); - } - this.instance.teardown(); - }, - toString: function () { - return this.instance.fragment.toString(); - }, - find: function (selector) { - return this.instance.fragment.find(selector); - }, - findAll: function (selector, query) { - return this.instance.fragment.findAll(selector, query); - }, - findComponent: function (selector) { - if (!selector || selector === this.name) { - return this.instance; - } - return null; - }, - findAllComponents: function (selector, query) { - query._test(this, true); - if (this.instance.fragment) { - this.instance.fragment.findAllComponents(selector, query); - } - } - }; - return DomComponent; - }(render_DomFragment_Component_initialise__initialise); -var render_DomFragment_Comment = function (types) { - - var DomComment = function (options, docFrag) { - this.type = types.COMMENT; - this.descriptor = options.descriptor; - if (docFrag) { - this.node = document.createComment(options.descriptor.f); - docFrag.appendChild(this.node); - } - }; - DomComment.prototype = { - detach: function () { - this.node.parentNode.removeChild(this.node); - return this.node; - }, - teardown: function (destroy) { - if (destroy) { - this.detach(); - } - }, - firstNode: function () { - return this.node; - }, - toString: function () { - return ''; - } - }; - return DomComment; - }(config_types); -var render_DomFragment__DomFragment = function (types, matches, initFragment, insertHtml, Text, Interpolator, Section, Triple, Element, Partial, Component, Comment, circular) { - - var DomFragment = function (options) { - if (options.pNode) { - this.docFrag = document.createDocumentFragment(); - } - if (typeof options.descriptor === 'string') { - this.html = options.descriptor; - if (this.docFrag) { - this.nodes = insertHtml(this.html, options.pNode.tagName, this.docFrag); - } - } else { - initFragment(this, options); - } - }; - DomFragment.prototype = { - detach: function () { - var len, i; - if (this.nodes) { - i = this.nodes.length; - while (i--) { - this.docFrag.appendChild(this.nodes[i]); - } - } else if (this.items) { - len = this.items.length; - for (i = 0; i < len; i += 1) { - this.docFrag.appendChild(this.items[i].detach()); - } - } - return this.docFrag; - }, - createItem: function (options) { - if (typeof options.descriptor === 'string') { - return new Text(options, this.docFrag); - } - switch (options.descriptor.t) { - case types.INTERPOLATOR: - return new Interpolator(options, this.docFrag); - case types.SECTION: - return new Section(options, this.docFrag); - case types.TRIPLE: - return new Triple(options, this.docFrag); - case types.ELEMENT: - if (this.root.components[options.descriptor.e]) { - return new Component(options, this.docFrag); - } - return new Element(options, this.docFrag); - case types.PARTIAL: - return new Partial(options, this.docFrag); - case types.COMMENT: - return new Comment(options, this.docFrag); - default: - throw new Error('Something very strange happened. Please file an issue at https://github.com/RactiveJS/Ractive/issues. Thanks!'); - } - }, - teardown: function (destroy) { - var node; - if (this.nodes && destroy) { - while (node = this.nodes.pop()) { - node.parentNode.removeChild(node); - } - } else if (this.items) { - while (this.items.length) { - this.items.pop().teardown(destroy); - } - } - this.nodes = this.items = this.docFrag = null; - }, - firstNode: function () { - if (this.items && this.items[0]) { - return this.items[0].firstNode(); - } else if (this.nodes) { - return this.nodes[0] || null; - } - return null; - }, - findNextNode: function (item) { - var index = item.index; - if (this.items[index + 1]) { - return this.items[index + 1].firstNode(); - } - if (this.owner === this.root) { - if (!this.owner.component) { - return null; - } - return this.owner.component.findNextNode(); - } - return this.owner.findNextNode(this); - }, - toString: function () { - var html, i, len, item; - if (this.html) { - return this.html; - } - html = ''; - if (!this.items) { - return html; - } - len = this.items.length; - for (i = 0; i < len; i += 1) { - item = this.items[i]; - html += item.toString(); - } - return html; - }, - find: function (selector) { - var i, len, item, node, queryResult; - if (this.nodes) { - len = this.nodes.length; - for (i = 0; i < len; i += 1) { - node = this.nodes[i]; - if (node.nodeType !== 1) { - continue; - } - if (matches(node, selector)) { - return node; - } - if (queryResult = node.querySelector(selector)) { - return queryResult; - } - } - return null; - } - if (this.items) { - len = this.items.length; - for (i = 0; i < len; i += 1) { - item = this.items[i]; - if (item.find && (queryResult = item.find(selector))) { - return queryResult; - } - } - return null; - } - }, - findAll: function (selector, query) { - var i, len, item, node, queryAllResult, numNodes, j; - if (this.nodes) { - len = this.nodes.length; - for (i = 0; i < len; i += 1) { - node = this.nodes[i]; - if (node.nodeType !== 1) { - continue; - } - if (matches(node, selector)) { - query.push(node); - } - if (queryAllResult = node.querySelectorAll(selector)) { - numNodes = queryAllResult.length; - for (j = 0; j < numNodes; j += 1) { - query.push(queryAllResult[j]); - } - } - } - } else if (this.items) { - len = this.items.length; - for (i = 0; i < len; i += 1) { - item = this.items[i]; - if (item.findAll) { - item.findAll(selector, query); - } - } - } - return query; - }, - findComponent: function (selector) { - var len, i, item, queryResult; - if (this.items) { - len = this.items.length; - for (i = 0; i < len; i += 1) { - item = this.items[i]; - if (item.findComponent && (queryResult = item.findComponent(selector))) { - return queryResult; - } - } - return null; - } - }, - findAllComponents: function (selector, query) { - var i, len, item; - if (this.items) { - len = this.items.length; - for (i = 0; i < len; i += 1) { - item = this.items[i]; - if (item.findAllComponents) { - item.findAllComponents(selector, query); - } - } - } - return query; - } - }; - circular.DomFragment = DomFragment; - return DomFragment; - }(config_types, utils_matches, render_shared_initFragment, render_DomFragment_shared_insertHtml, render_DomFragment_Text, render_DomFragment_Interpolator, render_DomFragment_Section__Section, render_DomFragment_Triple, render_DomFragment_Element__Element, render_DomFragment_Partial__Partial, render_DomFragment_Component__Component, render_DomFragment_Comment, circular); -var Ractive_prototype_render = function (getElement, makeTransitionManager, preDomUpdate, postDomUpdate, DomFragment) { - - return function (target, complete) { - var transitionManager; - if (!this._initing) { - throw new Error('You cannot call ractive.render() directly!'); - } - this._transitionManager = transitionManager = makeTransitionManager(this, complete); - this.fragment = new DomFragment({ - descriptor: this.template, - root: this, - owner: this, - pNode: target - }); - preDomUpdate(this); - if (target) { - target.appendChild(this.fragment.docFrag); - } - postDomUpdate(this); - this._transitionManager = null; - transitionManager.ready(); - this.rendered = true; - }; - }(utils_getElement, shared_makeTransitionManager, shared_preDomUpdate, shared_postDomUpdate, render_DomFragment__DomFragment); -var Ractive_prototype_renderHTML = function (warn) { - - return function () { - warn('renderHTML() has been deprecated and will be removed in a future version. Please use toHTML() instead'); - return this.toHTML(); - }; - }(utils_warn); -var Ractive_prototype_toHTML = function () { - - return function () { - return this.fragment.toString(); - }; - }(); -var Ractive_prototype_teardown = function (makeTransitionManager, clearCache) { - - return function (complete) { - var keypath, transitionManager, previousTransitionManager; - this.fire('teardown'); - previousTransitionManager = this._transitionManager; - this._transitionManager = transitionManager = makeTransitionManager(this, complete); - this.fragment.teardown(true); - while (this._animations[0]) { - this._animations[0].stop(); - } - for (keypath in this._cache) { - clearCache(this, keypath); - } - this._transitionManager = previousTransitionManager; - transitionManager.ready(); - }; - }(shared_makeTransitionManager, shared_clearCache); -var Ractive_prototype_shared_add = function (isNumeric) { - - return function (root, keypath, d) { - var value; - if (typeof keypath !== 'string' || !isNumeric(d)) { - if (root.debug) { - throw new Error('Bad arguments'); - } - return; - } - value = root.get(keypath); - if (value === undefined) { - value = 0; - } - if (!isNumeric(value)) { - if (root.debug) { - throw new Error('Cannot add to a non-numeric value'); - } - return; - } - root.set(keypath, value + d); - }; - }(utils_isNumeric); -var Ractive_prototype_add = function (add) { - - return function (keypath, d) { - add(this, keypath, d === undefined ? 1 : d); - }; - }(Ractive_prototype_shared_add); -var Ractive_prototype_subtract = function (add) { - - return function (keypath, d) { - add(this, keypath, d === undefined ? -1 : -d); - }; - }(Ractive_prototype_shared_add); -var Ractive_prototype_toggle = function () { - - return function (keypath) { - var value; - if (typeof keypath !== 'string') { - if (this.debug) { - throw new Error('Bad arguments'); - } - return; - } - value = this.get(keypath); - this.set(keypath, !value); - }; - }(); -var Ractive_prototype_merge_mapOldToNewIndex = function () { - - return function (oldArray, newArray) { - var usedIndices, mapper, firstUnusedIndex, newIndices, changed; - usedIndices = {}; - firstUnusedIndex = 0; - mapper = function (item, i) { - var index, start, len; - start = firstUnusedIndex; - len = newArray.length; - do { - index = newArray.indexOf(item, start); - if (index === -1) { - changed = true; - return -1; - } - start = index + 1; - } while (usedIndices[index] && start < len); - if (index === firstUnusedIndex) { - firstUnusedIndex += 1; - } - if (index !== i) { - changed = true; - } - usedIndices[index] = true; - return index; - }; - newIndices = oldArray.map(mapper); - newIndices.unchanged = !changed; - return newIndices; - }; - }(); -var Ractive_prototype_merge_queueDependants = function (types) { - - return function queueDependants(keypath, deps, mergeQueue, updateQueue) { - var i, dependant; - i = deps.length; - while (i--) { - dependant = deps[i]; - if (dependant.type === types.REFERENCE) { - dependant.update(); - } else if (dependant.keypath === keypath && dependant.type === types.SECTION && !dependant.inverted && dependant.docFrag) { - mergeQueue[mergeQueue.length] = dependant; - } else { - updateQueue[updateQueue.length] = dependant; - } - } - }; - }(config_types); -var Ractive_prototype_merge__merge = function (warn, isArray, clearCache, preDomUpdate, processDeferredUpdates, makeTransitionManager, notifyDependants, replaceData, mapOldToNewIndex, queueDependants) { - - var identifiers = {}; - return function (keypath, array, options) { - var currentArray, oldArray, newArray, identifier, lengthUnchanged, i, newIndices, mergeQueue, updateQueue, depsByKeypath, deps, transitionManager, previousTransitionManager, upstreamQueue, keys; - currentArray = this.get(keypath); - if (!isArray(currentArray) || !isArray(array)) { - return this.set(keypath, array, options && options.complete); - } - lengthUnchanged = currentArray.length === array.length; - if (options && options.compare) { - if (options.compare === true) { - identifier = stringify; - } else if (typeof options.compare === 'string') { - identifier = getIdentifier(options.compare); - } else if (typeof options.compare == 'function') { - identifier = options.compare; - } else { - throw new Error('The `compare` option must be a function, or a string representing an identifying field (or `true` to use JSON.stringify)'); - } - try { - oldArray = currentArray.map(identifier); - newArray = array.map(identifier); - } catch (err) { - if (this.debug) { - throw err; - } else { - warn('Merge operation: comparison failed. Falling back to identity checking'); - } - oldArray = currentArray; - newArray = array; - } - } else { - oldArray = currentArray; - newArray = array; - } - newIndices = mapOldToNewIndex(oldArray, newArray); - clearCache(this, keypath); - replaceData(this, keypath, array); - if (newIndices.unchanged && lengthUnchanged) { - return; - } - previousTransitionManager = this._transitionManager; - this._transitionManager = transitionManager = makeTransitionManager(this, options && options.complete); - mergeQueue = []; - updateQueue = []; - for (i = 0; i < this._deps.length; i += 1) { - depsByKeypath = this._deps[i]; - if (!depsByKeypath) { - continue; - } - deps = depsByKeypath[keypath]; - if (deps) { - queueDependants(keypath, deps, mergeQueue, updateQueue); - preDomUpdate(this); - while (mergeQueue.length) { - mergeQueue.pop().merge(newIndices); - } - while (updateQueue.length) { - updateQueue.pop().update(); - } - } - } - processDeferredUpdates(this); - upstreamQueue = []; - keys = keypath.split('.'); - while (keys.length) { - keys.pop(); - upstreamQueue[upstreamQueue.length] = keys.join('.'); - } - notifyDependants.multiple(this, upstreamQueue, true); - if (oldArray.length !== newArray.length) { - notifyDependants(this, keypath + '.length', true); - } - this._transitionManager = previousTransitionManager; - transitionManager.ready(); - }; - function stringify(item) { - return JSON.stringify(item); - } - function getIdentifier(str) { - if (!identifiers[str]) { - identifiers[str] = function (item) { - return item[str]; - }; - } - return identifiers[str]; - } - }(utils_warn, utils_isArray, shared_clearCache, shared_preDomUpdate, shared_processDeferredUpdates, shared_makeTransitionManager, shared_notifyDependants, Ractive_prototype_shared_replaceData, Ractive_prototype_merge_mapOldToNewIndex, Ractive_prototype_merge_queueDependants); -var Ractive_prototype_detach = function () { - - return function () { - return this.fragment.detach(); - }; - }(); -var Ractive_prototype_insert = function (getElement) { - - return function (target, anchor) { - target = getElement(target); - anchor = getElement(anchor) || null; - if (!target) { - throw new Error('You must specify a valid target to insert into'); - } - target.insertBefore(this.detach(), anchor); - this.fragment.pNode = target; - }; - }(utils_getElement); -var Ractive_prototype__prototype = function (get, set, update, updateModel, animate, on, off, observe, fire, find, findAll, findComponent, findAllComponents, render, renderHTML, toHTML, teardown, add, subtract, toggle, merge, detach, insert) { - - return { - get: get, - set: set, - update: update, - updateModel: updateModel, - animate: animate, - on: on, - off: off, - observe: observe, - fire: fire, - find: find, - findAll: findAll, - findComponent: findComponent, - findAllComponents: findAllComponents, - renderHTML: renderHTML, - toHTML: toHTML, - render: render, - teardown: teardown, - add: add, - subtract: subtract, - toggle: toggle, - merge: merge, - detach: detach, - insert: insert - }; - }(Ractive_prototype_get__get, Ractive_prototype_set, Ractive_prototype_update, Ractive_prototype_updateModel, Ractive_prototype_animate__animate, Ractive_prototype_on, Ractive_prototype_off, Ractive_prototype_observe__observe, Ractive_prototype_fire, Ractive_prototype_find, Ractive_prototype_findAll, Ractive_prototype_findComponent, Ractive_prototype_findAllComponents, Ractive_prototype_render, Ractive_prototype_renderHTML, Ractive_prototype_toHTML, Ractive_prototype_teardown, Ractive_prototype_add, Ractive_prototype_subtract, Ractive_prototype_toggle, Ractive_prototype_merge__merge, Ractive_prototype_detach, Ractive_prototype_insert); -var extend_registries = function () { - - return [ - 'partials', - 'transitions', - 'events', - 'components', - 'decorators', - 'data' - ]; - }(); -var extend_initOptions = function () { - - return [ - 'el', - 'template', - 'complete', - 'modifyArrays', - 'magic', - 'twoway', - 'lazy', - 'append', - 'preserveWhitespace', - 'sanitize', - 'stripComments', - 'noIntro', - 'transitionsEnabled', - 'adaptors' - ]; - }(); -var extend_inheritFromParent = function (registries, initOptions, create) { - - return function (Child, Parent) { - registries.forEach(function (property) { - if (Parent[property]) { - Child[property] = create(Parent[property]); - } - }); - initOptions.forEach(function (property) { - Child[property] = Parent[property]; - }); - }; - }(extend_registries, extend_initOptions, utils_create); -var extend_wrapMethod = function () { - - return function (method, superMethod) { - if (/_super/.test(method)) { - return function () { - var _super = this._super, result; - this._super = superMethod; - result = method.apply(this, arguments); - this._super = _super; - return result; - }; - } else { - return method; - } - }; - }(); -var extend_utils_augment = function () { - - return function (target, source) { - var key; - for (key in source) { - if (source.hasOwnProperty(key)) { - target[key] = source[key]; - } - } - return target; - }; - }(); -var extend_inheritFromChildProps = function (registries, initOptions, wrapMethod, augment) { - - var blacklist, blacklisted; - blacklist = registries.concat(initOptions); - blacklisted = {}; - blacklist.forEach(function (property) { - blacklisted[property] = true; - }); - return function (Child, childProps) { - var key, member; - registries.forEach(function (property) { - var value = childProps[property]; - if (value) { - if (Child[property]) { - augment(Child[property], value); - } else { - Child[property] = value; - } - } - }); - initOptions.forEach(function (property) { - var value = childProps[property]; - if (value !== undefined) { - if (typeof value === 'function' && typeof Child[property] === 'function') { - Child[property] = wrapMethod(value, Child[property]); - } else { - Child[property] = childProps[property]; - } - } - }); - for (key in childProps) { - if (childProps.hasOwnProperty(key) && !blacklisted[key]) { - member = childProps[key]; - if (typeof member === 'function' && typeof Child.prototype[key] === 'function') { - Child.prototype[key] = wrapMethod(member, Child.prototype[key]); - } else { - Child.prototype[key] = member; - } - } - } - }; - }(extend_registries, extend_initOptions, extend_wrapMethod, extend_utils_augment); -var extend_extractInlinePartials = function (isObject, augment) { - - return function (Child, childProps) { - if (isObject(Child.template)) { - if (!Child.partials) { - Child.partials = {}; - } - augment(Child.partials, Child.template.partials); - if (childProps.partials) { - augment(Child.partials, childProps.partials); - } - Child.template = Child.template.main; - } - }; - }(utils_isObject, extend_utils_augment); -var extend_conditionallyParseTemplate = function (errors, isClient, parse) { - - return function (Child) { - var templateEl; - if (typeof Child.template === 'string') { - if (!parse) { - throw new Error(errors.missingParser); - } - if (Child.template.charAt(0) === '#' && isClient) { - templateEl = document.getElementById(Child.template.substring(1)); - if (templateEl && templateEl.tagName === 'SCRIPT') { - Child.template = parse(templateEl.innerHTML, Child); - } else { - throw new Error('Could not find template element (' + Child.template + ')'); - } - } else { - Child.template = parse(Child.template, Child); - } - } - }; - }(config_errors, config_isClient, parse__parse); -var extend_conditionallyParsePartials = function (errors, parse) { - - return function (Child) { - var key; - if (Child.partials) { - for (key in Child.partials) { - if (Child.partials.hasOwnProperty(key) && typeof Child.partials[key] === 'string') { - if (!parse) { - throw new Error(errors.missingParser); - } - Child.partials[key] = parse(Child.partials[key], Child); - } - } - } - }; - }(config_errors, parse__parse); -var extend_utils_clone = function () { - - return function (source) { - var target = {}, key; - for (key in source) { - if (source.hasOwnProperty(key)) { - target[key] = source[key]; - } - } - return target; - }; - }(); -var utils_extend = function () { - - return function (target) { - var prop, source, sources = Array.prototype.slice.call(arguments, 1); - while (source = sources.shift()) { - for (prop in source) { - if (source.hasOwnProperty(prop)) { - target[prop] = source[prop]; - } - } - } - return target; - }; - }(); -var Ractive_initialise = function (isClient, errors, warn, create, extend, defineProperty, defineProperties, getElement, isObject, magicAdaptor, parse) { - - var getObject, getArray, defaultOptions, registries; - getObject = function () { - return {}; - }; - getArray = function () { - return []; - }; - defaultOptions = create(null); - defineProperties(defaultOptions, { - preserveWhitespace: { - enumerable: true, - value: false - }, - append: { - enumerable: true, - value: false - }, - twoway: { - enumerable: true, - value: true - }, - modifyArrays: { - enumerable: true, - value: true - }, - data: { - enumerable: true, - value: getObject - }, - lazy: { - enumerable: true, - value: false - }, - debug: { - enumerable: true, - value: false - }, - transitions: { - enumerable: true, - value: getObject - }, - decorators: { - enumerable: true, - value: getObject - }, - events: { - enumerable: true, - value: getObject - }, - noIntro: { - enumerable: true, - value: false - }, - transitionsEnabled: { - enumerable: true, - value: true - }, - magic: { - enumerable: true, - value: false - }, - adaptors: { - enumerable: true, - value: getArray - } - }); - registries = [ - 'components', - 'decorators', - 'events', - 'partials', - 'transitions', - 'data' - ]; - return function (ractive, options) { - var key, template, templateEl, parsedTemplate; - for (key in defaultOptions) { - if (options[key] === undefined) { - options[key] = typeof defaultOptions[key] === 'function' ? defaultOptions[key]() : defaultOptions[key]; - } - } - defineProperties(ractive, { - _initing: { - value: true, - writable: true - }, - _guid: { - value: 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { - var r, v; - r = Math.random() * 16 | 0; - v = c == 'x' ? r : r & 3 | 8; - return v.toString(16); - }) - }, - _subs: { - value: create(null), - configurable: true - }, - _cache: { value: {} }, - _cacheMap: { value: create(null) }, - _deps: { value: [] }, - _depsMap: { value: create(null) }, - _patternObservers: { value: [] }, - _pendingResolution: { value: [] }, - _deferred: { value: {} }, - _evaluators: { value: create(null) }, - _twowayBindings: { value: {} }, - _transitionManager: { - value: null, - writable: true - }, - _animations: { value: [] }, - nodes: { value: {} }, - _wrapped: { value: create(null) }, - _liveQueries: { value: [] }, - _liveComponentQueries: { value: [] } - }); - defineProperties(ractive._deferred, { - attrs: { value: [] }, - evals: { value: [] }, - selectValues: { value: [] }, - checkboxes: { value: [] }, - radios: { value: [] }, - observers: { value: [] }, - transitions: { value: [] }, - liveQueries: { value: [] }, - decorators: { value: [] }, - focusable: { - value: null, - writable: true - } - }); - ractive.adaptors = options.adaptors; - ractive.modifyArrays = options.modifyArrays; - ractive.magic = options.magic; - ractive.twoway = options.twoway; - ractive.lazy = options.lazy; - ractive.debug = options.debug; - if (ractive.magic && !magicAdaptor) { - throw new Error('Getters and setters (magic mode) are not supported in this browser'); - } - if (options._parent) { - defineProperty(ractive, '_parent', { value: options._parent }); - } - if (options.el) { - ractive.el = getElement(options.el); - if (!ractive.el && ractive.debug) { - throw new Error('Could not find container element'); - } - } - if (options.eventDefinitions) { - warn('ractive.eventDefinitions has been deprecated in favour of ractive.events. Support will be removed in future versions'); - options.events = options.eventDefinitions; - } - registries.forEach(function (registry) { - if (ractive.constructor[registry]) { - ractive[registry] = extend(create(ractive.constructor[registry] || {}), options[registry]); - } else if (options[registry]) { - ractive[registry] = options[registry]; - } - }); - template = options.template; - if (typeof template === 'string') { - if (!parse) { - throw new Error(errors.missingParser); - } - if (template.charAt(0) === '#' && isClient) { - templateEl = document.getElementById(template.substring(1)); - if (templateEl) { - parsedTemplate = parse(templateEl.innerHTML, options); - } else { - throw new Error('Could not find template element (' + template + ')'); - } - } else { - parsedTemplate = parse(template, options); - } - } else { - parsedTemplate = template; - } - if (isObject(parsedTemplate)) { - extend(ractive.partials, parsedTemplate.partials); - parsedTemplate = parsedTemplate.main; - } - if (parsedTemplate && parsedTemplate.length === 1 && typeof parsedTemplate[0] === 'string') { - parsedTemplate = parsedTemplate[0]; - } - ractive.template = parsedTemplate; - extend(ractive.partials, options.partials); - ractive.parseOptions = { - preserveWhitespace: options.preserveWhitespace, - sanitize: options.sanitize, - stripComments: options.stripComments - }; - ractive.transitionsEnabled = options.noIntro ? false : options.transitionsEnabled; - if (isClient && !ractive.el) { - ractive.el = document.createDocumentFragment(); - } - if (ractive.el && !options.append) { - ractive.el.innerHTML = ''; - } - ractive.render(ractive.el, options.complete); - ractive.transitionsEnabled = options.transitionsEnabled; - ractive._initing = false; - }; - }(config_isClient, config_errors, utils_warn, utils_create, utils_extend, utils_defineProperty, utils_defineProperties, utils_getElement, utils_isObject, Ractive_prototype_get_magicAdaptor, parse__parse); -var extend_initChildInstance = function (fillGaps, initOptions, clone, wrapMethod, initialise) { - - return function (child, Child, options) { - initOptions.forEach(function (property) { - var value = options[property], defaultValue = Child[property]; - if (typeof value === 'function' && typeof defaultValue === 'function') { - options[property] = wrapMethod(value, defaultValue); - } else if (value === undefined && defaultValue !== undefined) { - options[property] = defaultValue; - } - }); - if (child.beforeInit) { - child.beforeInit(options); - } - initialise(child, options); - if (child.init) { - child.init(options); - } - }; - }(utils_fillGaps, extend_initOptions, extend_utils_clone, extend_wrapMethod, Ractive_initialise); -var extend__extend = function (create, inheritFromParent, inheritFromChildProps, extractInlinePartials, conditionallyParseTemplate, conditionallyParsePartials, initChildInstance, circular) { - - var Ractive; - circular.push(function () { - Ractive = circular.Ractive; - }); - return function (childProps) { - var Parent = this, Child; - Child = function (options) { - initChildInstance(this, Child, options || {}); - }; - Child.prototype = create(Parent.prototype); - Child.prototype.constructor = Child; - inheritFromParent(Child, Parent); - inheritFromChildProps(Child, childProps); - conditionallyParseTemplate(Child); - extractInlinePartials(Child, childProps); - conditionallyParsePartials(Child); - Child.extend = Parent.extend; - return Child; - }; - }(utils_create, extend_inheritFromParent, extend_inheritFromChildProps, extend_extractInlinePartials, extend_conditionallyParseTemplate, extend_conditionallyParsePartials, extend_initChildInstance, circular); -var Ractive__Ractive = function (svg, create, defineProperties, prototype, partialRegistry, adaptorRegistry, easingRegistry, Ractive_extend, parse, initialise, circular) { - - var Ractive = function (options) { - initialise(this, options); - }; - defineProperties(Ractive, { - prototype: { value: prototype }, - partials: { value: partialRegistry }, - adaptors: { value: adaptorRegistry }, - easing: { value: easingRegistry }, - transitions: { value: {} }, - events: { value: {} }, - components: { value: {} }, - decorators: { value: {} }, - svg: { value: svg }, - VERSION: { value: '0.3.9' } - }); - Ractive.eventDefinitions = Ractive.events; - Ractive.prototype.constructor = Ractive; - Ractive.delimiters = [ - '{{', - '}}' - ]; - Ractive.tripleDelimiters = [ - '{{{', - '}}}' - ]; - Ractive.extend = Ractive_extend; - Ractive.parse = parse; - circular.Ractive = Ractive; - return Ractive; - }(config_svg, utils_create, utils_defineProperties, Ractive_prototype__prototype, registries_partials, registries_adaptors, registries_easing, extend__extend, parse__parse, Ractive_initialise, circular); -var Ractive = function (Ractive, circular) { - - if (typeof window !== 'undefined' && window.Node && !window.Node.prototype.contains && window.HTMLElement && window.HTMLElement.prototype.contains) { - window.Node.prototype.contains = window.HTMLElement.prototype.contains; - } - while (circular.length) { - circular.pop()(); - } - return Ractive; - }(Ractive__Ractive, circular); -// export as Common JS module... -if ( typeof module !== "undefined" && module.exports ) { - module.exports = Ractive; -} - -// ... or as AMD module -else if ( typeof define === "function" && define.amd ) { - define( function () { - return Ractive; - }); -} - -// ... or as browser global -else { - global.Ractive = Ractive; -} - -}( typeof window !== 'undefined' ? window : this )); \ No newline at end of file diff --git a/build/Ractive.runtime.min.js b/build/Ractive.runtime.min.js deleted file mode 100644 index e0fe1dbd4e..0000000000 --- a/build/Ractive.runtime.min.js +++ /dev/null @@ -1,3 +0,0 @@ -!function(a){var b=function(){return"undefined"!=typeof document?document&&document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1"):void 0}(),c=function(){var a;try{Object.create(null),a=Object.create}catch(b){a=function(){var a=function(){};return function(b,c){var d;return null===b?{}:(a.prototype=b,d=new a,c&&Object.defineProperties(d,c),d)}}()}return a}(),d={html:"http://www.w3.org/1999/xhtml",mathml:"http://www.w3.org/1998/Math/MathML",svg:"http://www.w3.org/2000/svg",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"},e=function(a,b){return a?function(a,b){return b?document.createElementNS(b,a):document.createElement(a)}:function(a,c){if(c&&c!==b.html)throw"This browser does not support namespaces other than http://www.w3.org/1999/xhtml. The most likely cause of this error is that you're trying to render SVG in an older browser. See https://github.com/RactiveJS/Ractive/wiki/SVG-and-older-browsers for more information";return document.createElement(a)}}(b,d),f=function(){return"object"==typeof document?!0:!1}(),g=function(a){try{return Object.defineProperty({},"test",{value:0}),a&&Object.defineProperty(document.createElement("div"),"test",{value:0}),Object.defineProperty}catch(b){return function(a,b,c){a[b]=c.value}}}(f),h=function(a,b,c){try{try{Object.defineProperties({},{test:{value:0}})}catch(d){throw d}return c&&Object.defineProperties(a("div"),{test:{value:0}}),Object.defineProperties}catch(d){return function(a,c){var d;for(d in c)c.hasOwnProperty(d)&&b(a,d,c[d])}}}(e,g,f),i=function(){var a=/\[\s*(\*|[0-9]|[1-9][0-9]+)\s*\]/g;return function(b){return(b||"").replace(a,".$1")}}(),j={},k={TEXT:1,INTERPOLATOR:2,TRIPLE:3,SECTION:4,INVERTED:5,CLOSING:6,ELEMENT:7,PARTIAL:8,COMMENT:9,DELIMCHANGE:10,MUSTACHE:11,TAG:12,ATTRIBUTE:13,COMPONENT:15,NUMBER_LITERAL:20,STRING_LITERAL:21,ARRAY_LITERAL:22,OBJECT_LITERAL:23,BOOLEAN_LITERAL:24,GLOBAL:26,KEY_VALUE_PAIR:27,REFERENCE:30,REFINEMENT:31,MEMBER:32,PREFIX_OPERATOR:33,BRACKETED:34,CONDITIONAL:35,INFIX_OPERATOR:36,INVOCATION:40},l=function(){var a=Object.prototype.toString;return function(b){return"[object Array]"===a.call(b)}}(),m=function(){return function a(b,c){var d,e;if((e=b._wrapped[c])&&e.teardown()!==!1&&(b._wrapped[c]=null),b._cache[c]=void 0,d=b._cacheMap[c])for(;d.length;)a(b,d.pop())}}(),n=function(){return function(a,b){var c,d,e,f,g,h;for(c=[],h=a.rendered?a.el:a.fragment.docFrag,d=h.querySelectorAll('input[type="checkbox"][name="{{'+b+'}}"]'),f=d.length,g=0;f>g;g+=1)e=d[g],(e.hasAttribute("checked")||e.checked)&&(c[c.length]=e._ractive.value);return c}}(),o=function(a){return function(b){var c,d,e,f,g,h;for(c=b._deferred;d=c.evals.pop();)d.update().deferred=!1;for(;e=c.selectValues.pop();)e.deferredUpdate();for(;f=c.attrs.pop();)f.update().deferred=!1;for(;g=c.checkboxes.pop();)b.set(g,a(b,g));for(;h=c.radios.pop();)h.update()}}(n),p=function(){return function(a){var b,c,d,e,f,g;for(b=a._deferred,(c=b.focusable)&&(c.focus(),b.focusable=null);d=b.liveQueries.pop();)d._sort();for(;e=b.decorators.pop();)e.init();for(;f=b.transitions.pop();)f.init();for(;g=b.observers.pop();)g.update()}}(),q=function(){var a=function(a,b){var c,d,e,f;return a._parent&&a._parent._transitionManager?a._parent._transitionManager:(d=[],e=function(){var a,b;for(a=d.length;a--;)b=d[a],f(b.node)&&(b.detach(),d.splice(a,1))},f=function(a){var b,d;for(b=c.active.length;b--;)if(d=c.active[b],a.contains(d))return!1;return!0},c={active:[],push:function(a){c.active[c.active.length]=a},pop:function(a){var b;b=c.active.indexOf(a),-1!==b&&(c.active.splice(b,1),e(),!c.active.length&&c._ready&&c.complete())},complete:function(){b&&b.call(a)},ready:function(){e(),c._ready=!0,c.active.length||c.complete()},detachWhenReady:function(a){d[d.length]=a}})};return a}(),r=function(){function a(a,d,e,f){var g=a._deps[e];g&&(b(g[d]),f||c(a._depsMap[d],a,e))}function b(a){var b,c;if(a)for(c=a.length,b=0;c>b;b+=1)a[b].update()}function c(b,c,d,e){var f;if(b)for(f=b.length;f--;)a(c,b[f],d,e)}function d(a,b,c,f,g){var i,j,k,l,m,n,o,p;for(i=a._patternObservers.length;i--;)j=a._patternObservers[i],j.regex.test(c)&&j.update(c);f||(p=function(b){if(k=a._depsMap[b])for(i=k.length;i--;)l=k[i],m=h.exec(l)[0],n=c+"."+m,d(a,l,n)},g?(o=e(c),o.forEach(p)):p(b))}function e(a){var b,c,d,e,g,h;for(b=a.split("."),c=f(b.length),g=[],d=function(a,c){return a?"*":b[c]},e=c.length;e--;)h=c[e].map(d).join("."),g[h]||(g[g.length]=h,g[h]=!0);return g}function f(a){var b,c,d,e,f,g="";if(!i[a]){for(d=[];g.length=f;f+=1){for(c=f.toString(2);c.length2&&f[1])for(q=Math.min(f[1],f.length-2),r=f[0],s=r+q,f[1]===f.length-2&&(u=!0),p=r;s>p;p+=1)t=g+"."+p,h(a,t);for(e(a),m=[],l=g.split(".");l.length;)l.pop(),m[m.length]=l.join(".");h.multiple(a,m,!0),u||h(a,g+".length",!0)},i=function(b,c,d,e){var f,g;for(f=c.length;f--;)g=c[f],g.type===a.REFERENCE?g.update():g.keypath===b&&g.type===a.SECTION&&!g.inverted&&g.docFrag?d[d.length]=g:e[e.length]=g},j=b._ractive.wrappers,l=j.length;l--;)k=j[l],g(k.root,k.keypath)},n=[],p=["pop","push","reverse","shift","sort","splice","unshift"],q=function(){},p.forEach(function(a){var c=function(){var b,c,d,h,i={},k={};for(b=Array.prototype[a].apply(this,arguments),c=this._ractive.instances,h=c.length;h--;)d=c[h],i[d._guid]=d._transitionManager,d._transitionManager=k[d._guid]=g(d,q);for(this._ractive.setting=!0,j(this,a,arguments),this._ractive.setting=!1,h=c.length;h--;)d=c[h],d._transitionManager=i[d._guid],k[d._guid].ready(),e(d),f(d);return b};b(n,a,{value:c})}),o={},o.__proto__?(l=function(a){a.__proto__=n},m=function(a){a.__proto__=Array.prototype}):(l=function(a){var c,d;for(c=p.length;c--;)d=p[c],b(a,d,{value:n[d],configurable:!0})},m=function(a){var b;for(b=p.length;b--;)delete a[p[b]]}),r="Something went wrong in a rather interesting way",i}(k,g,l,m,o,p,q,r),t=function(){var a,b;try{Object.defineProperty({},"test",{value:0})}catch(c){return!1}return a={filter:function(a,b){return!!b},wrap:function(a,c,d){return new b(a,c,d)}},b=function(a,b,c){var d,e,f,g,h,i,j,k,l,m=this;if(this.ractive=a,this.keypath=c,d=c.split("."),this.prop=d.pop(),f=d.join("."),this.obj=f?a.get(f):a.data,g=this.originalDescriptor=Object.getOwnPropertyDescriptor(this.obj,this.prop),g&&g.set&&(h=g.set._ractiveWrappers))return-1===h.indexOf(this)&&h.push(this),void 0;if(g&&!g.configurable)throw new Error('Cannot use magic mode with property "'+e+'" - object is not configurable');g&&(this.value=g.value,i=g.get,j=g.set),k=i||function(){return m.value},l=function(a){var b,c,d;for(j&&j(a),b=l._ractiveWrappers,d=b.length;d--;)c=b[d],c.resetting||c.ractive.set(c.keypath,a)},l._ractiveWrappers=[this],Object.defineProperty(this.obj,this.prop,{get:k,set:l,enumerable:!0,configurable:!0})},b.prototype={get:function(){return this.value},reset:function(a){this.resetting=!0,this.value=a,this.resetting=!1},teardown:function(){var a,b,c,d;a=Object.getOwnPropertyDescriptor(this.obj,this.prop),b=a.set,d=b._ractiveWrappers,d.splice(d.indexOf(this),1),d.length||(c=this.obj[this.prop],Object.defineProperty(this.obj,this.prop,this.originalDescriptor||{writable:!0,enumerable:!0,configrable:!0}),this.obj[this.prop]=c)}},a}(),u=function(a,b,c){function d(a,b){var c,d={};if(!b)return a;b+=".";for(c in a)a.hasOwnProperty(c)&&(d[b+c]=a[c]);return d}function e(a){var b;return f[a]||(b=a?a+".":"",f[a]=function(c,e){var f;return"string"==typeof c?(f={},f[b+c]=e,f):"object"==typeof c?b?d(c,a):c:void 0}),f[a]}var f={};return function(d,f,g,h){var i,j,k,l;for(i=d.adaptors.length,j=0;i>j;j+=1){if(k=d.adaptors[j],"string"==typeof k){if(!a[k])throw new Error('Missing adaptor "'+k+'"');k=d.adaptors[j]=a[k]}if(k.filter(g,f,d))return l=d._wrapped[f]=k.wrap(d,g,f,e(f)),l.value=g,void 0}h||(d.magic&&c.filter(g,f,d)?d._wrapped[f]=c.wrap(d,g,f):d.modifyArrays&&b.filter(g,f,d)&&(d._wrapped[f]=b.wrap(d,g,f)))}}(j,s,t),v=function(a,b,c){var d,e,f;return d=function(a){return this._captured&&!this._captured[a]&&(this._captured.push(a),this._captured[a]=!0),e(this,a)},e=function(b,d){var e,g,h,i,j;return d=a(d),e=b._cache,void 0!==(g=e[d])?g:((i=b._wrapped[d])?h=i.value:d?h=(j=b._evaluators[d])?j.value:f(b,d):(c(b,"",b.data),h=b.data),e[d]=h,h)},f=function(a,b){var d,f,g,h,i,j,k;return d=b.split("."),f=d.pop(),g=d.join("."),h=e(a,g),(k=a._wrapped[g])&&(h=k.get()),null!==h&&void 0!==h?((i=a._cacheMap[g])?-1===i.indexOf(b)&&(i[i.length]=b):a._cacheMap[g]=[b],j=h[f],c(a,b,j),a._cache[b]=j,j):void 0},d}(i,j,u),w=function(){var a=Object.prototype.toString;return function(b){return"object"==typeof b&&"[object Object]"===a.call(b)}}(),x=function(){return function(a,b){return null===a&&null===b?!0:"object"==typeof a||"object"==typeof b?!1:a===b}}(),y=function(){var a;return a=function(a,b,c){var d,e,f,g,h,i,j,k,l,m,n;if(n='Could not resolve reference - too many "../" prefixes',"."===b){if(!c.length)return"";d=c[c.length-1]}else if("."===b.charAt(0))if(m=c[c.length-1],g=m?m.split("."):[],"../"===b.substr(0,3)){for(;"../"===b.substr(0,3);){if(!g.length)throw new Error(n);g.pop(),b=b.substring(3)}g.push(b),d=g.join(".")}else d=m?m+b:b.substring(1);else{for(e=b.split("."),f=e.pop(),i=e.length?"."+e.join("."):"",c=c.concat();c.length;)if(h=c.pop(),j=h+i,k=a.get(j),(l=a._wrapped[j])&&(k=l.get()),"object"==typeof k&&null!==k&&k.hasOwnProperty(f)){d=h+"."+b;break}d||void 0===a.get(b)||(d=b)}return d?d.replace(/^\./,""):d}}(),z=function(a){var b=Array.prototype.push;return function(c){for(var d,e,f;d=c._pendingResolution.pop();)e=a(c,d.ref,d.contextStack),void 0!==e?d.resolve(e):(f||(f=[])).push(d);f&&b.apply(c._pendingResolution,f)}}(y),A=function(a,b){return function(c){a(c),b(c)}}(o,p),B=function(){return function(a,b,c){var d,e,f,g,h,i,j;for(d=b.split("."),e=[],(f=a._wrapped[""])?(f.set&&f.set(d.join("."),c),g=f.get()):g=a.data;d.length>1;)h=e[e.length]=d.shift(),i=e.join("."),(f=a._wrapped[i])?(f.set&&f.set(d.join("."),c),g=f.get()):(g.hasOwnProperty(h)||(j||(j=i),g[h]=/^\s*[0-9]+\s*$/.test(d[0])?[]:{}),g=g[h]);return h=d[0],g[h]=c,j}}(),C=function(a,b,c,d,e,f,g,h,i){var j,k,l,m;return j=function(b,d,i){var j,m,n,o,p,q,r;if(m=[],a(b)&&(j=b,i=d),j)for(b in j)j.hasOwnProperty(b)&&(d=j[b],b=c(b),k(this,b,d,m));else b=c(b),k(this,b,d,m);if(m.length){if(o=this._transitionManager,this._transitionManager=p=g(this,i),n=l(m),n.length&&e.multiple(this,n,!0),e.multiple(this,m),this._pendingResolution.length&&f(this),h(this),this._transitionManager=o,p.ready(),!this.firingChangeEvent){for(this.firingChangeEvent=!0,r={},q=m.length;q--;)r[m[q]]=this.get(m[q]);this.fire("change",r),this.firingChangeEvent=!1}return this}},k=function(a,b,c,e){var f,g,h,j,k;if(!(h=a._wrapped[b])||!h.reset||m(a,b,c,h,e)===!1){if((k=a._evaluators[b])&&(k.value=c),f=a._cache[b],g=a.get(b),g===c||k){if(c===f&&"object"!=typeof c)return}else j=i(a,b,c);d(a,j||b),e[e.length]=b}},l=function(a){var b,c,d,e,f=[""];for(b=a.length;b--;)for(c=a[b],d=c.split(".");d.length>1;)d.pop(),e=d.join("."),f[e]||(f[f.length]=e,f[e]=!0);return f},m=function(a,c,e,f,g){var h,i,j,k;if(h=f.get(),!b(h,e)&&f.reset(e)===!1)return!1;if(e=f.get(),i=a._cache[c],!b(i,e)){if(a._cache[c]=e,j=a._cacheMap[c])for(k=j.length;k--;)d(a,j[k]);g[g.length]=c}},j}(w,x,i,m,r,z,q,A,B),D=function(a,b,c,d,e){return function(f,g){var h,i;return"function"==typeof f&&(g=f,f=""),i=this._transitionManager,this._transitionManager=h=a(this,g),b(this),c(this,f||""),d(this,f||""),e(this),this._transitionManager=i,h.ready(),"string"==typeof f?this.fire("update",f):this.fire("update"),this}}(q,z,m,r,A),E=function(a){return function(b,c){var d;if(!a(b)||!a(c))return!1;if(b.length!==c.length)return!1;for(d=b.length;d--;)if(b[d]!==c[d])return!1;return!0}}(l),F=function(a,b,c){function d(a,e,f,g,h){var i,j,k,l,m,n;if(i=a._twowayBindings[e])for(k=i.length;k--;)l=i[k],(!l.radioName||l.node.checked)&&(l.checkboxName?l.changed()&&!g[e]&&(g[e]=!0,g[g.length]=e):(m=l.attr.value,n=l.value(),b(m,n)||c(m,n)||(f[e]=n)));if(h&&(j=a._depsMap[e]))for(k=j.length;k--;)d(a,j[k],f,g,h)}return function(b,c){var e,f,g;if("string"!=typeof b&&(b="",c=!0),d(this,b,e={},f=[],c),g=f.length)for(;g--;)b=f[g],e[b]=a(this,b);this.set(e)}}(n,E,x),G=function(){return"undefined"!=typeof window?(function(a,b,c){var d,e;if(!c.requestAnimationFrame){for(d=0;d=this.duration?(null!==g&&this.root.set(g,this.to),this.step&&this.step(1,this.to),this.complete&&this.complete(1,this.to),f=this.root._animations.indexOf(this),-1===f&&a("Animation was not found"),this.root._animations.splice(f,1),this.running=!1,!1):(c=this.easing?this.easing(b/this.duration):b/this.duration,null!==g&&(d=this.interpolator(c),this.root.set(g,d)),this.step&&this.step(c,d),!0)):!1},stop:function(){var b;this.running=!1,b=this.root._animations.indexOf(this),-1===b&&a("Animation was not found"),this.root._animations.splice(b,1)}},c}(I,K),M=function(){return{linear:function(a){return a},easeIn:function(a){return Math.pow(a,3)},easeOut:function(a){return Math.pow(a-1,3)+1},easeInOut:function(a){return(a/=.5)<1?.5*Math.pow(a,3):.5*(Math.pow(a-2,3)+2)}}}(),N=function(a,b,c,d){function e(e,g,h,i){var j,k,l,m;return null!==g&&(m=e.get(g)),b.abort(g,e),a(m,h)?(i.complete&&i.complete(1,i.to),f):(i.easing&&(j="function"==typeof i.easing?i.easing:e.easing&&e.easing[i.easing]?e.easing[i.easing]:d[i.easing],"function"!=typeof j&&(j=null)),k=void 0===i.duration?400:i.duration,l=new c({keypath:g,from:m,to:h,root:e,duration:k,easing:j,step:i.step,complete:i.complete}),b.add(l),e._animations[e._animations.length]=l,l)}var f={stop:function(){}};return function(a,b,c){var d,f,g,h,i,j,k,l,m,n,o,p;if("object"==typeof a){c=b||{},h=c.easing,i=c.duration,g=[],j=c.step,k=c.complete,(j||k)&&(m={},c.step=null,c.complete=null,l=function(a){return function(b,c){m[a]=c}});for(d in a)a.hasOwnProperty(d)&&((j||k)&&(n=l(d),c={easing:h,duration:i},j&&(c.step=n),k&&(c.complete=n)),g[g.length]=e(this,d,a[d],c));return(j||k)&&(p={easing:h,duration:i},j&&(p.step=function(a){j(a,m)}),k&&(p.complete=function(a){k(a,m)}),g[g.length]=o=e(this,null,null,p)),{stop:function(){for(;g.length;)g.pop().stop();o&&o.stop()}}}return c=c||{},f=e(this,a,b,c),{stop:function(){f.stop()}}}}(x,H,L,M),O=function(){return function(a,b){var c,d,e=this;if("object"==typeof a){c=[];for(d in a)a.hasOwnProperty(d)&&(c[c.length]=this.on(d,a[d]));return{cancel:function(){for(;c.length;)c.pop().cancel()}}}return this._subs[a]?this._subs[a].push(b):this._subs[a]=[b],{cancel:function(){e.off(a,b)}}}}(),P=function(){return function(a,b){var c,d;if(!b)if(a)this._subs[a]=[];else for(a in this._subs)delete this._subs[a];c=this._subs[a],c&&(d=c.indexOf(b),-1!==d&&c.splice(d,1))}}(),Q=function(){return function(a){var b,c,d,e,f,g,h,i;if(g=a.root,h=a.keypath,i=a.priority,b=g._deps[i]||(g._deps[i]={}),c=b[h]||(b[h]=[]),c[c.length]=a,a.registered=!0,h)for(d=h.split(".");d.length;)d.pop(),e=d.join("."),f=g._depsMap[e]||(g._depsMap[e]=[]),void 0===f[h]&&(f[h]=0,f[f.length]=h),f[h]+=1,h=e}}(),R=function(){return function(a){var b,c,d,e,f,g,h,i;if(g=a.root,h=a.keypath,i=a.priority,b=g._deps[i][h],c=b.indexOf(a),-1===c||!a.registered)throw new Error("Attempted to remove a dependant that was no longer registered! This should not happen. If you are seeing this bug in development please raise an issue at https://github.com/RactiveJS/Ractive/issues - thanks");if(b.splice(c,1),a.registered=!1,h)for(d=h.split(".");d.length;)d.pop(),e=d.join("."),f=g._depsMap[e],f[h]-=1,f[h]||(f.splice(f.indexOf(h),1),f[h]=void 0),h=e}}(),S=function(a){var b=function(a,b,c,d){var e=this;this.root=a,this.keypath=b,this.callback=c,this.defer=d.defer,this.debug=d.debug,this.proxy={update:function(){e.reallyUpdate()}},this.priority=0,this.context=d&&d.context?d.context:a};return b.prototype={init:function(a){a!==!1?this.update():this.value=this.root.get(this.keypath)},update:function(){return this.defer&&this.ready?(this.root._deferred.observers.push(this.proxy),void 0):(this.reallyUpdate(),void 0)},reallyUpdate:function(){var b,c;if(b=this.value,c=this.root.get(this.keypath),this.value=c,!this.updating){if(this.updating=!0,!a(c,b)||!this.ready)try{this.callback.call(this.context,c,b,this.keypath)}catch(d){if(this.debug||this.root.debug)throw d}this.updating=!1}}},b}(x),T=function(){return function(a,b){var c,d,e,f,g,h,i;for(c=b.split("."),f=[],h=function(b){var c,d;c=a._wrapped[b]?a._wrapped[b].get():a.get(b);for(d in c)g.push(b+"."+d)},i=function(a){return a+"."+d};d=c.shift();)"*"===d?(g=[],f.forEach(h),f=g):f[0]?f=f.map(i):f[0]=d;return e={},f.forEach(function(b){e[b]=a.get(b)}),e}}(),U=function(a,b){var c,d=/\*/;return c=function(a,b,c,d){this.root=a,this.callback=c,this.defer=d.defer,this.debug=d.debug,this.keypath=b,this.regex=new RegExp("^"+b.replace(/\./g,"\\.").replace(/\*/g,"[^\\.]+")+"$"),this.values={},this.defer&&(this.proxies=[]),this.priority="pattern",this.context=d&&d.context?d.context:a},c.prototype={init:function(a){var c,d;if(c=b(this.root,this.keypath),a!==!1)for(d in c)c.hasOwnProperty(d)&&this.update(d);else this.values=c},update:function(a){var c;{if(!d.test(a))return this.defer&&this.ready?(this.root._deferred.observers.push(this.getProxy(a)),void 0):(this.reallyUpdate(a),void 0);c=b(this.root,a);for(a in c)c.hasOwnProperty(a)&&this.update(a)}},reallyUpdate:function(b){var c=this.root.get(b);if(this.updating)return this.values[b]=c,void 0;if(this.updating=!0,!a(c,this.values[b])||!this.ready){try{this.callback.call(this.context,c,this.values[b],b)}catch(d){if(this.debug||this.root.debug)throw d}this.values[b]=c}this.updating=!1},getProxy:function(a){var b=this;return this.proxies[a]||(this.proxies[a]={update:function(){b.reallyUpdate(a)}}),this.proxies[a]}},c}(x,T),V=function(a,b,c,d,e){var f=/\*/,g={};return function(h,i,j,k){var l,m;return i=a(i),k=k||g,f.test(i)?(l=new e(h,i,j,k),h._patternObservers.push(l),m=!0):l=new d(h,i,j,k),b(l),l.init(k.init),l.ready=!0,{cancel:function(){var a;m&&(a=h._patternObservers.indexOf(l),-1!==a&&h._patternObservers.splice(a,1)),c(l)}}}}(i,Q,R,S,U),W=function(a,b){return function(c,d,e){var f,g=[];if(a(c)){e=d;for(f in c)c.hasOwnProperty(f)&&(d=c[f],g[g.length]=b(this,f,d,e));return{cancel:function(){for(;g.length;)g.pop().cancel()}}}return b(this,c,d,e)}}(w,V),X=function(){return function(a){var b,c,d,e=this._subs[a];if(e)for(b=Array.prototype.slice.call(arguments,1),c=0,d=e.length;d>c;c+=1)e[c].apply(this,b)}}(),Y=function(){return function(a){return this.el?this.fragment.find(a):null}}(),Z=function(a,b){var c,d,e,f,g,h,i,j;if(a){for(c=b("div"),d=["matches","matchesSelector"],g=["o","ms","moz","webkit"],j=function(a){return function(b,c){return b[a](c)}},h=d.length;h--;){if(e=d[h],c[e])return j(e);for(i=g.length;i--;)if(f=g[h]+e.substr(0,1).toUpperCase()+e.substring(1),c[f])return j(f)}return function(a,b){var c,d;for(c=(a.parentNode||a.document).querySelectorAll(b),d=c.length;d--;)if(c[d]===a)return!0;return!1}}}(f,e),$=function(a){return function(b,c){var d=this._isComponentQuery?!this.selector||b.name===this.selector:a(b.node,this.selector);return d?(this.push(b.node||b.instance),c||this._makeDirty(),!0):void 0}}(Z),_=function(){return function(){var a,b,c;a=this._root[this._isComponentQuery?"liveComponentQueries":"liveQueries"],b=this.selector,c=a.indexOf(b),-1!==c&&(a.splice(c,1),a[b]=null)}}(),ab=function(){function a(a){var b;return(b=a.parentFragment)?b.owner:a.component&&(b=a.component.parentFragment)?b.owner:void 0}function b(b){var c,d;for(c=[b],d=a(b);d;)c.push(d),d=a(d);return c}return function(a,c){var d,e,f,g,h,i,j,k,l,m;for(d=b(a.component||a._ractive.proxy),e=b(c.component||c._ractive.proxy),f=d[d.length-1],g=e[e.length-1];f&&f===g;)d.pop(),e.pop(),h=f,f=d[d.length-1],g=e[e.length-1];if(f=f.component||f,g=g.component||g,l=f.parentFragment,m=g.parentFragment,l===m)return i=l.items.indexOf(f),j=m.items.indexOf(g),i-j||d.length-e.length;if(k=h.fragments)return i=k.indexOf(l),j=k.indexOf(m),i-j||d.length-e.length;throw new Error("An unexpected condition was met while comparing the position of two components. Please file an issue at https://github.com/RactiveJS/Ractive/issues - thanks!")}}(),bb=function(a){return function(b,c){var d;return b.compareDocumentPosition?(d=b.compareDocumentPosition(c),2&d?1:-1):a(b,c)}}(ab),cb=function(a,b){return function(){this.sort(this._isComponentQuery?b:a),this._dirty=!1}}(bb,ab),db=function(){return function(){this._dirty||(this._root._deferred.liveQueries.push(this),this._dirty=!0)}}(),eb=function(){return function(a){var b=this.indexOf(this._isComponentQuery?a.instance:a.node);-1!==b&&this.splice(b,1)}}(),fb=function(a,b,c,d,e,f){return function(g,h,i,j){var k;return k=[],a(k,{selector:{value:h},live:{value:i},_isComponentQuery:{value:j},_test:{value:b}}),i?(a(k,{cancel:{value:c},_root:{value:g},_sort:{value:d},_makeDirty:{value:e},_remove:{value:f},_dirty:{value:!1,writable:!0}}),k):k}}(h,$,_,cb,db,eb),gb=function(a,b,c,d){return function(a,b){var c,e;return this.el?(b=b||{},c=this._liveQueries,(e=c[a])?b&&b.live?e:e.slice():(e=d(this,a,!!b.live,!1),e.live&&(c.push(a),c[a]=e),this.fragment.findAll(a,e),e)):[]}}(I,Z,h,fb),hb=function(){return function(a){return this.fragment.findComponent(a)}}(),ib=function(a,b,c,d){return function(a,b){var c,e;return b=b||{},c=this._liveComponentQueries,(e=c[a])?b&&b.live?e:e.slice():(e=d(this,a,!!b.live,!0),e.live&&(c.push(a),c[a]=e),this.fragment.findAllComponents(a,e),e)}}(I,Z,h,fb),jb=function(){return function(a){var b;return"undefined"!=typeof window&&document&&a?a.nodeType?a:"string"==typeof a&&(b=document.getElementById(a),!b&&document.querySelector&&(b=document.querySelector(a)),b&&b.nodeType)?b:a[0]&&a[0].nodeType?a[0]:null:null}}(),kb=function(a,b){return function(c,d){var e,f,g,h,i;if(c.owner=d.owner,g=c.owner.parentFragment,c.root=d.root,c.pNode=d.pNode,c.contextStack=d.contextStack||[],c.owner.type===a.SECTION&&(c.index=d.index),g&&(h=g.indexRefs)){c.indexRefs=b(null);for(i in h)c.indexRefs[i]=h[i]}for(c.priority=g?g.priority+1:1,d.indexRef&&(c.indexRefs||(c.indexRefs={}),c.indexRefs[d.indexRef]=d.index),c.items=[],e=d.descriptor?d.descriptor.length:0,f=0;e>f;f+=1)c.items[c.items.length]=c.createItem({parentFragment:c,descriptor:d.descriptor[f],index:f})}}(k,c),lb=function(a){var b={};return function(c,d,e){var f,g=[];if(c)for(f=b[d]||(b[d]=a(d)),f.innerHTML=c;f.firstChild;)g[g.length]=f.firstChild,e.appendChild(f.firstChild);return g}}(e),mb=function(a){var b,c,d;return c=//g,b=function(b,c){this.type=a.TEXT,this.descriptor=b.descriptor,c&&(this.node=document.createTextNode(b.descriptor),c.appendChild(this.node))},b.prototype={detach:function(){return this.node.parentNode.removeChild(this.node),this.node},teardown:function(a){a&&this.detach()},firstNode:function(){return this.node},toString:function(){return(""+this.descriptor).replace(c,"<").replace(d,">")}},b}(k),nb=function(a){return function(b){if(b.keypath)a(b);else{var c=b.root._pendingResolution.indexOf(b);-1!==c&&b.root._pendingResolution.splice(c,1)}}}(R),ob=function(a,b,c,d,e){function f(a,b,d){var e,f,g;if(!h.test(a.toString()))return c(a,"_nowrap",{value:!0}),a;if(!a["_"+b._guid]){c(a,"_"+b._guid,{value:function(){var c,d,e,g;if(c=b._captured,c||(b._captured=[]),d=a.apply(b,arguments),b._captured.length)for(e=f.length;e--;)g=f[e],g.updateSoftDependencies(b._captured);return b._captured=c,d},writable:!0});for(e in a)a.hasOwnProperty(e)&&(a["_"+b._guid][e]=a[e]);a["_"+b._guid+"_evaluators"]=[]}return f=a["_"+b._guid+"_evaluators"],g=f.indexOf(d),-1===g&&f.push(d),a["_"+b._guid]}var g,h;return h=/this/,g=function(b,c,e,g,h){var i;this.evaluator=e,this.keypath=c,this.root=b,this.argNum=g,this.type=a.REFERENCE,this.priority=h,i=b.get(c),"function"==typeof i&&(i=f(i,b,e)),this.value=e.values[g]=i,d(this)},g.prototype={update:function(){var a=this.root.get(this.keypath);"function"!=typeof a||a._nowrap||(a=f(a,this.root,this.evaluator)),b(a,this.value)||(this.evaluator.values[this.argNum]=a,this.evaluator.bubble(),this.value=a)},teardown:function(){e(this)}},g}(k,x,g,Q,R),pb=function(a,b,c){var d=function(a,c,d){this.root=a,this.keypath=c,this.priority=d.priority,this.evaluator=d,b(this)};return d.prototype={update:function(){var b=this.root.get(this.keypath);a(b,this.value)||(this.evaluator.bubble(),this.value=b)},teardown:function(){c(this)}},d}(x,Q,R),qb=function(a,b,c,d,e,f,g,h,i){function j(a,b){var c,d;if(a=a.replace(/\$\{([0-9]+)\}/g,"_$1"),l[a])return l[a];for(d=[];b--;)d[b]="_"+b;return c=new Function(d.join(","),"return("+a+")"),l[a]=c,c}var k,l={};return k=function(a,b,c,d,e){var f,g;for(this.root=a,this.keypath=b,this.priority=e,this.fn=j(c,d.length),this.values=[],this.refs=[],f=d.length;f--;)(g=d[f])?g[0]?this.values[f]=g[1]:this.refs[this.refs.length]=new h(a,g[1],this,f,e):this.values[f]=void 0;this.selfUpdating=this.refs.length<=1,this.update()},k.prototype={bubble:function(){this.selfUpdating?this.update():this.deferred||(this.root._deferred.evals.push(this),this.deferred=!0)},update:function(){var b;if(this.evaluating)return this;this.evaluating=!0;try{b=this.fn.apply(null,this.values)}catch(e){if(this.root.debug)throw e;b=void 0}return a(b,this.value)||(c(this.root,this.keypath),this.root._cache[this.keypath]=b,g(this.root,this.keypath,b,!0),this.value=b,d(this.root,this.keypath)),this.evaluating=!1,this},teardown:function(){for(;this.refs.length;)this.refs.pop().teardown();c(this.root,this.keypath),this.root._evaluators[this.keypath]=null},refresh:function(){this.selfUpdating||(this.deferred=!0);for(var a=this.refs.length;a--;)this.refs[a].update();this.deferred&&(this.update(),this.deferred=!1)},updateSoftDependencies:function(a){var b,c,d;for(this.softRefs||(this.softRefs=[]),b=this.softRefs.length;b--;)d=this.softRefs[b],a[d.keypath]||(this.softRefs.splice(b,1),this.softRefs[d.keypath]=!1,d.teardown());for(b=a.length;b--;)c=a[b],this.softRefs[c]||(d=new i(this.root,c,this),this.softRefs[this.softRefs.length]=d,this.softRefs[c]=!0);this.selfUpdating=this.refs.length+this.softRefs.length<=1}},k}(x,g,m,r,Q,R,u,ob,pb),rb=function(a,b){var c=function(b,c,d,e){var f,g;g=this.root=b.root,f=a(g,c,d),void 0!==f?b.resolveRef(e,!1,f):(this.ref=c,this.argNum=e,this.resolver=b,this.contextStack=d,g._pendingResolution[g._pendingResolution.length]=this)};return c.prototype={resolve:function(a){this.keypath=a,this.resolver.resolveRef(this.argNum,!1,a)},teardown:function(){this.keypath||b(this)}},c}(y,nb),sb=function(){var a=/^(?:(?:[a-zA-Z$_][a-zA-Z$_0-9]*)|(?:[0-9]|[1-9][0-9]+))$/;return function(b){var c,d,e;for(c=b.split("."),e=c.length;e--;)if(d=c[e],"undefined"===d||!a.test(d))return!1;return!0}}(),tb=function(a,b){return function(c,d){var e,f;return e=c.replace(/\$\{([0-9]+)\}/g,function(a,b){return d[b]?d[b][1]:"undefined"}),f=a(e),b(f)?f:"${"+e.replace(/[\.\[\]]/g,"-")+"}"}}(i,sb),ub=function(a,b){function c(a,b,c){var e,f;if(e=a._depsMap[b])for(f=e.length;f--;)d(a,e[f],c)}function d(a,b,d){var e,f,g,h;for(e=a._deps.length;e--;)if(f=a._deps[e],f&&(g=f[b]))for(h=g.length;h--;)d.push(g[h]);c(a,b,d)}return function(c,e,f){var g,h,i;for(g=[],d(c,e,g),h=g.length;h--;)i=g[h],b(i),i.keypath=i.keypath.replace(e,f),a(i),i.update()}}(Q,R),vb=function(a,b,c,d){var e=function(a){var c,d,e,f,g;if(this.root=a.root,this.mustache=a,this.args=[],this.scouts=[],c=a.descriptor.x,g=a.parentFragment.indexRefs,this.str=c.s,e=this.unresolved=this.args.length=c.r?c.r.length:0,!e)return this.resolved=this.ready=!0,this.bubble(),void 0;for(d=0;e>d;d+=1)f=c.r[d],g&&void 0!==g[f]?this.resolveRef(d,!0,g[f]):this.scouts[this.scouts.length]=new b(this,f,a.contextStack,d);this.ready=!0,this.bubble()};return e.prototype={bubble:function(){var a;this.ready&&(a=this.keypath,this.keypath=c(this.str,this.args),"${"===this.keypath.substr(0,2)&&this.createEvaluator(),a?d(this.root,a,this.keypath):this.mustache.resolve(this.keypath))},teardown:function(){for(;this.scouts.length;)this.scouts.pop().teardown()},resolveRef:function(a,b,c){this.args[a]=[b,c],this.bubble(),this.resolved=!--this.unresolved},createEvaluator:function(){this.root._evaluators[this.keypath]?this.root._evaluators[this.keypath].refresh():this.root._evaluators[this.keypath]=new a(this.root,this.keypath,this.str,this.args,this.mustache.priority)}},e}(qb,rb,tb,ub),wb=function(a,b){return function(c,d){var e,f,g;g=c.parentFragment=d.parentFragment,c.root=g.root,c.contextStack=g.contextStack,c.descriptor=d.descriptor,c.index=d.index||0,c.priority=g.priority,c.type=d.descriptor.t,d.descriptor.r&&(g.indexRefs&&void 0!==g.indexRefs[d.descriptor.r]?(f=g.indexRefs[d.descriptor.r],c.indexRef=d.descriptor.r,c.value=f,c.render(c.value)):(e=a(c.root,d.descriptor.r,c.contextStack),void 0!==e?c.resolve(e):(c.ref=d.descriptor.r,c.root._pendingResolution[c.root._pendingResolution.length]=c))),d.descriptor.x&&(c.expressionResolver=new b(c)),c.descriptor.n&&!c.hasOwnProperty("value")&&c.render(void 0) -}}(y,vb),xb=function(a,b,c){return function(d){d!==this.keypath&&(this.registered&&c(this),this.keypath=d,b(this),this.update(),this.root.twoway&&this.parentFragment.owner.type===a.ATTRIBUTE&&this.parentFragment.owner.element.bind(),this.expressionResolver&&this.expressionResolver.resolved&&(this.expressionResolver=null))}}(k,Q,R),yb=function(a){return function(){var b,c;c=this.root.get(this.keypath),(b=this.root._wrapped[this.keypath])&&(c=b.get()),a(c,this.value)||(this.render(c),this.value=c)}}(x),zb=function(a,b,c,d,e){var f,g,h;return g=//g,f=function(b,d){this.type=a.INTERPOLATOR,d&&(this.node=document.createTextNode(""),d.appendChild(this.node)),c(this,b)},f.prototype={update:e,resolve:d,detach:function(){return this.node.parentNode.removeChild(this.node),this.node},teardown:function(a){a&&this.detach(),b(this)},render:function(a){this.node&&(this.node.data=void 0==a?"":a)},firstNode:function(){return this.node},toString:function(){var a=void 0!=this.value?""+this.value:"";return a.replace(g,"<").replace(h,">")}},f}(k,nb,wb,xb,yb),Ab=function(a,b,c){function d(a,b,c){var d,e,f;if(e=b.length,ea.length)for(d=a.length;e>d;d+=1)c.contextStack=a.contextStack.concat(a.keypath+"."+d),c.index=d,a.descriptor.i&&(c.indexRef=a.descriptor.i),a.fragments[d]=a.createFragment(c);a.length=e}function e(a,b,d){var e,f;f=a.fragmentsById||(a.fragmentsById=c(null));for(e in f)void 0===b[e]&&f[e]&&(f[e].teardown(!0),f[e]=null);for(e in b)void 0===b[e]||f[e]||(d.contextStack=a.contextStack.concat(a.keypath+"."+e),d.index=e,a.descriptor.i&&(d.indexRef=a.descriptor.i),f[e]=a.createFragment(d))}function f(a,b){a.length||(b.contextStack=a.contextStack.concat(a.keypath),b.index=0,a.fragments[0]=a.createFragment(b),a.length=1)}function g(b,c,d,e){var f,g,h,i;if(g=a(c)&&0===c.length,f=d?g||!c:c&&!g){if(b.length||(e.contextStack=b.contextStack,e.index=0,b.fragments[0]=b.createFragment(e),b.length=1),b.length>1)for(h=b.fragments.splice(1);i=h.pop();)i.teardown(!0)}else b.length&&(b.teardownFragments(!0),b.length=0)}return function(c,h){var i;return i={descriptor:c.descriptor.f,root:c.root,pNode:c.parentFragment.pNode,owner:c},c.descriptor.n?(g(c,h,!0,i),void 0):(a(h)?d(c,h,i):b(h)?c.descriptor.i?e(c,h,i):f(c,i):g(c,h,!1,i),void 0)}}(l,w,c),Bb=function(a,b,c){function d(b,c,g,h,i,j,k){var l,m,n,o;if(!b.html){for(b.indexRefs&&void 0!==b.indexRefs[c]&&(b.indexRefs[c]=h),l=b.contextStack.length;l--;)n=b.contextStack[l],n.substr(0,j.length)===j&&(b.contextStack[l]=n.replace(j,k));for(l=b.items.length;l--;)switch(m=b.items[l],m.type){case a.ELEMENT:e(m,c,g,h,i,j,k);break;case a.PARTIAL:d(m.fragment,c,g,h,i,j,k);break;case a.COMPONENT:d(m.instance.fragment,c,g,h,i,j,k),(o=b.root._liveComponentQueries[m.name])&&o._makeDirty();break;case a.SECTION:case a.INTERPOLATOR:case a.TRIPLE:f(m,c,g,h,i,j,k)}}}function e(a,b,c,e,f,g,h){var i,j,k,l,m,n,o,p,q,r;for(i=a.attributes.length;i--;)j=a.attributes[i],j.fragment&&(d(j.fragment,b,c,e,f,g,h),j.twoway&&j.updateBindings());if(k=a.node._ractive){k.keypath.substr(0,g.length)===g&&(k.keypath=k.keypath.replace(g,h)),void 0!==b&&(k.index[b]=e);for(l in k.events)for(m=k.events[l].proxies,i=m.length;i--;)n=m[i],"object"==typeof n.n&&d(n.a,b,c,e,f,g,h),n.d&&d(n.d,b,c,e,f,g,h);(o=k.binding)&&o.keypath.substr(0,g.length)===g&&(p=k.root._twowayBindings[o.keypath],p.splice(p.indexOf(o),1),o.keypath=o.keypath.replace(g,h),p=k.root._twowayBindings[o.keypath]||(k.root._twowayBindings[o.keypath]=[]),p.push(o))}if(a.fragment&&d(a.fragment,b,c,e,f,g,h),q=a.liveQueries)for(r=a.root,i=q.length;i--;)r._liveQueries[q[i]]._makeDirty()}function f(a,b,e,f,g,h,i){var j;if(a.descriptor.x&&(a.expressionResolver&&a.expressionResolver.teardown(),a.expressionResolver=new c(a)),a.keypath?a.keypath.substr(0,h.length)===h&&a.resolve(a.keypath.replace(h,i)):a.indexRef===b&&(a.value=f,a.render(f)),a.fragments)for(j=a.fragments.length;j--;)d(a.fragments[j],b,e,f,g,h,i)}return d}(k,R,vb),Cb=function(a,b,c){return function(a,d,e,f,g){var h,i,j,k,l,m,n;for(j=d.descriptor.i,h=e;f>h;h+=1)i=d.fragments[h],k=h-g,l=h,m=d.keypath+"."+(h-g),n=d.keypath+"."+h,i.index+=g,b(i,j,k,l,g,m,n);c(a)}}(k,Bb,o),Db=function(a){return function(b){var c,d,e,f,g,h,i,j,k,l,m=this;if(c=this.parentFragment,h=[],b.forEach(function(b,c){var f,g,j;return b===c?(h[b]=m.fragments[c],void 0):(void 0===d&&(d=c),-1===b?((i||(i=[])).push(m.fragments[c]),void 0):(f=b-c,g=m.keypath+"."+c,j=m.keypath+"."+b,a(m.fragments[c],m.descriptor.i,c,b,f,g,j),h[b]=m.fragments[c],e=!0,void 0))}),i)for(;k=i.pop();)k.teardown(!0);if(void 0===d&&(d=this.length),g=this.root.get(this.keypath).length,g!==d){for(j={descriptor:this.descriptor.f,root:this.root,pNode:c.pNode,owner:this},this.descriptor.i&&(j.indexRef=this.descriptor.i),f=d;g>f;f+=1)(k=h[f])?this.docFrag.appendChild(k.detach(!1)):(j.contextStack=this.contextStack.concat(this.keypath+"."+f),j.index=f,k=this.createFragment(j)),this.fragments[f]=k;l=c.findNextNode(this),c.pNode.insertBefore(this.docFrag,l),this.length=g}}}(Bb),Eb=function(){return[]}(),Fb=function(a,b,c,d,e,f,g,h,i,j,k){var l,m;return k.push(function(){m=k.DomFragment}),l=function(b,d){this.type=a.SECTION,this.inverted=!!b.descriptor.n,this.fragments=[],this.length=0,d&&(this.docFrag=document.createDocumentFragment()),this.initialising=!0,c(this,b),d&&d.appendChild(this.docFrag),this.initialising=!1},l.prototype={update:d,resolve:e,smartUpdate:function(a,b){var c;("push"===a||"unshift"===a||"splice"===a)&&(c={descriptor:this.descriptor.f,root:this.root,pNode:this.parentFragment.pNode,owner:this},this.descriptor.i&&(c.indexRef=this.descriptor.i)),this[a]&&(this.rendering=!0,this[a](c,b),this.rendering=!1)},pop:function(){this.length&&(this.fragments.pop().teardown(!0),this.length-=1)},push:function(a,b){var c,d,e;for(c=this.length,d=c+b.length,e=c;d>e;e+=1)a.contextStack=this.contextStack.concat(this.keypath+"."+e),a.index=e,this.fragments[e]=this.createFragment(a);this.length+=b.length,this.parentFragment.pNode.insertBefore(this.docFrag,this.parentFragment.findNextNode(this))},shift:function(){this.splice(null,[0,1])},unshift:function(a,b){this.splice(a,[0,0].concat(new Array(b.length)))},splice:function(a,b){var c,d,e,f,g,i,j,k,l;if(b.length&&(i=+(b[0]<0?this.length+b[0]:b[0]),d=Math.max(0,b.length-2),e=void 0!==b[1]?b[1]:this.length-i,e=Math.min(e,this.length-i),f=d-e)){if(0>f){for(j=i-f,g=i;j>g;g+=1)this.fragments[g].teardown(!0);this.fragments.splice(i,-f)}else{for(j=i+f,c=this.fragments[i]?this.fragments[i].firstNode():this.parentFragment.findNextNode(this),k=[i,0].concat(new Array(f)),this.fragments.splice.apply(this.fragments,k),g=i;j>g;g+=1)a.contextStack=this.contextStack.concat(this.keypath+"."+g),a.index=g,this.fragments[g]=this.createFragment(a);this.parentFragment.pNode.insertBefore(this.docFrag,c)}this.length+=f,l=i+d,h(this.root,this,l,this.length,f)}},merge:i,detach:function(){var a,b;for(b=this.fragments.length,a=0;b>a;a+=1)this.docFrag.appendChild(this.fragments[a].detach());return this.docFrag},teardown:function(a){this.teardownFragments(a),j(this)},firstNode:function(){return this.fragments[0]?this.fragments[0].firstNode():this.parentFragment.findNextNode(this)},findNextNode:function(a){return this.fragments[a.index+1]?this.fragments[a.index+1].firstNode():this.parentFragment.findNextNode(this)},teardownFragments:function(a){for(var b,c;c=this.fragments.shift();)c.teardown(a);if(this.fragmentsById)for(b in this.fragmentsById)this.fragments[b]&&(this.fragmentsById[b].teardown(a),this.fragmentsById[b]=null)},render:function(a){var c,d;(d=this.root._wrapped[this.keypath])&&(a=d.get()),this.rendering||(this.rendering=!0,f(this,a),this.rendering=!1,(!this.docFrag||this.docFrag.childNodes.length)&&!this.initialising&&b&&(c=this.parentFragment.findNextNode(this),c&&c.parentNode===this.parentFragment.pNode?this.parentFragment.pNode.insertBefore(this.docFrag,c):this.parentFragment.pNode.appendChild(this.docFrag)))},createFragment:function(a){var b=new m(a);return this.docFrag&&this.docFrag.appendChild(b.docFrag),b},toString:function(){var a,b,c,d;for(a="",b=0,d=this.length,b=0;d>b;b+=1)a+=this.fragments[b].toString();if(this.fragmentsById)for(c in this.fragmentsById)this.fragmentsById[c]&&(a+=this.fragmentsById[c].toString());return a},find:function(a){var b,c,d;for(c=this.fragments.length,b=0;c>b;b+=1)if(d=this.fragments[b].find(a))return d;return null},findAll:function(a,b){var c,d;for(d=this.fragments.length,c=0;d>c;c+=1)this.fragments[c].findAll(a,b)},findComponent:function(a){var b,c,d;for(c=this.fragments.length,b=0;c>b;b+=1)if(d=this.fragments[b].findComponent(a))return d;return null},findAllComponents:function(a,b){var c,d;for(d=this.fragments.length,c=0;d>c;c+=1)this.fragments[c].findAllComponents(a,b)}},l}(k,f,wb,yb,xb,Ab,Bb,Cb,Db,nb,Eb),Gb=function(a,b,c,d,e,f,g){var h=function(b,d){this.type=a.TRIPLE,d&&(this.nodes=[],this.docFrag=document.createDocumentFragment()),this.initialising=!0,c(this,b),d&&d.appendChild(this.docFrag),this.initialising=!1};return h.prototype={update:d,resolve:e,detach:function(){for(var a=this.nodes.length;a--;)this.docFrag.appendChild(this.nodes[a]);return this.docFrag},teardown:function(a){a&&(this.detach(),this.docFrag=this.nodes=null),g(this)},firstNode:function(){return this.nodes[0]?this.nodes[0]:this.parentFragment.findNextNode(this)},render:function(a){var b,c;if(this.nodes){for(;this.nodes.length;)b=this.nodes.pop(),b.parentNode.removeChild(b);if(!a)return this.nodes=[],void 0;c=this.parentFragment.pNode,this.nodes=f(a,c.tagName,this.docFrag),this.initialising||c.insertBefore(this.docFrag,this.parentFragment.findNextNode(this))}},toString:function(){return void 0!=this.value?this.value:""},find:function(a){var c,d,e,f;for(d=this.nodes.length,c=0;d>c;c+=1)if(e=this.nodes[c],1===e.nodeType){if(b(e,a))return e;if(f=e.querySelector(a))return f}return null},findAll:function(a,c){var d,e,f,g,h,i;for(e=this.nodes.length,d=0;e>d;d+=1)if(f=this.nodes[d],1===f.nodeType&&(b(f,a)&&c.push(f),g=f.querySelectorAll(a)))for(h=g.length,i=0;h>i;i+=1)c.push(g[i])}},h}(k,Z,wb,yb,xb,lb,nb),Hb=function(a){return function(b,c){return b.a&&b.a.xmlns?b.a.xmlns:"svg"===b.e?a.svg:c.namespaceURI||a.html}}(d),Ib=function(){var a,b,c,d;return a="altGlyph altGlyphDef altGlyphItem animateColor animateMotion animateTransform clipPath feBlend feColorMatrix feComponentTransfer feComposite feConvolveMatrix feDiffuseLighting feDisplacementMap feDistantLight feFlood feFuncA feFuncB feFuncG feFuncR feGaussianBlur feImage feMerge feMergeNode feMorphology feOffset fePointLight feSpecularLighting feSpotLight feTile feTurbulence foreignObject glyphRef linearGradient radialGradient textPath vkern".split(" "),b="attributeName attributeType baseFrequency baseProfile calcMode clipPathUnits contentScriptType contentStyleType diffuseConstant edgeMode externalResourcesRequired filterRes filterUnits glyphRef gradientTransform gradientUnits kernelMatrix kernelUnitLength keyPoints keySplines keyTimes lengthAdjust limitingConeAngle markerHeight markerUnits markerWidth maskContentUnits maskUnits numOctaves pathLength patternContentUnits patternTransform patternUnits pointsAtX pointsAtY pointsAtZ preserveAlpha preserveAspectRatio primitiveUnits refX refY repeatCount repeatDur requiredExtensions requiredFeatures specularConstant specularExponent spreadMethod startOffset stdDeviation stitchTiles surfaceScale systemLanguage tableValues targetX targetY textLength viewBox viewTarget xChannelSelector yChannelSelector zoomAndPan".split(" "),c=function(a){for(var b={},c=a.length;c--;)b[a[c].toLowerCase()]=a[c];return b},d=c(a.concat(b)),function(a){var b=a.toLowerCase();return d[b]||b}}(),Jb=function(a,b){return function(c,d){var e,f;if(e=d.indexOf(":"),-1===e||(f=d.substr(0,e),"xmlns"===f))c.name=c.element.namespace!==a.html?b(d):d,c.lcName=c.name.toLowerCase();else if(d=d.substring(e+1),c.name=b(d),c.lcName=c.name.toLowerCase(),c.namespace=a[f.toLowerCase()],!c.namespace)throw'Unknown namespace ("'+f+'")'}}(d,Ib),Kb=function(a){return function(b,c){var d,e=null===c.value?"":c.value;(d=c.pNode)&&(b.namespace?d.setAttributeNS(b.namespace,c.name,e):"style"===c.name&&d.style.setAttribute?d.style.setAttribute("cssText",e):"class"!==c.name||d.namespaceURI&&d.namespaceURI!==a.html?d.setAttribute(c.name,e):d.className=e,"id"===b.name&&(c.root.nodes[c.value]=d),"value"===b.name&&(d._ractive.value=c.value)),b.value=c.value}}(d),Lb=function(a){var b={"accept-charset":"acceptCharset",accesskey:"accessKey",bgcolor:"bgColor","class":"className",codebase:"codeBase",colspan:"colSpan",contenteditable:"contentEditable",datetime:"dateTime",dirname:"dirName","for":"htmlFor","http-equiv":"httpEquiv",ismap:"isMap",maxlength:"maxLength",novalidate:"noValidate",pubdate:"pubDate",readonly:"readOnly",rowspan:"rowSpan",tabindex:"tabIndex",usemap:"useMap"};return function(c,d){var e;!c.pNode||c.namespace||d.pNode.namespaceURI&&d.pNode.namespaceURI!==a.html||(e=b[c.name]||c.name,void 0!==d.pNode[e]&&(c.propertyName=e),("boolean"==typeof d.pNode[e]||"value"===e)&&(c.useProperty=!0))}}(d),Mb=function(a,b,c,d){var e,f,g,h,i,j,k,l,m,n,o,p,q,r;return e=function(){var a,b,c,d=this.pNode;return this.fragment?(a=f(this))?(this.interpolator=a,this.keypath=a.keypath||a.descriptor.r,(b=i(this))?(d._ractive.binding=this.element.binding=b,this.twoway=!0,c=this.root._twowayBindings[this.keypath]||(this.root._twowayBindings[this.keypath]=[]),c[c.length]=b,!0):!1):!1:!1},g=function(){this._ractive.binding.update()},h=function(){var a=this._ractive.root.get(this._ractive.binding.keypath);this.value=void 0==a?"":a},f=function(c){var d,e;return 1!==c.fragment.items.length?null:(d=c.fragment.items[0],d.type!==a.INTERPOLATOR?null:d.keypath||d.ref?d.keypath&&"${"===d.keypath.substr(0,2)?(e="You cannot set up two-way binding against an expression "+d.keypath,c.root.debug&&b(e),null):d:null)},i=function(a){var c=a.pNode;if("SELECT"===c.tagName)return c.multiple?new k(a,c):new l(a,c);if("checkbox"===c.type||"radio"===c.type){if("name"===a.propertyName){if("checkbox"===c.type)return new n(a,c);if("radio"===c.type)return new m(a,c)}return"checked"===a.propertyName?new o(a,c):null}return"value"!==a.lcName&&b("This is... odd"),"file"===c.type?new p(a,c):c.getAttribute("contenteditable")?new q(a,c):new r(a,c)},k=function(a,b){var c;j(this,a,b),b.addEventListener("change",g,!1),c=this.root.get(this.keypath),void 0===c&&this.update()},k.prototype={value:function(){var a,b,c,d;for(a=[],b=this.node.options,d=b.length,c=0;d>c;c+=1)b[c].selected&&(a[a.length]=b[c]._ractive.value);return a},update:function(){var a,b,d;return a=this.attr,b=a.value,d=this.value(),void 0!==b&&c(d,b)||(a.receiving=!0,a.value=d,this.root.set(this.keypath,d),a.receiving=!1),this},deferUpdate:function(){this.deferred!==!0&&(this.root._deferred.attrs.push(this),this.deferred=!0)},teardown:function(){this.node.removeEventListener("change",g,!1)}},l=function(a,b){var c;j(this,a,b),b.addEventListener("change",g,!1),c=this.root.get(this.keypath),void 0===c&&this.update()},l.prototype={value:function(){var a,b,c;for(a=this.node.options,c=a.length,b=0;c>b;b+=1)if(a[b].selected)return a[b]._ractive.value},update:function(){var a=this.value();return this.attr.receiving=!0,this.attr.value=a,this.root.set(this.keypath,a),this.attr.receiving=!1,this},deferUpdate:function(){this.deferred!==!0&&(this.root._deferred.attrs.push(this),this.deferred=!0)},teardown:function(){this.node.removeEventListener("change",g,!1)}},m=function(a,b){var c;this.radioName=!0,j(this,a,b),b.name="{{"+a.keypath+"}}",b.addEventListener("change",g,!1),b.attachEvent&&b.addEventListener("click",g,!1),c=this.root.get(this.keypath),void 0!==c?b.checked=c==b._ractive.value:this.root._deferred.radios.push(this)},m.prototype={value:function(){return this.node._ractive?this.node._ractive.value:this.node.value},update:function(){var a=this.node;a.checked&&(this.attr.receiving=!0,this.root.set(this.keypath,this.value()),this.attr.receiving=!1)},teardown:function(){this.node.removeEventListener("change",g,!1),this.node.removeEventListener("click",g,!1)}},n=function(a,b){var c,d;this.checkboxName=!0,j(this,a,b),b.name="{{"+this.keypath+"}}",b.addEventListener("change",g,!1),b.attachEvent&&b.addEventListener("click",g,!1),c=this.root.get(this.keypath),void 0!==c?(d=-1!==c.indexOf(b._ractive.value),b.checked=d):-1===this.root._deferred.checkboxes.indexOf(this.keypath)&&this.root._deferred.checkboxes.push(this.keypath)},n.prototype={changed:function(){return this.node.checked!==!!this.checked},update:function(){this.checked=this.node.checked,this.attr.receiving=!0,this.root.set(this.keypath,d(this.root,this.keypath)),this.attr.receiving=!1},teardown:function(){this.node.removeEventListener("change",g,!1),this.node.removeEventListener("click",g,!1)}},o=function(a,b){j(this,a,b),b.addEventListener("change",g,!1),b.attachEvent&&b.addEventListener("click",g,!1)},o.prototype={value:function(){return this.node.checked},update:function(){this.attr.receiving=!0,this.root.set(this.keypath,this.value()),this.attr.receiving=!1},teardown:function(){this.node.removeEventListener("change",g,!1),this.node.removeEventListener("click",g,!1)}},p=function(a,b){j(this,a,b),b.addEventListener("change",g,!1)},p.prototype={value:function(){return this.attr.pNode.files},update:function(){this.attr.root.set(this.attr.keypath,this.value())},teardown:function(){this.node.removeEventListener("change",g,!1)}},q=function(a,b){j(this,a,b),b.addEventListener("change",g,!1),this.root.lazy||(b.addEventListener("input",g,!1),b.attachEvent&&b.addEventListener("keyup",g,!1))},q.prototype={update:function(){this.attr.receiving=!0,this.root.set(this.keypath,this.node.innerHTML),this.attr.receiving=!1},teardown:function(){this.node.removeEventListener("change",g,!1),this.node.removeEventListener("input",g,!1),this.node.removeEventListener("keyup",g,!1)}},r=function(a,b){j(this,a,b),b.addEventListener("change",g,!1),this.root.lazy||(b.addEventListener("input",g,!1),b.attachEvent&&b.addEventListener("keyup",g,!1)),this.node.addEventListener("blur",h,!1)},r.prototype={value:function(){var a=this.attr.pNode.value;return+a+""===a&&-1===a.indexOf("e")&&(a=+a),a},update:function(){var a=this.attr,b=this.value();a.receiving=!0,a.root.set(a.keypath,b),a.receiving=!1},teardown:function(){this.node.removeEventListener("change",g,!1),this.node.removeEventListener("input",g,!1),this.node.removeEventListener("keyup",g,!1),this.node.removeEventListener("blur",h,!1)}},j=function(a,b,c){a.attr=b,a.node=c,a.root=b.root,a.keypath=b.keypath},e}(k,I,E,n),Nb=function(a,b){var c,d,e,f,g,h,i,j,k,l,m,n;return c=function(){var a;if(!this.ready)return this;if(a=this.pNode,"SELECT"===a.tagName&&"value"===this.lcName)return this.update=e,this.deferredUpdate=f,this.update();if(this.isFileInputValue)return this.update=d,this;if(this.twoway&&"name"===this.lcName){if("radio"===a.type)return this.update=i,this.update();if("checkbox"===a.type)return this.update=j,this.update()}return"style"===this.lcName&&a.style.setAttribute?(this.update=k,this.update()):"class"!==this.lcName||a.namespaceURI&&a.namespaceURI!==b.html?a.getAttribute("contenteditable")&&"value"===this.lcName?(this.update=m,this.update()):(this.update=n,this.update()):(this.update=l,this.update())},d=function(){return this},f=function(){this.deferredUpdate=this.pNode.multiple?h:g,this.deferredUpdate()},e=function(){return this.root._deferred.selectValues.push(this),this},g=function(){var a,b,c,d=this.fragment.getValue();for(this.value=this.pNode._ractive.value=d,a=this.pNode.options,c=a.length;c--;)if(b=a[c],b._ractive.value==d)return b.selected=!0,this;return this},h=function(){var b,c,d=this.fragment.getValue();for(a(d)||(d=[d]),b=this.pNode.options,c=b.length;c--;)b[c].selected=-1!==d.indexOf(b[c]._ractive.value);return this.value=d,this},i=function(){var a,b;return a=this.pNode,b=this.fragment.getValue(),a.checked=b==a._ractive.value,this},j=function(){var b,c;return b=this.pNode,c=this.fragment.getValue(),a(c)?(b.checked=-1!==c.indexOf(b._ractive.value),this):(b.checked=c==b._ractive.value,this)},k=function(){var a,b;return a=this.pNode,b=this.fragment.getValue(),void 0===b&&(b=""),b!==this.value&&(a.style.setAttribute("cssText",b),this.value=b),this},l=function(){var a,b;return a=this.pNode,b=this.fragment.getValue(),void 0===b&&(b=""),b!==this.value&&(a.className=b,this.value=b),this},m=function(){var a,b;return a=this.pNode,b=this.fragment.getValue(),void 0===b&&(b=""),b!==this.value&&(this.receiving||(a.innerHTML=b),this.value=b),this},n=function(){var a,b;if(a=this.pNode,b=this.fragment.getValue(),this.isValueAttribute&&(a._ractive.value=b),void 0===b&&(b=""),b!==this.value){if(this.useProperty)return this.receiving||(a[this.propertyName]=b),this.value=b,this;if(this.namespace)return a.setAttributeNS(this.namespace,this.name,b),this.value=b,this;"id"===this.lcName&&(void 0!==this.value&&(this.root.nodes[this.value]=void 0),this.root.nodes[b]=a),a.setAttribute(this.name,b),this.value=b}return this},c}(l,d),Ob=function(){return function(a){var b;return b=this.str.substr(this.pos,a.length),b===a?(this.pos+=a.length,a):null}}(),Pb=function(){var a=/^\s+/;return function(){var b=a.exec(this.remaining());return b?(this.pos+=b[0].length,b[0]):null}}(),Qb=function(){return function(a){return function(b){var c=a.exec(b.str.substring(b.pos));return c?(b.pos+=c[0].length,c[1]||c[0]):null}}}(),Rb=function(){function a(a){var b;return a.getStringMatch("\\")?(b=a.str.charAt(a.pos),a.pos+=1,b):null}return function(b){var c,d="";for(c=a(b);c;)d+=c,c=a(b);return d||null}}(),Sb=function(a,b){var c=a(/^[^\\"]+/),d=a(/^[^\\']+/);return function e(a,f){var g,h,i,j,k,l;if(g=a.pos,h="",l=f?d:c,i=b(a),i&&(h+=i),j=l(a),j&&(h+=j),!h)return"";for(k=e(a,f);""!==k;)h+=k;return h}}(Qb,Rb),Tb=function(a,b){return function(c){var d,e;return d=c.pos,c.getStringMatch('"')?(e=b(c,!1),c.getStringMatch('"')?{t:a.STRING_LITERAL,v:e}:(c.pos=d,null)):c.getStringMatch("'")?(e=b(c,!0),c.getStringMatch("'")?{t:a.STRING_LITERAL,v:e}:(c.pos=d,null)):null}}(k,Sb),Ub=function(a,b){var c=b(/^(?:[+-]?)(?:(?:(?:0|[1-9]\d*)?\.\d+)|(?:(?:0|[1-9]\d*)\.)|(?:0|[1-9]\d*))(?:[eE][+-]?\d+)?/);return function(b){var d;return(d=c(b))?{t:a.NUMBER_LITERAL,v:d}:null}}(k,Qb),Vb=function(a){return a(/^[a-zA-Z_$][a-zA-Z_$0-9]*/)}(Qb),Wb=function(a,b,c){var d=/^[a-zA-Z_$][a-zA-Z_$0-9]*$/;return function(e){var f;return(f=a(e))?d.test(f.v)?f.v:'"'+f.v.replace(/"/g,'\\"')+'"':(f=b(e))?f.v:(f=c(e))?f:void 0}}(Tb,Ub,Vb),Xb=function(a,b,c,d){function e(a){var b,c,e;return a.allowWhitespace(),(b=d(a))?(e={key:b},a.allowWhitespace(),a.getStringMatch(":")?(a.allowWhitespace(),(c=a.getToken())?(e.value=c.v,e):null):null):null}var f,g,h,i,j,k;return g={"true":!0,"false":!1,undefined:void 0,"null":null},h=new RegExp("^(?:"+Object.keys(g).join("|")+")"),i=/^(?:[+-]?)(?:(?:(?:0|[1-9]\d*)?\.\d+)|(?:(?:0|[1-9]\d*)\.)|(?:0|[1-9]\d*))(?:[eE][+-]?\d+)?/,j=/\$\{([^\}]+)\}/g,k=/^\$\{([^\}]+)\}/,f=function(a,b){this.str=a,this.values=b,this.pos=0,this.result=this.getToken()},f.prototype={remaining:function(){return this.str.substring(this.pos)},getStringMatch:a,getToken:function(){return this.allowWhitespace(),this.getPlaceholder()||this.getSpecial()||this.getNumber()||this.getString()||this.getObject()||this.getArray()},getPlaceholder:function(){var a;return this.values?(a=k.exec(this.remaining()))&&this.values.hasOwnProperty(a[1])?(this.pos+=a[0].length,{v:this.values[a[1]]}):void 0:null},getSpecial:function(){var a;return(a=h.exec(this.remaining()))?(this.pos+=a[0].length,{v:g[a[0]]}):void 0},getNumber:function(){var a;return(a=i.exec(this.remaining()))?(this.pos+=a[0].length,{v:+a[0]}):void 0},getString:function(){var a,b=c(this);return b&&(a=this.values)?{v:b.v.replace(j,function(b,c){return a[c]||c})}:b},getObject:function(){var a,b;if(!this.getStringMatch("{"))return null;for(a={};b=e(this);){if(a[b.key]=b.value,this.allowWhitespace(),this.getStringMatch("}"))return{v:a};if(!this.getStringMatch(","))return null}return null},getArray:function(){var a,b;if(!this.getStringMatch("["))return null;for(a=[];b=this.getToken();){if(a.push(b.v),this.getStringMatch("]"))return{v:a};if(!this.getStringMatch(","))return null}return null},allowWhitespace:b},function(a,b){var c=new f(a,b);return c.result?{value:c.result.v,remaining:c.remaining()}:null}}(Ob,Pb,Tb,Wb),Yb=function(a,b,c,d,e){function f(a){return"string"==typeof a?a:JSON.stringify(a)}var g=function(b){this.type=a.INTERPOLATOR,c(this,b)};return g.prototype={update:d,resolve:e,render:function(a){this.value=a,this.parentFragment.bubble()},teardown:function(){b(this)},toString:function(){return void 0==this.value?"":f(this.value)}},g}(k,nb,wb,yb,xb),Zb=function(a,b,c,d,e,f,g){var h,i;return g.push(function(){i=g.StringFragment}),h=function(c){this.type=a.SECTION,this.fragments=[],this.length=0,b(this,c)},h.prototype={update:c,resolve:d,teardown:function(){this.teardownFragments(),f(this)},teardownFragments:function(){for(;this.fragments.length;)this.fragments.shift().teardown();this.length=0},bubble:function(){this.value=this.fragments.join(""),this.parentFragment.bubble()},render:function(a){var b;(b=this.root._wrapped[this.keypath])&&(a=b.get()),e(this,a),this.parentFragment.bubble()},createFragment:function(a){return new i(a)},toString:function(){return this.fragments.join("")}},h}(k,wb,yb,xb,Ab,nb,Eb),$b=function(a){var b=function(b){this.type=a.TEXT,this.text=b};return b.prototype={toString:function(){return this.text},teardown:function(){}},b}(k),_b=function(a,b){return function(){var c,d,e,f,g,h,i;if(!this.argsList||this.dirty){if(c={},d=0,f=this.root._guid,i=function(a){return a.map(function(a){var b,e,g;return a.text?a.text:a.fragments?a.fragments.map(function(a){return i(a.items)}).join(""):(b=f+"-"+d++,g=(e=a.root._wrapped[a.keypath])?e.value:a.value,c[b]=g,"${"+b+"}")}).join("")},e=i(this.items),h=b("["+e+"]",c))this.argsList=h.value;else{if(g="Could not parse directive arguments ("+this.toString()+"). If you think this is a bug, please file an issue at http://github.com/RactiveJS/Ractive/issues",this.root.debug)throw new Error(g);a(g),this.argsList=[e]}this.dirty=!1}return this.argsList}}(I,Xb),ac=function(a,b,c,d,e,f,g,h){var i=function(a){c(this,a)};return i.prototype={createItem:function(b){if("string"==typeof b.descriptor)return new f(b.descriptor);switch(b.descriptor.t){case a.INTERPOLATOR:return new d(b);case a.TRIPLE:return new d(b);case a.SECTION:return new e(b);default:throw"Something went wrong in a rather interesting way"}},bubble:function(){this.dirty=!0,this.owner.bubble()},teardown:function(){var a,b;for(a=this.items.length,b=0;a>b;b+=1)this.items[b].teardown()},getValue:function(){var b;return 1===this.items.length&&this.items[0].type===a.INTERPOLATOR&&(b=this.items[0].value,void 0!==b)?b:this.toString()},isSimple:function(){var b,c,d;if(void 0!==this.simple)return this.simple;for(b=this.items.length;b--;)if(c=this.items[b],c.type!==a.TEXT){if(c.type!==a.INTERPOLATOR)return this.simple=!1;if(d)return!1;d=!0}return this.simple=!0},toString:function(){return this.items.join("")},toJSON:function(){var a,c=this.getValue();return"string"==typeof c&&(a=b(c),c=a?a.value:c),c},toArgsList:g},h.StringFragment=i,i}(k,Xb,kb,Yb,Zb,$b,_b,Eb),bc=function(a,b,c,d,e,f,g){var h=function(e){return this.type=a.ATTRIBUTE,this.element=e.element,b(this,e.name),null===e.value||"string"==typeof e.value?(c(this,e),void 0):(this.root=e.root,this.pNode=e.pNode,this.parentFragment=this.element.parentFragment,this.fragment=new g({descriptor:e.value,root:this.root,owner:this,contextStack:e.contextStack}),this.pNode&&("value"===this.name&&(this.isValueAttribute=!0,"INPUT"===this.pNode.tagName&&"file"===this.pNode.type&&(this.isFileInputValue=!0)),d(this,e),this.selfUpdating=this.fragment.isSimple(),this.ready=!0),void 0)};return h.prototype={bind:e,update:f,updateBindings:function(){this.keypath=this.interpolator.keypath||this.interpolator.ref,"name"===this.propertyName&&(this.pNode.name="{{"+this.keypath+"}}")},teardown:function(){var a;if(this.boundEvents)for(a=this.boundEvents.length;a--;)this.pNode.removeEventListener(this.boundEvents[a],this.updateModel,!1);this.fragment&&this.fragment.teardown()},bubble:function(){this.selfUpdating?this.update():!this.deferred&&this.ready&&(this.root._deferred.attrs.push(this),this.deferred=!0)},toString:function(){var a;return null===this.value?this.name:this.fragment?(a=this.fragment.toString(),this.name+"="+JSON.stringify(a)):this.name+"="+JSON.stringify(this.value)}},h}(k,Jb,Kb,Lb,Mb,Nb,ac),cc=function(a){return function(b,c){var d,e,f;b.attributes=[];for(d in c)c.hasOwnProperty(d)&&(e=c[d],f=new a({element:b,name:d,value:e,root:b.root,pNode:b.node,contextStack:b.parentFragment.contextStack}),b.attributes[b.attributes.length]=b.attributes[d]=f,"name"!==d&&f.update());return b.attributes}}(bc),dc=function(a,b,c,d){var e,f,g;return d.push(function(){e=d.DomFragment}),f=function(){var a=this.node,b=this.fragment.toString();a.styleSheet&&(a.styleSheet.cssText=b),a.innerHTML=b},g=function(){this.node.type&&"text/javascript"!==this.node.type||a("Script tag was updated. This does not cause the code to be re-evaluated!"),this.node.innerHTML=this.fragment.toString()},function(a,d,h,i){var j,k,l,m,n;if("script"===a.lcName||"style"===a.lcName)return a.fragment=new c({descriptor:h.f,root:a.root,contextStack:a.parentFragment.contextStack,owner:a}),i&&("script"===a.lcName?(a.bubble=g,a.node.innerHTML=a.fragment.toString()):(a.bubble=f,a.bubble())),void 0;if("string"!=typeof h.f||d&&d.namespaceURI&&d.namespaceURI!==b.html)a.fragment=new e({descriptor:h.f,root:a.root,pNode:d,contextStack:a.parentFragment.contextStack,owner:a}),i&&d.appendChild(a.fragment.docFrag);else if(a.html=h.f,i)for(d.innerHTML=a.html,j=a.root._liveQueries,k=j.length;k--;)if(l=j[k],(m=d.querySelectorAll(l))&&(n=m.length))for((a.liveQueries||(a.liveQueries=[])).push(l),a.liveQueries[l]=[];n--;)a.liveQueries[l][n]=m[n]}}(I,d,ac,Eb),ec=function(a,b){var c=function(c,d,e,f){var g,h,i;if(this.root=d,this.node=e.node,g=c.n||c,"string"!=typeof g&&(h=new b({descriptor:g,root:this.root,owner:e,contextStack:f}),g=h.toString(),h.teardown()),c.a?this.params=c.a:c.d&&(h=new b({descriptor:c.d,root:this.root,owner:e,contextStack:f}),this.params=h.toArgsList(),h.teardown()),this.fn=d.decorators[g],!this.fn){if(i='Missing "'+g+'" decorator. You may need to download a plugin via https://github.com/RactiveJS/Ractive/wiki/Plugins#decorators',d.debug)throw new Error(i);a(i)}};return c.prototype={init:function(){var a,b;if(this.params?(b=[this.node].concat(this.params),a=this.fn.apply(this.root,b)):a=this.fn.call(this.root,this.node),!a||!a.teardown)throw new Error("Decorator definition must return an object with a teardown method");this.teardown=a.teardown}},c}(I,ac),fc=function(a){return function(b,c,d,e){d.decorator=new a(b,c,d,e),d.decorator.fn&&c._deferred.decorators.push(d.decorator)}}(ec),gc=function(a,b){var c,d,e,f,g,h,i,j,k;return c=function(a,b,c,e,f){var g,h;g=a.node._ractive.events,h=g[b]||(g[b]=new d(a,b,e,f)),h.add(c)},d=function(b,c,d){var e;this.element=b,this.root=b.root,this.node=b.node,this.name=c,this.contextStack=d,this.proxies=[],(e=this.root.events[c])?this.custom=e(this.node,k(c)):("on"+c in this.node||a('Missing "'+this.name+'" event. You may need to download a plugin via https://github.com/RactiveJS/Ractive/wiki/Plugins#events'),this.node.addEventListener(c,j,!1))},d.prototype={add:function(a){this.proxies[this.proxies.length]=new e(this.element,this.root,a,this.contextStack)},teardown:function(){var a;for(this.custom?this.custom.teardown():this.node.removeEventListener(this.name,j,!1),a=this.proxies.length;a--;)this.proxies[a].teardown()},fire:function(a){for(var b=this.proxies.length;b--;)this.proxies[b].fire(a)}},e=function(a,c,d,e){var i;return this.root=c,i=d.n||d,this.n="string"==typeof i?i:new b({descriptor:d.n,root:this.root,owner:a,contextStack:e}),d.a?(this.a=d.a,this.fire=g,void 0):d.d?(this.d=new b({descriptor:d.d,root:this.root,owner:a,contextStack:e}),this.fire=h,void 0):(this.fire=f,void 0) -},e.prototype={teardown:function(){this.n.teardown&&this.n.teardown(),this.d&&this.d.teardown()},bubble:function(){}},f=function(a){this.root.fire(this.n.toString(),a)},g=function(a){this.root.fire.apply(this.root,[this.n.toString(),a].concat(this.a))},h=function(a){var b=this.d.toArgsList();"string"==typeof b&&(b=b.substr(1,b.length-2)),this.root.fire.apply(this.root,[this.n.toString(),a].concat(b))},j=function(a){var b=this._ractive;b.events[a.type].fire({node:this,original:a,index:b.index,keypath:b.keypath,context:b.root.get(b.keypath)})},i={},k=function(a){return i[a]?i[a]:i[a]=function(b){var c=b.node._ractive;b.index=c.index,b.keypath=c.keypath,b.context=c.root.get(c.keypath),c.events[a].fire(b)}},c}(I,ac),hc=function(a){return function(b,c){var d,e,f;for(e in c)if(c.hasOwnProperty(e))for(f=e.split("-"),d=f.length;d--;)a(b,f[d],c[e],b.parentFragment.contextStack)}}(gc),ic=function(){return function(a){var b,c,d,e,f;for(b=a.root,c=b._liveQueries,d=c.length;d--;)e=c[d],f=c[e],f._test(a)&&((a.liveQueries||(a.liveQueries=[])).push(e),a.liveQueries[e]=[a.node])}}(),jc=function(){return function(a){return a.replace(/-([a-zA-Z])/g,function(a,b){return b.toUpperCase()})}}(),kc=function(){return function(a,b){var c;for(c in b)b.hasOwnProperty(c)&&!a.hasOwnProperty(c)&&(a[c]=b[c]);return a}}(),lc=function(a,b,c,d,e,f,g,h){function i(a){var b,c,d;if(!q[a])if(void 0!==m[a])q[a]=a;else for(d=a.charAt(0).toUpperCase()+a.substring(1),b=n.length;b--;)if(c=n[b],void 0!==m[c+d]){q[a]=c+d;break}return q[a]}function j(a){return a.replace(p,"")}function k(a){var b;return o.test(a)&&(a="-"+a),b=a.replace(/[A-Z]/g,function(a){return"-"+a.toLowerCase()})}var l,m,n,o,p,q,r,s,t,u,v,w;if(a)return m=b("div").style,function(){void 0!==m.transition?(s="transition",w="transitionend",r=!0):void 0!==m.webkitTransition?(s="webkitTransition",w="webkitTransitionEnd",r=!0):r=!1}(),s&&(t=s+"Duration",u=s+"Property",v=s+"TimingFunction"),l=function(a,b,d,e,f){var g,i,j,k=this;if(this.root=b,this.node=d.node,this.isIntro=f,this.originalStyle=this.node.getAttribute("style"),this.complete=function(a){!a&&k.isIntro&&k.resetStyle(),k._manager.pop(k.node),k.node._ractive.transition=null},g=a.n||a,"string"!=typeof g&&(i=new h({descriptor:g,root:this.root,owner:d,contextStack:e}),g=i.toString(),i.teardown()),this.name=g,a.a?this.params=a.a:a.d&&(i=new h({descriptor:a.d,root:this.root,owner:d,contextStack:e}),this.params=i.toArgsList(),i.teardown()),this._fn=b.transitions[g],!this._fn){if(j='Missing "'+g+'" transition. You may need to download a plugin via https://github.com/RactiveJS/Ractive/wiki/Plugins#transitions',b.debug)throw new Error(j);return c(j),void 0}},l.prototype={init:function(){if(this._inited)throw new Error("Cannot initialize a transition more than once");this._inited=!0,this._fn.apply(this.root,[this].concat(this.params))},getStyle:function(a){var b,c,d,f,g;if(b=window.getComputedStyle(this.node),"string"==typeof a)return g=b[i(a)],"0px"===g&&(g=0),g;if(!e(a))throw new Error("Transition#getStyle must be passed a string, or an array of strings representing CSS properties");for(c={},d=a.length;d--;)f=a[d],g=b[i(f)],"0px"===g&&(g=0),c[f]=g;return c},setStyle:function(a,b){var c;if("string"==typeof a)this.node.style[i(a)]=b;else for(c in a)a.hasOwnProperty(c)&&(this.node.style[i(c)]=a[c]);return this},animateStyle:function(a,b,d,e){var g,h,l,m,n,o,p,q,r,s=this;for("string"==typeof a?(n={},n[a]=b):(n=a,e=d,d=b),d||(c('The "'+s.name+'" transition does not supply an options object to `t.animateStyle()`. This will break in a future version of Ractive. For more info see https://github.com/RactiveJS/Ractive/issues/340'),d=s,e=s.complete),d.duration||(s.setStyle(n),e&&e()),g=Object.keys(n),h=[],l=window.getComputedStyle(s.node),o={},q=g.length;q--;)r=g[q],m=l[i(r)],"0px"===m&&(m=0),m!=n[r]&&(h[h.length]=r,s.node.style[i(r)]=m);return h.length?(setTimeout(function(){s.node.style[u]=g.map(i).map(k).join(","),s.node.style[v]=k(d.easing||"linear"),s.node.style[t]=d.duration/1e3+"s",p=function(a){var b;b=h.indexOf(f(j(a.propertyName))),-1!==b&&h.splice(b,1),h.length||(s.root.fire(s.name+":end"),s.node.removeEventListener(w,p,!1),e&&e())},s.node.addEventListener(w,p,!1),setTimeout(function(){for(var a=h.length;a--;)r=h[a],s.node.style[i(r)]=n[r]},0)},d.delay||0),void 0):(e&&e(),void 0)},resetStyle:function(){this.originalStyle?this.node.setAttribute("style",this.originalStyle):(this.node.getAttribute("style"),this.node.removeAttribute("style"))},processParams:function(a,b){return"number"==typeof a?a={duration:a}:"string"==typeof a?a="slow"===a?{duration:600}:"fast"===a?{duration:200}:{duration:400}:a||(a={}),g(a,b)}},n=["o","ms","moz","webkit"],o=new RegExp("^(?:"+n.join("|")+")([A-Z])"),p=new RegExp("^-(?:"+n.join("|")+")-"),q={},l}(f,e,I,J,l,jc,kc,ac),mc=function(a,b){return function(a,c,d,e,f){var g,h,i;!c.transitionsEnabled||c._parent&&!c._parent.transitionsEnabled||(g=new b(a,c,d,e,f),g._fn&&(h=g.node,g._manager=c._transitionManager,(i=h._ractive.transition)&&i.complete(),h._ractive.transition=g,g._manager.push(h),f?c._deferred.transitions.push(g):g.init()))}}(I,lc),nc=function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){return function(e,p,q){var r,s,t,u,v,w,x,y,z,A,B,C,D;if(e.type=a.ELEMENT,r=e.parentFragment=p.parentFragment,s=r.pNode,t=r.contextStack,u=e.descriptor=p.descriptor,e.root=B=r.root,e.index=p.index,e.lcName=u.e.toLowerCase(),e.eventListeners=[],e.customEventListeners=[],s&&(v=e.namespace=h(u,s),w=v!==b.html?o(u.e):u.e,e.node=g(w,v),d(e.node,"_ractive",{value:{proxy:e,keypath:t.length?t[t.length-1]:"",index:r.indexRefs,events:c(null),root:B}})),x=i(e,u.a),u.f){if(e.node&&e.node.getAttribute("contenteditable")&&e.node.innerHTML){if(D="A pre-populated contenteditable element should not have children",B.debug)throw new Error(D);f(D)}j(e,e.node,u,q)}q&&u.v&&l(e,u.v),q&&(B.twoway&&(e.bind(),e.node.getAttribute("contenteditable")&&e.node._ractive.binding&&e.node._ractive.binding.update()),x.name&&!x.name.twoway&&x.name.update(),"IMG"===e.node.tagName&&((y=e.attributes.width)||(z=e.attributes.height))&&e.node.addEventListener("load",A=function(){y&&(e.node.width=y.value),z&&(e.node.height=z.value),e.node.removeEventListener("load",A,!1)},!1),q.appendChild(e.node),u.o&&k(u.o,B,e,t),u.t1&&n(u.t1,B,e,t,!0),"OPTION"===e.node.tagName&&("SELECT"===s.tagName&&(C=s._ractive.binding)&&C.deferUpdate(),e.node._ractive.value==s._ractive.value&&(e.node.selected=!0)),e.node.autofocus&&(B._deferred.focusable=e.node)),m(e)}}(k,d,c,g,Z,I,e,Hb,cc,dc,fc,hc,ic,mc,Ib),oc=function(a){return function(b){var c,d,e,f,g,h,i,j,k;for(this.fragment&&this.fragment.teardown(!1);this.attributes.length;)this.attributes.pop().teardown();if(this.node){for(c in this.node._ractive.events)this.node._ractive.events[c].teardown();(d=this.node._ractive.binding)&&(d.teardown(),e=this.root._twowayBindings[d.attr.keypath],e.splice(e.indexOf(d),1))}if(this.decorator&&this.decorator.teardown(),this.descriptor.t2&&a(this.descriptor.t2,this.root,this,this.parentFragment.contextStack,!1),b&&this.root._transitionManager.detachWhenReady(this),g=this.liveQueries)for(f=g.length;f--;)if(h=g[f],j=this.liveQueries[h])for(k=j.length,i=this.root._liveQueries[h];k--;)i._remove(j[k])}}(mc),pc=function(){return"area base br col command doctype embed hr img input keygen link meta param source track wbr".split(" ")}(),qc=function(a){return function(){var b,c,d;for(b="<"+(this.descriptor.y?"!doctype":this.descriptor.e),d=this.attributes.length,c=0;d>c;c+=1)b+=" "+this.attributes[c].toString();return b+=">",this.html?b+=this.html:this.fragment&&(b+=this.fragment.toString()),-1===a.indexOf(this.descriptor.e)&&(b+=""),b}}(pc),rc=function(a){return function(b){var c;return a(this.node,b)?this.node:this.html&&(c=this.node.querySelector(b))?c:this.fragment&&this.fragment.find?this.fragment.find(b):void 0}}(Z),sc=function(){return function(a,b){var c,d,e,f,g;if(b._test(this,!0)&&b.live&&((this.liveQueries||(this.liveQueries=[])).push(a),this.liveQueries[a]=[this.node]),this.html&&(c=this.node.querySelectorAll(a))&&(e=c.length))for(b.live&&(this.liveQueries[a]||((this.liveQueries||(this.liveQueries=[])).push(a),this.liveQueries[a]=[]),g=this.liveQueries[a]),d=0;e>d;d+=1)f=c[d],b.push(f),b.live&&g.push(f);this.fragment&&this.fragment.findAll(a,b)}}(),tc=function(){return function(a){return this.fragment?this.fragment.findComponent(a):void 0}}(),uc=function(){return function(a,b){this.fragment&&this.fragment.findAllComponents(a,b)}}(),vc=function(){return function(){var a=this.attributes;if(this.node&&(this.binding&&(this.binding.teardown(),this.binding=null),!(this.node.getAttribute("contenteditable")&&a.value&&a.value.bind())))switch(this.descriptor.e){case"select":case"textarea":return a.value&&a.value.bind(),void 0;case"input":if("radio"===this.node.type||"checkbox"===this.node.type){if(a.name&&a.name.bind())return;if(a.checked&&a.checked.bind())return}if(a.value&&a.value.bind())return}}}(),wc=function(a,b,c,d,e,f,g,h){var i=function(b,c){a(this,b,c)};return i.prototype={detach:function(){return this.node?(this.node.parentNode&&this.node.parentNode.removeChild(this.node),this.node):void 0},teardown:b,firstNode:function(){return this.node},findNextNode:function(){return null},bubble:function(){},toString:c,find:d,findAll:e,findComponent:f,findAllComponents:g,bind:h},i}(nc,oc,qc,rc,sc,tc,uc,vc),xc={missingParser:"Missing Ractive.parse - cannot parse template. Either preparse or use the version that includes the parser"},yc={},zc=function(a,b,c,d,e,f){var g,h,i,j;return g=function(d,g){var k,l,m;if(l=i(d,g))return l;if(b&&(k=document.getElementById(g),k&&"SCRIPT"===k.tagName)){if(!f)throw new Error(a.missingParser);h(f(k.innerHTML),g,e)}if(l=e[g],!l){if(m='Could not find descriptor for partial "'+g+'"',d.debug)throw new Error(m);return c(m),[]}return j(l)},i=function(b,c){var d;if(b.partials[c]){if("string"==typeof b.partials[c]){if(!f)throw new Error(a.missingParser);d=f(b.partials[c],b.parseOptions),h(d,c,b.partials)}return j(b.partials[c])}},h=function(a,b,c){var e;if(d(a)){c[b]=a.main;for(e in a.partials)a.partials.hasOwnProperty(e)&&(c[e]=a.partials[e])}else c[b]=a},j=function(a){return 1===a.length&&"string"==typeof a[0]?a[0]:a},g}(xc,f,I,w,yc,parse__parse),Ac=function(a,b,c){var d,e;return c.push(function(){e=c.DomFragment}),d=function(c,d){var f,g=this.parentFragment=c.parentFragment;if(this.type=a.PARTIAL,this.name=c.descriptor.r,this.index=c.index,!c.descriptor.r)throw new Error("Partials must have a static reference (no expressions). This may change in a future version of Ractive.");f=b(g.root,c.descriptor.r),this.fragment=new e({descriptor:f,root:g.root,pNode:g.pNode,contextStack:g.contextStack,owner:this}),d&&d.appendChild(this.fragment.docFrag)},d.prototype={firstNode:function(){return this.fragment.firstNode()},findNextNode:function(){return this.parentFragment.findNextNode(this)},detach:function(){return this.fragment.detach()},teardown:function(a){this.fragment.teardown(a)},toString:function(){return this.fragment.toString()},find:function(a){return this.fragment.find(a)},findAll:function(a,b){return this.fragment.findAll(a,b)},findComponent:function(a){return this.fragment.findComponent(a)},findAllComponents:function(a,b){return this.fragment.findAllComponents(a,b)}},d}(k,zc,Eb),Bc=function(a){var b=function(b,c,d){this.parentFragment=b.parentFragment,this.component=b,this.key=c,this.fragment=new a({descriptor:d,root:b.root,owner:this,contextStack:b.parentFragment.contextStack}),this.selfUpdating=this.fragment.isSimple(),this.value=this.fragment.getValue()};return b.prototype={bubble:function(){this.selfUpdating?this.update():!this.deferred&&this.ready&&(this.root._deferred.attrs.push(this),this.deferred=!0)},update:function(){var a=this.fragment.getValue();this.component.instance.set(this.key,a),this.value=a},teardown:function(){this.fragment.teardown()}},b}(ac),Cc=function(a,b,c,d){function e(e,f,g,h){var i,j,k,l,m;return k=e.root,l=e.parentFragment,"string"==typeof g?(j=b(g),j?j.value:g):null===g?!0:1===g.length&&g[0].t===a.INTERPOLATOR&&g[0].r?l.indexRefs&&void 0!==l.indexRefs[g[0].r]?l.indexRefs[g[0].r]:(m=c(k,g[0].r,l.contextStack)||g[0].r,h.push({childKeypath:f,parentKeypath:m}),k.get(m)):(i=new d(e,f,g),e.complexParameters.push(i),i.value)}return function(a,b,c){var d,f,g;d={},a.complexParameters=[];for(f in b)b.hasOwnProperty(f)&&(g=e(a,f,b[f],c),void 0!==g&&(d[f]=g));return d}}(k,Xb,y,Bc),Dc=function(){return function(a,b,c,d,e){var f,g,h,i;return g=a.parentFragment,i=a.root,h={content:e||[]},f=new b({el:g.pNode.cloneNode(!1),data:c,partials:h,_parent:i,adaptors:i.adaptors}),f.component=a,a.instance=f,f.insert(d),f.fragment.pNode=g.pNode,f}}(),Ec=function(){function a(a,c,d){var e,f,g,h,i,j,k;e=a.root,f=a.instance,i=a.observers,j=e.observe(c,function(a){g||e._wrapped[c]||(h=!0,f.set(d,a),h=!1)},b),i.push(j),f.twoway&&(j=f.observe(d,function(a){h||(g=!0,e.set(c,a),g=!1)},b),i.push(j),k=f.get(d),void 0!==k&&e.set(c,k))}var b={init:!1,debug:!0};return function(b,c){var d,e;for(b.observers=[],e=c.length;e--;)d=c[e],a(b,d.parentKeypath,d.childKeypath)}}(),Fc=function(a){function b(b,d,e,f){if("string"!=typeof f){if(d.debug)throw new Error(c);return a(c),void 0}b.on(e,function(){var a=Array.prototype.slice.call(arguments);a.unshift(f),d.fire.apply(d,a)})}var c="Components currently only support simple events - you cannot include arguments. Sorry!";return function(a,c){var d;for(d in c)c.hasOwnProperty(d)&&b(a.instance,a.root,d,c[d])}}(I),Gc=function(){return function(a){var b,c;for(b=a.root;b;)(c=b._liveComponentQueries[a.name])&&c.push(a.instance),b=b._parent}}(),Hc=function(a,b,c,d,e,f,g){return function(h,i,j){var k,l,m,n,o;if(k=h.parentFragment=i.parentFragment,l=k.root,h.root=l,h.type=a.COMPONENT,h.name=i.descriptor.e,h.index=i.index,h.observers=[],m=l.components[i.descriptor.e],!m)throw new Error('Component "'+i.descriptor.e+'" not found');o=[],n=c(h,i.descriptor.a,o),d(h,m,n,j,i.descriptor.f),e(h,o),f(h,i.descriptor.v),(i.descriptor.t1||i.descriptor.t2||i.descriptor.o)&&b('The "intro", "outro" and "decorator" directives have no effect on components'),g(h)}}(k,I,Cc,Dc,Ec,Fc,Gc),Ic=function(a){var b=function(b,c){a(this,b,c)};return b.prototype={firstNode:function(){return this.instance.fragment.firstNode()},findNextNode:function(){return this.parentFragment.findNextNode(this)},detach:function(){return this.instance.fragment.detach()},teardown:function(){for(var a;this.complexParameters.length;)this.complexParameters.pop().teardown();for(;this.observers.length;)this.observers.pop().cancel();(a=this.root._liveComponentQueries[this.name])&&a._remove(this),this.instance.teardown()},toString:function(){return this.instance.fragment.toString()},find:function(a){return this.instance.fragment.find(a)},findAll:function(a,b){return this.instance.fragment.findAll(a,b)},findComponent:function(a){return a&&a!==this.name?null:this.instance},findAllComponents:function(a,b){b._test(this,!0),this.instance.fragment&&this.instance.fragment.findAllComponents(a,b)}},b}(Hc),Jc=function(a){var b=function(b,c){this.type=a.COMMENT,this.descriptor=b.descriptor,c&&(this.node=document.createComment(b.descriptor.f),c.appendChild(this.node))};return b.prototype={detach:function(){return this.node.parentNode.removeChild(this.node),this.node},teardown:function(a){a&&this.detach()},firstNode:function(){return this.node},toString:function(){return""}},b}(k),Kc=function(a,b,c,d,e,f,g,h,i,j,k,l,m){var n=function(a){a.pNode&&(this.docFrag=document.createDocumentFragment()),"string"==typeof a.descriptor?(this.html=a.descriptor,this.docFrag&&(this.nodes=d(this.html,a.pNode.tagName,this.docFrag))):c(this,a)};return n.prototype={detach:function(){var a,b;if(this.nodes)for(b=this.nodes.length;b--;)this.docFrag.appendChild(this.nodes[b]);else if(this.items)for(a=this.items.length,b=0;a>b;b+=1)this.docFrag.appendChild(this.items[b].detach());return this.docFrag},createItem:function(b){if("string"==typeof b.descriptor)return new e(b,this.docFrag);switch(b.descriptor.t){case a.INTERPOLATOR:return new f(b,this.docFrag);case a.SECTION:return new g(b,this.docFrag);case a.TRIPLE:return new h(b,this.docFrag);case a.ELEMENT:return this.root.components[b.descriptor.e]?new k(b,this.docFrag):new i(b,this.docFrag);case a.PARTIAL:return new j(b,this.docFrag);case a.COMMENT:return new l(b,this.docFrag);default:throw new Error("Something very strange happened. Please file an issue at https://github.com/RactiveJS/Ractive/issues. Thanks!")}},teardown:function(a){var b;if(this.nodes&&a)for(;b=this.nodes.pop();)b.parentNode.removeChild(b);else if(this.items)for(;this.items.length;)this.items.pop().teardown(a);this.nodes=this.items=this.docFrag=null},firstNode:function(){return this.items&&this.items[0]?this.items[0].firstNode():this.nodes?this.nodes[0]||null:null},findNextNode:function(a){var b=a.index;return this.items[b+1]?this.items[b+1].firstNode():this.owner===this.root?this.owner.component?this.owner.component.findNextNode():null:this.owner.findNextNode(this)},toString:function(){var a,b,c,d;if(this.html)return this.html;if(a="",!this.items)return a;for(c=this.items.length,b=0;c>b;b+=1)d=this.items[b],a+=d.toString();return a},find:function(a){var c,d,e,f,g;if(this.nodes){for(d=this.nodes.length,c=0;d>c;c+=1)if(f=this.nodes[c],1===f.nodeType){if(b(f,a))return f;if(g=f.querySelector(a))return g}return null}if(this.items){for(d=this.items.length,c=0;d>c;c+=1)if(e=this.items[c],e.find&&(g=e.find(a)))return g;return null}},findAll:function(a,c){var d,e,f,g,h,i,j;if(this.nodes){for(e=this.nodes.length,d=0;e>d;d+=1)if(g=this.nodes[d],1===g.nodeType&&(b(g,a)&&c.push(g),h=g.querySelectorAll(a)))for(i=h.length,j=0;i>j;j+=1)c.push(h[j])}else if(this.items)for(e=this.items.length,d=0;e>d;d+=1)f=this.items[d],f.findAll&&f.findAll(a,c);return c},findComponent:function(a){var b,c,d,e;if(this.items){for(b=this.items.length,c=0;b>c;c+=1)if(d=this.items[c],d.findComponent&&(e=d.findComponent(a)))return e;return null}},findAllComponents:function(a,b){var c,d,e;if(this.items)for(d=this.items.length,c=0;d>c;c+=1)e=this.items[c],e.findAllComponents&&e.findAllComponents(a,b);return b}},m.DomFragment=n,n}(k,Z,kb,lb,mb,zb,Fb,Gb,wc,Ac,Ic,Jc,Eb),Lc=function(a,b,c,d,e){return function(a,f){var g;if(!this._initing)throw new Error("You cannot call ractive.render() directly!");this._transitionManager=g=b(this,f),this.fragment=new e({descriptor:this.template,root:this,owner:this,pNode:a}),c(this),a&&a.appendChild(this.fragment.docFrag),d(this),this._transitionManager=null,g.ready(),this.rendered=!0}}(jb,q,o,p,Kc),Mc=function(a){return function(){return a("renderHTML() has been deprecated and will be removed in a future version. Please use toHTML() instead"),this.toHTML()}}(I),Nc=function(){return function(){return this.fragment.toString()}}(),Oc=function(a,b){return function(c){var d,e,f;for(this.fire("teardown"),f=this._transitionManager,this._transitionManager=e=a(this,c),this.fragment.teardown(!0);this._animations[0];)this._animations[0].stop();for(d in this._cache)b(this,d);this._transitionManager=f,e.ready()}}(q,m),Pc=function(a){return function(b,c,d){var e;if("string"==typeof c&&a(d)){if(e=b.get(c),void 0===e&&(e=0),a(e))b.set(c,e+d);else if(b.debug)throw new Error("Cannot add to a non-numeric value")}else if(b.debug)throw new Error("Bad arguments")}}(J),Qc=function(a){return function(b,c){a(this,b,void 0===c?1:c)}}(Pc),Rc=function(a){return function(b,c){a(this,b,void 0===c?-1:-c)}}(Pc),Sc=function(){return function(a){var b;if("string"==typeof a)b=this.get(a),this.set(a,!b);else if(this.debug)throw new Error("Bad arguments")}}(),Tc=function(){return function(a,b){var c,d,e,f,g;return c={},e=0,d=function(a,d){var f,h,i;h=e,i=b.length;do{if(f=b.indexOf(a,h),-1===f)return g=!0,-1;h=f+1}while(c[f]&&i>h);return f===e&&(e+=1),f!==d&&(g=!0),c[f]=!0,f},f=a.map(d),f.unchanged=!g,f}}(),Uc=function(a){return function(b,c,d,e){var f,g;for(f=c.length;f--;)g=c[f],g.type===a.REFERENCE?g.update():g.keypath===b&&g.type===a.SECTION&&!g.inverted&&g.docFrag?d[d.length]=g:e[e.length]=g}}(k),Vc=function(a,b,c,d,e,f,g,h,i,j){function k(a){return JSON.stringify(a)}function l(a){return m[a]||(m[a]=function(b){return b[a]}),m[a]}var m={};return function(m,n,o){var p,q,r,s,t,u,v,w,x,y,z,A,B,C,D;if(p=this.get(m),!b(p)||!b(n))return this.set(m,n,o&&o.complete);if(t=p.length===n.length,o&&o.compare){if(o.compare===!0)s=k;else if("string"==typeof o.compare)s=l(o.compare);else{if("function"!=typeof o.compare)throw new Error("The `compare` option must be a function, or a string representing an identifying field (or `true` to use JSON.stringify)");s=o.compare}try{q=p.map(s),r=n.map(s)}catch(E){if(this.debug)throw E;a("Merge operation: comparison failed. Falling back to identity checking"),q=p,r=n}}else q=p,r=n;if(v=i(q,r),c(this,m),h(this,m,n),!v.unchanged||!t){for(B=this._transitionManager,this._transitionManager=A=f(this,o&&o.complete),w=[],x=[],u=0;u', + footer: '<%= outro %>' + } + }, + banner: { + files: [{ + expand: true, + cwd: 'tmp/', + src: '*.js', + dest: 'build/' + }], + options: { + process: true, + banner: '<%= banner %>' + } + } +}; diff --git a/grunt/config/copy.js b/grunt/config/copy.js new file mode 100644 index 0000000000..370e542a65 --- /dev/null +++ b/grunt/config/copy.js @@ -0,0 +1,14 @@ +module.exports = { + release: { + files: [{ + expand: true, + cwd: 'build/', + src: [ '**/*' ], + dest: 'release/<%= pkg.version %>/' + }] + }, + link: { + src: 'build/ractive.js', + dest: 'ractive.js' + } +}; diff --git a/grunt/config/jsbeautifier.js b/grunt/config/jsbeautifier.js new file mode 100644 index 0000000000..066a28ac8f --- /dev/null +++ b/grunt/config/jsbeautifier.js @@ -0,0 +1,10 @@ +module.exports = { + files: 'tmp/**/*.js', + options: { + js: { + indentWithTabs: true, + spaceBeforeConditional: true, + spaceInParen: true + } + } +}; diff --git a/grunt/config/jshint.js b/grunt/config/jshint.js new file mode 100644 index 0000000000..8cb0486e00 --- /dev/null +++ b/grunt/config/jshint.js @@ -0,0 +1,27 @@ +module.exports = { + files: [ 'src/**/*.js' ], + options: { + boss: true, + eqnull: true, + evil: true, + laxbreak: true, + proto: true, + smarttabs: true, + strict: true, + undef: true, + unused: true, + '-W018': true, + '-W041': false, + globals: { + clearInterval: true, + define: true, + document: true, + Element: true, + module: true, + require: true, + setInterval: true, + setTimeout: true, + window: true + } + } +}; diff --git a/grunt/config/nodeunit.js b/grunt/config/nodeunit.js new file mode 100644 index 0000000000..60528a64cd --- /dev/null +++ b/grunt/config/nodeunit.js @@ -0,0 +1,15 @@ +module.exports = function ( grunt ) { + + 'use strict'; + + var nodeunitConfig = {}; + + grunt.file.expand( 'test/node/*.js' ).forEach( function ( path ) { + var testName = /test\/node\/(.+)\.js/.exec( path )[1]; + + nodeunitConfig[ testName ] = path; + }); + + return nodeunitConfig; + +}; diff --git a/grunt/config/qunit.js b/grunt/config/qunit.js new file mode 100644 index 0000000000..e185010168 --- /dev/null +++ b/grunt/config/qunit.js @@ -0,0 +1,19 @@ +module.exports = function ( grunt ) { + + 'use strict'; + + var qunitConfig = {}; + + grunt.file.expand( 'test/tests/*.html' ).forEach( function ( path ) { + var testName = /test\/tests\/(.+)\.html/.exec( path )[1]; + + if ( testName === 'index' ) { + testName = 'all'; + } + + qunitConfig[ testName ] = path; + }); + + return qunitConfig; + +}; \ No newline at end of file diff --git a/grunt/config/requirejs.js b/grunt/config/requirejs.js new file mode 100644 index 0000000000..b1bf1c8e10 --- /dev/null +++ b/grunt/config/requirejs.js @@ -0,0 +1,45 @@ +module.exports = { + full: { + options: { + out: 'tmp/ractive.js', + paths: { + 'legacy': 'empty/legacy' + } + } + }, + legacy: { + options: { + out: 'tmp/ractive-legacy.js' + } + }, + runtime: { + options: { + out: 'tmp/ractive.runtime.js', + paths: { + 'parse/_parse': 'empty/parse', + 'legacy': 'empty/legacy' + } + } + }, + runtime_legacy: { + options: { + out: 'tmp/ractive-legacy.runtime.js', + paths: { + 'parse/_parse': 'empty/parse' + } + } + }, + options: { + baseUrl: 'src/', + name: 'Ractive', + optimize: 'none', + logLevel: 2, + onBuildWrite: function( name, path, contents ) { + var moduleNames = {}; + + return require( 'amdclean' ).clean({ + code: contents + }) + '\n'; + } + } +}; diff --git a/grunt/config/uglify.js b/grunt/config/uglify.js new file mode 100644 index 0000000000..9aa4a5335c --- /dev/null +++ b/grunt/config/uglify.js @@ -0,0 +1,6 @@ +module.exports = { + 'tmp/ractive.min.js': 'tmp/ractive.js', + 'tmp/ractive-legacy.min.js': 'tmp/ractive-legacy.js', + 'tmp/ractive.runtime.min.js': 'tmp/ractive.runtime.js', + 'tmp/ractive-legacy.runtime.min.js': 'tmp/ractive-legacy.runtime.js' +}; diff --git a/grunt/config/watch.js b/grunt/config/watch.js new file mode 100644 index 0000000000..09451932e9 --- /dev/null +++ b/grunt/config/watch.js @@ -0,0 +1,10 @@ +module.exports = { + js: { + files: [ 'src/**/*.js', 'wrapper/**/*.js' ], + tasks: [ 'clean:tmp', 'requirejs' ], + options: { + interrupt: true, + force: true + } + } +}; \ No newline at end of file diff --git a/grunt/tasks/build.js b/grunt/tasks/build.js new file mode 100644 index 0000000000..c068dbe95c --- /dev/null +++ b/grunt/tasks/build.js @@ -0,0 +1,14 @@ +module.exports = function ( grunt ) { + + 'use strict'; + + grunt.registerTask( 'build', [ + 'jshint', + 'clean:tmp', + 'requirejs', + 'concat:closure', + 'revision', + 'jsbeautifier' + ]); + +}; diff --git a/grunt/tasks/default.js b/grunt/tasks/default.js new file mode 100644 index 0000000000..30054a2faf --- /dev/null +++ b/grunt/tasks/default.js @@ -0,0 +1,12 @@ +module.exports = function ( grunt ) { + + 'use strict'; + + grunt.registerTask( 'default', [ + 'build', + 'test', + 'uglify', + 'concat:banner' + ]); + +}; diff --git a/grunt/tasks/promises-aplus-tests.js b/grunt/tasks/promises-aplus-tests.js new file mode 100644 index 0000000000..598f158262 --- /dev/null +++ b/grunt/tasks/promises-aplus-tests.js @@ -0,0 +1,16 @@ +module.exports = function ( grunt ) { + + 'use strict'; + + grunt.registerTask( 'promises-aplus-tests', 'Run the Promises/A+ test suite.', function () { + var promisesAplusTests, adaptor, done; + + promisesAplusTests = require( 'promises-aplus-tests' ); + adaptor = require( '../../test/promises-aplus-adaptor' ); + + done = this.async(); + + promisesAplusTests( adaptor, { reporter: 'dot' }, done ); + }); + +}; \ No newline at end of file diff --git a/grunt/tasks/release.js b/grunt/tasks/release.js new file mode 100644 index 0000000000..15e6c571ed --- /dev/null +++ b/grunt/tasks/release.js @@ -0,0 +1,7 @@ +module.exports = function ( grunt ) { + + 'use strict'; + + grunt.registerTask( 'release', [ 'default', 'copy:release', 'copy:link' ] ); + +}; \ No newline at end of file diff --git a/grunt/tasks/revision.js b/grunt/tasks/revision.js new file mode 100644 index 0000000000..2522483515 --- /dev/null +++ b/grunt/tasks/revision.js @@ -0,0 +1,19 @@ +module.exports = function ( grunt ) { + + 'use strict'; + + grunt.registerTask( 'revision', 'Set revision to grunt config pkg.version', function () { + var done = this.async(); + + require( 'child_process' ).exec( 'git rev-parse HEAD', function ( err, commitHash ) { + if ( err ) { + done( err ); + return; + } + + grunt.config( 'commitHash', commitHash ); + done(); + }); + }); + +}; diff --git a/grunt/tasks/test.js b/grunt/tasks/test.js new file mode 100644 index 0000000000..944acc50ef --- /dev/null +++ b/grunt/tasks/test.js @@ -0,0 +1,10 @@ +module.exports = function ( grunt ) { + + 'use strict'; + + grunt.registerTask( 'test', [ + 'nodeunit', + 'qunit:all' + ]); + +}; diff --git a/package.json b/package.json index 95fbb6adb7..edc33570b2 100755 --- a/package.json +++ b/package.json @@ -1,9 +1,9 @@ { "name": "ractive", "description": "Next-generation DOM manipulation", - "version": "0.3.9", + "version": "0.4.0", "homepage": "http://ractivejs.org", - "main": "build/Ractive.js", + "main": "ractive.js", "keywords": [ "template", "templating", @@ -21,18 +21,18 @@ } ], "jam": { - "name": "Ractive", - "main": "Ractive.js", + "name": "ractive", + "main": "ractive.js", "include": [ - "Ractive.js", - "build/Ractive.js", - "build/Ractive.runtime.js", - "build/Ractive.min.js", - "build/Ractive.runtime.min.js", - "build/Ractive-legacy.js", - "build/Ractive-legacy.runtime.js", - "build/Ractive-legacy.min.js", - "build/Ractive-legacy.runtime.min.js", + "ractive.js", + "build/ractive.js", + "build/ractive.runtime.js", + "build/ractive.min.js", + "build/ractive.runtime.min.js", + "build/ractive-legacy.js", + "build/ractive-legacy.runtime.js", + "build/ractive-legacy.min.js", + "build/ractive-legacy.runtime.min.js", "README.md" ] }, @@ -41,7 +41,7 @@ "Templating" ], "bugs": { - "url": "https://github.com/RactiveJS/Ractive/issues" + "url": "https://github.com/ractivejs/ractive/issues" }, "contributors": [ { @@ -59,22 +59,24 @@ ], "repository": { "type": "git", - "url": "https://github.com/RactiveJS/Ractive.git" + "url": "https://github.com/ractivejs/ractive.git" }, - "github": "https://github.com/RactiveJS/Ractive", + "github": "https://github.com/ractivejs/ractive", "devDependencies": { - "grunt": "~0.4.1", - "grunt-contrib-jshint": "~0.8.0", + "grunt": "~0.4.4", + "grunt-contrib-jshint": "~0.10.0", "grunt-contrib-clean": "~0.5.0", - "grunt-contrib-qunit": "~0.3.0", - "grunt-contrib-nodeunit": "~0.2.2", - "grunt-contrib-concat": "~0.3.0", - "grunt-contrib-uglify": "~0.2.7", + "grunt-contrib-qunit": "~0.4.0", + "grunt-contrib-nodeunit": "~0.3.3", + "grunt-contrib-concat": "~0.4.0", + "grunt-contrib-uglify": "~0.4.0", "grunt-contrib-copy": "~0.5.0", - "grunt-contrib-watch": "~0.5.3", - "grunt-contrib-requirejs": "~0.4.1", - "amdclean": "~0.3.2", - "cheerio": "~0.13.0" + "grunt-contrib-watch": "~0.6.1", + "amdclean": "~1.5.0", + "cheerio": "~0.15.0", + "promises-aplus-tests": "*", + "grunt-jsbeautifier": "~0.2.7", + "grunt-contrib-requirejs": "~0.4.3" }, "testling": { "html": "test/testling.html", @@ -93,8 +95,5 @@ "ipad/6.0", "android-browser/4.2" ] - }, - "scripts": { - "test": "grunt test" } } diff --git a/ractive.js b/ractive.js new file mode 100644 index 0000000000..789cbf9429 --- /dev/null +++ b/ractive.js @@ -0,0 +1,12026 @@ +/* + Ractive.js v0.4.0 + 2014-04-08 - commit 276c0e2b + + http://ractivejs.org + http://twitter.com/RactiveJS + + Released under the MIT License. +*/ + +( function( global ) { + + 'use strict'; + + var noConflict = global.Ractive; + + var legacy = undefined; + + var config_initOptions = function() { + + var defaults, initOptions; + defaults = { + el: null, + template: '', + complete: null, + preserveWhitespace: false, + append: false, + twoway: true, + modifyArrays: true, + lazy: false, + debug: false, + noIntro: false, + transitionsEnabled: true, + magic: false, + noCssTransform: false, + adapt: [], + sanitize: false, + stripComments: true, + isolated: false, + delimiters: [ + '{{', + '}}' + ], + tripleDelimiters: [ + '{{{', + '}}}' + ], + computed: null + }; + initOptions = { + keys: Object.keys( defaults ), + defaults: defaults + }; + return initOptions; + }( legacy ); + + var config_svg = function() { + + if ( typeof document === 'undefined' ) { + return; + } + return document && document.implementation.hasFeature( 'http://www.w3.org/TR/SVG11/feature#BasicStructure', '1.1' ); + }(); + + var config_namespaces = { + html: 'http://www.w3.org/1999/xhtml', + mathml: 'http://www.w3.org/1998/Math/MathML', + svg: 'http://www.w3.org/2000/svg', + xlink: 'http://www.w3.org/1999/xlink', + xml: 'http://www.w3.org/XML/1998/namespace', + xmlns: 'http://www.w3.org/2000/xmlns/' + }; + + var utils_createElement = function( svg, namespaces ) { + + // Test for SVG support + if ( !svg ) { + return function( type, ns ) { + if ( ns && ns !== namespaces.html ) { + throw 'This browser does not support namespaces other than http://www.w3.org/1999/xhtml. The most likely cause of this error is that you\'re trying to render SVG in an older browser. See http://docs.ractivejs.org/latest/svg-and-older-browsers for more information'; + } + return document.createElement( type ); + }; + } else { + return function( type, ns ) { + if ( !ns || ns === namespaces.html ) { + return document.createElement( type ); + } + return document.createElementNS( ns, type ); + }; + } + }( config_svg, config_namespaces ); + + var config_isClient = typeof document === 'object'; + + var utils_defineProperty = function( isClient ) { + + try { + Object.defineProperty( {}, 'test', { + value: 0 + } ); + if ( isClient ) { + Object.defineProperty( document.createElement( 'div' ), 'test', { + value: 0 + } ); + } + return Object.defineProperty; + } catch ( err ) { + // Object.defineProperty doesn't exist, or we're in IE8 where you can + // only use it with DOM objects (what the fuck were you smoking, MSFT?) + return function( obj, prop, desc ) { + obj[ prop ] = desc.value; + }; + } + }( config_isClient ); + + var utils_defineProperties = function( createElement, defineProperty, isClient ) { + + try { + try { + Object.defineProperties( {}, { + test: { + value: 0 + } + } ); + } catch ( err ) { + // TODO how do we account for this? noMagic = true; + throw err; + } + if ( isClient ) { + Object.defineProperties( createElement( 'div' ), { + test: { + value: 0 + } + } ); + } + return Object.defineProperties; + } catch ( err ) { + return function( obj, props ) { + var prop; + for ( prop in props ) { + if ( props.hasOwnProperty( prop ) ) { + defineProperty( obj, prop, props[ prop ] ); + } + } + }; + } + }( utils_createElement, utils_defineProperty, config_isClient ); + + var utils_isNumeric = function( thing ) { + return !isNaN( parseFloat( thing ) ) && isFinite( thing ); + }; + + var Ractive_prototype_shared_add = function( isNumeric ) { + + return function( root, keypath, d ) { + var value; + if ( typeof keypath !== 'string' || !isNumeric( d ) ) { + throw new Error( 'Bad arguments' ); + } + value = +root.get( keypath ) || 0; + if ( !isNumeric( value ) ) { + throw new Error( 'Cannot add to a non-numeric value' ); + } + return root.set( keypath, value + d ); + }; + }( utils_isNumeric ); + + var Ractive_prototype_add = function( add ) { + + return function( keypath, d ) { + return add( this, keypath, d === undefined ? 1 : +d ); + }; + }( Ractive_prototype_shared_add ); + + var utils_isEqual = function( a, b ) { + if ( a === null && b === null ) { + return true; + } + if ( typeof a === 'object' || typeof b === 'object' ) { + return false; + } + return a === b; + }; + + var utils_Promise = function() { + + var Promise, PENDING = {}, FULFILLED = {}, REJECTED = {}; + Promise = function( callback ) { + var fulfilledHandlers = [], + rejectedHandlers = [], + state = PENDING, + result, dispatchHandlers, makeResolver, fulfil, reject, promise; + makeResolver = function( newState ) { + return function( value ) { + if ( state !== PENDING ) { + return; + } + result = value; + state = newState; + dispatchHandlers = makeDispatcher( state === FULFILLED ? fulfilledHandlers : rejectedHandlers, result ); + // dispatch onFulfilled and onRejected handlers asynchronously + wait( dispatchHandlers ); + }; + }; + fulfil = makeResolver( FULFILLED ); + reject = makeResolver( REJECTED ); + callback( fulfil, reject ); + promise = { + // `then()` returns a Promise - 2.2.7 + then: function( onFulfilled, onRejected ) { + var promise2 = new Promise( function( fulfil, reject ) { + var processResolutionHandler = function( handler, handlers, forward ) { + // 2.2.1.1 + if ( typeof handler === 'function' ) { + handlers.push( function( p1result ) { + var x; + try { + x = handler( p1result ); + resolve( promise2, x, fulfil, reject ); + } catch ( err ) { + reject( err ); + } + } ); + } else { + // Forward the result of promise1 to promise2, if resolution handlers + // are not given + handlers.push( forward ); + } + }; + // 2.2 + processResolutionHandler( onFulfilled, fulfilledHandlers, fulfil ); + processResolutionHandler( onRejected, rejectedHandlers, reject ); + if ( state !== PENDING ) { + // If the promise has resolved already, dispatch the appropriate handlers asynchronously + wait( dispatchHandlers ); + } + } ); + return promise2; + } + }; + promise[ 'catch' ] = function( onRejected ) { + return this.then( null, onRejected ); + }; + return promise; + }; + Promise.all = function( promises ) { + return new Promise( function( fulfil, reject ) { + var result = [], + pending, i, processPromise; + if ( !promises.length ) { + fulfil( result ); + return; + } + processPromise = function( i ) { + promises[ i ].then( function( value ) { + result[ i ] = value; + if ( !--pending ) { + fulfil( result ); + } + }, reject ); + }; + pending = i = promises.length; + while ( i-- ) { + processPromise( i ); + } + } ); + }; + Promise.resolve = function( value ) { + return new Promise( function( fulfil ) { + fulfil( value ); + } ); + }; + Promise.reject = function( reason ) { + return new Promise( function( fulfil, reject ) { + reject( reason ); + } ); + }; + return Promise; + // TODO use MutationObservers or something to simulate setImmediate + function wait( callback ) { + setTimeout( callback, 0 ); + } + + function makeDispatcher( handlers, result ) { + return function() { + var handler; + while ( handler = handlers.shift() ) { + handler( result ); + } + }; + } + + function resolve( promise, x, fulfil, reject ) { + // Promise Resolution Procedure + var then; + // 2.3.1 + if ( x === promise ) { + throw new TypeError( 'A promise\'s fulfillment handler cannot return the same promise' ); + } + // 2.3.2 + if ( x instanceof Promise ) { + x.then( fulfil, reject ); + } else if ( x && ( typeof x === 'object' || typeof x === 'function' ) ) { + try { + then = x.then; + } catch ( e ) { + reject( e ); + // 2.3.3.2 + return; + } + // 2.3.3.3 + if ( typeof then === 'function' ) { + var called, resolvePromise, rejectPromise; + resolvePromise = function( y ) { + if ( called ) { + return; + } + called = true; + resolve( promise, y, fulfil, reject ); + }; + rejectPromise = function( r ) { + if ( called ) { + return; + } + called = true; + reject( r ); + }; + try { + then.call( x, resolvePromise, rejectPromise ); + } catch ( e ) { + if ( !called ) { + // 2.3.3.3.4.1 + reject( e ); + // 2.3.3.3.4.2 + called = true; + return; + } + } + } else { + fulfil( x ); + } + } else { + fulfil( x ); + } + } + }(); + + var utils_normaliseKeypath = function() { + + var regex = /\[\s*(\*|[0-9]|[1-9][0-9]+)\s*\]/g; + return function normaliseKeypath( keypath ) { + return ( keypath || '' ).replace( regex, '.$1' ); + }; + }(); + + var config_vendors = [ + 'o', + 'ms', + 'moz', + 'webkit' + ]; + + var utils_requestAnimationFrame = function( vendors ) { + + // If window doesn't exist, we don't need requestAnimationFrame + if ( typeof window === 'undefined' ) { + return; + } + // https://gist.github.com/paulirish/1579671 + ( function( vendors, lastTime, window ) { + var x, setTimeout; + if ( window.requestAnimationFrame ) { + return; + } + for ( x = 0; x < vendors.length && !window.requestAnimationFrame; ++x ) { + window.requestAnimationFrame = window[ vendors[ x ] + 'RequestAnimationFrame' ]; + } + if ( !window.requestAnimationFrame ) { + setTimeout = window.setTimeout; + window.requestAnimationFrame = function( callback ) { + var currTime, timeToCall, id; + currTime = Date.now(); + timeToCall = Math.max( 0, 16 - ( currTime - lastTime ) ); + id = setTimeout( function() { + callback( currTime + timeToCall ); + }, timeToCall ); + lastTime = currTime + timeToCall; + return id; + }; + } + }( vendors, 0, window ) ); + return window.requestAnimationFrame; + }( config_vendors ); + + var utils_getTime = function() { + + if ( typeof window !== 'undefined' && window.performance && typeof window.performance.now === 'function' ) { + return function() { + return window.performance.now(); + }; + } else { + return function() { + return Date.now(); + }; + } + }(); + + // This module provides a place to store a) circular dependencies and + // b) the callback functions that require those circular dependencies + var circular = []; + + var utils_removeFromArray = function( array, member ) { + var index = array.indexOf( member ); + if ( index !== -1 ) { + array.splice( index, 1 ); + } + }; + + var global_css = function( circular, isClient, removeFromArray ) { + + var runloop, styleElement, head, styleSheet, inDom, prefix = '/* Ractive.js component styles */\n', + componentsInPage = {}, styles = []; + if ( !isClient ) { + return; + } + circular.push( function() { + runloop = circular.runloop; + } ); + styleElement = document.createElement( 'style' ); + styleElement.type = 'text/css'; + head = document.getElementsByTagName( 'head' )[ 0 ]; + inDom = false; + // Internet Exploder won't let you use styleSheet.innerHTML - we have to + // use styleSheet.cssText instead + styleSheet = styleElement.styleSheet; + return { + add: function( Component ) { + if ( !Component.css ) { + return; + } + if ( !componentsInPage[ Component._guid ] ) { + // we create this counter so that we can in/decrement it as + // instances are added and removed. When all components are + // removed, the style is too + componentsInPage[ Component._guid ] = 0; + styles.push( Component.css ); + runloop.scheduleCssUpdate(); + } + componentsInPage[ Component._guid ] += 1; + }, + remove: function( Component ) { + if ( !Component.css ) { + return; + } + componentsInPage[ Component._guid ] -= 1; + if ( !componentsInPage[ Component._guid ] ) { + removeFromArray( styles, Component.css ); + runloop.scheduleCssUpdate(); + } + }, + update: function() { + var css; + if ( styles.length ) { + css = prefix + styles.join( ' ' ); + if ( styleSheet ) { + styleSheet.cssText = css; + } else { + styleElement.innerHTML = css; + } + if ( !inDom ) { + head.appendChild( styleElement ); + } + } else if ( inDom ) { + head.removeChild( styleElement ); + } + } + }; + }( circular, config_isClient, utils_removeFromArray ); + + var shared_getValueFromCheckboxes = function( ractive, keypath ) { + var value, checkboxes, checkbox, len, i, rootEl; + value = []; + // TODO in edge cases involving components with inputs bound to the same keypath, this + // could get messy + // if we're still in the initial render, we need to find the inputs from the as-yet off-DOM + // document fragment. otherwise, the root element + rootEl = ractive._rendering ? ractive.fragment.docFrag : ractive.el; + checkboxes = rootEl.querySelectorAll( 'input[type="checkbox"][name="{{' + keypath + '}}"]' ); + len = checkboxes.length; + for ( i = 0; i < len; i += 1 ) { + checkbox = checkboxes[ i ]; + if ( checkbox.hasAttribute( 'checked' ) || checkbox.checked ) { + value.push( checkbox._ractive.value ); + } + } + return value; + }; + + var utils_hasOwnProperty = Object.prototype.hasOwnProperty; + + var shared_getInnerContext = function( fragment ) { + do { + if ( fragment.context ) { + return fragment.context; + } + } while ( fragment = fragment.parent ); + return ''; + }; + + var shared_resolveRef = function( circular, normaliseKeypath, hasOwnProperty, getInnerContext ) { + + var get, ancestorErrorMessage = 'Could not resolve reference - too many "../" prefixes'; + circular.push( function() { + get = circular.get; + } ); + return function resolveRef( ractive, ref, fragment ) { + var context, contextKeys, keys, lastKey, postfix, parentKeypath, parentValue, wrapped, hasContextChain; + ref = normaliseKeypath( ref ); + // Implicit iterators - i.e. {{.}} - are a special case + if ( ref === '.' ) { + return getInnerContext( fragment ); + } + // If a reference begins with '.', it's either a restricted reference or + // an ancestor reference... + if ( ref.charAt( 0 ) === '.' ) { + // ...either way we need to get the innermost context + context = getInnerContext( fragment ); + contextKeys = context ? context.split( '.' ) : []; + // ancestor references (starting "../") go up the tree + if ( ref.substr( 0, 3 ) === '../' ) { + while ( ref.substr( 0, 3 ) === '../' ) { + if ( !contextKeys.length ) { + throw new Error( ancestorErrorMessage ); + } + contextKeys.pop(); + ref = ref.substring( 3 ); + } + contextKeys.push( ref ); + return contextKeys.join( '.' ); + } + // not an ancestor reference - must be a restricted reference (prepended with ".") + if ( !context ) { + return ref.substring( 1 ); + } + return context + ref; + } + // Now we need to try and resolve the reference against any + // contexts set by parent list/object sections + keys = ref.split( '.' ); + lastKey = keys.pop(); + postfix = keys.length ? '.' + keys.join( '.' ) : ''; + do { + context = fragment.context; + if ( !context ) { + continue; + } + hasContextChain = true; + parentKeypath = context + postfix; + parentValue = get( ractive, parentKeypath ); + if ( wrapped = ractive._wrapped[ parentKeypath ] ) { + parentValue = wrapped.get(); + } + if ( parentValue && ( typeof parentValue === 'object' || typeof parentValue === 'function' ) && lastKey in parentValue ) { + return context + '.' + ref; + } + } while ( fragment = fragment.parent ); + // Still no keypath? + // If there's no context chain, and the instance is either a) isolated or + // b) an orphan, then we know that the keypath is identical to the reference + if ( !hasContextChain && ( !ractive._parent || ractive.isolated ) ) { + return ref; + } + // We need both of these - the first enables components to treat data contexts + // like lexical scopes in JavaScript functions... + if ( hasOwnProperty.call( ractive.data, ref ) ) { + return ref; + } else if ( get( ractive, ref ) !== undefined ) { + return ref; + } + }; + }( circular, utils_normaliseKeypath, utils_hasOwnProperty, shared_getInnerContext ); + + var shared_getUpstreamChanges = function getUpstreamChanges( changes ) { + var upstreamChanges = [ '' ], + i, keypath, keys, upstreamKeypath; + i = changes.length; + while ( i-- ) { + keypath = changes[ i ]; + keys = keypath.split( '.' ); + while ( keys.length > 1 ) { + keys.pop(); + upstreamKeypath = keys.join( '.' ); + if ( upstreamChanges[ upstreamKeypath ] !== true ) { + upstreamChanges.push( upstreamKeypath ); + upstreamChanges[ upstreamKeypath ] = true; + } + } + } + return upstreamChanges; + }; + + var shared_notifyDependants = function() { + + var lastKey, starMaps = {}; + lastKey = /[^\.]+$/; + + function notifyDependants( ractive, keypath, onlyDirect ) { + var i; + // Notify any pattern observers + if ( ractive._patternObservers.length ) { + notifyPatternObservers( ractive, keypath, keypath, onlyDirect, true ); + } + for ( i = 0; i < ractive._deps.length; i += 1 ) { + // can't cache ractive._deps.length, it may change + notifyDependantsAtPriority( ractive, keypath, i, onlyDirect ); + } + } + notifyDependants.multiple = function notifyMultipleDependants( ractive, keypaths, onlyDirect ) { + var i, j, len; + len = keypaths.length; + // Notify any pattern observers + if ( ractive._patternObservers.length ) { + i = len; + while ( i-- ) { + notifyPatternObservers( ractive, keypaths[ i ], keypaths[ i ], onlyDirect, true ); + } + } + for ( i = 0; i < ractive._deps.length; i += 1 ) { + if ( ractive._deps[ i ] ) { + j = len; + while ( j-- ) { + notifyDependantsAtPriority( ractive, keypaths[ j ], i, onlyDirect ); + } + } + } + }; + return notifyDependants; + + function notifyDependantsAtPriority( ractive, keypath, priority, onlyDirect ) { + var depsByKeypath = ractive._deps[ priority ]; + if ( !depsByKeypath ) { + return; + } + // update dependants of this keypath + updateAll( depsByKeypath[ keypath ] ); + // If we're only notifying direct dependants, not dependants + // of downstream keypaths, then YOU SHALL NOT PASS + if ( onlyDirect ) { + return; + } + // otherwise, cascade + cascade( ractive._depsMap[ keypath ], ractive, priority ); + } + + function updateAll( deps ) { + var i, len; + if ( deps ) { + len = deps.length; + for ( i = 0; i < len; i += 1 ) { + deps[ i ].update(); + } + } + } + + function cascade( childDeps, ractive, priority, onlyDirect ) { + var i; + if ( childDeps ) { + i = childDeps.length; + while ( i-- ) { + notifyDependantsAtPriority( ractive, childDeps[ i ], priority, onlyDirect ); + } + } + } + // TODO split into two functions? i.e. one for the top-level call, one for the cascade + function notifyPatternObservers( ractive, registeredKeypath, actualKeypath, isParentOfChangedKeypath, isTopLevelCall ) { + var i, patternObserver, children, child, key, childActualKeypath, potentialWildcardMatches, cascade; + // First, observers that match patterns at the same level + // or higher in the tree + i = ractive._patternObservers.length; + while ( i-- ) { + patternObserver = ractive._patternObservers[ i ]; + if ( patternObserver.regex.test( actualKeypath ) ) { + patternObserver.update( actualKeypath ); + } + } + if ( isParentOfChangedKeypath ) { + return; + } + // If the changed keypath is 'foo.bar', we need to see if there are + // any pattern observer dependants of keypaths below any of + // 'foo.bar', 'foo.*', '*.bar' or '*.*' (e.g. 'foo.bar.*' or 'foo.*.baz' ) + cascade = function( keypath ) { + if ( children = ractive._depsMap[ keypath ] ) { + i = children.length; + while ( i-- ) { + child = children[ i ]; + // foo.*.baz + key = lastKey.exec( child )[ 0 ]; + // 'baz' + childActualKeypath = actualKeypath ? actualKeypath + '.' + key : key; + // 'foo.bar.baz' + notifyPatternObservers( ractive, child, childActualKeypath ); + } + } + }; + if ( isTopLevelCall ) { + potentialWildcardMatches = getPotentialWildcardMatches( actualKeypath ); + potentialWildcardMatches.forEach( cascade ); + } else { + cascade( registeredKeypath ); + } + } + // This function takes a keypath such as 'foo.bar.baz', and returns + // all the variants of that keypath that include a wildcard in place + // of a key, such as 'foo.bar.*', 'foo.*.baz', 'foo.*.*' and so on. + // These are then checked against the dependants map (ractive._depsMap) + // to see if any pattern observers are downstream of one or more of + // these wildcard keypaths (e.g. 'foo.bar.*.status') + function getPotentialWildcardMatches( keypath ) { + var keys, starMap, mapper, i, result, wildcardKeypath; + keys = keypath.split( '.' ); + starMap = getStarMap( keys.length ); + result = []; + mapper = function( star, i ) { + return star ? '*' : keys[ i ]; + }; + i = starMap.length; + while ( i-- ) { + wildcardKeypath = starMap[ i ].map( mapper ).join( '.' ); + if ( !result[ wildcardKeypath ] ) { + result.push( wildcardKeypath ); + result[ wildcardKeypath ] = true; + } + } + return result; + } + // This function returns all the possible true/false combinations for + // a given number - e.g. for two, the possible combinations are + // [ true, true ], [ true, false ], [ false, true ], [ false, false ]. + // It does so by getting all the binary values between 0 and e.g. 11 + function getStarMap( num ) { + var ones = '', + max, binary, starMap, mapper, i; + if ( !starMaps[ num ] ) { + starMap = []; + while ( ones.length < num ) { + ones += 1; + } + max = parseInt( ones, 2 ); + mapper = function( digit ) { + return digit === '1'; + }; + for ( i = 0; i <= max; i += 1 ) { + binary = i.toString( 2 ); + while ( binary.length < num ) { + binary = '0' + binary; + } + starMap[ i ] = Array.prototype.map.call( binary, mapper ); + } + starMaps[ num ] = starMap; + } + return starMaps[ num ]; + } + }(); + + var shared_makeTransitionManager = function( removeFromArray ) { + + var makeTransitionManager, checkComplete, remove, init; + makeTransitionManager = function( callback, previous ) { + var transitionManager = []; + transitionManager.detachQueue = []; + transitionManager.remove = remove; + transitionManager.init = init; + transitionManager._check = checkComplete; + transitionManager._callback = callback; + transitionManager._previous = previous; + if ( previous ) { + previous.push( transitionManager ); + } + return transitionManager; + }; + checkComplete = function() { + var element; + if ( this._ready && !this.length ) { + while ( element = this.detachQueue.pop() ) { + element.detach(); + } + if ( typeof this._callback === 'function' ) { + this._callback(); + } + if ( this._previous ) { + this._previous.remove( this ); + } + } + }; + remove = function( transition ) { + removeFromArray( this, transition ); + this._check(); + }; + init = function() { + this._ready = true; + this._check(); + }; + return makeTransitionManager; + }( utils_removeFromArray ); + + var global_runloop = function( circular, css, removeFromArray, getValueFromCheckboxes, resolveRef, getUpstreamChanges, notifyDependants, makeTransitionManager ) { + + circular.push( function() { + get = circular.get; + set = circular.set; + } ); + var runloop, get, set, dirty = false, + flushing = false, + pendingCssChanges, inFlight = 0, + toFocus = null, + liveQueries = [], + decorators = [], + transitions = [], + observers = [], + attributes = [], + activeBindings = [], + evaluators = [], + computations = [], + selectValues = [], + checkboxKeypaths = {}, checkboxes = [], + radios = [], + unresolved = [], + instances = [], + transitionManager; + runloop = { + start: function( instance, callback ) { + this.addInstance( instance ); + if ( !flushing ) { + inFlight += 1; + // create a new transition manager + transitionManager = makeTransitionManager( callback, transitionManager ); + } + }, + end: function() { + if ( flushing ) { + attemptKeypathResolution(); + return; + } + if ( !--inFlight ) { + flushing = true; + flushChanges(); + flushing = false; + land(); + } + transitionManager.init(); + transitionManager = transitionManager._previous; + }, + trigger: function() { + if ( inFlight || flushing ) { + attemptKeypathResolution(); + return; + } + flushing = true; + flushChanges(); + flushing = false; + land(); + }, + focus: function( node ) { + toFocus = node; + }, + addInstance: function( instance ) { + if ( instance && !instances[ instance._guid ] ) { + instances.push( instance ); + instances[ instances._guid ] = true; + } + }, + addLiveQuery: function( query ) { + liveQueries.push( query ); + }, + addDecorator: function( decorator ) { + decorators.push( decorator ); + }, + addTransition: function( transition ) { + transition._manager = transitionManager; + transitionManager.push( transition ); + transitions.push( transition ); + }, + addObserver: function( observer ) { + observers.push( observer ); + }, + addAttribute: function( attribute ) { + attributes.push( attribute ); + }, + addBinding: function( binding ) { + binding.active = true; + activeBindings.push( binding ); + }, + scheduleCssUpdate: function() { + // if runloop isn't currently active, we need to trigger change immediately + if ( !inFlight && !flushing ) { + // TODO does this ever happen? + css.update(); + } else { + pendingCssChanges = true; + } + }, + // changes that may cause additional changes... + addEvaluator: function( evaluator ) { + dirty = true; + evaluators.push( evaluator ); + }, + addComputation: function( thing ) { + dirty = true; + computations.push( thing ); + }, + addSelectValue: function( selectValue ) { + dirty = true; + selectValues.push( selectValue ); + }, + addCheckbox: function( checkbox ) { + if ( !checkboxKeypaths[ checkbox.keypath ] ) { + dirty = true; + checkboxes.push( checkbox ); + } + }, + addRadio: function( radio ) { + dirty = true; + radios.push( radio ); + }, + addUnresolved: function( thing ) { + dirty = true; + unresolved.push( thing ); + }, + removeUnresolved: function( thing ) { + removeFromArray( unresolved, thing ); + }, + // synchronise node detachments with transition ends + detachWhenReady: function( thing ) { + transitionManager.detachQueue.push( thing ); + } + }; + circular.runloop = runloop; + return runloop; + + function land() { + var thing, changedKeypath, changeHash; + if ( toFocus ) { + toFocus.focus(); + toFocus = null; + } + while ( thing = attributes.pop() ) { + thing.update().deferred = false; + } + while ( thing = liveQueries.pop() ) { + thing._sort(); + } + while ( thing = decorators.pop() ) { + thing.init(); + } + while ( thing = transitions.pop() ) { + thing.init(); + } + while ( thing = observers.pop() ) { + thing.update(); + } + while ( thing = activeBindings.pop() ) { + thing.active = false; + } + // Change events are fired last + while ( thing = instances.pop() ) { + instances[ thing._guid ] = false; + if ( thing._changes.length ) { + changeHash = {}; + while ( changedKeypath = thing._changes.pop() ) { + changeHash[ changedKeypath ] = get( thing, changedKeypath ); + } + thing.fire( 'change', changeHash ); + } + } + if ( pendingCssChanges ) { + css.update(); + pendingCssChanges = false; + } + } + + function flushChanges() { + var thing, upstreamChanges, i; + i = instances.length; + while ( i-- ) { + thing = instances[ i ]; + if ( thing._changes.length ) { + upstreamChanges = getUpstreamChanges( thing._changes ); + notifyDependants.multiple( thing, upstreamChanges, true ); + } + } + attemptKeypathResolution(); + while ( dirty ) { + dirty = false; + while ( thing = computations.pop() ) { + thing.update(); + } + while ( thing = evaluators.pop() ) { + thing.update().deferred = false; + } + while ( thing = selectValues.pop() ) { + thing.deferredUpdate(); + } + while ( thing = checkboxes.pop() ) { + set( thing.root, thing.keypath, getValueFromCheckboxes( thing.root, thing.keypath ) ); + } + while ( thing = radios.pop() ) { + thing.update(); + } + } + } + + function attemptKeypathResolution() { + var array, thing, keypath; + if ( !unresolved.length ) { + return; + } + // see if we can resolve any unresolved references + array = unresolved.splice( 0, unresolved.length ); + while ( thing = array.pop() ) { + if ( thing.keypath ) { + continue; + } + keypath = resolveRef( thing.root, thing.ref, thing.parentFragment ); + if ( keypath !== undefined ) { + // If we've resolved the keypath, we can initialise this item + thing.resolve( keypath ); + } else { + // If we can't resolve the reference, try again next time + unresolved.push( thing ); + } + } + } + }( circular, global_css, utils_removeFromArray, shared_getValueFromCheckboxes, shared_resolveRef, shared_getUpstreamChanges, shared_notifyDependants, shared_makeTransitionManager ); + + var shared_animations = function( rAF, getTime, runloop ) { + + var queue = []; + var animations = { + tick: function() { + var i, animation, now; + now = getTime(); + runloop.start(); + for ( i = 0; i < queue.length; i += 1 ) { + animation = queue[ i ]; + if ( !animation.tick( now ) ) { + // animation is complete, remove it from the stack, and decrement i so we don't miss one + queue.splice( i--, 1 ); + } + } + runloop.end(); + if ( queue.length ) { + rAF( animations.tick ); + } else { + animations.running = false; + } + }, + add: function( animation ) { + queue.push( animation ); + if ( !animations.running ) { + animations.running = true; + rAF( animations.tick ); + } + }, + // TODO optimise this + abort: function( keypath, root ) { + var i = queue.length, + animation; + while ( i-- ) { + animation = queue[ i ]; + if ( animation.root === root && animation.keypath === keypath ) { + animation.stop(); + } + } + } + }; + return animations; + }( utils_requestAnimationFrame, utils_getTime, global_runloop ); + + var utils_isArray = function() { + + var toString = Object.prototype.toString; + // thanks, http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/ + return function( thing ) { + return toString.call( thing ) === '[object Array]'; + }; + }(); + + var utils_clone = function( isArray ) { + + return function( source ) { + var target, key; + if ( !source || typeof source !== 'object' ) { + return source; + } + if ( isArray( source ) ) { + return source.slice(); + } + target = {}; + for ( key in source ) { + if ( source.hasOwnProperty( key ) ) { + target[ key ] = source[ key ]; + } + } + return target; + }; + }( utils_isArray ); + + var registries_adaptors = {}; + + var shared_get_arrayAdaptor_getSpliceEquivalent = function( array, methodName, args ) { + switch ( methodName ) { + case 'splice': + return args; + case 'sort': + case 'reverse': + return null; + case 'pop': + if ( array.length ) { + return [ -1 ]; + } + return null; + case 'push': + return [ + array.length, + 0 + ].concat( args ); + case 'shift': + return [ + 0, + 1 + ]; + case 'unshift': + return [ + 0, + 0 + ].concat( args ); + } + }; + + var shared_get_arrayAdaptor_summariseSpliceOperation = function( array, args ) { + var start, addedItems, removedItems, balance; + if ( !args ) { + return null; + } + // figure out where the changes started... + start = +( args[ 0 ] < 0 ? array.length + args[ 0 ] : args[ 0 ] ); + // ...and how many items were added to or removed from the array + addedItems = Math.max( 0, args.length - 2 ); + removedItems = args[ 1 ] !== undefined ? args[ 1 ] : array.length - start; + // It's possible to do e.g. [ 1, 2, 3 ].splice( 2, 2 ) - i.e. the second argument + // means removing more items from the end of the array than there are. In these + // cases we need to curb JavaScript's enthusiasm or we'll get out of sync + removedItems = Math.min( removedItems, array.length - start ); + balance = addedItems - removedItems; + return { + start: start, + balance: balance, + added: addedItems, + removed: removedItems + }; + }; + + var config_types = { + TEXT: 1, + INTERPOLATOR: 2, + TRIPLE: 3, + SECTION: 4, + INVERTED: 5, + CLOSING: 6, + ELEMENT: 7, + PARTIAL: 8, + COMMENT: 9, + DELIMCHANGE: 10, + MUSTACHE: 11, + TAG: 12, + ATTRIBUTE: 13, + COMPONENT: 15, + NUMBER_LITERAL: 20, + STRING_LITERAL: 21, + ARRAY_LITERAL: 22, + OBJECT_LITERAL: 23, + BOOLEAN_LITERAL: 24, + GLOBAL: 26, + KEY_VALUE_PAIR: 27, + REFERENCE: 30, + REFINEMENT: 31, + MEMBER: 32, + PREFIX_OPERATOR: 33, + BRACKETED: 34, + CONDITIONAL: 35, + INFIX_OPERATOR: 36, + INVOCATION: 40 + }; + + var shared_clearCache = function clearCache( ractive, keypath, dontTeardownWrapper ) { + var cacheMap, wrappedProperty; + if ( !dontTeardownWrapper ) { + // Is there a wrapped property at this keypath? + if ( wrappedProperty = ractive._wrapped[ keypath ] ) { + // Did we unwrap it? + if ( wrappedProperty.teardown() !== false ) { + ractive._wrapped[ keypath ] = null; + } + } + } + ractive._cache[ keypath ] = undefined; + if ( cacheMap = ractive._cacheMap[ keypath ] ) { + while ( cacheMap.length ) { + clearCache( ractive, cacheMap.pop() ); + } + } + }; + + var utils_createBranch = function() { + + var numeric = /^\s*[0-9]+\s*$/; + return function( key ) { + return numeric.test( key ) ? [] : {}; + }; + }(); + + var shared_set = function( circular, isEqual, createBranch, clearCache, notifyDependants ) { + + var get; + circular.push( function() { + get = circular.get; + } ); + + function set( ractive, keypath, value, silent ) { + var keys, lastKey, parentKeypath, parentValue, computation, wrapper, evaluator, dontTeardownWrapper; + if ( isEqual( ractive._cache[ keypath ], value ) ) { + return; + } + computation = ractive._computations[ keypath ]; + wrapper = ractive._wrapped[ keypath ]; + evaluator = ractive._evaluators[ keypath ]; + if ( computation && !computation.setting ) { + computation.set( value ); + } + // If we have a wrapper with a `reset()` method, we try and use it. If the + // `reset()` method returns false, the wrapper should be torn down, and + // (most likely) a new one should be created later + if ( wrapper && wrapper.reset ) { + dontTeardownWrapper = wrapper.reset( value ) !== false; + if ( dontTeardownWrapper ) { + value = wrapper.get(); + } + } + // Update evaluator value. This may be from the evaluator itself, or + // it may be from the wrapper that wraps an evaluator's result - it + // doesn't matter + if ( evaluator ) { + evaluator.value = value; + } + if ( !computation && !evaluator && !dontTeardownWrapper ) { + keys = keypath.split( '.' ); + lastKey = keys.pop(); + parentKeypath = keys.join( '.' ); + wrapper = ractive._wrapped[ parentKeypath ]; + if ( wrapper && wrapper.set ) { + wrapper.set( lastKey, value ); + } else { + parentValue = wrapper ? wrapper.get() : get( ractive, parentKeypath ); + if ( !parentValue ) { + parentValue = createBranch( lastKey ); + set( ractive, parentKeypath, parentValue, true ); + } + parentValue[ lastKey ] = value; + } + } + clearCache( ractive, keypath, dontTeardownWrapper ); + if ( !silent ) { + ractive._changes.push( keypath ); + notifyDependants( ractive, keypath ); + } + } + circular.set = set; + return set; + }( circular, utils_isEqual, utils_createBranch, shared_clearCache, shared_notifyDependants ); + + var shared_get_arrayAdaptor_processWrapper = function( types, clearCache, notifyDependants, set ) { + + return function( wrapper, array, methodName, spliceSummary ) { + var root, keypath, clearEnd, updateDependant, i, changed, start, end, childKeypath, lengthUnchanged; + root = wrapper.root; + keypath = wrapper.keypath; + root._changes.push( keypath ); + // If this is a sort or reverse, we just do root.set()... + // TODO use merge logic? + if ( methodName === 'sort' || methodName === 'reverse' ) { + set( root, keypath, array ); + return; + } + if ( !spliceSummary ) { + // (presumably we tried to pop from an array of zero length. + // in which case there's nothing to do) + return; + } + // ...otherwise we do a smart update whereby elements are added/removed + // in the right place. But we do need to clear the cache downstream + clearEnd = !spliceSummary.balance ? spliceSummary.added : array.length - Math.min( spliceSummary.balance, 0 ); + for ( i = spliceSummary.start; i < clearEnd; i += 1 ) { + clearCache( root, keypath + '.' + i ); + } + // Propagate changes + updateDependant = function( dependant ) { + // is this a DOM section? + if ( dependant.keypath === keypath && dependant.type === types.SECTION && !dependant.inverted && dependant.docFrag ) { + dependant.splice( spliceSummary ); + } else { + dependant.update(); + } + }; + // Go through all dependant priority levels, finding smart update targets + root._deps.forEach( function( depsByKeypath ) { + var dependants = depsByKeypath[ keypath ]; + if ( dependants ) { + dependants.forEach( updateDependant ); + } + } ); + // if we're removing old items and adding new ones, simultaneously, we need to force an update + if ( spliceSummary.added && spliceSummary.removed ) { + changed = Math.max( spliceSummary.added, spliceSummary.removed ); + start = spliceSummary.start; + end = start + changed; + lengthUnchanged = spliceSummary.added === spliceSummary.removed; + for ( i = start; i < end; i += 1 ) { + childKeypath = keypath + '.' + i; + notifyDependants( root, childKeypath ); + } + } + // length property has changed - notify dependants + // TODO in some cases (e.g. todo list example, when marking all as complete, then + // adding a new item (which should deactivate the 'all complete' checkbox + // but doesn't) this needs to happen before other updates. But doing so causes + // other mental problems. not sure what's going on... + if ( !lengthUnchanged ) { + clearCache( root, keypath + '.length' ); + notifyDependants( root, keypath + '.length', true ); + } + }; + }( config_types, shared_clearCache, shared_notifyDependants, shared_set ); + + var shared_get_arrayAdaptor_patch = function( runloop, defineProperty, getSpliceEquivalent, summariseSpliceOperation, processWrapper ) { + + var patchedArrayProto = [], + mutatorMethods = [ + 'pop', + 'push', + 'reverse', + 'shift', + 'sort', + 'splice', + 'unshift' + ], + testObj, patchArrayMethods, unpatchArrayMethods; + mutatorMethods.forEach( function( methodName ) { + var method = function() { + var spliceEquivalent, spliceSummary, result, wrapper, i; + // push, pop, shift and unshift can all be represented as a splice operation. + // this makes life easier later + spliceEquivalent = getSpliceEquivalent( this, methodName, Array.prototype.slice.call( arguments ) ); + spliceSummary = summariseSpliceOperation( this, spliceEquivalent ); + // apply the underlying method + result = Array.prototype[ methodName ].apply( this, arguments ); + // trigger changes + this._ractive.setting = true; + i = this._ractive.wrappers.length; + while ( i-- ) { + wrapper = this._ractive.wrappers[ i ]; + runloop.start( wrapper.root ); + processWrapper( wrapper, this, methodName, spliceSummary ); + runloop.end(); + } + this._ractive.setting = false; + return result; + }; + defineProperty( patchedArrayProto, methodName, { + value: method + } ); + } ); + // can we use prototype chain injection? + // http://perfectionkills.com/how-ecmascript-5-still-does-not-allow-to-subclass-an-array/#wrappers_prototype_chain_injection + testObj = {}; + if ( testObj.__proto__ ) { + // yes, we can + patchArrayMethods = function( array ) { + array.__proto__ = patchedArrayProto; + }; + unpatchArrayMethods = function( array ) { + array.__proto__ = Array.prototype; + }; + } else { + // no, we can't + patchArrayMethods = function( array ) { + var i, methodName; + i = mutatorMethods.length; + while ( i-- ) { + methodName = mutatorMethods[ i ]; + defineProperty( array, methodName, { + value: patchedArrayProto[ methodName ], + configurable: true + } ); + } + }; + unpatchArrayMethods = function( array ) { + var i; + i = mutatorMethods.length; + while ( i-- ) { + delete array[ mutatorMethods[ i ] ]; + } + }; + } + patchArrayMethods.unpatch = unpatchArrayMethods; + return patchArrayMethods; + }( global_runloop, utils_defineProperty, shared_get_arrayAdaptor_getSpliceEquivalent, shared_get_arrayAdaptor_summariseSpliceOperation, shared_get_arrayAdaptor_processWrapper ); + + var shared_get_arrayAdaptor__arrayAdaptor = function( defineProperty, isArray, patch ) { + + var arrayAdaptor, + // helpers + ArrayWrapper, errorMessage; + arrayAdaptor = { + filter: function( object ) { + // wrap the array if a) b) it's an array, and b) either it hasn't been wrapped already, + // or the array didn't trigger the get() itself + return isArray( object ) && ( !object._ractive || !object._ractive.setting ); + }, + wrap: function( ractive, array, keypath ) { + return new ArrayWrapper( ractive, array, keypath ); + } + }; + ArrayWrapper = function( ractive, array, keypath ) { + this.root = ractive; + this.value = array; + this.keypath = keypath; + // if this array hasn't already been ractified, ractify it + if ( !array._ractive ) { + // define a non-enumerable _ractive property to store the wrappers + defineProperty( array, '_ractive', { + value: { + wrappers: [], + instances: [], + setting: false + }, + configurable: true + } ); + patch( array ); + } + // store the ractive instance, so we can handle transitions later + if ( !array._ractive.instances[ ractive._guid ] ) { + array._ractive.instances[ ractive._guid ] = 0; + array._ractive.instances.push( ractive ); + } + array._ractive.instances[ ractive._guid ] += 1; + array._ractive.wrappers.push( this ); + }; + ArrayWrapper.prototype = { + get: function() { + return this.value; + }, + teardown: function() { + var array, storage, wrappers, instances, index; + array = this.value; + storage = array._ractive; + wrappers = storage.wrappers; + instances = storage.instances; + // if teardown() was invoked because we're clearing the cache as a result of + // a change that the array itself triggered, we can save ourselves the teardown + // and immediate setup + if ( storage.setting ) { + return false; + } + index = wrappers.indexOf( this ); + if ( index === -1 ) { + throw new Error( errorMessage ); + } + wrappers.splice( index, 1 ); + // if nothing else depends on this array, we can revert it to its + // natural state + if ( !wrappers.length ) { + delete array._ractive; + patch.unpatch( this.value ); + } else { + // remove ractive instance if possible + instances[ this.root._guid ] -= 1; + if ( !instances[ this.root._guid ] ) { + index = instances.indexOf( this.root ); + if ( index === -1 ) { + throw new Error( errorMessage ); + } + instances.splice( index, 1 ); + } + } + } + }; + errorMessage = 'Something went wrong in a rather interesting way'; + return arrayAdaptor; + }( utils_defineProperty, utils_isArray, shared_get_arrayAdaptor_patch ); + + var shared_get_magicAdaptor = function( runloop, createBranch, isArray, clearCache, notifyDependants ) { + + var magicAdaptor, MagicWrapper; + try { + Object.defineProperty( {}, 'test', { + value: 0 + } ); + } catch ( err ) { + return false; + } + magicAdaptor = { + filter: function( object, keypath, ractive ) { + var keys, key, parentKeypath, parentWrapper, parentValue; + if ( !keypath ) { + return false; + } + keys = keypath.split( '.' ); + key = keys.pop(); + parentKeypath = keys.join( '.' ); + // If the parent value is a wrapper, other than a magic wrapper, + // we shouldn't wrap this property + if ( ( parentWrapper = ractive._wrapped[ parentKeypath ] ) && !parentWrapper.magic ) { + return false; + } + parentValue = ractive.get( parentKeypath ); + // if parentValue is an array that doesn't include this member, + // we should return false otherwise lengths will get messed up + if ( isArray( parentValue ) && /^[0-9]+$/.test( key ) ) { + return false; + } + return parentValue && ( typeof parentValue === 'object' || typeof parentValue === 'function' ); + }, + wrap: function( ractive, property, keypath ) { + return new MagicWrapper( ractive, property, keypath ); + } + }; + MagicWrapper = function( ractive, value, keypath ) { + var keys, objKeypath, descriptor, siblings; + this.magic = true; + this.ractive = ractive; + this.keypath = keypath; + this.value = value; + keys = keypath.split( '.' ); + this.prop = keys.pop(); + objKeypath = keys.join( '.' ); + this.obj = objKeypath ? ractive.get( objKeypath ) : ractive.data; + descriptor = this.originalDescriptor = Object.getOwnPropertyDescriptor( this.obj, this.prop ); + // Has this property already been wrapped? + if ( descriptor && descriptor.set && ( siblings = descriptor.set._ractiveWrappers ) ) { + // Yes. Register this wrapper to this property, if it hasn't been already + if ( siblings.indexOf( this ) === -1 ) { + siblings.push( this ); + } + return; + } + // No, it hasn't been wrapped + createAccessors( this, value, descriptor ); + }; + MagicWrapper.prototype = { + get: function() { + return this.value; + }, + reset: function( value ) { + if ( this.updating ) { + return; + } + this.updating = true; + this.obj[ this.prop ] = value; + // trigger set() accessor + clearCache( this.ractive, this.keypath ); + this.updating = false; + }, + set: function( key, value ) { + if ( this.updating ) { + return; + } + if ( !this.obj[ this.prop ] ) { + this.updating = true; + this.obj[ this.prop ] = createBranch( key ); + this.updating = false; + } + this.obj[ this.prop ][ key ] = value; + }, + teardown: function() { + var descriptor, set, value, wrappers, index; + // If this method was called because the cache was being cleared as a + // result of a set()/update() call made by this wrapper, we return false + // so that it doesn't get torn down + if ( this.updating ) { + return false; + } + descriptor = Object.getOwnPropertyDescriptor( this.obj, this.prop ); + set = descriptor && descriptor.set; + if ( !set ) { + // most likely, this was an array member that was spliced out + return; + } + wrappers = set._ractiveWrappers; + index = wrappers.indexOf( this ); + if ( index !== -1 ) { + wrappers.splice( index, 1 ); + } + // Last one out, turn off the lights + if ( !wrappers.length ) { + value = this.obj[ this.prop ]; + Object.defineProperty( this.obj, this.prop, this.originalDescriptor || { + writable: true, + enumerable: true, + configurable: true + } ); + this.obj[ this.prop ] = value; + } + } + }; + + function createAccessors( originalWrapper, value, descriptor ) { + var object, property, oldGet, oldSet, get, set; + object = originalWrapper.obj; + property = originalWrapper.prop; + // Is this descriptor configurable? + if ( descriptor && !descriptor.configurable ) { + // Special case - array length + if ( property === 'length' ) { + return; + } + throw new Error( 'Cannot use magic mode with property "' + property + '" - object is not configurable' ); + } + // Time to wrap this property + if ( descriptor ) { + oldGet = descriptor.get; + oldSet = descriptor.set; + } + get = oldGet || function() { + return value; + }; + set = function( v ) { + if ( oldSet ) { + oldSet( v ); + } + value = oldGet ? oldGet() : v; + set._ractiveWrappers.forEach( updateWrapper ); + }; + + function updateWrapper( wrapper ) { + var keypath, ractive; + wrapper.value = value; + if ( wrapper.updating ) { + return; + } + ractive = wrapper.ractive; + keypath = wrapper.keypath; + wrapper.updating = true; + runloop.start( ractive ); + ractive._changes.push( keypath ); + clearCache( ractive, keypath ); + notifyDependants( ractive, keypath ); + runloop.end(); + wrapper.updating = false; + } + // Create an array of wrappers, in case other keypaths/ractives depend on this property. + // Handily, we can store them as a property of the set function. Yay JavaScript. + set._ractiveWrappers = [ originalWrapper ]; + Object.defineProperty( object, property, { + get: get, + set: set, + enumerable: true, + configurable: true + } ); + } + return magicAdaptor; + }( global_runloop, utils_createBranch, utils_isArray, shared_clearCache, shared_notifyDependants ); + + var shared_get_magicArrayAdaptor = function( magicAdaptor, arrayAdaptor ) { + + if ( !magicAdaptor ) { + return false; + } + var magicArrayAdaptor, MagicArrayWrapper; + magicArrayAdaptor = { + filter: function( object, keypath, ractive ) { + return magicAdaptor.filter( object, keypath, ractive ) && arrayAdaptor.filter( object ); + }, + wrap: function( ractive, array, keypath ) { + return new MagicArrayWrapper( ractive, array, keypath ); + } + }; + MagicArrayWrapper = function( ractive, array, keypath ) { + this.value = array; + this.magic = true; + this.magicWrapper = magicAdaptor.wrap( ractive, array, keypath ); + this.arrayWrapper = arrayAdaptor.wrap( ractive, array, keypath ); + }; + MagicArrayWrapper.prototype = { + get: function() { + return this.value; + }, + teardown: function() { + this.arrayWrapper.teardown(); + this.magicWrapper.teardown(); + }, + reset: function( value ) { + return this.magicWrapper.reset( value ); + } + }; + return magicArrayAdaptor; + }( shared_get_magicAdaptor, shared_get_arrayAdaptor__arrayAdaptor ); + + var shared_adaptIfNecessary = function( adaptorRegistry, arrayAdaptor, magicAdaptor, magicArrayAdaptor ) { + + var prefixers = {}; + return function adaptIfNecessary( ractive, keypath, value, isExpressionResult ) { + var len, i, adaptor, wrapped; + // Do we have an adaptor for this value? + len = ractive.adapt.length; + for ( i = 0; i < len; i += 1 ) { + adaptor = ractive.adapt[ i ]; + // Adaptors can be specified as e.g. [ 'Backbone.Model', 'Backbone.Collection' ] - + // we need to get the actual adaptor if that's the case + if ( typeof adaptor === 'string' ) { + if ( !adaptorRegistry[ adaptor ] ) { + throw new Error( 'Missing adaptor "' + adaptor + '"' ); + } + adaptor = ractive.adapt[ i ] = adaptorRegistry[ adaptor ]; + } + if ( adaptor.filter( value, keypath, ractive ) ) { + wrapped = ractive._wrapped[ keypath ] = adaptor.wrap( ractive, value, keypath, getPrefixer( keypath ) ); + wrapped.value = value; + return value; + } + } + if ( !isExpressionResult ) { + if ( ractive.magic ) { + if ( magicArrayAdaptor.filter( value, keypath, ractive ) ) { + ractive._wrapped[ keypath ] = magicArrayAdaptor.wrap( ractive, value, keypath ); + } else if ( magicAdaptor.filter( value, keypath, ractive ) ) { + ractive._wrapped[ keypath ] = magicAdaptor.wrap( ractive, value, keypath ); + } + } else if ( ractive.modifyArrays && arrayAdaptor.filter( value, keypath, ractive ) ) { + ractive._wrapped[ keypath ] = arrayAdaptor.wrap( ractive, value, keypath ); + } + } + return value; + }; + + function prefixKeypath( obj, prefix ) { + var prefixed = {}, key; + if ( !prefix ) { + return obj; + } + prefix += '.'; + for ( key in obj ) { + if ( obj.hasOwnProperty( key ) ) { + prefixed[ prefix + key ] = obj[ key ]; + } + } + return prefixed; + } + + function getPrefixer( rootKeypath ) { + var rootDot; + if ( !prefixers[ rootKeypath ] ) { + rootDot = rootKeypath ? rootKeypath + '.' : ''; + prefixers[ rootKeypath ] = function( relativeKeypath, value ) { + var obj; + if ( typeof relativeKeypath === 'string' ) { + obj = {}; + obj[ rootDot + relativeKeypath ] = value; + return obj; + } + if ( typeof relativeKeypath === 'object' ) { + // 'relativeKeypath' is in fact a hash, not a keypath + return rootDot ? prefixKeypath( relativeKeypath, rootKeypath ) : relativeKeypath; + } + }; + } + return prefixers[ rootKeypath ]; + } + }( registries_adaptors, shared_get_arrayAdaptor__arrayAdaptor, shared_get_magicAdaptor, shared_get_magicArrayAdaptor ); + + var shared_registerDependant = function() { + + return function registerDependant( dependant ) { + var depsByKeypath, deps, ractive, keypath, priority; + ractive = dependant.root; + keypath = dependant.keypath; + priority = dependant.priority; + depsByKeypath = ractive._deps[ priority ] || ( ractive._deps[ priority ] = {} ); + deps = depsByKeypath[ keypath ] || ( depsByKeypath[ keypath ] = [] ); + deps.push( dependant ); + dependant.registered = true; + if ( !keypath ) { + return; + } + updateDependantsMap( ractive, keypath ); + }; + + function updateDependantsMap( ractive, keypath ) { + var keys, parentKeypath, map; + // update dependants map + keys = keypath.split( '.' ); + while ( keys.length ) { + keys.pop(); + parentKeypath = keys.join( '.' ); + map = ractive._depsMap[ parentKeypath ] || ( ractive._depsMap[ parentKeypath ] = [] ); + if ( map[ keypath ] === undefined ) { + map[ keypath ] = 0; + map[ map.length ] = keypath; + } + map[ keypath ] += 1; + keypath = parentKeypath; + } + } + }(); + + var shared_unregisterDependant = function() { + + return function unregisterDependant( dependant ) { + var deps, index, ractive, keypath, priority; + ractive = dependant.root; + keypath = dependant.keypath; + priority = dependant.priority; + deps = ractive._deps[ priority ][ keypath ]; + index = deps.indexOf( dependant ); + if ( index === -1 || !dependant.registered ) { + throw new Error( 'Attempted to remove a dependant that was no longer registered! This should not happen. If you are seeing this bug in development please raise an issue at https://github.com/RactiveJS/Ractive/issues - thanks' ); + } + deps.splice( index, 1 ); + dependant.registered = false; + if ( !keypath ) { + return; + } + updateDependantsMap( ractive, keypath ); + }; + + function updateDependantsMap( ractive, keypath ) { + var keys, parentKeypath, map; + // update dependants map + keys = keypath.split( '.' ); + while ( keys.length ) { + keys.pop(); + parentKeypath = keys.join( '.' ); + map = ractive._depsMap[ parentKeypath ]; + map[ keypath ] -= 1; + if ( !map[ keypath ] ) { + // remove from parent deps map + map.splice( map.indexOf( keypath ), 1 ); + map[ keypath ] = undefined; + } + keypath = parentKeypath; + } + } + }(); + + var shared_createComponentBinding = function( circular, runloop, isArray, isEqual, registerDependant, unregisterDependant ) { + + var get, set; + circular.push( function() { + get = circular.get; + set = circular.set; + } ); + var Binding = function( ractive, keypath, otherInstance, otherKeypath, priority ) { + this.root = ractive; + this.keypath = keypath; + this.priority = priority; + this.otherInstance = otherInstance; + this.otherKeypath = otherKeypath; + registerDependant( this ); + this.value = get( this.root, this.keypath ); + }; + Binding.prototype = { + update: function() { + var value; + // Only *you* can prevent infinite loops + if ( this.updating || this.counterpart && this.counterpart.updating ) { + return; + } + value = get( this.root, this.keypath ); + // Is this a smart array update? If so, it'll update on its + // own, we shouldn't do anything + if ( isArray( value ) && value._ractive && value._ractive.setting ) { + return; + } + if ( !isEqual( value, this.value ) ) { + this.updating = true; + // TODO maybe the case that `value === this.value` - should that result + // in an update rather than a set? + runloop.addInstance( this.otherInstance ); + set( this.otherInstance, this.otherKeypath, value ); + this.value = value; + // TODO will the counterpart update after this line, during + // the runloop end cycle? may be a problem... + this.updating = false; + } + }, + reassign: function( newKeypath ) { + unregisterDependant( this ); + unregisterDependant( this.counterpart ); + this.keypath = newKeypath; + this.counterpart.otherKeypath = newKeypath; + registerDependant( this ); + registerDependant( this.counterpart ); + }, + teardown: function() { + unregisterDependant( this ); + } + }; + return function createComponentBinding( component, parentInstance, parentKeypath, childKeypath ) { + var hash, childInstance, bindings, priority, parentToChildBinding, childToParentBinding; + hash = parentKeypath + '=' + childKeypath; + bindings = component.bindings; + if ( bindings[ hash ] ) { + // TODO does this ever happen? + return; + } + bindings[ hash ] = true; + childInstance = component.instance; + priority = component.parentFragment.priority; + parentToChildBinding = new Binding( parentInstance, parentKeypath, childInstance, childKeypath, priority ); + bindings.push( parentToChildBinding ); + if ( childInstance.twoway ) { + childToParentBinding = new Binding( childInstance, childKeypath, parentInstance, parentKeypath, 1 ); + bindings.push( childToParentBinding ); + parentToChildBinding.counterpart = childToParentBinding; + childToParentBinding.counterpart = parentToChildBinding; + } + }; + }( circular, global_runloop, utils_isArray, utils_isEqual, shared_registerDependant, shared_unregisterDependant ); + + var shared_get_getFromParent = function( circular, createComponentBinding, set ) { + + var get; + circular.push( function() { + get = circular.get; + } ); + return function getFromParent( child, keypath ) { + var parent, fragment, keypathToTest, value, index; + parent = child._parent; + fragment = child.component.parentFragment; + // Special case - index refs + if ( fragment.indexRefs && ( index = fragment.indexRefs[ keypath ] ) !== undefined ) { + // create an index ref binding, so that it can be reassigned letter if necessary + child.component.indexRefBindings[ keypath ] = keypath; + return index; + } + do { + if ( !fragment.context ) { + continue; + } + keypathToTest = fragment.context + '.' + keypath; + value = get( parent, keypathToTest ); + if ( value !== undefined ) { + createLateComponentBinding( parent, child, keypathToTest, keypath, value ); + return value; + } + } while ( fragment = fragment.parent ); + value = get( parent, keypath ); + if ( value !== undefined ) { + createLateComponentBinding( parent, child, keypath, keypath, value ); + return value; + } + }; + + function createLateComponentBinding( parent, child, parentKeypath, childKeypath, value ) { + set( child, childKeypath, value, true ); + createComponentBinding( child.component, parent, parentKeypath, childKeypath ); + } + }( circular, shared_createComponentBinding, shared_set ); + + var shared_get_FAILED_LOOKUP = { + FAILED_LOOKUP: true + }; + + var shared_get__get = function( circular, hasOwnProperty, clone, adaptIfNecessary, getFromParent, FAILED_LOOKUP ) { + + function get( ractive, keypath, options ) { + var cache = ractive._cache, + value, computation, wrapped, evaluator; + if ( cache[ keypath ] === undefined ) { + // Is this a computed property? + if ( computation = ractive._computations[ keypath ] ) { + value = computation.value; + } else if ( wrapped = ractive._wrapped[ keypath ] ) { + value = wrapped.value; + } else if ( !keypath ) { + adaptIfNecessary( ractive, '', ractive.data ); + value = ractive.data; + } else if ( evaluator = ractive._evaluators[ keypath ] ) { + value = evaluator.value; + } else { + value = retrieve( ractive, keypath ); + } + cache[ keypath ] = value; + } else { + value = cache[ keypath ]; + } + // If the property doesn't exist on this viewmodel, we + // can try going up a scope. This will create bindings + // between parent and child if possible + if ( value === FAILED_LOOKUP ) { + if ( ractive._parent && !ractive.isolated ) { + value = getFromParent( ractive, keypath, options ); + } else { + value = undefined; + } + } + if ( options && options.evaluateWrapped && ( wrapped = ractive._wrapped[ keypath ] ) ) { + value = wrapped.get(); + } + return value; + } + circular.get = get; + return get; + + function retrieve( ractive, keypath ) { + var keys, key, parentKeypath, parentValue, cacheMap, value, wrapped, shouldClone; + keys = keypath.split( '.' ); + key = keys.pop(); + parentKeypath = keys.join( '.' ); + parentValue = get( ractive, parentKeypath ); + if ( wrapped = ractive._wrapped[ parentKeypath ] ) { + parentValue = wrapped.get(); + } + if ( parentValue === null || parentValue === undefined ) { + return; + } + // update cache map + if ( !( cacheMap = ractive._cacheMap[ parentKeypath ] ) ) { + ractive._cacheMap[ parentKeypath ] = [ keypath ]; + } else { + if ( cacheMap.indexOf( keypath ) === -1 ) { + cacheMap.push( keypath ); + } + } + // If this property doesn't exist, we return a sentinel value + // so that we know to query parent scope (if such there be) + if ( typeof parentValue === 'object' && !( key in parentValue ) ) { + return ractive._cache[ keypath ] = FAILED_LOOKUP; + } + // If this value actually lives on the prototype of this + // instance's `data`, and not as an own property, we need to + // clone it. Otherwise the instance could end up manipulating + // data that doesn't belong to it + shouldClone = !hasOwnProperty.call( parentValue, key ); + value = shouldClone ? clone( parentValue[ key ] ) : parentValue[ key ]; + // Do we have an adaptor for this value? + value = adaptIfNecessary( ractive, keypath, value, false ); + // Update cache + ractive._cache[ keypath ] = value; + return value; + } + }( circular, utils_hasOwnProperty, utils_clone, shared_adaptIfNecessary, shared_get_getFromParent, shared_get_FAILED_LOOKUP ); + + /* global console */ + var utils_warn = function() { + + if ( typeof console !== 'undefined' && typeof console.warn === 'function' && typeof console.warn.apply === 'function' ) { + return function() { + console.warn.apply( console, arguments ); + }; + } + return function() {}; + }(); + + var utils_isObject = function() { + + var toString = Object.prototype.toString; + return function( thing ) { + return typeof thing === 'object' && toString.call( thing ) === '[object Object]'; + }; + }(); + + var registries_interpolators = function( circular, hasOwnProperty, isArray, isObject, isNumeric ) { + + var interpolators, interpolate, cssLengthPattern; + circular.push( function() { + interpolate = circular.interpolate; + } ); + cssLengthPattern = /^([+-]?[0-9]+\.?(?:[0-9]+)?)(px|em|ex|%|in|cm|mm|pt|pc)$/; + interpolators = { + number: function( from, to ) { + var delta; + if ( !isNumeric( from ) || !isNumeric( to ) ) { + return null; + } + from = +from; + to = +to; + delta = to - from; + if ( !delta ) { + return function() { + return from; + }; + } + return function( t ) { + return from + t * delta; + }; + }, + array: function( from, to ) { + var intermediate, interpolators, len, i; + if ( !isArray( from ) || !isArray( to ) ) { + return null; + } + intermediate = []; + interpolators = []; + i = len = Math.min( from.length, to.length ); + while ( i-- ) { + interpolators[ i ] = interpolate( from[ i ], to[ i ] ); + } + // surplus values - don't interpolate, but don't exclude them either + for ( i = len; i < from.length; i += 1 ) { + intermediate[ i ] = from[ i ]; + } + for ( i = len; i < to.length; i += 1 ) { + intermediate[ i ] = to[ i ]; + } + return function( t ) { + var i = len; + while ( i-- ) { + intermediate[ i ] = interpolators[ i ]( t ); + } + return intermediate; + }; + }, + object: function( from, to ) { + var properties, len, interpolators, intermediate, prop; + if ( !isObject( from ) || !isObject( to ) ) { + return null; + } + properties = []; + intermediate = {}; + interpolators = {}; + for ( prop in from ) { + if ( hasOwnProperty.call( from, prop ) ) { + if ( hasOwnProperty.call( to, prop ) ) { + properties.push( prop ); + interpolators[ prop ] = interpolate( from[ prop ], to[ prop ] ); + } else { + intermediate[ prop ] = from[ prop ]; + } + } + } + for ( prop in to ) { + if ( hasOwnProperty.call( to, prop ) && !hasOwnProperty.call( from, prop ) ) { + intermediate[ prop ] = to[ prop ]; + } + } + len = properties.length; + return function( t ) { + var i = len, + prop; + while ( i-- ) { + prop = properties[ i ]; + intermediate[ prop ] = interpolators[ prop ]( t ); + } + return intermediate; + }; + }, + cssLength: function( from, to ) { + var fromMatch, toMatch, fromUnit, toUnit, fromValue, toValue, unit, delta; + if ( from !== 0 && typeof from !== 'string' || to !== 0 && typeof to !== 'string' ) { + return null; + } + fromMatch = cssLengthPattern.exec( from ); + toMatch = cssLengthPattern.exec( to ); + fromUnit = fromMatch ? fromMatch[ 2 ] : ''; + toUnit = toMatch ? toMatch[ 2 ] : ''; + if ( fromUnit && toUnit && fromUnit !== toUnit ) { + return null; + } + unit = fromUnit || toUnit; + fromValue = fromMatch ? +fromMatch[ 1 ] : 0; + toValue = toMatch ? +toMatch[ 1 ] : 0; + delta = toValue - fromValue; + if ( !delta ) { + return function() { + return fromValue + unit; + }; + } + return function( t ) { + return fromValue + t * delta + unit; + }; + } + }; + return interpolators; + }( circular, utils_hasOwnProperty, utils_isArray, utils_isObject, utils_isNumeric ); + + var shared_interpolate = function( circular, warn, interpolators ) { + + var interpolate = function( from, to, ractive, type ) { + if ( from === to ) { + return snap( to ); + } + if ( type ) { + if ( ractive.interpolators[ type ] ) { + return ractive.interpolators[ type ]( from, to ) || snap( to ); + } + warn( 'Missing "' + type + '" interpolator. You may need to download a plugin from [TODO]' ); + } + return interpolators.number( from, to ) || interpolators.array( from, to ) || interpolators.object( from, to ) || interpolators.cssLength( from, to ) || snap( to ); + }; + circular.interpolate = interpolate; + return interpolate; + + function snap( to ) { + return function() { + return to; + }; + } + }( circular, utils_warn, registries_interpolators ); + + var Ractive_prototype_animate_Animation = function( warn, runloop, interpolate, set ) { + + var Animation = function( options ) { + var key; + this.startTime = Date.now(); + // from and to + for ( key in options ) { + if ( options.hasOwnProperty( key ) ) { + this[ key ] = options[ key ]; + } + } + this.interpolator = interpolate( this.from, this.to, this.root, this.interpolator ); + this.running = true; + }; + Animation.prototype = { + tick: function() { + var elapsed, t, value, timeNow, index, keypath; + keypath = this.keypath; + if ( this.running ) { + timeNow = Date.now(); + elapsed = timeNow - this.startTime; + if ( elapsed >= this.duration ) { + if ( keypath !== null ) { + runloop.start( this.root ); + set( this.root, keypath, this.to ); + runloop.end(); + } + if ( this.step ) { + this.step( 1, this.to ); + } + this.complete( this.to ); + index = this.root._animations.indexOf( this ); + // TODO investigate why this happens + if ( index === -1 ) { + warn( 'Animation was not found' ); + } + this.root._animations.splice( index, 1 ); + this.running = false; + return false; + } + t = this.easing ? this.easing( elapsed / this.duration ) : elapsed / this.duration; + if ( keypath !== null ) { + value = this.interpolator( t ); + runloop.start( this.root ); + set( this.root, keypath, value ); + runloop.end(); + } + if ( this.step ) { + this.step( t, value ); + } + return true; + } + return false; + }, + stop: function() { + var index; + this.running = false; + index = this.root._animations.indexOf( this ); + // TODO investigate why this happens + if ( index === -1 ) { + warn( 'Animation was not found' ); + } + this.root._animations.splice( index, 1 ); + } + }; + return Animation; + }( utils_warn, global_runloop, shared_interpolate, shared_set ); + + var Ractive_prototype_animate__animate = function( isEqual, Promise, normaliseKeypath, animations, get, Animation ) { + + var noop = function() {}, noAnimation = { + stop: noop + }; + return function( keypath, to, options ) { + var promise, fulfilPromise, k, animation, animations, easing, duration, step, complete, makeValueCollector, currentValues, collectValue, dummy, dummyOptions; + promise = new Promise( function( fulfil ) { + fulfilPromise = fulfil; + } ); + // animate multiple keypaths + if ( typeof keypath === 'object' ) { + options = to || {}; + easing = options.easing; + duration = options.duration; + animations = []; + // we don't want to pass the `step` and `complete` handlers, as they will + // run for each animation! So instead we'll store the handlers and create + // our own... + step = options.step; + complete = options.complete; + if ( step || complete ) { + currentValues = {}; + options.step = null; + options.complete = null; + makeValueCollector = function( keypath ) { + return function( t, value ) { + currentValues[ keypath ] = value; + }; + }; + } + for ( k in keypath ) { + if ( keypath.hasOwnProperty( k ) ) { + if ( step || complete ) { + collectValue = makeValueCollector( k ); + options = { + easing: easing, + duration: duration + }; + if ( step ) { + options.step = collectValue; + } + } + options.complete = complete ? collectValue : noop; + animations.push( animate( this, k, keypath[ k ], options ) ); + } + } + if ( step || complete ) { + dummyOptions = { + easing: easing, + duration: duration + }; + if ( step ) { + dummyOptions.step = function( t ) { + step( t, currentValues ); + }; + } + if ( complete ) { + promise.then( function( t ) { + complete( t, currentValues ); + } ); + } + dummyOptions.complete = fulfilPromise; + dummy = animate( this, null, null, dummyOptions ); + animations.push( dummy ); + } + return { + stop: function() { + var animation; + while ( animation = animations.pop() ) { + animation.stop(); + } + if ( dummy ) { + dummy.stop(); + } + } + }; + } + // animate a single keypath + options = options || {}; + if ( options.complete ) { + promise.then( options.complete ); + } + options.complete = fulfilPromise; + animation = animate( this, keypath, to, options ); + promise.stop = function() { + animation.stop(); + }; + return promise; + }; + + function animate( root, keypath, to, options ) { + var easing, duration, animation, from; + if ( keypath ) { + keypath = normaliseKeypath( keypath ); + } + if ( keypath !== null ) { + from = get( root, keypath ); + } + // cancel any existing animation + // TODO what about upstream/downstream keypaths? + animations.abort( keypath, root ); + // don't bother animating values that stay the same + if ( isEqual( from, to ) ) { + if ( options.complete ) { + options.complete( options.to ); + } + return noAnimation; + } + // easing function + if ( options.easing ) { + if ( typeof options.easing === 'function' ) { + easing = options.easing; + } else { + easing = root.easing[ options.easing ]; + } + if ( typeof easing !== 'function' ) { + easing = null; + } + } + // duration + duration = options.duration === undefined ? 400 : options.duration; + // TODO store keys, use an internal set method + animation = new Animation( { + keypath: keypath, + from: from, + to: to, + root: root, + duration: duration, + easing: easing, + interpolator: options.interpolator, + // TODO wrap callbacks if necessary, to use instance as context + step: options.step, + complete: options.complete + } ); + animations.add( animation ); + root._animations.push( animation ); + return animation; + } + }( utils_isEqual, utils_Promise, utils_normaliseKeypath, shared_animations, shared_get__get, Ractive_prototype_animate_Animation ); + + var Ractive_prototype_detach = function() { + return this.fragment.detach(); + }; + + var Ractive_prototype_find = function( selector ) { + if ( !this.el ) { + return null; + } + return this.fragment.find( selector ); + }; + + var utils_matches = function( isClient, vendors, createElement ) { + + var div, methodNames, unprefixed, prefixed, i, j, makeFunction; + if ( !isClient ) { + return; + } + div = createElement( 'div' ); + methodNames = [ + 'matches', + 'matchesSelector' + ]; + makeFunction = function( methodName ) { + return function( node, selector ) { + return node[ methodName ]( selector ); + }; + }; + i = methodNames.length; + while ( i-- ) { + unprefixed = methodNames[ i ]; + if ( div[ unprefixed ] ) { + return makeFunction( unprefixed ); + } + j = vendors.length; + while ( j-- ) { + prefixed = vendors[ i ] + unprefixed.substr( 0, 1 ).toUpperCase() + unprefixed.substring( 1 ); + if ( div[ prefixed ] ) { + return makeFunction( prefixed ); + } + } + } + // IE8... + return function( node, selector ) { + var nodes, i; + nodes = ( node.parentNode || node.document ).querySelectorAll( selector ); + i = nodes.length; + while ( i-- ) { + if ( nodes[ i ] === node ) { + return true; + } + } + return false; + }; + }( config_isClient, config_vendors, utils_createElement ); + + var Ractive_prototype_shared_makeQuery_test = function( matches ) { + + return function( item, noDirty ) { + var itemMatches = this._isComponentQuery ? !this.selector || item.name === this.selector : matches( item.node, this.selector ); + if ( itemMatches ) { + this.push( item.node || item.instance ); + if ( !noDirty ) { + this._makeDirty(); + } + return true; + } + }; + }( utils_matches ); + + var Ractive_prototype_shared_makeQuery_cancel = function() { + var liveQueries, selector, index; + liveQueries = this._root[ this._isComponentQuery ? 'liveComponentQueries' : 'liveQueries' ]; + selector = this.selector; + index = liveQueries.indexOf( selector ); + if ( index !== -1 ) { + liveQueries.splice( index, 1 ); + liveQueries[ selector ] = null; + } + }; + + var Ractive_prototype_shared_makeQuery_sortByItemPosition = function() { + + return function( a, b ) { + var ancestryA, ancestryB, oldestA, oldestB, mutualAncestor, indexA, indexB, fragments, fragmentA, fragmentB; + ancestryA = getAncestry( a.component || a._ractive.proxy ); + ancestryB = getAncestry( b.component || b._ractive.proxy ); + oldestA = ancestryA[ ancestryA.length - 1 ]; + oldestB = ancestryB[ ancestryB.length - 1 ]; + // remove items from the end of both ancestries as long as they are identical + // - the final one removed is the closest mutual ancestor + while ( oldestA && oldestA === oldestB ) { + ancestryA.pop(); + ancestryB.pop(); + mutualAncestor = oldestA; + oldestA = ancestryA[ ancestryA.length - 1 ]; + oldestB = ancestryB[ ancestryB.length - 1 ]; + } + // now that we have the mutual ancestor, we can find which is earliest + oldestA = oldestA.component || oldestA; + oldestB = oldestB.component || oldestB; + fragmentA = oldestA.parentFragment; + fragmentB = oldestB.parentFragment; + // if both items share a parent fragment, our job is easy + if ( fragmentA === fragmentB ) { + indexA = fragmentA.items.indexOf( oldestA ); + indexB = fragmentB.items.indexOf( oldestB ); + // if it's the same index, it means one contains the other, + // so we see which has the longest ancestry + return indexA - indexB || ancestryA.length - ancestryB.length; + } + // if mutual ancestor is a section, we first test to see which section + // fragment comes first + if ( fragments = mutualAncestor.fragments ) { + indexA = fragments.indexOf( fragmentA ); + indexB = fragments.indexOf( fragmentB ); + return indexA - indexB || ancestryA.length - ancestryB.length; + } + throw new Error( 'An unexpected condition was met while comparing the position of two components. Please file an issue at https://github.com/RactiveJS/Ractive/issues - thanks!' ); + }; + + function getParent( item ) { + var parentFragment; + if ( parentFragment = item.parentFragment ) { + return parentFragment.owner; + } + if ( item.component && ( parentFragment = item.component.parentFragment ) ) { + return parentFragment.owner; + } + } + + function getAncestry( item ) { + var ancestry, ancestor; + ancestry = [ item ]; + ancestor = getParent( item ); + while ( ancestor ) { + ancestry.push( ancestor ); + ancestor = getParent( ancestor ); + } + return ancestry; + } + }(); + + var Ractive_prototype_shared_makeQuery_sortByDocumentPosition = function( sortByItemPosition ) { + + return function( node, otherNode ) { + var bitmask; + if ( node.compareDocumentPosition ) { + bitmask = node.compareDocumentPosition( otherNode ); + return bitmask & 2 ? 1 : -1; + } + // In old IE, we can piggy back on the mechanism for + // comparing component positions + return sortByItemPosition( node, otherNode ); + }; + }( Ractive_prototype_shared_makeQuery_sortByItemPosition ); + + var Ractive_prototype_shared_makeQuery_sort = function( sortByDocumentPosition, sortByItemPosition ) { + + return function() { + this.sort( this._isComponentQuery ? sortByItemPosition : sortByDocumentPosition ); + this._dirty = false; + }; + }( Ractive_prototype_shared_makeQuery_sortByDocumentPosition, Ractive_prototype_shared_makeQuery_sortByItemPosition ); + + var Ractive_prototype_shared_makeQuery_dirty = function( runloop ) { + + return function() { + if ( !this._dirty ) { + runloop.addLiveQuery( this ); + this._dirty = true; + } + }; + }( global_runloop ); + + var Ractive_prototype_shared_makeQuery_remove = function( nodeOrComponent ) { + var index = this.indexOf( this._isComponentQuery ? nodeOrComponent.instance : nodeOrComponent ); + if ( index !== -1 ) { + this.splice( index, 1 ); + } + }; + + var Ractive_prototype_shared_makeQuery__makeQuery = function( defineProperties, test, cancel, sort, dirty, remove ) { + + return function( ractive, selector, live, isComponentQuery ) { + var query = []; + defineProperties( query, { + selector: { + value: selector + }, + live: { + value: live + }, + _isComponentQuery: { + value: isComponentQuery + }, + _test: { + value: test + } + } ); + if ( !live ) { + return query; + } + defineProperties( query, { + cancel: { + value: cancel + }, + _root: { + value: ractive + }, + _sort: { + value: sort + }, + _makeDirty: { + value: dirty + }, + _remove: { + value: remove + }, + _dirty: { + value: false, + writable: true + } + } ); + return query; + }; + }( utils_defineProperties, Ractive_prototype_shared_makeQuery_test, Ractive_prototype_shared_makeQuery_cancel, Ractive_prototype_shared_makeQuery_sort, Ractive_prototype_shared_makeQuery_dirty, Ractive_prototype_shared_makeQuery_remove ); + + var Ractive_prototype_findAll = function( makeQuery ) { + + return function( selector, options ) { + var liveQueries, query; + if ( !this.el ) { + return []; + } + options = options || {}; + liveQueries = this._liveQueries; + // Shortcut: if we're maintaining a live query with this + // selector, we don't need to traverse the parallel DOM + if ( query = liveQueries[ selector ] ) { + // Either return the exact same query, or (if not live) a snapshot + return options && options.live ? query : query.slice(); + } + query = makeQuery( this, selector, !! options.live, false ); + // Add this to the list of live queries Ractive needs to maintain, + // if applicable + if ( query.live ) { + liveQueries.push( selector ); + liveQueries[ selector ] = query; + } + this.fragment.findAll( selector, query ); + return query; + }; + }( Ractive_prototype_shared_makeQuery__makeQuery ); + + var Ractive_prototype_findAllComponents = function( makeQuery ) { + + return function( selector, options ) { + var liveQueries, query; + options = options || {}; + liveQueries = this._liveComponentQueries; + // Shortcut: if we're maintaining a live query with this + // selector, we don't need to traverse the parallel DOM + if ( query = liveQueries[ selector ] ) { + // Either return the exact same query, or (if not live) a snapshot + return options && options.live ? query : query.slice(); + } + query = makeQuery( this, selector, !! options.live, true ); + // Add this to the list of live queries Ractive needs to maintain, + // if applicable + if ( query.live ) { + liveQueries.push( selector ); + liveQueries[ selector ] = query; + } + this.fragment.findAllComponents( selector, query ); + return query; + }; + }( Ractive_prototype_shared_makeQuery__makeQuery ); + + var Ractive_prototype_findComponent = function( selector ) { + return this.fragment.findComponent( selector ); + }; + + var Ractive_prototype_fire = function( eventName ) { + var args, i, len, subscribers = this._subs[ eventName ]; + if ( !subscribers ) { + return; + } + args = Array.prototype.slice.call( arguments, 1 ); + for ( i = 0, len = subscribers.length; i < len; i += 1 ) { + subscribers[ i ].apply( this, args ); + } + }; + + var shared_get_UnresolvedImplicitDependency = function( circular, removeFromArray, runloop, notifyDependants ) { + + var get, empty = {}; + circular.push( function() { + get = circular.get; + } ); + var UnresolvedImplicitDependency = function( ractive, keypath ) { + this.root = ractive; + this.ref = keypath; + this.parentFragment = empty; + ractive._unresolvedImplicitDependencies[ keypath ] = true; + ractive._unresolvedImplicitDependencies.push( this ); + runloop.addUnresolved( this ); + }; + UnresolvedImplicitDependency.prototype = { + resolve: function() { + var ractive = this.root; + notifyDependants( ractive, this.ref ); + ractive._unresolvedImplicitDependencies[ this.ref ] = false; + removeFromArray( ractive._unresolvedImplicitDependencies, this ); + }, + teardown: function() { + runloop.removeUnresolved( this ); + } + }; + return UnresolvedImplicitDependency; + }( circular, utils_removeFromArray, global_runloop, shared_notifyDependants ); + + var Ractive_prototype_get = function( normaliseKeypath, get, UnresolvedImplicitDependency ) { + + var options = { + isTopLevel: true + }; + return function Ractive_prototype_get( keypath ) { + var value; + keypath = normaliseKeypath( keypath ); + value = get( this, keypath, options ); + // capture the dependency, if we're inside an evaluator + if ( this._captured && this._captured[ keypath ] !== true ) { + this._captured.push( keypath ); + this._captured[ keypath ] = true; + // if we couldn't resolve the keypath, we need to make it as a failed + // lookup, so that the evaluator updates correctly once we CAN + // resolve the keypath + if ( value === undefined && this._unresolvedImplicitDependencies[ keypath ] !== true ) { + new UnresolvedImplicitDependency( this, keypath ); + } + } + return value; + }; + }( utils_normaliseKeypath, shared_get__get, shared_get_UnresolvedImplicitDependency ); + + var utils_getElement = function( input ) { + var output; + if ( typeof window === 'undefined' || !document || !input ) { + return null; + } + // We already have a DOM node - no work to do. (Duck typing alert!) + if ( input.nodeType ) { + return input; + } + // Get node from string + if ( typeof input === 'string' ) { + // try ID first + output = document.getElementById( input ); + // then as selector, if possible + if ( !output && document.querySelector ) { + output = document.querySelector( input ); + } + // did it work? + if ( output && output.nodeType ) { + return output; + } + } + // If we've been given a collection (jQuery, Zepto etc), extract the first item + if ( input[ 0 ] && input[ 0 ].nodeType ) { + return input[ 0 ]; + } + return null; + }; + + var Ractive_prototype_insert = function( getElement ) { + + return function( target, anchor ) { + target = getElement( target ); + anchor = getElement( anchor ) || null; + if ( !target ) { + throw new Error( 'You must specify a valid target to insert into' ); + } + target.insertBefore( this.detach(), anchor ); + this.fragment.pNode = this.el = target; + }; + }( utils_getElement ); + + var Ractive_prototype_merge_mapOldToNewIndex = function( oldArray, newArray ) { + var usedIndices, firstUnusedIndex, newIndices, changed; + usedIndices = {}; + firstUnusedIndex = 0; + newIndices = oldArray.map( function( item, i ) { + var index, start, len; + start = firstUnusedIndex; + len = newArray.length; + do { + index = newArray.indexOf( item, start ); + if ( index === -1 ) { + changed = true; + return -1; + } + start = index + 1; + } while ( usedIndices[ index ] && start < len ); + // keep track of the first unused index, so we don't search + // the whole of newArray for each item in oldArray unnecessarily + if ( index === firstUnusedIndex ) { + firstUnusedIndex += 1; + } + if ( index !== i ) { + changed = true; + } + usedIndices[ index ] = true; + return index; + } ); + newIndices.unchanged = !changed; + return newIndices; + }; + + var Ractive_prototype_merge_propagateChanges = function( types, notifyDependants ) { + + return function( ractive, keypath, newIndices, lengthUnchanged ) { + var updateDependant; + ractive._changes.push( keypath ); + updateDependant = function( dependant ) { + // references need to get processed before mustaches + if ( dependant.type === types.REFERENCE ) { + dependant.update(); + } else if ( dependant.keypath === keypath && dependant.type === types.SECTION && !dependant.inverted && dependant.docFrag ) { + dependant.merge( newIndices ); + } else { + dependant.update(); + } + }; + // Go through all dependant priority levels, finding merge targets + ractive._deps.forEach( function( depsByKeypath ) { + var dependants = depsByKeypath[ keypath ]; + if ( dependants ) { + dependants.forEach( updateDependant ); + } + } ); + // length property has changed - notify dependants + // TODO in some cases (e.g. todo list example, when marking all as complete, then + // adding a new item (which should deactivate the 'all complete' checkbox + // but doesn't) this needs to happen before other updates. But doing so causes + // other mental problems. not sure what's going on... + if ( !lengthUnchanged ) { + notifyDependants( ractive, keypath + '.length', true ); + } + }; + }( config_types, shared_notifyDependants ); + + var Ractive_prototype_merge__merge = function( runloop, warn, isArray, Promise, set, mapOldToNewIndex, propagateChanges ) { + + var comparators = {}; + return function merge( keypath, array, options ) { + var currentArray, oldArray, newArray, comparator, lengthUnchanged, newIndices, promise, fulfilPromise; + currentArray = this.get( keypath ); + // If either the existing value or the new value isn't an + // array, just do a regular set + if ( !isArray( currentArray ) || !isArray( array ) ) { + return this.set( keypath, array, options && options.complete ); + } + lengthUnchanged = currentArray.length === array.length; + if ( options && options.compare ) { + comparator = getComparatorFunction( options.compare ); + try { + oldArray = currentArray.map( comparator ); + newArray = array.map( comparator ); + } catch ( err ) { + // fallback to an identity check - worst case scenario we have + // to do more DOM manipulation than we thought... + // ...unless we're in debug mode of course + if ( this.debug ) { + throw err; + } else { + warn( 'Merge operation: comparison failed. Falling back to identity checking' ); + } + oldArray = currentArray; + newArray = array; + } + } else { + oldArray = currentArray; + newArray = array; + } + // find new indices for members of oldArray + newIndices = mapOldToNewIndex( oldArray, newArray ); + // Manage transitions + promise = new Promise( function( fulfil ) { + fulfilPromise = fulfil; + } ); + runloop.start( this, fulfilPromise ); + // Update the model + // TODO allow existing array to be updated in place, rather than replaced? + set( this, keypath, array, true ); + propagateChanges( this, keypath, newIndices, lengthUnchanged ); + runloop.end(); + // attach callback as fulfilment handler, if specified + if ( options && options.complete ) { + promise.then( options.complete ); + } + return promise; + }; + + function stringify( item ) { + return JSON.stringify( item ); + } + + function getComparatorFunction( comparator ) { + // If `compare` is `true`, we use JSON.stringify to compare + // objects that are the same shape, but non-identical - i.e. + // { foo: 'bar' } !== { foo: 'bar' } + if ( comparator === true ) { + return stringify; + } + if ( typeof comparator === 'string' ) { + if ( !comparators[ comparator ] ) { + comparators[ comparator ] = function( item ) { + return item[ comparator ]; + }; + } + return comparators[ comparator ]; + } + if ( typeof comparator === 'function' ) { + return comparator; + } + throw new Error( 'The `compare` option must be a function, or a string representing an identifying field (or `true` to use JSON.stringify)' ); + } + }( global_runloop, utils_warn, utils_isArray, utils_Promise, shared_set, Ractive_prototype_merge_mapOldToNewIndex, Ractive_prototype_merge_propagateChanges ); + + var Ractive_prototype_observe_Observer = function( runloop, isEqual, get ) { + + var Observer = function( ractive, keypath, callback, options ) { + var self = this; + this.root = ractive; + this.keypath = keypath; + this.callback = callback; + this.defer = options.defer; + this.debug = options.debug; + this.proxy = { + update: function() { + self.reallyUpdate(); + } + }; + // Observers are notified before any DOM changes take place (though + // they can defer execution until afterwards) + this.priority = 0; + // default to root as context, but allow it to be overridden + this.context = options && options.context ? options.context : ractive; + }; + Observer.prototype = { + init: function( immediate ) { + if ( immediate !== false ) { + this.update(); + } else { + this.value = get( this.root, this.keypath ); + } + }, + update: function() { + if ( this.defer && this.ready ) { + runloop.addObserver( this.proxy ); + return; + } + this.reallyUpdate(); + }, + reallyUpdate: function() { + var oldValue, newValue; + oldValue = this.value; + newValue = get( this.root, this.keypath ); + this.value = newValue; + // Prevent infinite loops + if ( this.updating ) { + return; + } + this.updating = true; + if ( !isEqual( newValue, oldValue ) || !this.ready ) { + // wrap the callback in a try-catch block, and only throw error in + // debug mode + try { + this.callback.call( this.context, newValue, oldValue, this.keypath ); + } catch ( err ) { + if ( this.debug || this.root.debug ) { + throw err; + } + } + } + this.updating = false; + } + }; + return Observer; + }( global_runloop, utils_isEqual, shared_get__get ); + + var Ractive_prototype_observe_getPattern = function( isArray ) { + + return function( ractive, pattern ) { + var keys, key, values, toGet, newToGet, expand, concatenate; + keys = pattern.split( '.' ); + toGet = []; + expand = function( keypath ) { + var value, key; + value = ractive._wrapped[ keypath ] ? ractive._wrapped[ keypath ].get() : ractive.get( keypath ); + for ( key in value ) { + if ( value.hasOwnProperty( key ) && ( key !== '_ractive' || !isArray( value ) ) ) { + // for benefit of IE8 + newToGet.push( keypath + '.' + key ); + } + } + }; + concatenate = function( keypath ) { + return keypath + '.' + key; + }; + while ( key = keys.shift() ) { + if ( key === '*' ) { + newToGet = []; + toGet.forEach( expand ); + toGet = newToGet; + } else { + if ( !toGet[ 0 ] ) { + toGet[ 0 ] = key; + } else { + toGet = toGet.map( concatenate ); + } + } + } + values = {}; + toGet.forEach( function( keypath ) { + values[ keypath ] = ractive.get( keypath ); + } ); + return values; + }; + }( utils_isArray ); + + var Ractive_prototype_observe_PatternObserver = function( runloop, isEqual, get, getPattern ) { + + var PatternObserver, wildcard = /\*/; + PatternObserver = function( ractive, keypath, callback, options ) { + this.root = ractive; + this.callback = callback; + this.defer = options.defer; + this.debug = options.debug; + this.keypath = keypath; + this.regex = new RegExp( '^' + keypath.replace( /\./g, '\\.' ).replace( /\*/g, '[^\\.]+' ) + '$' ); + this.values = {}; + if ( this.defer ) { + this.proxies = []; + } + // Observers are notified before any DOM changes take place (though + // they can defer execution until afterwards) + this.priority = 'pattern'; + // default to root as context, but allow it to be overridden + this.context = options && options.context ? options.context : ractive; + }; + PatternObserver.prototype = { + init: function( immediate ) { + var values, keypath; + values = getPattern( this.root, this.keypath ); + if ( immediate !== false ) { + for ( keypath in values ) { + if ( values.hasOwnProperty( keypath ) ) { + this.update( keypath ); + } + } + } else { + this.values = values; + } + }, + update: function( keypath ) { + var values; + if ( wildcard.test( keypath ) ) { + values = getPattern( this.root, keypath ); + for ( keypath in values ) { + if ( values.hasOwnProperty( keypath ) ) { + this.update( keypath ); + } + } + return; + } + if ( this.defer && this.ready ) { + runloop.addObserver( this.getProxy( keypath ) ); + return; + } + this.reallyUpdate( keypath ); + }, + reallyUpdate: function( keypath ) { + var value = get( this.root, keypath ); + // Prevent infinite loops + if ( this.updating ) { + this.values[ keypath ] = value; + return; + } + this.updating = true; + if ( !isEqual( value, this.values[ keypath ] ) || !this.ready ) { + // wrap the callback in a try-catch block, and only throw error in + // debug mode + try { + this.callback.call( this.context, value, this.values[ keypath ], keypath ); + } catch ( err ) { + if ( this.debug || this.root.debug ) { + throw err; + } + } + this.values[ keypath ] = value; + } + this.updating = false; + }, + getProxy: function( keypath ) { + var self = this; + if ( !this.proxies[ keypath ] ) { + this.proxies[ keypath ] = { + update: function() { + self.reallyUpdate( keypath ); + } + }; + } + return this.proxies[ keypath ]; + } + }; + return PatternObserver; + }( global_runloop, utils_isEqual, shared_get__get, Ractive_prototype_observe_getPattern ); + + var Ractive_prototype_observe_getObserverFacade = function( normaliseKeypath, registerDependant, unregisterDependant, Observer, PatternObserver ) { + + var wildcard = /\*/, + emptyObject = {}; + return function getObserverFacade( ractive, keypath, callback, options ) { + var observer, isPatternObserver; + keypath = normaliseKeypath( keypath ); + options = options || emptyObject; + // pattern observers are treated differently + if ( wildcard.test( keypath ) ) { + observer = new PatternObserver( ractive, keypath, callback, options ); + ractive._patternObservers.push( observer ); + isPatternObserver = true; + } else { + observer = new Observer( ractive, keypath, callback, options ); + } + registerDependant( observer ); + observer.init( options.init ); + // This flag allows observers to initialise even with undefined values + observer.ready = true; + return { + cancel: function() { + var index; + if ( isPatternObserver ) { + index = ractive._patternObservers.indexOf( observer ); + if ( index !== -1 ) { + ractive._patternObservers.splice( index, 1 ); + } + } + unregisterDependant( observer ); + } + }; + }; + }( utils_normaliseKeypath, shared_registerDependant, shared_unregisterDependant, Ractive_prototype_observe_Observer, Ractive_prototype_observe_PatternObserver ); + + var Ractive_prototype_observe__observe = function( isObject, getObserverFacade ) { + + return function observe( keypath, callback, options ) { + var observers, map, keypaths, i; + // Allow a map of keypaths to handlers + if ( isObject( keypath ) ) { + options = callback; + map = keypath; + observers = []; + for ( keypath in map ) { + if ( map.hasOwnProperty( keypath ) ) { + callback = map[ keypath ]; + observers.push( this.observe( keypath, callback, options ) ); + } + } + return { + cancel: function() { + while ( observers.length ) { + observers.pop().cancel(); + } + } + }; + } + // Allow `ractive.observe( callback )` - i.e. observe entire model + if ( typeof keypath === 'function' ) { + options = callback; + callback = keypath; + keypath = ''; + return getObserverFacade( this, keypath, callback, options ); + } + keypaths = keypath.split( ' ' ); + // Single keypath + if ( keypaths.length === 1 ) { + return getObserverFacade( this, keypath, callback, options ); + } + // Multiple space-separated keypaths + observers = []; + i = keypaths.length; + while ( i-- ) { + keypath = keypaths[ i ]; + if ( keypath ) { + observers.push( getObserverFacade( this, keypath, callback, options ) ); + } + } + return { + cancel: function() { + while ( observers.length ) { + observers.pop().cancel(); + } + } + }; + }; + }( utils_isObject, Ractive_prototype_observe_getObserverFacade ); + + var Ractive_prototype_off = function( eventName, callback ) { + var subscribers, index; + // if no callback specified, remove all callbacks + if ( !callback ) { + // if no event name specified, remove all callbacks for all events + if ( !eventName ) { + // TODO use this code instead, once the following issue has been resolved + // in PhantomJS (tests are unpassable otherwise!) + // https://github.com/ariya/phantomjs/issues/11856 + // defineProperty( this, '_subs', { value: create( null ), configurable: true }); + for ( eventName in this._subs ) { + delete this._subs[ eventName ]; + } + } else { + this._subs[ eventName ] = []; + } + } + subscribers = this._subs[ eventName ]; + if ( subscribers ) { + index = subscribers.indexOf( callback ); + if ( index !== -1 ) { + subscribers.splice( index, 1 ); + } + } + }; + + var Ractive_prototype_on = function( eventName, callback ) { + var self = this, + listeners, n; + // allow mutliple listeners to be bound in one go + if ( typeof eventName === 'object' ) { + listeners = []; + for ( n in eventName ) { + if ( eventName.hasOwnProperty( n ) ) { + listeners.push( this.on( n, eventName[ n ] ) ); + } + } + return { + cancel: function() { + var listener; + while ( listener = listeners.pop() ) { + listener.cancel(); + } + } + }; + } + if ( !this._subs[ eventName ] ) { + this._subs[ eventName ] = [ callback ]; + } else { + this._subs[ eventName ].push( callback ); + } + return { + cancel: function() { + self.off( eventName, callback ); + } + }; + }; + + var utils_create = function() { + + var create; + try { + Object.create( null ); + create = Object.create; + } catch ( err ) { + // sigh + create = function() { + var F = function() {}; + return function( proto, props ) { + var obj; + if ( proto === null ) { + return {}; + } + F.prototype = proto; + obj = new F(); + if ( props ) { + Object.defineProperties( obj, props ); + } + return obj; + }; + }(); + } + return create; + }(); + + var render_shared_Fragment_initialise = function( types, create ) { + + return function initFragment( fragment, options ) { + var numItems, i, parentFragment, parentRefs, ref; + // The item that owns this fragment - an element, section, partial, or attribute + fragment.owner = options.owner; + parentFragment = fragment.parent = fragment.owner.parentFragment; + // inherited properties + fragment.root = options.root; + fragment.pNode = options.pNode; + fragment.pElement = options.pElement; + fragment.context = options.context; + // If parent item is a section, this may not be the only fragment + // that belongs to it - we need to make a note of the index + if ( fragment.owner.type === types.SECTION ) { + fragment.index = options.index; + } + // index references (the 'i' in {{#section:i}}{{/section}}) need to cascade + // down the tree + if ( parentFragment ) { + parentRefs = parentFragment.indexRefs; + if ( parentRefs ) { + fragment.indexRefs = create( null ); + // avoids need for hasOwnProperty + for ( ref in parentRefs ) { + fragment.indexRefs[ ref ] = parentRefs[ ref ]; + } + } + } + // inherit priority + fragment.priority = parentFragment ? parentFragment.priority + 1 : 1; + if ( options.indexRef ) { + if ( !fragment.indexRefs ) { + fragment.indexRefs = {}; + } + fragment.indexRefs[ options.indexRef ] = options.index; + } + // Time to create this fragment's child items; + fragment.items = []; + numItems = options.descriptor ? options.descriptor.length : 0; + for ( i = 0; i < numItems; i += 1 ) { + fragment.items[ fragment.items.length ] = fragment.createItem( { + parentFragment: fragment, + pElement: options.pElement, + descriptor: options.descriptor[ i ], + index: i + } ); + } + }; + }( config_types, utils_create ); + + var render_shared_utils_startsWithKeypath = function startsWithKeypath( target, keypath ) { + return target.substr( 0, keypath.length + 1 ) === keypath + '.'; + }; + + var render_shared_utils_startsWith = function( startsWithKeypath ) { + + return function startsWith( target, keypath ) { + return target === keypath || startsWithKeypath( target, keypath ); + }; + }( render_shared_utils_startsWithKeypath ); + + var render_shared_utils_getNewKeypath = function( startsWithKeypath ) { + + return function getNewKeypath( targetKeypath, oldKeypath, newKeypath ) { + //exact match + if ( targetKeypath === oldKeypath ) { + return newKeypath; + } + //partial match based on leading keypath segments + if ( startsWithKeypath( targetKeypath, oldKeypath ) ) { + return targetKeypath.replace( oldKeypath + '.', newKeypath + '.' ); + } + }; + }( render_shared_utils_startsWithKeypath ); + + var render_shared_utils_assignNewKeypath = function( startsWith, getNewKeypath ) { + + return function assignNewKeypath( target, property, oldKeypath, newKeypath ) { + if ( !target[ property ] || startsWith( target[ property ], newKeypath ) ) { + return; + } + target[ property ] = getNewKeypath( target[ property ], oldKeypath, newKeypath ); + }; + }( render_shared_utils_startsWith, render_shared_utils_getNewKeypath ); + + var render_shared_Fragment_reassign = function( assignNewKeypath ) { + + return function reassignFragment( indexRef, newIndex, oldKeypath, newKeypath ) { + // If this fragment was rendered with innerHTML, we have nothing to do + // TODO a less hacky way of determining this + if ( this.html !== undefined ) { + return; + } + // assign new context keypath if needed + assignNewKeypath( this, 'context', oldKeypath, newKeypath ); + if ( this.indexRefs && this.indexRefs[ indexRef ] !== undefined && this.indexRefs[ indexRef ] !== newIndex ) { + this.indexRefs[ indexRef ] = newIndex; + } + this.items.forEach( function( item ) { + item.reassign( indexRef, newIndex, oldKeypath, newKeypath ); + } ); + }; + }( render_shared_utils_assignNewKeypath ); + + var render_shared_Fragment__Fragment = function( init, reassign ) { + + return { + init: init, + reassign: reassign + }; + }( render_shared_Fragment_initialise, render_shared_Fragment_reassign ); + + var render_DomFragment_shared_insertHtml = function( namespaces, createElement ) { + + var elementCache = {}, ieBug, ieBlacklist; + try { + createElement( 'table' ).innerHTML = 'foo'; + } catch ( err ) { + ieBug = true; + ieBlacklist = { + TABLE: [ + '', + '
' + ], + THEAD: [ + '', + '
' + ], + TBODY: [ + '', + '
' + ], + TR: [ + '', + '
' + ], + SELECT: [ + '' + ] + }; + } + return function( html, tagName, namespace, docFrag ) { + var container, nodes = [], + wrapper; + if ( html ) { + if ( ieBug && ( wrapper = ieBlacklist[ tagName ] ) ) { + container = element( 'DIV' ); + container.innerHTML = wrapper[ 0 ] + html + wrapper[ 1 ]; + container = container.querySelector( '.x' ); + } else if ( namespace === namespaces.svg ) { + container = element( 'DIV' ); + container.innerHTML = '' + html + ''; + container = container.querySelector( '.x' ); + } else { + container = element( tagName ); + container.innerHTML = html; + } + while ( container.firstChild ) { + nodes.push( container.firstChild ); + docFrag.appendChild( container.firstChild ); + } + } + return nodes; + }; + + function element( tagName ) { + return elementCache[ tagName ] || ( elementCache[ tagName ] = createElement( tagName ) ); + } + }( config_namespaces, utils_createElement ); + + var render_DomFragment_shared_detach = function() { + var node = this.node, + parentNode; + if ( node && ( parentNode = node.parentNode ) ) { + parentNode.removeChild( node ); + return node; + } + }; + + var render_DomFragment_Text = function( types, detach ) { + + var DomText, lessThan, greaterThan; + lessThan = //g; + DomText = function( options, docFrag ) { + this.type = types.TEXT; + this.descriptor = options.descriptor; + if ( docFrag ) { + this.node = document.createTextNode( options.descriptor ); + docFrag.appendChild( this.node ); + } + }; + DomText.prototype = { + detach: detach, + reassign: function() {}, + //no-op + teardown: function( destroy ) { + if ( destroy ) { + this.detach(); + } + }, + firstNode: function() { + return this.node; + }, + toString: function() { + return ( '' + this.descriptor ).replace( lessThan, '<' ).replace( greaterThan, '>' ); + } + }; + return DomText; + }( config_types, render_DomFragment_shared_detach ); + + var shared_teardown = function( runloop, unregisterDependant ) { + + return function( thing ) { + if ( !thing.keypath ) { + // this was on the 'unresolved' list, we need to remove it + runloop.removeUnresolved( thing ); + } else { + // this was registered as a dependant + unregisterDependant( thing ); + } + }; + }( global_runloop, shared_unregisterDependant ); + + var shared_Unresolved = function( runloop ) { + + var Unresolved = function( ractive, ref, parentFragment, callback ) { + this.root = ractive; + this.ref = ref; + this.parentFragment = parentFragment; + this.resolve = callback; + runloop.addUnresolved( this ); + }; + Unresolved.prototype = { + teardown: function() { + runloop.removeUnresolved( this ); + } + }; + return Unresolved; + }( global_runloop ); + + var render_shared_Evaluator_Reference = function( types, isEqual, defineProperty, registerDependant, unregisterDependant ) { + + var Reference, thisPattern; + thisPattern = /this/; + Reference = function( root, keypath, evaluator, argNum, priority ) { + var value; + this.evaluator = evaluator; + this.keypath = keypath; + this.root = root; + this.argNum = argNum; + this.type = types.REFERENCE; + this.priority = priority; + value = root.get( keypath ); + if ( typeof value === 'function' ) { + value = wrapFunction( value, root, evaluator ); + } + this.value = evaluator.values[ argNum ] = value; + registerDependant( this ); + }; + Reference.prototype = { + update: function() { + var value = this.root.get( this.keypath ); + if ( typeof value === 'function' && !value._nowrap ) { + value = wrapFunction( value, this.root, this.evaluator ); + } + if ( !isEqual( value, this.value ) ) { + this.evaluator.values[ this.argNum ] = value; + this.evaluator.bubble(); + this.value = value; + } + }, + teardown: function() { + unregisterDependant( this ); + } + }; + return Reference; + + function wrapFunction( fn, ractive, evaluator ) { + var prop, evaluators, index; + // If the function doesn't refer to `this`, we don't need + // to set the context, because we're not doing `this.get()` + // (which is how dependencies are tracked) + if ( !thisPattern.test( fn.toString() ) ) { + defineProperty( fn, '_nowrap', { + // no point doing this every time + value: true + } ); + return fn; + } + // If this function is being wrapped for the first time... + if ( !fn[ '_' + ractive._guid ] ) { + // ...we need to do some work + defineProperty( fn, '_' + ractive._guid, { + value: function() { + var originalCaptured, result, i, evaluator; + originalCaptured = ractive._captured; + if ( !originalCaptured ) { + ractive._captured = []; + } + result = fn.apply( ractive, arguments ); + if ( ractive._captured.length ) { + i = evaluators.length; + while ( i-- ) { + evaluator = evaluators[ i ]; + evaluator.updateSoftDependencies( ractive._captured ); + } + } + // reset + ractive._captured = originalCaptured; + return result; + }, + writable: true + } ); + for ( prop in fn ) { + if ( fn.hasOwnProperty( prop ) ) { + fn[ '_' + ractive._guid ][ prop ] = fn[ prop ]; + } + } + fn[ '_' + ractive._guid + '_evaluators' ] = []; + } + // We need to make a note of which evaluators are using this function, + // so that they can all be notified of changes + evaluators = fn[ '_' + ractive._guid + '_evaluators' ]; + index = evaluators.indexOf( evaluator ); + if ( index === -1 ) { + evaluators.push( evaluator ); + } + // Return the wrapped function + return fn[ '_' + ractive._guid ]; + } + }( config_types, utils_isEqual, utils_defineProperty, shared_registerDependant, shared_unregisterDependant ); + + var render_shared_Evaluator_SoftReference = function( isEqual, registerDependant, unregisterDependant ) { + + var SoftReference = function( root, keypath, evaluator ) { + this.root = root; + this.keypath = keypath; + this.priority = evaluator.priority; + this.evaluator = evaluator; + registerDependant( this ); + }; + SoftReference.prototype = { + update: function() { + var value = this.root.get( this.keypath ); + if ( !isEqual( value, this.value ) ) { + this.evaluator.bubble(); + this.value = value; + } + }, + teardown: function() { + unregisterDependant( this ); + } + }; + return SoftReference; + }( utils_isEqual, shared_registerDependant, shared_unregisterDependant ); + + var render_shared_Evaluator__Evaluator = function( runloop, warn, isEqual, clearCache, notifyDependants, adaptIfNecessary, Reference, SoftReference ) { + + var Evaluator, cache = {}; + Evaluator = function( root, keypath, uniqueString, functionStr, args, priority ) { + var evaluator = this; + evaluator.root = root; + evaluator.uniqueString = uniqueString; + evaluator.keypath = keypath; + evaluator.priority = priority; + evaluator.fn = getFunctionFromString( functionStr, args.length ); + evaluator.values = []; + evaluator.refs = []; + args.forEach( function( arg, i ) { + if ( !arg ) { + return; + } + if ( arg.indexRef ) { + // this is an index ref... we don't need to register a dependant + evaluator.values[ i ] = arg.value; + } else { + evaluator.refs.push( new Reference( root, arg.keypath, evaluator, i, priority ) ); + } + } ); + evaluator.selfUpdating = evaluator.refs.length <= 1; + }; + Evaluator.prototype = { + bubble: function() { + // If we only have one reference, we can update immediately... + if ( this.selfUpdating ) { + this.update(); + } else if ( !this.deferred ) { + runloop.addEvaluator( this ); + this.deferred = true; + } + }, + update: function() { + var value; + // prevent infinite loops + if ( this.evaluating ) { + return this; + } + this.evaluating = true; + try { + value = this.fn.apply( null, this.values ); + } catch ( err ) { + if ( this.root.debug ) { + warn( 'Error evaluating "' + this.uniqueString + '": ' + err.message || err ); + } + value = undefined; + } + if ( !isEqual( value, this.value ) ) { + this.value = value; + clearCache( this.root, this.keypath ); + adaptIfNecessary( this.root, this.keypath, value, true ); + notifyDependants( this.root, this.keypath ); + } + this.evaluating = false; + return this; + }, + // TODO should evaluators ever get torn down? At present, they don't... + teardown: function() { + while ( this.refs.length ) { + this.refs.pop().teardown(); + } + clearCache( this.root, this.keypath ); + this.root._evaluators[ this.keypath ] = null; + }, + // This method forces the evaluator to sync with the current model + // in the case of a smart update + refresh: function() { + if ( !this.selfUpdating ) { + this.deferred = true; + } + var i = this.refs.length; + while ( i-- ) { + this.refs[ i ].update(); + } + if ( this.deferred ) { + this.update(); + this.deferred = false; + } + }, + updateSoftDependencies: function( softDeps ) { + var i, keypath, ref; + if ( !this.softRefs ) { + this.softRefs = []; + } + // teardown any references that are no longer relevant + i = this.softRefs.length; + while ( i-- ) { + ref = this.softRefs[ i ]; + if ( !softDeps[ ref.keypath ] ) { + this.softRefs.splice( i, 1 ); + this.softRefs[ ref.keypath ] = false; + ref.teardown(); + } + } + // add references for any new soft dependencies + i = softDeps.length; + while ( i-- ) { + keypath = softDeps[ i ]; + if ( !this.softRefs[ keypath ] ) { + ref = new SoftReference( this.root, keypath, this ); + this.softRefs.push( ref ); + this.softRefs[ keypath ] = true; + } + } + this.selfUpdating = this.refs.length + this.softRefs.length <= 1; + } + }; + return Evaluator; + + function getFunctionFromString( str, i ) { + var fn, args; + str = str.replace( /\$\{([0-9]+)\}/g, '_$1' ); + if ( cache[ str ] ) { + return cache[ str ]; + } + args = []; + while ( i-- ) { + args[ i ] = '_' + i; + } + fn = new Function( args.join( ',' ), 'return(' + str + ')' ); + cache[ str ] = fn; + return fn; + } + }( global_runloop, utils_warn, utils_isEqual, shared_clearCache, shared_notifyDependants, shared_adaptIfNecessary, render_shared_Evaluator_Reference, render_shared_Evaluator_SoftReference ); + + var render_shared_Resolvers_ExpressionResolver = function( removeFromArray, resolveRef, Unresolved, Evaluator, getNewKeypath ) { + + var ExpressionResolver = function( owner, parentFragment, expression, callback ) { + var expressionResolver = this, + ractive, indexRefs, args; + ractive = owner.root; + this.root = ractive; + this.callback = callback; + this.owner = owner; + this.str = expression.s; + this.args = args = []; + this.unresolved = []; + this.pending = 0; + indexRefs = parentFragment.indexRefs; + // some expressions don't have references. edge case, but, yeah. + if ( !expression.r || !expression.r.length ) { + this.resolved = this.ready = true; + this.bubble(); + return; + } + // Create resolvers for each reference + expression.r.forEach( function( reference, i ) { + var index, keypath, unresolved; + // Is this an index reference? + if ( indexRefs && ( index = indexRefs[ reference ] ) !== undefined ) { + args[ i ] = { + indexRef: reference, + value: index + }; + return; + } + // Can we resolve it immediately? + if ( keypath = resolveRef( ractive, reference, parentFragment ) ) { + args[ i ] = { + keypath: keypath + }; + return; + } + // Couldn't resolve yet + args[ i ] = undefined; + expressionResolver.pending += 1; + unresolved = new Unresolved( ractive, reference, parentFragment, function( keypath ) { + expressionResolver.resolve( i, keypath ); + removeFromArray( expressionResolver.unresolved, unresolved ); + } ); + expressionResolver.unresolved.push( unresolved ); + } ); + this.ready = true; + this.bubble(); + }; + ExpressionResolver.prototype = { + bubble: function() { + if ( !this.ready ) { + return; + } + this.uniqueString = getUniqueString( this.str, this.args ); + this.keypath = getKeypath( this.uniqueString ); + this.createEvaluator(); + this.callback( this.keypath ); + }, + teardown: function() { + var unresolved; + while ( unresolved = this.unresolved.pop() ) { + unresolved.teardown(); + } + }, + resolve: function( index, keypath ) { + this.args[ index ] = { + keypath: keypath + }; + this.bubble(); + // when all references have been resolved, we can flag the entire expression + // as having been resolved + this.resolved = !--this.pending; + }, + createEvaluator: function() { + var evaluator; + // only if it doesn't exist yet! + if ( !this.root._evaluators[ this.keypath ] ) { + evaluator = new Evaluator( this.root, this.keypath, this.uniqueString, this.str, this.args, this.owner.priority ); + this.root._evaluators[ this.keypath ] = evaluator; + evaluator.update(); + } else { + // we need to trigger a refresh of the evaluator, since it + // will have become de-synced from the model if we're in a + // reassignment cycle + this.root._evaluators[ this.keypath ].refresh(); + } + }, + reassign: function( indexRef, newIndex, oldKeypath, newKeypath ) { + var changed; + this.args.forEach( function( arg ) { + var changedKeypath; + if ( arg.keypath && ( changedKeypath = getNewKeypath( arg.keypath, oldKeypath, newKeypath ) ) ) { + arg.keypath = changedKeypath; + changed = true; + } else if ( arg.indexRef === indexRef ) { + arg.value = newIndex; + changed = true; + } + } ); + if ( changed ) { + this.bubble(); + } + } + }; + return ExpressionResolver; + + function getUniqueString( str, args ) { + // get string that is unique to this expression + return str.replace( /\$\{([0-9]+)\}/g, function( match, $1 ) { + return args[ $1 ] ? args[ $1 ].value || args[ $1 ].keypath : 'undefined'; + } ); + } + + function getKeypath( uniqueString ) { + // Sanitize by removing any periods or square brackets. Otherwise + // we can't split the keypath into keys! + return '${' + uniqueString.replace( /[\.\[\]]/g, '-' ) + '}'; + } + }( utils_removeFromArray, shared_resolveRef, shared_Unresolved, render_shared_Evaluator__Evaluator, render_shared_utils_getNewKeypath ); + + var render_shared_Resolvers_KeypathExpressionResolver = function( types, removeFromArray, resolveRef, Unresolved, registerDependant, unregisterDependant, ExpressionResolver ) { + + var KeypathExpressionResolver = function( mustache, descriptor, callback ) { + var resolver = this, + ractive, parentFragment, keypath, dynamic, members; + ractive = mustache.root; + parentFragment = mustache.parentFragment; + this.ref = descriptor.r; + this.root = mustache.root; + this.mustache = mustache; + this.callback = callback; + this.pending = 0; + this.unresolved = []; + members = this.members = []; + this.indexRefMembers = []; + this.keypathObservers = []; + this.expressionResolvers = []; + descriptor.m.forEach( function( member, i ) { + var ref, indexRefs, index, createKeypathObserver, unresolved, expressionResolver; + if ( typeof member === 'string' ) { + resolver.members[ i ] = member; + return; + } + // simple reference? + if ( member.t === types.REFERENCE ) { + ref = member.n; + indexRefs = parentFragment.indexRefs; + if ( indexRefs && ( index = indexRefs[ ref ] ) !== undefined ) { + members[ i ] = index; + // make a note of it, in case of reassignments + resolver.indexRefMembers.push( { + ref: ref, + index: i + } ); + return; + } + dynamic = true; + createKeypathObserver = function( keypath ) { + var keypathObserver = new KeypathObserver( ractive, keypath, mustache.priority, resolver, i ); + resolver.keypathObservers.push( keypathObserver ); + }; + // Can we resolve the reference immediately? + if ( keypath = resolveRef( ractive, ref, parentFragment ) ) { + createKeypathObserver( keypath ); + return; + } + // Couldn't resolve yet + members[ i ] = undefined; + resolver.pending += 1; + unresolved = new Unresolved( ractive, ref, parentFragment, function( keypath ) { + resolver.resolve( i, keypath ); + removeFromArray( resolver.unresolved, unresolved ); + } ); + resolver.unresolved.push( unresolved ); + return null; + } + // Otherwise we have an expression in its own right + dynamic = true; + resolver.pending += 1; + expressionResolver = new ExpressionResolver( resolver, parentFragment, member, function( keypath ) { + resolver.resolve( i, keypath ); + removeFromArray( resolver.unresolved, expressionResolver ); + } ); + resolver.unresolved.push( expressionResolver ); + } ); + // Some keypath expressions (e.g. foo["bar"], or foo[i] where `i` is an + // index reference) won't change. So we don't need to register any watchers + if ( !dynamic ) { + keypath = this.getKeypath(); + callback( keypath ); + return; + } + this.ready = true; + this.bubble(); + }; + KeypathExpressionResolver.prototype = { + getKeypath: function() { + return this.ref + '.' + this.members.join( '.' ); + }, + bubble: function() { + if ( !this.ready || this.pending ) { + return; + } + this.callback( this.getKeypath() ); + }, + resolve: function( index, value ) { + var keypathObserver = new KeypathObserver( this.root, value, this.mustache.priority, this, index ); + keypathObserver.update(); + this.keypathObservers.push( keypathObserver ); + // when all references have been resolved, we can flag the entire expression + // as having been resolved + this.resolved = !--this.pending; + this.bubble(); + }, + teardown: function() { + var unresolved; + while ( unresolved = this.unresolved.pop() ) { + unresolved.teardown(); + } + }, + reassign: function( indexRef, newIndex ) { + var changed, i, member; + i = this.indexRefMembers.length; + while ( i-- ) { + member = this.indexRefMembers[ i ]; + if ( member.ref === indexRef ) { + changed = true; + this.members[ member.index ] = newIndex; + } + } + if ( changed ) { + this.bubble(); + } + } + }; + var KeypathObserver = function( ractive, keypath, priority, resolver, index ) { + this.root = ractive; + this.keypath = keypath; + this.priority = priority; + this.resolver = resolver; + this.index = index; + registerDependant( this ); + this.update(); + }; + KeypathObserver.prototype = { + update: function() { + var resolver = this.resolver; + resolver.members[ this.index ] = this.root.get( this.keypath ); + resolver.bubble(); + }, + teardown: function() { + unregisterDependant( this ); + } + }; + return KeypathExpressionResolver; + }( config_types, utils_removeFromArray, shared_resolveRef, shared_Unresolved, shared_registerDependant, shared_unregisterDependant, render_shared_Resolvers_ExpressionResolver ); + + var render_shared_Mustache_initialise = function( runloop, resolveRef, KeypathExpressionResolver, ExpressionResolver ) { + + return function initMustache( mustache, options ) { + var ref, keypath, indexRefs, index, parentFragment, descriptor, resolve; + parentFragment = options.parentFragment; + descriptor = options.descriptor; + mustache.root = parentFragment.root; + mustache.parentFragment = parentFragment; + mustache.descriptor = options.descriptor; + mustache.index = options.index || 0; + mustache.priority = parentFragment.priority; + mustache.type = options.descriptor.t; + resolve = function( keypath ) { + mustache.resolve( keypath ); + }; + // if this is a simple mustache, with a reference, we just need to resolve + // the reference to a keypath + if ( ref = descriptor.r ) { + indexRefs = parentFragment.indexRefs; + if ( indexRefs && ( index = indexRefs[ ref ] ) !== undefined ) { + mustache.indexRef = ref; + mustache.value = index; + mustache.render( mustache.value ); + } else { + keypath = resolveRef( mustache.root, ref, mustache.parentFragment ); + if ( keypath !== undefined ) { + resolve( keypath ); + } else { + mustache.ref = ref; + runloop.addUnresolved( mustache ); + } + } + } + // if it's an expression, we have a bit more work to do + if ( options.descriptor.x ) { + mustache.resolver = new ExpressionResolver( mustache, parentFragment, options.descriptor.x, resolve ); + } + if ( options.descriptor.kx ) { + mustache.resolver = new KeypathExpressionResolver( mustache, options.descriptor.kx, resolve ); + } + // Special case - inverted sections + if ( mustache.descriptor.n && !mustache.hasOwnProperty( 'value' ) ) { + mustache.render( undefined ); + } + }; + }( global_runloop, shared_resolveRef, render_shared_Resolvers_KeypathExpressionResolver, render_shared_Resolvers_ExpressionResolver ); + + var render_shared_Mustache_update = function( isEqual, get ) { + + var options = { + evaluateWrapped: true + }; + return function updateMustache() { + var value = get( this.root, this.keypath, options ); + if ( !isEqual( value, this.value ) ) { + this.render( value ); + this.value = value; + } + }; + }( utils_isEqual, shared_get__get ); + + var render_shared_Mustache_resolve = function( types, registerDependant, unregisterDependant ) { + + return function resolveMustache( keypath ) { + var i; + // In some cases, we may resolve to the same keypath (if this is + // an expression mustache that was reassigned due to an ancestor's + // keypath) - in which case, this is a no-op + if ( keypath === this.keypath ) { + return; + } + // if we resolved previously, we need to unregister + if ( this.registered ) { + unregisterDependant( this ); + // is this a section? if so, we may have children that need + // to be reassigned + // TODO only DOM sections? + if ( this.type === types.SECTION ) { + i = this.fragments.length; + while ( i-- ) { + this.fragments[ i ].reassign( null, null, this.keypath, keypath ); + } + } + } + this.keypath = keypath; + registerDependant( this ); + this.update(); + }; + }( config_types, shared_registerDependant, shared_unregisterDependant ); + + var render_shared_Mustache_reassign = function( getNewKeypath ) { + + return function reassignMustache( indexRef, newIndex, oldKeypath, newKeypath ) { + var updated, i; + // expression mustache? + if ( this.resolver ) { + this.resolver.reassign( indexRef, newIndex, oldKeypath, newKeypath ); + } else if ( this.keypath ) { + updated = getNewKeypath( this.keypath, oldKeypath, newKeypath ); + // was a new keypath created? + if ( updated ) { + // resolve it + this.resolve( updated ); + } + } else if ( indexRef !== undefined && this.indexRef === indexRef ) { + this.value = newIndex; + this.render( newIndex ); + } + // otherwise, it's an unresolved reference. the context stack has been updated + // so it will take care of itself + // if it's a section mustache, we need to go through any children + if ( this.fragments ) { + i = this.fragments.length; + while ( i-- ) { + this.fragments[ i ].reassign( indexRef, newIndex, oldKeypath, newKeypath ); + } + } + }; + }( render_shared_utils_getNewKeypath ); + + var render_shared_Mustache__Mustache = function( init, update, resolve, reassign ) { + + return { + init: init, + update: update, + resolve: resolve, + reassign: reassign + }; + }( render_shared_Mustache_initialise, render_shared_Mustache_update, render_shared_Mustache_resolve, render_shared_Mustache_reassign ); + + var render_DomFragment_Interpolator = function( types, teardown, Mustache, detach ) { + + var DomInterpolator, lessThan, greaterThan; + lessThan = //g; + DomInterpolator = function( options, docFrag ) { + this.type = types.INTERPOLATOR; + if ( docFrag ) { + this.node = document.createTextNode( '' ); + docFrag.appendChild( this.node ); + } + // extend Mustache + Mustache.init( this, options ); + }; + DomInterpolator.prototype = { + update: Mustache.update, + resolve: Mustache.resolve, + reassign: Mustache.reassign, + detach: detach, + teardown: function( destroy ) { + if ( destroy ) { + this.detach(); + } + teardown( this ); + }, + render: function( value ) { + if ( this.node ) { + this.node.data = value == undefined ? '' : value; + } + }, + firstNode: function() { + return this.node; + }, + toString: function() { + var value = this.value != undefined ? '' + this.value : ''; + return value.replace( lessThan, '<' ).replace( greaterThan, '>' ); + } + }; + return DomInterpolator; + }( config_types, shared_teardown, render_shared_Mustache__Mustache, render_DomFragment_shared_detach ); + + var render_DomFragment_Section_prototype_merge = function() { + + var toTeardown = []; + return function sectionMerge( newIndices ) { + var section = this, + parentFragment, firstChange, i, newLength, reassignedFragments, fragmentOptions, fragment, nextNode; + parentFragment = this.parentFragment; + reassignedFragments = []; + // first, reassign existing fragments + newIndices.forEach( function reassignIfNecessary( newIndex, oldIndex ) { + var fragment, by, oldKeypath, newKeypath; + if ( newIndex === oldIndex ) { + reassignedFragments[ newIndex ] = section.fragments[ oldIndex ]; + return; + } + if ( firstChange === undefined ) { + firstChange = oldIndex; + } + // does this fragment need to be torn down? + if ( newIndex === -1 ) { + toTeardown.push( section.fragments[ oldIndex ] ); + return; + } + // Otherwise, it needs to be reassigned to a new index + fragment = section.fragments[ oldIndex ]; + by = newIndex - oldIndex; + oldKeypath = section.keypath + '.' + oldIndex; + newKeypath = section.keypath + '.' + newIndex; + fragment.reassign( section.descriptor.i, oldIndex, newIndex, by, oldKeypath, newKeypath ); + reassignedFragments[ newIndex ] = fragment; + } ); + while ( fragment = toTeardown.pop() ) { + fragment.teardown( true ); + } + // If nothing changed with the existing fragments, then we start adding + // new fragments at the end... + if ( firstChange === undefined ) { + firstChange = this.length; + } + this.length = newLength = this.root.get( this.keypath ).length; + if ( newLength === firstChange ) { + // ...unless there are no new fragments to add + return; + } + // Prepare new fragment options + fragmentOptions = { + descriptor: this.descriptor.f, + root: this.root, + pNode: parentFragment.pNode, + owner: this + }; + if ( this.descriptor.i ) { + fragmentOptions.indexRef = this.descriptor.i; + } + // Add as many new fragments as we need to, or add back existing + // (detached) fragments + for ( i = firstChange; i < newLength; i += 1 ) { + // is this an existing fragment? + if ( fragment = reassignedFragments[ i ] ) { + this.docFrag.appendChild( fragment.detach( false ) ); + } else { + fragmentOptions.context = this.keypath + '.' + i; + fragmentOptions.index = i; + fragment = this.createFragment( fragmentOptions ); + } + this.fragments[ i ] = fragment; + } + // reinsert fragment + nextNode = parentFragment.findNextNode( this ); + parentFragment.pNode.insertBefore( this.docFrag, nextNode ); + }; + }(); + + var render_shared_updateSection = function( isArray, isObject ) { + + return function updateSection( section, value ) { + var fragmentOptions = { + descriptor: section.descriptor.f, + root: section.root, + pNode: section.parentFragment.pNode, + pElement: section.parentFragment.pElement, + owner: section + }; + // if section is inverted, only check for truthiness/falsiness + if ( section.descriptor.n ) { + updateConditionalSection( section, value, true, fragmentOptions ); + return; + } + // otherwise we need to work out what sort of section we're dealing with + // if value is an array, or an object with an index reference, iterate through + if ( isArray( value ) ) { + updateListSection( section, value, fragmentOptions ); + } else if ( isObject( value ) || typeof value === 'function' ) { + if ( section.descriptor.i ) { + updateListObjectSection( section, value, fragmentOptions ); + } else { + updateContextSection( section, fragmentOptions ); + } + } else { + updateConditionalSection( section, value, false, fragmentOptions ); + } + }; + + function updateListSection( section, value, fragmentOptions ) { + var i, length, fragmentsToRemove; + length = value.length; + // if the array is shorter than it was previously, remove items + if ( length < section.length ) { + fragmentsToRemove = section.fragments.splice( length, section.length - length ); + while ( fragmentsToRemove.length ) { + fragmentsToRemove.pop().teardown( true ); + } + } else { + if ( length > section.length ) { + // add any new ones + for ( i = section.length; i < length; i += 1 ) { + // append list item to context stack + fragmentOptions.context = section.keypath + '.' + i; + fragmentOptions.index = i; + if ( section.descriptor.i ) { + fragmentOptions.indexRef = section.descriptor.i; + } + section.fragments[ i ] = section.createFragment( fragmentOptions ); + } + } + } + section.length = length; + } + + function updateListObjectSection( section, value, fragmentOptions ) { + var id, i, hasKey, fragment; + hasKey = section.hasKey || ( section.hasKey = {} ); + // remove any fragments that should no longer exist + i = section.fragments.length; + while ( i-- ) { + fragment = section.fragments[ i ]; + if ( !( fragment.index in value ) ) { + section.fragments[ i ].teardown( true ); + section.fragments.splice( i, 1 ); + hasKey[ fragment.index ] = false; + } + } + // add any that haven't been created yet + for ( id in value ) { + if ( !hasKey[ id ] ) { + fragmentOptions.context = section.keypath + '.' + id; + fragmentOptions.index = id; + if ( section.descriptor.i ) { + fragmentOptions.indexRef = section.descriptor.i; + } + section.fragments.push( section.createFragment( fragmentOptions ) ); + hasKey[ id ] = true; + } + } + section.length = section.fragments.length; + } + + function updateContextSection( section, fragmentOptions ) { + // ...then if it isn't rendered, render it, adding section.keypath to the context stack + // (if it is already rendered, then any children dependent on the context stack + // will update themselves without any prompting) + if ( !section.length ) { + // append this section to the context stack + fragmentOptions.context = section.keypath; + fragmentOptions.index = 0; + section.fragments[ 0 ] = section.createFragment( fragmentOptions ); + section.length = 1; + } + } + + function updateConditionalSection( section, value, inverted, fragmentOptions ) { + var doRender, emptyArray, fragmentsToRemove, fragment; + emptyArray = isArray( value ) && value.length === 0; + if ( inverted ) { + doRender = emptyArray || !value; + } else { + doRender = value && !emptyArray; + } + if ( doRender ) { + if ( !section.length ) { + // no change to context stack + fragmentOptions.index = 0; + section.fragments[ 0 ] = section.createFragment( fragmentOptions ); + section.length = 1; + } + if ( section.length > 1 ) { + fragmentsToRemove = section.fragments.splice( 1 ); + while ( fragment = fragmentsToRemove.pop() ) { + fragment.teardown( true ); + } + } + } else if ( section.length ) { + section.teardownFragments( true ); + section.length = 0; + } + } + }( utils_isArray, utils_isObject ); + + var render_DomFragment_Section_prototype_render = function( isClient, updateSection ) { + + return function DomSection_prototype_render( value ) { + var nextNode, wrapped; + // with sections, we need to get the fake value if we have a wrapped object + if ( wrapped = this.root._wrapped[ this.keypath ] ) { + value = wrapped.get(); + } + // prevent sections from rendering multiple times (happens if + // evaluators evaluate while update is happening) + if ( this.rendering ) { + return; + } + this.rendering = true; + updateSection( this, value ); + this.rendering = false; + // if we have no new nodes to insert (i.e. the section length stayed the + // same, or shrank), we don't need to go any further + if ( this.docFrag && !this.docFrag.childNodes.length ) { + return; + } + // if this isn't the initial render, we need to insert any new nodes in + // the right place + if ( !this.initialising && isClient ) { + // Normally this is just a case of finding the next node, and inserting + // items before it... + nextNode = this.parentFragment.findNextNode( this ); + if ( nextNode && nextNode.parentNode === this.parentFragment.pNode ) { + this.parentFragment.pNode.insertBefore( this.docFrag, nextNode ); + } else { + // TODO could there be a situation in which later nodes could have + // been attached to the parent node, i.e. we need to find a sibling + // to insert before? + this.parentFragment.pNode.appendChild( this.docFrag ); + } + } + }; + }( config_isClient, render_shared_updateSection ); + + var render_DomFragment_Section_reassignFragments = function( section, start, end, by ) { + var i, fragment, indexRef, oldKeypath, newKeypath; + indexRef = section.descriptor.i; + for ( i = start; i < end; i += 1 ) { + fragment = section.fragments[ i ]; + oldKeypath = section.keypath + '.' + ( i - by ); + newKeypath = section.keypath + '.' + i; + // change the fragment index + fragment.index = i; + fragment.reassign( indexRef, i, oldKeypath, newKeypath ); + } + }; + + var render_DomFragment_Section_prototype_splice = function( reassignFragments ) { + + return function( spliceSummary ) { + var section = this, + balance, start, insertStart, insertEnd, spliceArgs; + balance = spliceSummary.balance; + if ( !balance ) { + // The array length hasn't changed - we don't need to add or remove anything + return; + } + start = spliceSummary.start; + section.length += balance; + // If more items were removed from the array than added, we tear down + // the excess fragments and remove them... + if ( balance < 0 ) { + section.fragments.splice( start, -balance ).forEach( teardown ); + // Reassign fragments after the ones we've just removed + reassignFragments( section, start, section.length, balance ); + // Nothing more to do + return; + } + // ...otherwise we need to add some things to the DOM. + insertStart = start + spliceSummary.removed; + insertEnd = start + spliceSummary.added; + // Make room for the new fragments by doing a splice that simulates + // what happened to the data array + spliceArgs = [ + insertStart, + 0 + ]; + spliceArgs.length += balance; + section.fragments.splice.apply( section.fragments, spliceArgs ); + // Reassign existing fragments at the end of the array + reassignFragments( section, insertEnd, section.length, balance ); + // Create the new ones + renderNewFragments( section, insertStart, insertEnd ); + }; + + function teardown( fragment ) { + fragment.teardown( true ); + } + + function renderNewFragments( section, start, end ) { + var fragmentOptions, i, insertionPoint; + section.rendering = true; + fragmentOptions = { + descriptor: section.descriptor.f, + root: section.root, + pNode: section.parentFragment.pNode, + owner: section, + indexRef: section.descriptor.i + }; + for ( i = start; i < end; i += 1 ) { + fragmentOptions.context = section.keypath + '.' + i; + fragmentOptions.index = i; + section.fragments[ i ] = section.createFragment( fragmentOptions ); + } + // Figure out where these new nodes need to be inserted + insertionPoint = section.fragments[ end ] ? section.fragments[ end ].firstNode() : section.parentFragment.findNextNode( section ); + // Append docfrag in front of insertion point + section.parentFragment.pNode.insertBefore( section.docFrag, insertionPoint ); + section.rendering = false; + } + }( render_DomFragment_Section_reassignFragments ); + + var render_DomFragment_Section__Section = function( types, Mustache, merge, render, splice, teardown, circular ) { + + var DomSection, DomFragment; + circular.push( function() { + DomFragment = circular.DomFragment; + } ); + // Section + DomSection = function( options, docFrag ) { + this.type = types.SECTION; + this.inverted = !! options.descriptor.n; + this.fragments = []; + this.length = 0; + // number of times this section is rendered + if ( docFrag ) { + this.docFrag = document.createDocumentFragment(); + } + this.initialising = true; + Mustache.init( this, options ); + if ( docFrag ) { + docFrag.appendChild( this.docFrag ); + } + this.initialising = false; + }; + DomSection.prototype = { + update: Mustache.update, + resolve: Mustache.resolve, + reassign: Mustache.reassign, + splice: splice, + merge: merge, + detach: function() { + var i, len; + if ( this.docFrag ) { + len = this.fragments.length; + for ( i = 0; i < len; i += 1 ) { + this.docFrag.appendChild( this.fragments[ i ].detach() ); + } + return this.docFrag; + } + }, + teardown: function( destroy ) { + this.teardownFragments( destroy ); + teardown( this ); + }, + firstNode: function() { + if ( this.fragments[ 0 ] ) { + return this.fragments[ 0 ].firstNode(); + } + return this.parentFragment.findNextNode( this ); + }, + findNextNode: function( fragment ) { + if ( this.fragments[ fragment.index + 1 ] ) { + return this.fragments[ fragment.index + 1 ].firstNode(); + } + return this.parentFragment.findNextNode( this ); + }, + teardownFragments: function( destroy ) { + var fragment; + while ( fragment = this.fragments.shift() ) { + fragment.teardown( destroy ); + } + }, + render: render, + createFragment: function( options ) { + var fragment = new DomFragment( options ); + if ( this.docFrag ) { + this.docFrag.appendChild( fragment.docFrag ); + } + return fragment; + }, + toString: function() { + var str, i, len; + str = ''; + i = 0; + len = this.length; + for ( i = 0; i < len; i += 1 ) { + str += this.fragments[ i ].toString(); + } + return str; + }, + find: function( selector ) { + var i, len, queryResult; + len = this.fragments.length; + for ( i = 0; i < len; i += 1 ) { + if ( queryResult = this.fragments[ i ].find( selector ) ) { + return queryResult; + } + } + return null; + }, + findAll: function( selector, query ) { + var i, len; + len = this.fragments.length; + for ( i = 0; i < len; i += 1 ) { + this.fragments[ i ].findAll( selector, query ); + } + }, + findComponent: function( selector ) { + var i, len, queryResult; + len = this.fragments.length; + for ( i = 0; i < len; i += 1 ) { + if ( queryResult = this.fragments[ i ].findComponent( selector ) ) { + return queryResult; + } + } + return null; + }, + findAllComponents: function( selector, query ) { + var i, len; + len = this.fragments.length; + for ( i = 0; i < len; i += 1 ) { + this.fragments[ i ].findAllComponents( selector, query ); + } + } + }; + return DomSection; + }( config_types, render_shared_Mustache__Mustache, render_DomFragment_Section_prototype_merge, render_DomFragment_Section_prototype_render, render_DomFragment_Section_prototype_splice, shared_teardown, circular ); + + var render_DomFragment_Triple = function( types, matches, Mustache, insertHtml, teardown ) { + + var DomTriple = function( options, docFrag ) { + this.type = types.TRIPLE; + if ( docFrag ) { + this.nodes = []; + this.docFrag = document.createDocumentFragment(); + } + this.initialising = true; + Mustache.init( this, options ); + if ( docFrag ) { + docFrag.appendChild( this.docFrag ); + } + this.initialising = false; + }; + DomTriple.prototype = { + update: Mustache.update, + resolve: Mustache.resolve, + reassign: Mustache.reassign, + detach: function() { + var len, i; + if ( this.docFrag ) { + len = this.nodes.length; + for ( i = 0; i < len; i += 1 ) { + this.docFrag.appendChild( this.nodes[ i ] ); + } + return this.docFrag; + } + }, + teardown: function( destroy ) { + if ( destroy ) { + this.detach(); + this.docFrag = this.nodes = null; + } + teardown( this ); + }, + firstNode: function() { + if ( this.nodes[ 0 ] ) { + return this.nodes[ 0 ]; + } + return this.parentFragment.findNextNode( this ); + }, + render: function( html ) { + var node, pNode; + if ( !this.nodes ) { + // looks like we're in a server environment... + // nothing to see here, move along + return; + } + // remove existing nodes + while ( this.nodes.length ) { + node = this.nodes.pop(); + node.parentNode.removeChild( node ); + } + if ( !html ) { + this.nodes = []; + return; + } + // get new nodes + pNode = this.parentFragment.pNode; + this.nodes = insertHtml( html, pNode.tagName, pNode.namespaceURI, this.docFrag ); + if ( !this.initialising ) { + pNode.insertBefore( this.docFrag, this.parentFragment.findNextNode( this ) ); + } + // Special case - we're inserting the contents of a + if ( this.isFileInputValue ) { + this.update = updateFileInputValue; + // save ourselves the trouble next time + return this; + } + // special case - + if ( this.twoway && this.lcName === 'name' ) { + if ( node.type === 'radio' ) { + this.update = updateRadioName; + return this.update(); + } + if ( node.type === 'checkbox' ) { + this.update = updateCheckboxName; + return this.update(); + } + } + // special case - style attributes in Internet Exploder + if ( this.lcName === 'style' && node.style.setAttribute ) { + this.update = updateIEStyleAttribute; + return this.update(); + } + // special case - class names. IE fucks things up, again + if ( this.lcName === 'class' && ( !node.namespaceURI || node.namespaceURI === namespaces.html ) ) { + this.update = updateClassName; + return this.update(); + } + // special case - contenteditable + if ( node.getAttribute( 'contenteditable' ) && this.lcName === 'value' ) { + this.update = updateContentEditableValue; + return this.update(); + } + this.update = updateEverythingElse; + return this.update(); + }; + updateFileInputValue = function() { + return this; + }; + initSelect = function() { + // we're now in a position to decide whether this is a select-one or select-multiple + this.deferredUpdate = this.pNode.multiple ? updateMultipleSelect : updateSelect; + this.deferredUpdate(); + }; + deferSelect = function() { + // because select values depend partly on the values of their children, and their + // children may be entering and leaving the DOM, we wait until updates are + // complete before updating + runloop.addSelectValue( this ); + return this; + }; + updateSelect = function() { + var value = this.fragment.getValue(), + options, option, optionValue, i; + this.value = this.pNode._ractive.value = value; + options = this.pNode.options; + i = options.length; + while ( i-- ) { + option = options[ i ]; + optionValue = option._ractive ? option._ractive.value : option.value; + // options inserted via a triple don't have _ractive + if ( optionValue == value ) { + // double equals as we may be comparing numbers with strings + option.selected = true; + return this; + } + } + // if we're still here, it means the new value didn't match any of the options... + // TODO figure out what to do in this situation + return this; + }; + updateMultipleSelect = function() { + var value = this.fragment.getValue(), + options, i, option, optionValue; + if ( !isArray( value ) ) { + value = [ value ]; + } + options = this.pNode.options; + i = options.length; + while ( i-- ) { + option = options[ i ]; + optionValue = option._ractive ? option._ractive.value : option.value; + // options inserted via a triple don't have _ractive + option.selected = value.indexOf( optionValue ) !== -1; + } + this.value = value; + return this; + }; + updateRadioName = function() { + var node, value; + node = this.pNode; + value = this.fragment.getValue(); + node.checked = value == node._ractive.value; + return this; + }; + updateCheckboxName = function() { + var node, value; + node = this.pNode; + value = this.fragment.getValue(); + if ( !isArray( value ) ) { + node.checked = value == node._ractive.value; + return this; + } + node.checked = value.indexOf( node._ractive.value ) !== -1; + return this; + }; + updateIEStyleAttribute = function() { + var node, value; + node = this.pNode; + value = this.fragment.getValue(); + if ( value === undefined ) { + value = ''; + } + if ( value !== this.value ) { + node.style.setAttribute( 'cssText', value ); + this.value = value; + } + return this; + }; + updateClassName = function() { + var node, value; + node = this.pNode; + value = this.fragment.getValue(); + if ( value === undefined ) { + value = ''; + } + if ( value !== this.value ) { + node.className = value; + this.value = value; + } + return this; + }; + updateContentEditableValue = function() { + var node, value; + node = this.pNode; + value = this.fragment.getValue(); + if ( value === undefined ) { + value = ''; + } + if ( value !== this.value ) { + if ( !this.active ) { + node.innerHTML = value; + } + this.value = value; + } + return this; + }; + updateEverythingElse = function() { + var node, value, binding; + node = this.pNode; + value = this.fragment.getValue(); + // store actual value, so it doesn't get coerced to a string + if ( this.isValueAttribute ) { + node._ractive.value = value; + } + if ( value == undefined ) { + value = ''; + } + if ( value !== this.value ) { + if ( this.useProperty ) { + // with two-way binding, only update if the change wasn't initiated by the user + // otherwise the cursor will often be sent to the wrong place + if ( !this.active ) { + node[ this.propertyName ] = value; + } + // special case - a selected option whose select element has two-way binding + if ( node.tagName === 'OPTION' && node.selected && ( binding = this.element.select.binding ) ) { + binding.update(); + } + this.value = value; + return this; + } + if ( this.namespace ) { + node.setAttributeNS( this.namespace, this.name, value ); + this.value = value; + return this; + } + if ( this.lcName === 'id' ) { + if ( this.value !== undefined ) { + this.root.nodes[ this.value ] = undefined; + } + this.root.nodes[ value ] = node; + } + node.setAttribute( this.name, value ); + this.value = value; + } + return this; + }; + return updateAttribute; + }( global_runloop, config_namespaces, utils_isArray ); + + var parse_Tokenizer_utils_getStringMatch = function( string ) { + var substr; + substr = this.str.substr( this.pos, string.length ); + if ( substr === string ) { + this.pos += string.length; + return string; + } + return null; + }; + + var parse_Tokenizer_utils_allowWhitespace = function() { + + var leadingWhitespace = /^\s+/; + return function() { + var match = leadingWhitespace.exec( this.remaining() ); + if ( !match ) { + return null; + } + this.pos += match[ 0 ].length; + return match[ 0 ]; + }; + }(); + + var parse_Tokenizer_utils_makeRegexMatcher = function( regex ) { + return function( tokenizer ) { + var match = regex.exec( tokenizer.str.substring( tokenizer.pos ) ); + if ( !match ) { + return null; + } + tokenizer.pos += match[ 0 ].length; + return match[ 1 ] || match[ 0 ]; + }; + }; + + var parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral_makeQuotedStringMatcher = function( makeRegexMatcher ) { + + var getStringMiddle, getEscapeSequence, getLineContinuation; + // Match one or more characters until: ", ', \, or EOL/EOF. + // EOL/EOF is written as (?!.) (meaning there's no non-newline char next). + getStringMiddle = makeRegexMatcher( /^(?=.)[^"'\\]+?(?:(?!.)|(?=["'\\]))/ ); + // Match one escape sequence, including the backslash. + getEscapeSequence = makeRegexMatcher( /^\\(?:['"\\bfnrt]|0(?![0-9])|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|(?=.)[^ux0-9])/ ); + // Match one ES5 line continuation (backslash + line terminator). + getLineContinuation = makeRegexMatcher( /^\\(?:\r\n|[\u000A\u000D\u2028\u2029])/ ); + // Helper for defining getDoubleQuotedString and getSingleQuotedString. + return function( okQuote ) { + return function( tokenizer ) { + var start, literal, done, next; + start = tokenizer.pos; + literal = '"'; + done = false; + while ( !done ) { + next = getStringMiddle( tokenizer ) || getEscapeSequence( tokenizer ) || tokenizer.getStringMatch( okQuote ); + if ( next ) { + if ( next === '"' ) { + literal += '\\"'; + } else if ( next === '\\\'' ) { + literal += '\''; + } else { + literal += next; + } + } else { + next = getLineContinuation( tokenizer ); + if ( next ) { + // convert \(newline-like) into a \u escape, which is allowed in JSON + literal += '\\u' + ( '000' + next.charCodeAt( 1 ).toString( 16 ) ).slice( -4 ); + } else { + done = true; + } + } + } + literal += '"'; + // use JSON.parse to interpret escapes + return JSON.parse( literal ); + }; + }; + }( parse_Tokenizer_utils_makeRegexMatcher ); + + var parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral_getSingleQuotedString = function( makeQuotedStringMatcher ) { + + return makeQuotedStringMatcher( '"' ); + }( parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral_makeQuotedStringMatcher ); + + var parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral_getDoubleQuotedString = function( makeQuotedStringMatcher ) { + + return makeQuotedStringMatcher( '\'' ); + }( parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral_makeQuotedStringMatcher ); + + var parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral__getStringLiteral = function( types, getSingleQuotedString, getDoubleQuotedString ) { + + return function( tokenizer ) { + var start, string; + start = tokenizer.pos; + if ( tokenizer.getStringMatch( '"' ) ) { + string = getDoubleQuotedString( tokenizer ); + if ( !tokenizer.getStringMatch( '"' ) ) { + tokenizer.pos = start; + return null; + } + return { + t: types.STRING_LITERAL, + v: string + }; + } + if ( tokenizer.getStringMatch( '\'' ) ) { + string = getSingleQuotedString( tokenizer ); + if ( !tokenizer.getStringMatch( '\'' ) ) { + tokenizer.pos = start; + return null; + } + return { + t: types.STRING_LITERAL, + v: string + }; + } + return null; + }; + }( config_types, parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral_getSingleQuotedString, parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral_getDoubleQuotedString ); + + var parse_Tokenizer_getExpression_getPrimary_getLiteral_getNumberLiteral = function( types, makeRegexMatcher ) { + + // bulletproof number regex from https://gist.github.com/Rich-Harris/7544330 + var getNumber = makeRegexMatcher( /^(?:[+-]?)(?:(?:(?:0|[1-9]\d*)?\.\d+)|(?:(?:0|[1-9]\d*)\.)|(?:0|[1-9]\d*))(?:[eE][+-]?\d+)?/ ); + return function( tokenizer ) { + var result; + if ( result = getNumber( tokenizer ) ) { + return { + t: types.NUMBER_LITERAL, + v: result + }; + } + return null; + }; + }( config_types, parse_Tokenizer_utils_makeRegexMatcher ); + + var parse_Tokenizer_getExpression_shared_getName = function( makeRegexMatcher ) { + + return makeRegexMatcher( /^[a-zA-Z_$][a-zA-Z_$0-9]*/ ); + }( parse_Tokenizer_utils_makeRegexMatcher ); + + var parse_Tokenizer_getExpression_shared_getKey = function( getStringLiteral, getNumberLiteral, getName ) { + + var identifier = /^[a-zA-Z_$][a-zA-Z_$0-9]*$/; + // http://mathiasbynens.be/notes/javascript-properties + // can be any name, string literal, or number literal + return function( tokenizer ) { + var token; + if ( token = getStringLiteral( tokenizer ) ) { + return identifier.test( token.v ) ? token.v : '"' + token.v.replace( /"/g, '\\"' ) + '"'; + } + if ( token = getNumberLiteral( tokenizer ) ) { + return token.v; + } + if ( token = getName( tokenizer ) ) { + return token; + } + }; + }( parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral__getStringLiteral, parse_Tokenizer_getExpression_getPrimary_getLiteral_getNumberLiteral, parse_Tokenizer_getExpression_shared_getName ); + + var utils_parseJSON = function( getStringMatch, allowWhitespace, getStringLiteral, getKey ) { + + // simple JSON parser, without the restrictions of JSON parse + // (i.e. having to double-quote keys). + // + // This re-uses logic from the main template parser, albeit + // messily. Could probably use a cleanup at some point. + // + // If passed a hash of values as the second argument, ${placeholders} + // will be replaced with those values + var Tokenizer, specials, specialsPattern, numberPattern, placeholderPattern, placeholderAtStartPattern; + specials = { + 'true': true, + 'false': false, + 'undefined': undefined, + 'null': null + }; + specialsPattern = new RegExp( '^(?:' + Object.keys( specials ).join( '|' ) + ')' ); + numberPattern = /^(?:[+-]?)(?:(?:(?:0|[1-9]\d*)?\.\d+)|(?:(?:0|[1-9]\d*)\.)|(?:0|[1-9]\d*))(?:[eE][+-]?\d+)?/; + placeholderPattern = /\$\{([^\}]+)\}/g; + placeholderAtStartPattern = /^\$\{([^\}]+)\}/; + Tokenizer = function( str, values ) { + this.str = str; + this.values = values; + this.pos = 0; + this.result = this.getToken(); + }; + Tokenizer.prototype = { + remaining: function() { + return this.str.substring( this.pos ); + }, + getStringMatch: getStringMatch, + getToken: function() { + this.allowWhitespace(); + return this.getPlaceholder() || this.getSpecial() || this.getNumber() || this.getString() || this.getObject() || this.getArray(); + }, + getPlaceholder: function() { + var match; + if ( !this.values ) { + return null; + } + if ( ( match = placeholderAtStartPattern.exec( this.remaining() ) ) && this.values.hasOwnProperty( match[ 1 ] ) ) { + this.pos += match[ 0 ].length; + return { + v: this.values[ match[ 1 ] ] + }; + } + }, + getSpecial: function() { + var match; + if ( match = specialsPattern.exec( this.remaining() ) ) { + this.pos += match[ 0 ].length; + return { + v: specials[ match[ 0 ] ] + }; + } + }, + getNumber: function() { + var match; + if ( match = numberPattern.exec( this.remaining() ) ) { + this.pos += match[ 0 ].length; + return { + v: +match[ 0 ] + }; + } + }, + getString: function() { + var stringLiteral = getStringLiteral( this ), + values; + if ( stringLiteral && ( values = this.values ) ) { + return { + v: stringLiteral.v.replace( placeholderPattern, function( match, $1 ) { + return values[ $1 ] || $1; + } ) + }; + } + return stringLiteral; + }, + getObject: function() { + var result, pair; + if ( !this.getStringMatch( '{' ) ) { + return null; + } + result = {}; + while ( pair = getKeyValuePair( this ) ) { + result[ pair.key ] = pair.value; + this.allowWhitespace(); + if ( this.getStringMatch( '}' ) ) { + return { + v: result + }; + } + if ( !this.getStringMatch( ',' ) ) { + return null; + } + } + return null; + }, + getArray: function() { + var result, valueToken; + if ( !this.getStringMatch( '[' ) ) { + return null; + } + result = []; + while ( valueToken = this.getToken() ) { + result.push( valueToken.v ); + if ( this.getStringMatch( ']' ) ) { + return { + v: result + }; + } + if ( !this.getStringMatch( ',' ) ) { + return null; + } + } + return null; + }, + allowWhitespace: allowWhitespace + }; + + function getKeyValuePair( tokenizer ) { + var key, valueToken, pair; + tokenizer.allowWhitespace(); + key = getKey( tokenizer ); + if ( !key ) { + return null; + } + pair = { + key: key + }; + tokenizer.allowWhitespace(); + if ( !tokenizer.getStringMatch( ':' ) ) { + return null; + } + tokenizer.allowWhitespace(); + valueToken = tokenizer.getToken(); + if ( !valueToken ) { + return null; + } + pair.value = valueToken.v; + return pair; + } + return function( str, values ) { + var tokenizer = new Tokenizer( str, values ); + if ( tokenizer.result ) { + return { + value: tokenizer.result.v, + remaining: tokenizer.remaining() + }; + } + return null; + }; + }( parse_Tokenizer_utils_getStringMatch, parse_Tokenizer_utils_allowWhitespace, parse_Tokenizer_getExpression_getPrimary_getLiteral_getStringLiteral__getStringLiteral, parse_Tokenizer_getExpression_shared_getKey ); + + var render_StringFragment_Interpolator = function( types, teardown, Mustache ) { + + var StringInterpolator = function( options ) { + this.type = types.INTERPOLATOR; + Mustache.init( this, options ); + }; + StringInterpolator.prototype = { + update: Mustache.update, + resolve: Mustache.resolve, + reassign: Mustache.reassign, + render: function( value ) { + this.value = value; + this.parentFragment.bubble(); + }, + teardown: function() { + teardown( this ); + }, + toString: function() { + if ( this.value == undefined ) { + return ''; + } + return stringify( this.value ); + } + }; + return StringInterpolator; + + function stringify( value ) { + if ( typeof value === 'string' ) { + return value; + } + return JSON.stringify( value ); + } + }( config_types, shared_teardown, render_shared_Mustache__Mustache ); + + var render_StringFragment_Section = function( types, Mustache, updateSection, teardown, circular ) { + + var StringSection, StringFragment; + circular.push( function() { + StringFragment = circular.StringFragment; + } ); + StringSection = function( options ) { + this.type = types.SECTION; + this.fragments = []; + this.length = 0; + Mustache.init( this, options ); + }; + StringSection.prototype = { + update: Mustache.update, + resolve: Mustache.resolve, + reassign: Mustache.reassign, + teardown: function() { + this.teardownFragments(); + teardown( this ); + }, + teardownFragments: function() { + while ( this.fragments.length ) { + this.fragments.shift().teardown(); + } + this.length = 0; + }, + bubble: function() { + this.value = this.fragments.join( '' ); + this.parentFragment.bubble(); + }, + render: function( value ) { + var wrapped; + // with sections, we need to get the fake value if we have a wrapped object + if ( wrapped = this.root._wrapped[ this.keypath ] ) { + value = wrapped.get(); + } + updateSection( this, value ); + this.parentFragment.bubble(); + }, + createFragment: function( options ) { + return new StringFragment( options ); + }, + toString: function() { + return this.fragments.join( '' ); + } + }; + return StringSection; + }( config_types, render_shared_Mustache__Mustache, render_shared_updateSection, shared_teardown, circular ); + + var render_StringFragment_Text = function( types ) { + + var StringText = function( text ) { + this.type = types.TEXT; + this.text = text; + }; + StringText.prototype = { + toString: function() { + return this.text; + }, + reassign: function() {}, + //no-op + teardown: function() {} + }; + return StringText; + }( config_types ); + + var render_StringFragment_prototype_toArgsList = function( warn, parseJSON ) { + + return function() { + var values, counter, jsonesque, guid, errorMessage, parsed, processItems; + if ( !this.argsList || this.dirty ) { + values = {}; + counter = 0; + guid = this.root._guid; + processItems = function( items ) { + return items.map( function( item ) { + var placeholderId, wrapped, value; + if ( item.text ) { + return item.text; + } + if ( item.fragments ) { + return item.fragments.map( function( fragment ) { + return processItems( fragment.items ); + } ).join( '' ); + } + placeholderId = guid + '-' + counter++; + if ( wrapped = item.root._wrapped[ item.keypath ] ) { + value = wrapped.value; + } else { + value = item.value; + } + values[ placeholderId ] = value; + return '${' + placeholderId + '}'; + } ).join( '' ); + }; + jsonesque = processItems( this.items ); + parsed = parseJSON( '[' + jsonesque + ']', values ); + if ( !parsed ) { + errorMessage = 'Could not parse directive arguments (' + this.toString() + '). If you think this is a bug, please file an issue at http://github.com/RactiveJS/Ractive/issues'; + if ( this.root.debug ) { + throw new Error( errorMessage ); + } else { + warn( errorMessage ); + this.argsList = [ jsonesque ]; + } + } else { + this.argsList = parsed.value; + } + this.dirty = false; + } + return this.argsList; + }; + }( utils_warn, utils_parseJSON ); + + var render_StringFragment__StringFragment = function( types, parseJSON, Fragment, Interpolator, Section, Text, toArgsList, circular ) { + + var StringFragment = function( options ) { + Fragment.init( this, options ); + }; + StringFragment.prototype = { + reassign: Fragment.reassign, + createItem: function( options ) { + if ( typeof options.descriptor === 'string' ) { + return new Text( options.descriptor ); + } + switch ( options.descriptor.t ) { + case types.INTERPOLATOR: + return new Interpolator( options ); + case types.TRIPLE: + return new Interpolator( options ); + case types.SECTION: + return new Section( options ); + default: + throw 'Something went wrong in a rather interesting way'; + } + }, + bubble: function() { + this.dirty = true; + this.owner.bubble(); + }, + teardown: function() { + var numItems, i; + numItems = this.items.length; + for ( i = 0; i < numItems; i += 1 ) { + this.items[ i ].teardown(); + } + }, + getValue: function() { + var value; + // Accommodate boolean attributes + if ( this.items.length === 1 && this.items[ 0 ].type === types.INTERPOLATOR ) { + value = this.items[ 0 ].value; + if ( value !== undefined ) { + return value; + } + } + return this.toString(); + }, + isSimple: function() { + var i, item, containsInterpolator; + if ( this.simple !== undefined ) { + return this.simple; + } + i = this.items.length; + while ( i-- ) { + item = this.items[ i ]; + if ( item.type === types.TEXT ) { + continue; + } + // we can only have one interpolator and still be self-updating + if ( item.type === types.INTERPOLATOR ) { + if ( containsInterpolator ) { + return false; + } else { + containsInterpolator = true; + continue; + } + } + // anything that isn't text or an interpolator (i.e. a section) + // and we can't self-update + return this.simple = false; + } + return this.simple = true; + }, + toString: function() { + return this.items.join( '' ); + }, + toJSON: function() { + var value = this.getValue(), + parsed; + if ( typeof value === 'string' ) { + parsed = parseJSON( value ); + value = parsed ? parsed.value : value; + } + return value; + }, + toArgsList: toArgsList + }; + circular.StringFragment = StringFragment; + return StringFragment; + }( config_types, utils_parseJSON, render_shared_Fragment__Fragment, render_StringFragment_Interpolator, render_StringFragment_Section, render_StringFragment_Text, render_StringFragment_prototype_toArgsList, circular ); + + var render_DomFragment_Attribute__Attribute = function( runloop, types, determineNameAndNamespace, setStaticAttribute, determinePropertyName, getInterpolator, bind, update, StringFragment ) { + + var DomAttribute = function( options ) { + this.type = types.ATTRIBUTE; + this.element = options.element; + determineNameAndNamespace( this, options.name ); + // if it's an empty attribute, or just a straight key-value pair, with no + // mustache shenanigans, set the attribute accordingly and go home + if ( options.value === null || typeof options.value === 'string' ) { + setStaticAttribute( this, options ); + return; + } + // otherwise we need to do some work + this.root = options.root; + this.pNode = options.pNode; + // share parentFragment with parent element + this.parentFragment = this.element.parentFragment; + this.fragment = new StringFragment( { + descriptor: options.value, + root: this.root, + owner: this + } ); + // Store a reference to this attribute's interpolator, if its fragment + // takes the form `{{foo}}`. This is necessary for two-way binding and + // for correctly rendering HTML later + this.interpolator = getInterpolator( this ); + // if we're not rendering (i.e. we're just stringifying), we can stop here + if ( !this.pNode ) { + return; + } + // special cases + if ( this.name === 'value' ) { + this.isValueAttribute = true; + // TODO need to wait until afterwards to determine type, in case we + // haven't initialised that attribute yet + // + if ( this.pNode.tagName === 'INPUT' && this.pNode.type === 'file' ) { + this.isFileInputValue = true; + } + } + // can we establish this attribute's property name equivalent? + determinePropertyName( this, options ); + // determine whether this attribute can be marked as self-updating + this.selfUpdating = this.fragment.isSimple(); + // mark as ready + this.ready = true; + }; + DomAttribute.prototype = { + bind: bind, + update: update, + updateBindings: function() { + // if the fragment this attribute belongs to gets reassigned (as a result of + // as section being updated via an array shift, unshift or splice), this + // attribute needs to recognise that its keypath has changed + this.keypath = this.interpolator.keypath || this.interpolator.ref; + // if we encounter the special case described above, update the name attribute + if ( this.propertyName === 'name' ) { + // replace actual name attribute + this.pNode.name = '{{' + this.keypath + '}}'; + } + }, + reassign: function( indexRef, newIndex, oldKeypath, newKeypath ) { + if ( this.fragment ) { + this.fragment.reassign( indexRef, newIndex, oldKeypath, newKeypath ); + if ( this.twoway ) { + this.updateBindings(); + } + } + }, + teardown: function() { + var i; + if ( this.boundEvents ) { + i = this.boundEvents.length; + while ( i-- ) { + this.pNode.removeEventListener( this.boundEvents[ i ], this.updateModel, false ); + } + } + // ignore non-dynamic attributes + if ( this.fragment ) { + this.fragment.teardown(); + } + }, + bubble: function() { + // If an attribute's text fragment contains a single item, we can + // update the DOM immediately... + if ( this.selfUpdating ) { + this.update(); + } else if ( !this.deferred && this.ready ) { + runloop.addAttribute( this ); + this.deferred = true; + } + }, + toString: function() { + var str, interpolator; + if ( this.value === null ) { + return this.name; + } + // Special case - select values (should not be stringified) + if ( this.name === 'value' && this.element.lcName === 'select' ) { + return; + } + // Special case - radio names + if ( this.name === 'name' && this.element.lcName === 'input' && ( interpolator = this.interpolator ) ) { + return 'name={{' + ( interpolator.keypath || interpolator.ref ) + '}}'; + } + // TODO don't use JSON.stringify? + if ( !this.fragment ) { + return this.name + '=' + JSON.stringify( this.value ); + } + // TODO deal with boolean attributes correctly + str = this.fragment.toString(); + return this.name + '=' + JSON.stringify( str ); + } + }; + return DomAttribute; + }( global_runloop, config_types, render_DomFragment_Attribute_helpers_determineNameAndNamespace, render_DomFragment_Attribute_helpers_setStaticAttribute, render_DomFragment_Attribute_helpers_determinePropertyName, render_DomFragment_Attribute_helpers_getInterpolator, render_DomFragment_Attribute_prototype_bind, render_DomFragment_Attribute_prototype_update, render_StringFragment__StringFragment ); + + var render_DomFragment_Element_initialise_createElementAttribute = function( Attribute ) { + + return function createElementAttribute( element, name, fragment ) { + var attr = new Attribute( { + element: element, + name: name, + value: fragment, + root: element.root, + pNode: element.node + } ); + // store against both index and name, for fast iteration and lookup + element.attributes.push( element.attributes[ name ] = attr ); + // The name attribute is a special case - it is the only two-way attribute that updates + // the viewmodel based on the value of another attribute. For that reason it must wait + // until the node has been initialised, and the viewmodel has had its first two-way + // update, before updating itself (otherwise it may disable a checkbox or radio that + // was enabled in the template) + if ( name !== 'name' ) { + attr.update(); + } + }; + }( render_DomFragment_Attribute__Attribute ); + + var render_DomFragment_Element_initialise_createElementAttributes = function( createElementAttribute ) { + + return function( element, attributes ) { + var attrName; + element.attributes = []; + for ( attrName in attributes ) { + if ( attributes.hasOwnProperty( attrName ) ) { + createElementAttribute( element, attrName, attributes[ attrName ] ); + } + } + return element.attributes; + }; + }( render_DomFragment_Element_initialise_createElementAttribute ); + + var utils_toArray = function toArray( arrayLike ) { + var array = [], + i = arrayLike.length; + while ( i-- ) { + array[ i ] = arrayLike[ i ]; + } + return array; + }; + + var render_DomFragment_Element_shared_getMatchingStaticNodes = function( toArray ) { + + return function getMatchingStaticNodes( element, selector ) { + if ( !element.matchingStaticNodes[ selector ] ) { + element.matchingStaticNodes[ selector ] = toArray( element.node.querySelectorAll( selector ) ); + } + return element.matchingStaticNodes[ selector ]; + }; + }( utils_toArray ); + + var render_DomFragment_Element_initialise_appendElementChildren = function( warn, namespaces, StringFragment, getMatchingStaticNodes, circular ) { + + var DomFragment, updateCss, updateScript; + circular.push( function() { + DomFragment = circular.DomFragment; + } ); + updateCss = function() { + var node = this.node, + content = this.fragment.toString(); + if ( node.styleSheet ) { + node.styleSheet.cssText = content; + } else { + node.innerHTML = content; + } + }; + updateScript = function() { + if ( !this.node.type || this.node.type === 'text/javascript' ) { + warn( 'Script tag was updated. This does not cause the code to be re-evaluated!' ); + } + this.node.text = this.fragment.toString(); + }; + return function appendElementChildren( element, node, descriptor, docFrag ) { + // Special case - script and style tags + if ( element.lcName === 'script' || element.lcName === 'style' ) { + element.fragment = new StringFragment( { + descriptor: descriptor.f, + root: element.root, + owner: element + } ); + if ( docFrag ) { + if ( element.lcName === 'script' ) { + element.bubble = updateScript; + element.node.text = element.fragment.toString(); + } else { + element.bubble = updateCss; + element.bubble(); + } + } + return; + } + if ( typeof descriptor.f === 'string' && ( !node || ( !node.namespaceURI || node.namespaceURI === namespaces.html ) ) ) { + // great! we can use innerHTML + element.html = descriptor.f; + if ( docFrag ) { + node.innerHTML = element.html; + // Update live queries, if applicable + element.matchingStaticNodes = {}; + // so we can remove matches made with querySelectorAll at teardown time + updateLiveQueries( element ); + } + } else { + element.fragment = new DomFragment( { + descriptor: descriptor.f, + root: element.root, + pNode: node, + owner: element, + pElement: element + } ); + if ( docFrag ) { + node.appendChild( element.fragment.docFrag ); + } + } + }; + + function updateLiveQueries( element ) { + var instance, liveQueries, node, selector, query, matchingStaticNodes, i; + node = element.node; + instance = element.root; + do { + liveQueries = instance._liveQueries; + i = liveQueries.length; + while ( i-- ) { + selector = liveQueries[ i ]; + query = liveQueries[ selector ]; + matchingStaticNodes = getMatchingStaticNodes( element, selector ); + query.push.apply( query, matchingStaticNodes ); + } + } while ( instance = instance._parent ); + } + }( utils_warn, config_namespaces, render_StringFragment__StringFragment, render_DomFragment_Element_shared_getMatchingStaticNodes, circular ); + + var render_DomFragment_Element_initialise_decorate_Decorator = function( warn, StringFragment ) { + + var Decorator = function( descriptor, ractive, owner ) { + var decorator = this, + name, fragment, errorMessage; + decorator.root = ractive; + decorator.node = owner.node; + name = descriptor.n || descriptor; + if ( typeof name !== 'string' ) { + fragment = new StringFragment( { + descriptor: name, + root: ractive, + owner: owner + } ); + name = fragment.toString(); + fragment.teardown(); + } + if ( descriptor.a ) { + decorator.params = descriptor.a; + } else if ( descriptor.d ) { + decorator.fragment = new StringFragment( { + descriptor: descriptor.d, + root: ractive, + owner: owner + } ); + decorator.params = decorator.fragment.toArgsList(); + decorator.fragment.bubble = function() { + this.dirty = true; + decorator.params = this.toArgsList(); + if ( decorator.ready ) { + decorator.update(); + } + }; + } + decorator.fn = ractive.decorators[ name ]; + if ( !decorator.fn ) { + errorMessage = 'Missing "' + name + '" decorator. You may need to download a plugin via http://docs.ractivejs.org/latest/plugins#decorators'; + if ( ractive.debug ) { + throw new Error( errorMessage ); + } else { + warn( errorMessage ); + } + } + }; + Decorator.prototype = { + init: function() { + var result, args; + if ( this.params ) { + args = [ this.node ].concat( this.params ); + result = this.fn.apply( this.root, args ); + } else { + result = this.fn.call( this.root, this.node ); + } + if ( !result || !result.teardown ) { + throw new Error( 'Decorator definition must return an object with a teardown method' ); + } + // TODO does this make sense? + this.actual = result; + this.ready = true; + }, + update: function() { + if ( this.actual.update ) { + this.actual.update.apply( this.root, this.params ); + } else { + this.actual.teardown( true ); + this.init(); + } + }, + teardown: function( updating ) { + this.actual.teardown(); + if ( !updating && this.fragment ) { + this.fragment.teardown(); + } + } + }; + return Decorator; + }( utils_warn, render_StringFragment__StringFragment ); + + var render_DomFragment_Element_initialise_decorate__decorate = function( runloop, Decorator ) { + + return function( descriptor, root, owner ) { + var decorator = new Decorator( descriptor, root, owner ); + if ( decorator.fn ) { + owner.decorator = decorator; + runloop.addDecorator( owner.decorator ); + } + }; + }( global_runloop, render_DomFragment_Element_initialise_decorate_Decorator ); + + var render_DomFragment_Element_initialise_addEventProxies_addEventProxy = function( warn, StringFragment ) { + + var addEventProxy, + // helpers + MasterEventHandler, ProxyEvent, firePlainEvent, fireEventWithArgs, fireEventWithDynamicArgs, customHandlers, genericHandler, getCustomHandler; + addEventProxy = function( element, triggerEventName, proxyDescriptor, indexRefs ) { + var events, master; + events = element.node._ractive.events; + master = events[ triggerEventName ] || ( events[ triggerEventName ] = new MasterEventHandler( element, triggerEventName, indexRefs ) ); + master.add( proxyDescriptor ); + }; + MasterEventHandler = function( element, eventName ) { + var definition; + this.element = element; + this.root = element.root; + this.node = element.node; + this.name = eventName; + this.proxies = []; + if ( definition = this.root.events[ eventName ] ) { + this.custom = definition( this.node, getCustomHandler( eventName ) ); + } else { + // Looks like we're dealing with a standard DOM event... but let's check + if ( !( 'on' + eventName in this.node ) ) { + warn( 'Missing "' + this.name + '" event. You may need to download a plugin via http://docs.ractivejs.org/latest/plugins#events' ); + } + this.node.addEventListener( eventName, genericHandler, false ); + } + }; + MasterEventHandler.prototype = { + add: function( proxy ) { + this.proxies.push( new ProxyEvent( this.element, this.root, proxy ) ); + }, + // TODO teardown when element torn down + teardown: function() { + var i; + if ( this.custom ) { + this.custom.teardown(); + } else { + this.node.removeEventListener( this.name, genericHandler, false ); + } + i = this.proxies.length; + while ( i-- ) { + this.proxies[ i ].teardown(); + } + }, + fire: function( event ) { + var i = this.proxies.length; + while ( i-- ) { + this.proxies[ i ].fire( event ); + } + } + }; + ProxyEvent = function( element, ractive, descriptor ) { + var name; + this.root = ractive; + name = descriptor.n || descriptor; + if ( typeof name === 'string' ) { + this.n = name; + } else { + this.n = new StringFragment( { + descriptor: descriptor.n, + root: this.root, + owner: element + } ); + } + if ( descriptor.a ) { + this.a = descriptor.a; + this.fire = fireEventWithArgs; + return; + } + if ( descriptor.d ) { + this.d = new StringFragment( { + descriptor: descriptor.d, + root: this.root, + owner: element + } ); + this.fire = fireEventWithDynamicArgs; + return; + } + this.fire = firePlainEvent; + }; + ProxyEvent.prototype = { + teardown: function() { + if ( this.n.teardown ) { + this.n.teardown(); + } + if ( this.d ) { + this.d.teardown(); + } + }, + bubble: function() {} + }; + // the ProxyEvent instance fire method could be any of these + firePlainEvent = function( event ) { + this.root.fire( this.n.toString(), event ); + }; + fireEventWithArgs = function( event ) { + this.root.fire.apply( this.root, [ + this.n.toString(), + event + ].concat( this.a ) ); + }; + fireEventWithDynamicArgs = function( event ) { + var args = this.d.toArgsList(); + // need to strip [] from ends if a string! + if ( typeof args === 'string' ) { + args = args.substr( 1, args.length - 2 ); + } + this.root.fire.apply( this.root, [ + this.n.toString(), + event + ].concat( args ) ); + }; + // all native DOM events dealt with by Ractive share a single handler + genericHandler = function( event ) { + var storage = this._ractive; + storage.events[ event.type ].fire( { + node: this, + original: event, + index: storage.index, + keypath: storage.keypath, + context: storage.root.get( storage.keypath ) + } ); + }; + customHandlers = {}; + getCustomHandler = function( eventName ) { + if ( customHandlers[ eventName ] ) { + return customHandlers[ eventName ]; + } + return customHandlers[ eventName ] = function( event ) { + var storage = event.node._ractive; + event.index = storage.index; + event.keypath = storage.keypath; + event.context = storage.root.get( storage.keypath ); + storage.events[ eventName ].fire( event ); + }; + }; + return addEventProxy; + }( utils_warn, render_StringFragment__StringFragment ); + + var render_DomFragment_Element_initialise_addEventProxies__addEventProxies = function( addEventProxy ) { + + return function( element, proxies ) { + var i, eventName, eventNames; + for ( eventName in proxies ) { + if ( proxies.hasOwnProperty( eventName ) ) { + eventNames = eventName.split( '-' ); + i = eventNames.length; + while ( i-- ) { + addEventProxy( element, eventNames[ i ], proxies[ eventName ] ); + } + } + } + }; + }( render_DomFragment_Element_initialise_addEventProxies_addEventProxy ); + + var render_DomFragment_Element_initialise_updateLiveQueries = function( element ) { + var instance, liveQueries, i, selector, query; + // Does this need to be added to any live queries? + instance = element.root; + do { + liveQueries = instance._liveQueries; + i = liveQueries.length; + while ( i-- ) { + selector = liveQueries[ i ]; + query = liveQueries[ selector ]; + if ( query._test( element ) ) { + // keep register of applicable selectors, for when we teardown + ( element.liveQueries || ( element.liveQueries = [] ) ).push( query ); + } + } + } while ( instance = instance._parent ); + }; + + var render_DomFragment_Element_shared_executeTransition_Transition_prototype_init = function() { + if ( this._inited ) { + throw new Error( 'Cannot initialize a transition more than once' ); + } + this._inited = true; + this._fn.apply( this.root, [ this ].concat( this.params ) ); + }; + + var render_DomFragment_Element_shared_executeTransition_Transition_helpers_prefix = function( isClient, vendors, createElement ) { + + var prefixCache, testStyle; + if ( !isClient ) { + return; + } + prefixCache = {}; + testStyle = createElement( 'div' ).style; + return function( prop ) { + var i, vendor, capped; + if ( !prefixCache[ prop ] ) { + if ( testStyle[ prop ] !== undefined ) { + prefixCache[ prop ] = prop; + } else { + // test vendors... + capped = prop.charAt( 0 ).toUpperCase() + prop.substring( 1 ); + i = vendors.length; + while ( i-- ) { + vendor = vendors[ i ]; + if ( testStyle[ vendor + capped ] !== undefined ) { + prefixCache[ prop ] = vendor + capped; + break; + } + } + } + } + return prefixCache[ prop ]; + }; + }( config_isClient, config_vendors, utils_createElement ); + + var render_DomFragment_Element_shared_executeTransition_Transition_prototype_getStyle = function( legacy, isClient, isArray, prefix ) { + + var getComputedStyle; + if ( !isClient ) { + return; + } + getComputedStyle = window.getComputedStyle || legacy.getComputedStyle; + return function( props ) { + var computedStyle, styles, i, prop, value; + computedStyle = window.getComputedStyle( this.node ); + if ( typeof props === 'string' ) { + value = computedStyle[ prefix( props ) ]; + if ( value === '0px' ) { + value = 0; + } + return value; + } + if ( !isArray( props ) ) { + throw new Error( 'Transition#getStyle must be passed a string, or an array of strings representing CSS properties' ); + } + styles = {}; + i = props.length; + while ( i-- ) { + prop = props[ i ]; + value = computedStyle[ prefix( prop ) ]; + if ( value === '0px' ) { + value = 0; + } + styles[ prop ] = value; + } + return styles; + }; + }( legacy, config_isClient, utils_isArray, render_DomFragment_Element_shared_executeTransition_Transition_helpers_prefix ); + + var render_DomFragment_Element_shared_executeTransition_Transition_prototype_setStyle = function( prefix ) { + + return function( style, value ) { + var prop; + if ( typeof style === 'string' ) { + this.node.style[ prefix( style ) ] = value; + } else { + for ( prop in style ) { + if ( style.hasOwnProperty( prop ) ) { + this.node.style[ prefix( prop ) ] = style[ prop ]; + } + } + } + return this; + }; + }( render_DomFragment_Element_shared_executeTransition_Transition_helpers_prefix ); + + var utils_camelCase = function( hyphenatedStr ) { + return hyphenatedStr.replace( /-([a-zA-Z])/g, function( match, $1 ) { + return $1.toUpperCase(); + } ); + }; + + var shared_Ticker = function( warn, getTime, animations ) { + + // TODO what happens if a transition is aborted? + // TODO use this with Animation to dedupe some code? + var Ticker = function( options ) { + var easing; + this.duration = options.duration; + this.step = options.step; + this.complete = options.complete; + // easing + if ( typeof options.easing === 'string' ) { + easing = options.root.easing[ options.easing ]; + if ( !easing ) { + warn( 'Missing easing function ("' + options.easing + '"). You may need to download a plugin from [TODO]' ); + easing = linear; + } + } else if ( typeof options.easing === 'function' ) { + easing = options.easing; + } else { + easing = linear; + } + this.easing = easing; + this.start = getTime(); + this.end = this.start + this.duration; + this.running = true; + animations.add( this ); + }; + Ticker.prototype = { + tick: function( now ) { + var elapsed, eased; + if ( !this.running ) { + return false; + } + if ( now > this.end ) { + if ( this.step ) { + this.step( 1 ); + } + if ( this.complete ) { + this.complete( 1 ); + } + return false; + } + elapsed = now - this.start; + eased = this.easing( elapsed / this.duration ); + if ( this.step ) { + this.step( eased ); + } + return true; + }, + stop: function() { + if ( this.abort ) { + this.abort(); + } + this.running = false; + } + }; + return Ticker; + + function linear( t ) { + return t; + } + }( utils_warn, utils_getTime, shared_animations ); + + var render_DomFragment_Element_shared_executeTransition_Transition_helpers_unprefix = function( vendors ) { + + var unprefixPattern = new RegExp( '^-(?:' + vendors.join( '|' ) + ')-' ); + return function( prop ) { + return prop.replace( unprefixPattern, '' ); + }; + }( config_vendors ); + + var render_DomFragment_Element_shared_executeTransition_Transition_helpers_hyphenate = function( vendors ) { + + var vendorPattern = new RegExp( '^(?:' + vendors.join( '|' ) + ')([A-Z])' ); + return function( str ) { + var hyphenated; + if ( !str ) { + return ''; + } + if ( vendorPattern.test( str ) ) { + str = '-' + str; + } + hyphenated = str.replace( /[A-Z]/g, function( match ) { + return '-' + match.toLowerCase(); + } ); + return hyphenated; + }; + }( config_vendors ); + + var render_DomFragment_Element_shared_executeTransition_Transition_prototype_animateStyle_createTransitions = function( isClient, warn, createElement, camelCase, interpolate, Ticker, prefix, unprefix, hyphenate ) { + + var testStyle, TRANSITION, TRANSITIONEND, CSS_TRANSITIONS_ENABLED, TRANSITION_DURATION, TRANSITION_PROPERTY, TRANSITION_TIMING_FUNCTION, canUseCssTransitions = {}, cannotUseCssTransitions = {}; + if ( !isClient ) { + return; + } + testStyle = createElement( 'div' ).style; + // determine some facts about our environment + ( function() { + if ( testStyle.transition !== undefined ) { + TRANSITION = 'transition'; + TRANSITIONEND = 'transitionend'; + CSS_TRANSITIONS_ENABLED = true; + } else if ( testStyle.webkitTransition !== undefined ) { + TRANSITION = 'webkitTransition'; + TRANSITIONEND = 'webkitTransitionEnd'; + CSS_TRANSITIONS_ENABLED = true; + } else { + CSS_TRANSITIONS_ENABLED = false; + } + }() ); + if ( TRANSITION ) { + TRANSITION_DURATION = TRANSITION + 'Duration'; + TRANSITION_PROPERTY = TRANSITION + 'Property'; + TRANSITION_TIMING_FUNCTION = TRANSITION + 'TimingFunction'; + } + return function( t, to, options, changedProperties, transitionEndHandler, resolve ) { + // Wait a beat (otherwise the target styles will be applied immediately) + // TODO use a fastdom-style mechanism? + setTimeout( function() { + var hashPrefix, jsTransitionsComplete, cssTransitionsComplete, checkComplete; + checkComplete = function() { + if ( jsTransitionsComplete && cssTransitionsComplete ) { + resolve(); + } + }; + // this is used to keep track of which elements can use CSS to animate + // which properties + hashPrefix = t.node.namespaceURI + t.node.tagName; + t.node.style[ TRANSITION_PROPERTY ] = changedProperties.map( prefix ).map( hyphenate ).join( ',' ); + t.node.style[ TRANSITION_TIMING_FUNCTION ] = hyphenate( options.easing || 'linear' ); + t.node.style[ TRANSITION_DURATION ] = options.duration / 1000 + 's'; + transitionEndHandler = function( event ) { + var index; + index = changedProperties.indexOf( camelCase( unprefix( event.propertyName ) ) ); + if ( index !== -1 ) { + changedProperties.splice( index, 1 ); + } + if ( changedProperties.length ) { + // still transitioning... + return; + } + t.root.fire( t.name + ':end' ); + t.node.removeEventListener( TRANSITIONEND, transitionEndHandler, false ); + cssTransitionsComplete = true; + checkComplete(); + }; + t.node.addEventListener( TRANSITIONEND, transitionEndHandler, false ); + setTimeout( function() { + var i = changedProperties.length, + hash, originalValue, index, propertiesToTransitionInJs = [], + prop; + while ( i-- ) { + prop = changedProperties[ i ]; + hash = hashPrefix + prop; + if ( canUseCssTransitions[ hash ] ) { + // We can definitely use CSS transitions, because + // we've already tried it and it worked + t.node.style[ prefix( prop ) ] = to[ prop ]; + } else { + // one way or another, we'll need this + originalValue = t.getStyle( prop ); + } + if ( canUseCssTransitions[ hash ] === undefined ) { + // We're not yet sure if we can use CSS transitions - + // let's find out + t.node.style[ prefix( prop ) ] = to[ prop ]; + // if this property is transitionable in this browser, + // the current style will be different from the target style + canUseCssTransitions[ hash ] = t.getStyle( prop ) != to[ prop ]; + cannotUseCssTransitions[ hash ] = !canUseCssTransitions[ hash ]; + } + if ( cannotUseCssTransitions[ hash ] ) { + // we need to fall back to timer-based stuff + // need to remove this from changedProperties, otherwise transitionEndHandler + // will get confused + index = changedProperties.indexOf( prop ); + if ( index === -1 ) { + warn( 'Something very strange happened with transitions. If you see this message, please let @RactiveJS know. Thanks!' ); + } else { + changedProperties.splice( index, 1 ); + } + // TODO Determine whether this property is animatable at all + // for now assume it is. First, we need to set the value to what it was... + t.node.style[ prefix( prop ) ] = originalValue; + // ...then kick off a timer-based transition + propertiesToTransitionInJs.push( { + name: prefix( prop ), + interpolator: interpolate( originalValue, to[ prop ] ) + } ); + } + } + // javascript transitions + if ( propertiesToTransitionInJs.length ) { + new Ticker( { + root: t.root, + duration: options.duration, + easing: camelCase( options.easing ), + step: function( pos ) { + var prop, i; + i = propertiesToTransitionInJs.length; + while ( i-- ) { + prop = propertiesToTransitionInJs[ i ]; + t.node.style[ prop.name ] = prop.interpolator( pos ); + } + }, + complete: function() { + jsTransitionsComplete = true; + checkComplete(); + } + } ); + } else { + jsTransitionsComplete = true; + } + if ( !changedProperties.length ) { + // We need to cancel the transitionEndHandler, and deal with + // the fact that it will never fire + t.node.removeEventListener( TRANSITIONEND, transitionEndHandler, false ); + cssTransitionsComplete = true; + checkComplete(); + } + }, 0 ); + }, options.delay || 0 ); + }; + }( config_isClient, utils_warn, utils_createElement, utils_camelCase, shared_interpolate, shared_Ticker, render_DomFragment_Element_shared_executeTransition_Transition_helpers_prefix, render_DomFragment_Element_shared_executeTransition_Transition_helpers_unprefix, render_DomFragment_Element_shared_executeTransition_Transition_helpers_hyphenate ); + + var render_DomFragment_Element_shared_executeTransition_Transition_prototype_animateStyle__animateStyle = function( legacy, isClient, warn, Promise, prefix, createTransitions ) { + + var getComputedStyle; + if ( !isClient ) { + return; + } + getComputedStyle = window.getComputedStyle || legacy.getComputedStyle; + return function( style, value, options, complete ) { + var t = this, + to; + if ( typeof style === 'string' ) { + to = {}; + to[ style ] = value; + } else { + to = style; + // shuffle arguments + complete = options; + options = value; + } + // As of 0.3.9, transition authors should supply an `option` object with + // `duration` and `easing` properties (and optional `delay`), plus a + // callback function that gets called after the animation completes + // TODO remove this check in a future version + if ( !options ) { + warn( 'The "' + t.name + '" transition does not supply an options object to `t.animateStyle()`. This will break in a future version of Ractive. For more info see https://github.com/RactiveJS/Ractive/issues/340' ); + options = t; + complete = t.complete; + } + var promise = new Promise( function( resolve ) { + var propertyNames, changedProperties, computedStyle, current, from, transitionEndHandler, i, prop; + // Edge case - if duration is zero, set style synchronously and complete + if ( !options.duration ) { + t.setStyle( to ); + resolve(); + return; + } + // Get a list of the properties we're animating + propertyNames = Object.keys( to ); + changedProperties = []; + // Store the current styles + computedStyle = window.getComputedStyle( t.node ); + from = {}; + i = propertyNames.length; + while ( i-- ) { + prop = propertyNames[ i ]; + current = computedStyle[ prefix( prop ) ]; + if ( current === '0px' ) { + current = 0; + } + // we need to know if we're actually changing anything + if ( current != to[ prop ] ) { + // use != instead of !==, so we can compare strings with numbers + changedProperties.push( prop ); + // make the computed style explicit, so we can animate where + // e.g. height='auto' + t.node.style[ prefix( prop ) ] = current; + } + } + // If we're not actually changing anything, the transitionend event + // will never fire! So we complete early + if ( !changedProperties.length ) { + resolve(); + return; + } + createTransitions( t, to, options, changedProperties, transitionEndHandler, resolve ); + } ); + // If a callback was supplied, do the honours + // TODO remove this check in future + if ( complete ) { + warn( 't.animateStyle returns a Promise as of 0.4.0. Transition authors should do t.animateStyle(...).then(callback)' ); + promise.then( complete ); + } + return promise; + }; + }( legacy, config_isClient, utils_warn, utils_Promise, render_DomFragment_Element_shared_executeTransition_Transition_helpers_prefix, render_DomFragment_Element_shared_executeTransition_Transition_prototype_animateStyle_createTransitions ); + + var utils_fillGaps = function( target, source ) { + var key; + for ( key in source ) { + if ( source.hasOwnProperty( key ) && !( key in target ) ) { + target[ key ] = source[ key ]; + } + } + return target; + }; + + var render_DomFragment_Element_shared_executeTransition_Transition_prototype_processParams = function( fillGaps ) { + + return function( params, defaults ) { + if ( typeof params === 'number' ) { + params = { + duration: params + }; + } else if ( typeof params === 'string' ) { + if ( params === 'slow' ) { + params = { + duration: 600 + }; + } else if ( params === 'fast' ) { + params = { + duration: 200 + }; + } else { + params = { + duration: 400 + }; + } + } else if ( !params ) { + params = {}; + } + return fillGaps( params, defaults ); + }; + }( utils_fillGaps ); + + var render_DomFragment_Element_shared_executeTransition_Transition_prototype_resetStyle = function() { + if ( this.originalStyle ) { + this.node.setAttribute( 'style', this.originalStyle ); + } else { + // Next line is necessary, to remove empty style attribute! + // See http://stackoverflow.com/a/7167553 + this.node.getAttribute( 'style' ); + this.node.removeAttribute( 'style' ); + } + }; + + var render_DomFragment_Element_shared_executeTransition_Transition__Transition = function( warn, StringFragment, init, getStyle, setStyle, animateStyle, processParams, resetStyle ) { + + var Transition; + Transition = function( descriptor, root, owner, isIntro ) { + var t = this, + name, fragment, errorMessage; + this.root = root; + this.node = owner.node; + this.isIntro = isIntro; + // store original style attribute + this.originalStyle = this.node.getAttribute( 'style' ); + // create t.complete() - we don't want this on the prototype, + // because we don't want `this` silliness when passing it as + // an argument + t.complete = function( noReset ) { + if ( !noReset && t.isIntro ) { + t.resetStyle(); + } + t.node._ractive.transition = null; + t._manager.remove( t ); + }; + name = descriptor.n || descriptor; + if ( typeof name !== 'string' ) { + fragment = new StringFragment( { + descriptor: name, + root: this.root, + owner: owner + } ); + name = fragment.toString(); + fragment.teardown(); + } + this.name = name; + if ( descriptor.a ) { + this.params = descriptor.a; + } else if ( descriptor.d ) { + // TODO is there a way to interpret dynamic arguments without all the + // 'dependency thrashing'? + fragment = new StringFragment( { + descriptor: descriptor.d, + root: this.root, + owner: owner + } ); + this.params = fragment.toArgsList(); + fragment.teardown(); + } + this._fn = root.transitions[ name ]; + if ( !this._fn ) { + errorMessage = 'Missing "' + name + '" transition. You may need to download a plugin via http://docs.ractivejs.org/latest/plugins#transitions'; + if ( root.debug ) { + throw new Error( errorMessage ); + } else { + warn( errorMessage ); + } + return; + } + }; + Transition.prototype = { + init: init, + getStyle: getStyle, + setStyle: setStyle, + animateStyle: animateStyle, + processParams: processParams, + resetStyle: resetStyle + }; + return Transition; + }( utils_warn, render_StringFragment__StringFragment, render_DomFragment_Element_shared_executeTransition_Transition_prototype_init, render_DomFragment_Element_shared_executeTransition_Transition_prototype_getStyle, render_DomFragment_Element_shared_executeTransition_Transition_prototype_setStyle, render_DomFragment_Element_shared_executeTransition_Transition_prototype_animateStyle__animateStyle, render_DomFragment_Element_shared_executeTransition_Transition_prototype_processParams, render_DomFragment_Element_shared_executeTransition_Transition_prototype_resetStyle ); + + var render_DomFragment_Element_shared_executeTransition__executeTransition = function( runloop, Transition ) { + + return function( descriptor, ractive, owner, isIntro ) { + var transition, node, oldTransition; + // TODO this can't be right! + if ( !ractive.transitionsEnabled || ractive._parent && !ractive._parent.transitionsEnabled ) { + return; + } + // get transition name, args and function + transition = new Transition( descriptor, ractive, owner, isIntro ); + if ( transition._fn ) { + node = transition.node; + // Existing transition (i.e. we're outroing before intro is complete)? + // End it prematurely + if ( oldTransition = node._ractive.transition ) { + oldTransition.complete(); + } + node._ractive.transition = transition; + runloop.addTransition( transition ); + } + }; + }( global_runloop, render_DomFragment_Element_shared_executeTransition_Transition__Transition ); + + var render_DomFragment_Element_initialise__initialise = function( runloop, types, namespaces, create, defineProperty, warn, createElement, getInnerContext, getElementNamespace, createElementAttribute, createElementAttributes, appendElementChildren, decorate, addEventProxies, updateLiveQueries, executeTransition, enforceCase ) { + + return function initialiseElement( element, options, docFrag ) { + var parentFragment, pNode, descriptor, namespace, name, attributes, width, height, loadHandler, root, selectBinding, errorMessage; + element.type = types.ELEMENT; + // stuff we'll need later + parentFragment = element.parentFragment = options.parentFragment; + pNode = parentFragment.pNode; + descriptor = element.descriptor = options.descriptor; + element.parent = options.pElement; + element.root = root = parentFragment.root; + element.index = options.index; + element.lcName = descriptor.e.toLowerCase(); + element.eventListeners = []; + element.customEventListeners = []; + element.cssDetachQueue = []; + // get namespace, if we're actually rendering (not server-side stringifying) + if ( pNode ) { + namespace = element.namespace = getElementNamespace( descriptor, pNode ); + // non-HTML elements (i.e. SVG) are case-sensitive + name = namespace !== namespaces.html ? enforceCase( descriptor.e ) : descriptor.e; + // create the DOM node + element.node = createElement( name, namespace ); + // Is this a top-level node of a component? If so, we may need to add + // a data-rvcguid attribute, for CSS encapsulation + if ( root.css && pNode === root.el ) { + element.node.setAttribute( 'data-rvcguid', root.constructor._guid || root._guid ); + } + // Add _ractive property to the node - we use this object to store stuff + // related to proxy events, two-way bindings etc + defineProperty( element.node, '_ractive', { + value: { + proxy: element, + keypath: getInnerContext( parentFragment ), + index: parentFragment.indexRefs, + events: create( null ), + root: root + } + } ); + } + // set attributes + attributes = createElementAttributes( element, descriptor.a ); + // append children, if there are any + if ( descriptor.f ) { + // Special case - contenteditable + if ( element.node && element.node.getAttribute( 'contenteditable' ) ) { + if ( element.node.innerHTML ) { + // This is illegal. You can't have content inside a contenteditable + // element that's already populated + errorMessage = 'A pre-populated contenteditable element should not have children'; + if ( root.debug ) { + throw new Error( errorMessage ); + } else { + warn( errorMessage ); + } + } + } + appendElementChildren( element, element.node, descriptor, docFrag ); + } + // create event proxies + if ( docFrag && descriptor.v ) { + addEventProxies( element, descriptor.v ); + } + // if we're actually rendering (i.e. not server-side stringifying), proceed + if ( docFrag ) { + // deal with two-way bindings + if ( root.twoway ) { + element.bind(); + // Special case - contenteditable + if ( element.node.getAttribute( 'contenteditable' ) && element.node._ractive.binding ) { + // We need to update the model + element.node._ractive.binding.update(); + } + } + // name attributes are deferred, because they're a special case - if two-way + // binding is involved they need to update later. But if it turns out they're + // not two-way we can update them now + if ( attributes.name && !attributes.name.twoway ) { + attributes.name.update(); + } + // if this is an , and we're in a crap browser, we may need to prevent it + // from overriding width and height when it loads the src + if ( element.node.tagName === 'IMG' && ( ( width = element.attributes.width ) || ( height = element.attributes.height ) ) ) { + element.node.addEventListener( 'load', loadHandler = function() { + if ( width ) { + element.node.width = width.value; + } + if ( height ) { + element.node.height = height.value; + } + element.node.removeEventListener( 'load', loadHandler, false ); + }, false ); + } + docFrag.appendChild( element.node ); + // apply decorator(s) + if ( descriptor.o ) { + decorate( descriptor.o, root, element ); + } + // trigger intro transition + if ( descriptor.t1 ) { + executeTransition( descriptor.t1, root, element, true ); + } + if ( element.node.tagName === 'OPTION' ) { + // Special case... if this option's parent select was previously + // empty, it's possible that it should initialise to the value of + // this option. + if ( pNode.tagName === 'SELECT' && ( selectBinding = pNode._ractive.binding ) ) { + // it should be! + selectBinding.deferUpdate(); + } + // If a value attribute was not given, we need to create one based on + // the content of the node, so that `` behaves the + // same as `` with two-way binding + if ( !attributes.value ) { + createElementAttribute( element, 'value', descriptor.f ); + } + // Special case... a select may have had its value set before a matching + // option was rendered. This might be that option element + if ( element.node._ractive.value == pNode._ractive.value ) { + element.node.selected = true; + } + } + if ( element.node.autofocus ) { + // Special case. Some browsers (*cough* Firefix *cough*) have a problem + // with dynamically-generated elements having autofocus, and they won't + // allow you to programmatically focus the element until it's in the DOM + runloop.focus( element.node ); + } + } + // If this is an option element, we need to store a reference to its select + if ( element.lcName === 'option' ) { + element.select = findParentSelect( element.parent ); + } + updateLiveQueries( element ); + }; + + function findParentSelect( element ) { + do { + if ( element.lcName === 'select' ) { + return element; + } + } while ( element = element.parent ); + } + }( global_runloop, config_types, config_namespaces, utils_create, utils_defineProperty, utils_warn, utils_createElement, shared_getInnerContext, render_DomFragment_Element_initialise_getElementNamespace, render_DomFragment_Element_initialise_createElementAttribute, render_DomFragment_Element_initialise_createElementAttributes, render_DomFragment_Element_initialise_appendElementChildren, render_DomFragment_Element_initialise_decorate__decorate, render_DomFragment_Element_initialise_addEventProxies__addEventProxies, render_DomFragment_Element_initialise_updateLiveQueries, render_DomFragment_Element_shared_executeTransition__executeTransition, render_DomFragment_shared_enforceCase ); + + var render_DomFragment_Element_prototype_teardown = function( runloop, executeTransition ) { + + return function Element_prototype_teardown( destroy ) { + var eventName, binding, bindings; + // Detach as soon as we can + if ( destroy ) { + this.willDetach = true; + runloop.detachWhenReady( this ); + } + // Children first. that way, any transitions on child elements will be + // handled by the current transitionManager + if ( this.fragment ) { + this.fragment.teardown( false ); + } + while ( this.attributes.length ) { + this.attributes.pop().teardown(); + } + if ( this.node ) { + for ( eventName in this.node._ractive.events ) { + this.node._ractive.events[ eventName ].teardown(); + } + // tear down two-way binding, if such there be + if ( binding = this.node._ractive.binding ) { + binding.teardown(); + bindings = this.root._twowayBindings[ binding.attr.keypath ]; + bindings.splice( bindings.indexOf( binding ), 1 ); + } + } + if ( this.decorator ) { + this.decorator.teardown(); + } + // Outro, if necessary + if ( this.descriptor.t2 ) { + executeTransition( this.descriptor.t2, this.root, this, false ); + } + // Remove this node from any live queries + if ( this.liveQueries ) { + removeFromLiveQueries( this ); + } + }; + + function removeFromLiveQueries( element ) { + var query, selector, matchingStaticNodes, i, j; + i = element.liveQueries.length; + while ( i-- ) { + query = element.liveQueries[ i ]; + selector = query.selector; + query._remove( element.node ); + if ( element.matchingStaticNodes && ( matchingStaticNodes = element.matchingStaticNodes[ selector ] ) ) { + j = matchingStaticNodes.length; + while ( j-- ) { + query.remove( matchingStaticNodes[ j ] ); + } + } + } + } + }( global_runloop, render_DomFragment_Element_shared_executeTransition__executeTransition ); + + var render_DomFragment_Element_prototype_reassign = function( assignNewKeypath ) { + + return function reassignElement( indexRef, newIndex, oldKeypath, newKeypath ) { + var i, storage, masterEventName, proxies, proxy, binding, bindings, liveQueries, ractive; + i = this.attributes.length; + while ( i-- ) { + this.attributes[ i ].reassign( indexRef, newIndex, oldKeypath, newKeypath ); + } + if ( storage = this.node._ractive ) { + //adjust keypath if needed + assignNewKeypath( storage, 'keypath', oldKeypath, newKeypath ); + if ( indexRef != undefined ) { + storage.index[ indexRef ] = newIndex; + } + for ( masterEventName in storage.events ) { + proxies = storage.events[ masterEventName ].proxies; + i = proxies.length; + while ( i-- ) { + proxy = proxies[ i ]; + if ( typeof proxy.n === 'object' ) { + proxy.a.reassign( indexRef, newIndex, oldKeypath, newKeypath ); + } + if ( proxy.d ) { + proxy.d.reassign( indexRef, newIndex, oldKeypath, newKeypath ); + } + } + } + if ( binding = storage.binding ) { + if ( binding.keypath.substr( 0, oldKeypath.length ) === oldKeypath ) { + bindings = storage.root._twowayBindings[ binding.keypath ]; + // remove binding reference for old keypath + bindings.splice( bindings.indexOf( binding ), 1 ); + // update keypath + binding.keypath = binding.keypath.replace( oldKeypath, newKeypath ); + // add binding reference for new keypath + bindings = storage.root._twowayBindings[ binding.keypath ] || ( storage.root._twowayBindings[ binding.keypath ] = [] ); + bindings.push( binding ); + } + } + } + // reassign children + if ( this.fragment ) { + this.fragment.reassign( indexRef, newIndex, oldKeypath, newKeypath ); + } + // Update live queries, if necessary + if ( liveQueries = this.liveQueries ) { + ractive = this.root; + i = liveQueries.length; + while ( i-- ) { + liveQueries[ i ]._makeDirty(); + } + } + }; + }( render_shared_utils_assignNewKeypath ); + + var config_voidElementNames = 'area base br col command doctype embed hr img input keygen link meta param source track wbr'.split( ' ' ); + + var render_DomFragment_Element_prototype_toString = function( voidElementNames, isArray ) { + + return function() { + var str, i, len, attrStr; + str = '<' + ( this.descriptor.y ? '!doctype' : this.descriptor.e ); + len = this.attributes.length; + for ( i = 0; i < len; i += 1 ) { + if ( attrStr = this.attributes[ i ].toString() ) { + str += ' ' + attrStr; + } + } + // Special case - selected options + if ( this.lcName === 'option' && optionIsSelected( this ) ) { + str += ' selected'; + } + // Special case - two-way radio name bindings + if ( this.lcName === 'input' && inputIsCheckedRadio( this ) ) { + str += ' checked'; + } + str += '>'; + if ( this.html ) { + str += this.html; + } else if ( this.fragment ) { + str += this.fragment.toString(); + } + // add a closing tag if this isn't a void element + if ( voidElementNames.indexOf( this.descriptor.e ) === -1 ) { + str += ''; + } + this.stringifying = false; + return str; + }; + + function optionIsSelected( element ) { + var optionValue, selectValueAttribute, selectValueInterpolator, selectValue, i; + optionValue = element.attributes.value.value; + selectValueAttribute = element.select.attributes.value; + selectValueInterpolator = selectValueAttribute.interpolator; + if ( !selectValueInterpolator ) { + return; + } + selectValue = element.root.get( selectValueInterpolator.keypath || selectValueInterpolator.ref ); + if ( selectValue == optionValue ) { + return true; + } + if ( element.select.attributes.multiple && isArray( selectValue ) ) { + i = selectValue.length; + while ( i-- ) { + if ( selectValue[ i ] == optionValue ) { + return true; + } + } + } + } + + function inputIsCheckedRadio( element ) { + var attributes, typeAttribute, valueAttribute, nameAttribute; + attributes = element.attributes; + typeAttribute = attributes.type; + valueAttribute = attributes.value; + nameAttribute = attributes.name; + if ( !typeAttribute || typeAttribute.value !== 'radio' || !valueAttribute || !nameAttribute.interpolator ) { + return; + } + if ( valueAttribute.value === nameAttribute.interpolator.value ) { + return true; + } + } + }( config_voidElementNames, utils_isArray ); + + var render_DomFragment_Element_prototype_find = function( matches ) { + + return function( selector ) { + var queryResult; + if ( matches( this.node, selector ) ) { + return this.node; + } + if ( this.html && ( queryResult = this.node.querySelector( selector ) ) ) { + return queryResult; + } + if ( this.fragment && this.fragment.find ) { + return this.fragment.find( selector ); + } + }; + }( utils_matches ); + + var render_DomFragment_Element_prototype_findAll = function( getMatchingStaticNodes ) { + + return function( selector, query ) { + var matchingStaticNodes, matchedSelf; + // Add this node to the query, if applicable, and register the + // query on this element + if ( query._test( this, true ) && query.live ) { + ( this.liveQueries || ( this.liveQueries = [] ) ).push( query ); + } + if ( this.html ) { + matchingStaticNodes = getMatchingStaticNodes( this, selector ); + query.push.apply( query, matchingStaticNodes ); + if ( query.live && !matchedSelf ) { + ( this.liveQueries || ( this.liveQueries = [] ) ).push( query ); + } + } + if ( this.fragment ) { + this.fragment.findAll( selector, query ); + } + }; + }( render_DomFragment_Element_shared_getMatchingStaticNodes ); + + var render_DomFragment_Element_prototype_findComponent = function( selector ) { + if ( this.fragment ) { + return this.fragment.findComponent( selector ); + } + }; + + var render_DomFragment_Element_prototype_findAllComponents = function( selector, query ) { + if ( this.fragment ) { + this.fragment.findAllComponents( selector, query ); + } + }; + + var render_DomFragment_Element_prototype_bind = function() { + var attributes = this.attributes; + if ( !this.node ) { + // we're not in a browser! + return; + } + // if this is a late binding, and there's already one, it + // needs to be torn down + if ( this.binding ) { + this.binding.teardown(); + this.binding = null; + } + // contenteditable + if ( this.node.getAttribute( 'contenteditable' ) && attributes.value && attributes.value.bind() ) { + return; + } + // an element can only have one two-way attribute + switch ( this.descriptor.e ) { + case 'select': + case 'textarea': + if ( attributes.value ) { + attributes.value.bind(); + } + return; + case 'input': + if ( this.node.type === 'radio' || this.node.type === 'checkbox' ) { + // we can either bind the name attribute, or the checked attribute - not both + if ( attributes.name && attributes.name.bind() ) { + return; + } + if ( attributes.checked && attributes.checked.bind() ) { + return; + } + } + if ( attributes.value && attributes.value.bind() ) { + return; + } + } + }; + + var render_DomFragment_Element__Element = function( runloop, css, initialise, teardown, reassign, toString, find, findAll, findComponent, findAllComponents, bind ) { + + var DomElement = function( options, docFrag ) { + initialise( this, options, docFrag ); + }; + DomElement.prototype = { + detach: function() { + var Component; + if ( this.node ) { + // need to check for parent node - DOM may have been altered + // by something other than Ractive! e.g. jQuery UI... + if ( this.node.parentNode ) { + this.node.parentNode.removeChild( this.node ); + } + return this.node; + } + // If this element has child components with their own CSS, that CSS needs to + // be removed now + // TODO optimise this + if ( this.cssDetachQueue.length ) { + runloop.start(); + while ( Component === this.cssDetachQueue.pop() ) { + css.remove( Component ); + } + runloop.end(); + } + }, + teardown: teardown, + reassign: reassign, + firstNode: function() { + return this.node; + }, + findNextNode: function() { + return null; + }, + // TODO can we get rid of this? + bubble: function() {}, + // just so event proxy and transition fragments have something to call! + toString: toString, + find: find, + findAll: findAll, + findComponent: findComponent, + findAllComponents: findAllComponents, + bind: bind + }; + return DomElement; + }( global_runloop, global_css, render_DomFragment_Element_initialise__initialise, render_DomFragment_Element_prototype_teardown, render_DomFragment_Element_prototype_reassign, render_DomFragment_Element_prototype_toString, render_DomFragment_Element_prototype_find, render_DomFragment_Element_prototype_findAll, render_DomFragment_Element_prototype_findComponent, render_DomFragment_Element_prototype_findAllComponents, render_DomFragment_Element_prototype_bind ); + + var config_errors = { + missingParser: 'Missing Ractive.parse - cannot parse template. Either preparse or use the version that includes the parser' + }; + + var registries_partials = {}; + + var parse_utils_stripHtmlComments = function( html ) { + var commentStart, commentEnd, processed; + processed = ''; + while ( html.length ) { + commentStart = html.indexOf( '' ); + // no comments? great + if ( commentStart === -1 && commentEnd === -1 ) { + processed += html; + break; + } + // comment start but no comment end + if ( commentStart !== -1 && commentEnd === -1 ) { + throw 'Illegal HTML - expected closing comment sequence (\'-->\')'; + } + // comment end but no comment start, or comment end before comment start + if ( commentEnd !== -1 && commentStart === -1 || commentEnd < commentStart ) { + throw 'Illegal HTML - unexpected closing comment sequence (\'-->\')'; + } + processed += html.substr( 0, commentStart ); + html = html.substring( commentEnd + 3 ); + } + return processed; + }; + + var parse_utils_stripStandalones = function( types ) { + + return function( tokens ) { + var i, current, backOne, backTwo, leadingLinebreak, trailingLinebreak; + leadingLinebreak = /^\s*\r?\n/; + trailingLinebreak = /\r?\n\s*$/; + for ( i = 2; i < tokens.length; i += 1 ) { + current = tokens[ i ]; + backOne = tokens[ i - 1 ]; + backTwo = tokens[ i - 2 ]; + // if we're at the end of a [text][mustache][text] sequence, where [mustache] isn't a partial... + if ( current.type === types.TEXT && ( backOne.type === types.MUSTACHE && backOne.mustacheType !== types.PARTIAL ) && backTwo.type === types.TEXT ) { + // ... and the mustache is a standalone (i.e. line breaks either side)... + if ( trailingLinebreak.test( backTwo.value ) && leadingLinebreak.test( current.value ) ) { + // ... then we want to remove the whitespace after the first line break + // if the mustache wasn't a triple or interpolator or partial + if ( backOne.mustacheType !== types.INTERPOLATOR && backOne.mustacheType !== types.TRIPLE ) { + backTwo.value = backTwo.value.replace( trailingLinebreak, '\n' ); + } + // and the leading line break of the second text token + current.value = current.value.replace( leadingLinebreak, '' ); + // if that means the current token is now empty, we should remove it + if ( current.value === '' ) { + tokens.splice( i--, 1 ); + } + } + } + } + return tokens; + }; + }( config_types ); + + var parse_utils_stripCommentTokens = function( types ) { + + return function( tokens ) { + var i, current, previous, next; + for ( i = 0; i < tokens.length; i += 1 ) { + current = tokens[ i ]; + previous = tokens[ i - 1 ]; + next = tokens[ i + 1 ]; + // if the current token is a comment or a delimiter change, remove it... + if ( current.mustacheType === types.COMMENT || current.mustacheType === types.DELIMCHANGE ) { + tokens.splice( i, 1 ); + // remove comment token + // ... and see if it has text nodes either side, in which case + // they can be concatenated + if ( previous && next ) { + if ( previous.type === types.TEXT && next.type === types.TEXT ) { + previous.value += next.value; + tokens.splice( i, 1 ); + } + } + i -= 1; + } + } + return tokens; + }; + }( config_types ); + + var parse_Tokenizer_getMustache_getDelimiterChange = function( makeRegexMatcher ) { + + var getDelimiter = makeRegexMatcher( /^[^\s=]+/ ); + return function( tokenizer ) { + var start, opening, closing; + if ( !tokenizer.getStringMatch( '=' ) ) { + return null; + } + start = tokenizer.pos; + // allow whitespace before new opening delimiter + tokenizer.allowWhitespace(); + opening = getDelimiter( tokenizer ); + if ( !opening ) { + tokenizer.pos = start; + return null; + } + // allow whitespace (in fact, it's necessary...) + tokenizer.allowWhitespace(); + closing = getDelimiter( tokenizer ); + if ( !closing ) { + tokenizer.pos = start; + return null; + } + // allow whitespace before closing '=' + tokenizer.allowWhitespace(); + if ( !tokenizer.getStringMatch( '=' ) ) { + tokenizer.pos = start; + return null; + } + return [ + opening, + closing + ]; + }; + }( parse_Tokenizer_utils_makeRegexMatcher ); + + var parse_Tokenizer_getMustache_getMustacheType = function( types ) { + + var mustacheTypes = { + '#': types.SECTION, + '^': types.INVERTED, + '/': types.CLOSING, + '>': types.PARTIAL, + '!': types.COMMENT, + '&': types.TRIPLE + }; + return function( tokenizer ) { + var type = mustacheTypes[ tokenizer.str.charAt( tokenizer.pos ) ]; + if ( !type ) { + return null; + } + tokenizer.pos += 1; + return type; + }; + }( config_types ); + + var parse_Tokenizer_getMustache_getMustacheContent = function( types, makeRegexMatcher, getMustacheType ) { + + var getIndexRef = makeRegexMatcher( /^\s*:\s*([a-zA-Z_$][a-zA-Z_$0-9]*)/ ), + arrayMember = /^[0-9][1-9]*$/; + return function( tokenizer, isTriple ) { + var start, mustache, type, expr, i, remaining, index, delimiter, keypathExpression; + start = tokenizer.pos; + mustache = { + type: isTriple ? types.TRIPLE : types.MUSTACHE + }; + // Determine mustache type + if ( !isTriple ) { + // We need to test for expressions before we test for mustache type, because + // an expression that begins '!' looks a lot like a comment + if ( expr = tokenizer.getExpression() ) { + mustache.mustacheType = types.INTERPOLATOR; + // Was it actually an expression, or a comment block in disguise? + tokenizer.allowWhitespace(); + if ( tokenizer.getStringMatch( tokenizer.delimiters[ 1 ] ) ) { + // expression + tokenizer.pos -= tokenizer.delimiters[ 1 ].length; + } else { + // comment block + tokenizer.pos = start; + expr = null; + } + } + if ( !expr ) { + type = getMustacheType( tokenizer ); + // Special case - ampersand mustaches + if ( type === types.TRIPLE ) { + mustache = { + type: types.TRIPLE + }; + } else { + mustache.mustacheType = type || types.INTERPOLATOR; + } + // if it's a comment or a section closer, allow any contents except '}}' + if ( type === types.COMMENT || type === types.CLOSING ) { + remaining = tokenizer.remaining(); + index = remaining.indexOf( tokenizer.delimiters[ 1 ] ); + if ( index !== -1 ) { + mustache.ref = remaining.substr( 0, index ); + tokenizer.pos += index; + return mustache; + } + } + } + } + if ( !expr ) { + // allow whitespace + tokenizer.allowWhitespace(); + // get expression + expr = tokenizer.getExpression(); + // With certain valid references that aren't valid expressions, + // e.g. {{1.foo}}, we have a problem: it looks like we've got an + // expression, but the expression didn't consume the entire + // reference. So we need to check that the mustache delimiters + // appear next, unless there's an index reference (i.e. a colon) + remaining = tokenizer.remaining(); + delimiter = isTriple ? tokenizer.tripleDelimiters[ 1 ] : tokenizer.delimiters[ 1 ]; + if ( remaining.substr( 0, delimiter.length ) !== delimiter && remaining.charAt( 0 ) !== ':' ) { + tokenizer.pos = start; + remaining = tokenizer.remaining(); + index = remaining.indexOf( tokenizer.delimiters[ 1 ] ); + if ( index !== -1 ) { + mustache.ref = remaining.substr( 0, index ).trim(); + tokenizer.pos += index; + return mustache; + } + } + } + while ( expr.t === types.BRACKETED && expr.x ) { + expr = expr.x; + } + // special case - integers should be treated as array members references, + // rather than as expressions in their own right + if ( expr.t === types.REFERENCE ) { + mustache.ref = expr.n; + } else if ( expr.t === types.NUMBER_LITERAL && arrayMember.test( expr.v ) ) { + mustache.ref = expr.v; + } else if ( keypathExpression = getKeypathExpression( expr ) ) { + mustache.keypathExpression = keypathExpression; + } else { + mustache.expression = expr; + } + // optional index reference + i = getIndexRef( tokenizer ); + if ( i !== null ) { + mustache.indexRef = i; + } + return mustache; + }; + + function getKeypathExpression( expr ) { + var members = []; + while ( expr.t === types.MEMBER && expr.r.t === types.REFINEMENT ) { + members.unshift( expr.r ); + expr = expr.x; + } + if ( expr.t !== types.REFERENCE ) { + return null; + } + return { + r: expr.n, + m: members + }; + } + }( config_types, parse_Tokenizer_utils_makeRegexMatcher, parse_Tokenizer_getMustache_getMustacheType ); + + var parse_Tokenizer_getMustache__getMustache = function( types, getDelimiterChange, getMustacheContent ) { + + return function() { + // if the triple delimiter (e.g. '{{{') is longer than the regular mustache + // delimiter (e.g. '{{') then we need to try and find a triple first. Otherwise + // we will get a false positive if the mustache delimiter is a substring of the + // triple delimiter, as in the default case + var seekTripleFirst = this.tripleDelimiters[ 0 ].length > this.delimiters[ 0 ].length; + return getMustache( this, seekTripleFirst ) || getMustache( this, !seekTripleFirst ); + }; + + function getMustache( tokenizer, seekTriple ) { + var start = tokenizer.pos, + content, delimiters; + delimiters = seekTriple ? tokenizer.tripleDelimiters : tokenizer.delimiters; + if ( !tokenizer.getStringMatch( delimiters[ 0 ] ) ) { + return null; + } + // delimiter change? + content = getDelimiterChange( tokenizer ); + if ( content ) { + // find closing delimiter or abort... + if ( !tokenizer.getStringMatch( delimiters[ 1 ] ) ) { + tokenizer.pos = start; + return null; + } + // ...then make the switch + tokenizer[ seekTriple ? 'tripleDelimiters' : 'delimiters' ] = content; + return { + type: types.MUSTACHE, + mustacheType: types.DELIMCHANGE + }; + } + tokenizer.allowWhitespace(); + content = getMustacheContent( tokenizer, seekTriple ); + if ( content === null ) { + tokenizer.pos = start; + return null; + } + // allow whitespace before closing delimiter + tokenizer.allowWhitespace(); + if ( !tokenizer.getStringMatch( delimiters[ 1 ] ) ) { + tokenizer.pos = start; + return null; + } + return content; + } + }( config_types, parse_Tokenizer_getMustache_getDelimiterChange, parse_Tokenizer_getMustache_getMustacheContent ); + + var parse_Tokenizer_getComment_getComment = function( types ) { + + return function() { + var content, remaining, endIndex; + if ( !this.getStringMatch( '' ); + if ( endIndex === -1 ) { + throw new Error( 'Unexpected end of input (expected "-->" to close comment)' ); + } + content = remaining.substr( 0, endIndex ); + this.pos += endIndex + 3; + return { + type: types.COMMENT, + content: content + }; + }; + }( config_types ); + + var parse_Tokenizer_utils_getLowestIndex = function( haystack, needles ) { + var i, index, lowest; + i = needles.length; + while ( i-- ) { + index = haystack.indexOf( needles[ i ] ); + // short circuit + if ( !index ) { + return 0; + } + if ( index === -1 ) { + continue; + } + if ( !lowest || index < lowest ) { + lowest = index; + } + } + return lowest || -1; + }; + + var parse_Tokenizer_getTag__getTag = function( types, makeRegexMatcher, getLowestIndex ) { + + var getTag, getOpeningTag, getClosingTag, getTagName, getAttributes, getAttribute, getAttributeName, getAttributeValue, getUnquotedAttributeValue, getUnquotedAttributeValueToken, getUnquotedAttributeValueText, getQuotedStringToken, getQuotedAttributeValue; + getTag = function() { + return getOpeningTag( this ) || getClosingTag( this ); + }; + getOpeningTag = function( tokenizer ) { + var start, tag, attrs, lowerCaseName; + start = tokenizer.pos; + if ( tokenizer.inside ) { + return null; + } + if ( !tokenizer.getStringMatch( '<' ) ) { + return null; + } + tag = { + type: types.TAG + }; + if ( tokenizer.getStringMatch( '!' ) ) { + tag.doctype = true; + } + // tag name + tag.name = getTagName( tokenizer ); + if ( !tag.name ) { + tokenizer.pos = start; + return null; + } + // attributes + attrs = getAttributes( tokenizer ); + if ( attrs ) { + tag.attrs = attrs; + } + // allow whitespace before closing solidus + tokenizer.allowWhitespace(); + // self-closing solidus? + if ( tokenizer.getStringMatch( '/' ) ) { + tag.selfClosing = true; + } + // closing angle bracket + if ( !tokenizer.getStringMatch( '>' ) ) { + tokenizer.pos = start; + return null; + } + // Special case - if we open a script tag, further tags should + // be ignored unless they're a closing script tag + lowerCaseName = tag.name.toLowerCase(); + if ( lowerCaseName === 'script' || lowerCaseName === 'style' ) { + tokenizer.inside = lowerCaseName; + } + return tag; + }; + getClosingTag = function( tokenizer ) { + var start, tag, expected; + start = tokenizer.pos; + expected = function( str ) { + throw new Error( 'Unexpected character ' + tokenizer.remaining().charAt( 0 ) + ' (expected ' + str + ')' ); + }; + if ( !tokenizer.getStringMatch( '<' ) ) { + return null; + } + tag = { + type: types.TAG, + closing: true + }; + // closing solidus + if ( !tokenizer.getStringMatch( '/' ) ) { + expected( '"/"' ); + } + // tag name + tag.name = getTagName( tokenizer ); + if ( !tag.name ) { + expected( 'tag name' ); + } + // closing angle bracket + if ( !tokenizer.getStringMatch( '>' ) ) { + expected( '">"' ); + } + if ( tokenizer.inside ) { + if ( tag.name.toLowerCase() !== tokenizer.inside ) { + tokenizer.pos = start; + return null; + } + tokenizer.inside = null; + } + return tag; + }; + getTagName = makeRegexMatcher( /^[a-zA-Z]{1,}:?[a-zA-Z0-9\-]*/ ); + getAttributes = function( tokenizer ) { + var start, attrs, attr; + start = tokenizer.pos; + // if the next character isn't whitespace, there are no attributes... + if ( !tokenizer.getStringMatch( ' ' ) && !tokenizer.getStringMatch( '\n' ) ) { + return null; + } + // ...but allow arbitrary amounts of whitespace + tokenizer.allowWhitespace(); + attr = getAttribute( tokenizer ); + if ( !attr ) { + tokenizer.pos = start; + return null; + } + attrs = []; + while ( attr !== null ) { + attrs.push( attr ); + tokenizer.allowWhitespace(); + attr = getAttribute( tokenizer ); + } + return attrs; + }; + getAttribute = function( tokenizer ) { + var attr, name, value; + name = getAttributeName( tokenizer ); + if ( !name ) { + return null; + } + attr = { + name: name + }; + value = getAttributeValue( tokenizer ); + if ( value ) { + attr.value = value; + } + return attr; + }; + getAttributeName = makeRegexMatcher( /^[^\s"'>\/=]+/ ); + getAttributeValue = function( tokenizer ) { + var start, value; + start = tokenizer.pos; + tokenizer.allowWhitespace(); + if ( !tokenizer.getStringMatch( '=' ) ) { + tokenizer.pos = start; + return null; + } + tokenizer.allowWhitespace(); + value = getQuotedAttributeValue( tokenizer, '\'' ) || getQuotedAttributeValue( tokenizer, '"' ) || getUnquotedAttributeValue( tokenizer ); + if ( value === null ) { + tokenizer.pos = start; + return null; + } + return value; + }; + getUnquotedAttributeValueText = makeRegexMatcher( /^[^\s"'=<>`]+/ ); + getUnquotedAttributeValueToken = function( tokenizer ) { + var start, text, index; + start = tokenizer.pos; + text = getUnquotedAttributeValueText( tokenizer ); + if ( !text ) { + return null; + } + if ( ( index = text.indexOf( tokenizer.delimiters[ 0 ] ) ) !== -1 ) { + text = text.substr( 0, index ); + tokenizer.pos = start + text.length; + } + return { + type: types.TEXT, + value: text + }; + }; + getUnquotedAttributeValue = function( tokenizer ) { + var tokens, token; + tokens = []; + token = tokenizer.getMustache() || getUnquotedAttributeValueToken( tokenizer ); + while ( token !== null ) { + tokens.push( token ); + token = tokenizer.getMustache() || getUnquotedAttributeValueToken( tokenizer ); + } + if ( !tokens.length ) { + return null; + } + return tokens; + }; + getQuotedAttributeValue = function( tokenizer, quoteMark ) { + var start, tokens, token; + start = tokenizer.pos; + if ( !tokenizer.getStringMatch( quoteMark ) ) { + return null; + } + tokens = []; + token = tokenizer.getMustache() || getQuotedStringToken( tokenizer, quoteMark ); + while ( token !== null ) { + tokens.push( token ); + token = tokenizer.getMustache() || getQuotedStringToken( tokenizer, quoteMark ); + } + if ( !tokenizer.getStringMatch( quoteMark ) ) { + tokenizer.pos = start; + return null; + } + return tokens; + }; + getQuotedStringToken = function( tokenizer, quoteMark ) { + var start, index, remaining; + start = tokenizer.pos; + remaining = tokenizer.remaining(); + index = getLowestIndex( remaining, [ + quoteMark, + tokenizer.delimiters[ 0 ], + tokenizer.delimiters[ 1 ] + ] ); + if ( index === -1 ) { + throw new Error( 'Quoted attribute value must have a closing quote' ); + } + if ( !index ) { + return null; + } + tokenizer.pos += index; + return { + type: types.TEXT, + value: remaining.substr( 0, index ) + }; + }; + return getTag; + }( config_types, parse_Tokenizer_utils_makeRegexMatcher, parse_Tokenizer_utils_getLowestIndex ); + + var parse_Tokenizer_getText__getText = function( types, getLowestIndex ) { + + return function() { + var index, remaining, barrier; + remaining = this.remaining(); + barrier = this.inside ? '> >>> < <= > >= in instanceof == != === !== & ^ | && ||'.split( ' ' ); + // A typeof operator is higher precedence than multiplication + fallthrough = getTypeOf; + for ( i = 0, len = infixOperators.length; i < len; i += 1 ) { + matcher = makeInfixSequenceMatcher( infixOperators[ i ], fallthrough ); + fallthrough = matcher; + } + // Logical OR is the fallthrough for the conditional matcher + getLogicalOr = fallthrough; + }() ); + return getLogicalOr; + }( config_types, parse_Tokenizer_getExpression_getTypeOf ); + + var parse_Tokenizer_getExpression_getConditional = function( types, getLogicalOr ) { + + // The conditional operator is the lowest precedence operator, so we start here + return function( tokenizer ) { + var start, expression, ifTrue, ifFalse; + expression = getLogicalOr( tokenizer ); + if ( !expression ) { + return null; + } + start = tokenizer.pos; + tokenizer.allowWhitespace(); + if ( !tokenizer.getStringMatch( '?' ) ) { + tokenizer.pos = start; + return expression; + } + tokenizer.allowWhitespace(); + ifTrue = tokenizer.getExpression(); + if ( !ifTrue ) { + tokenizer.pos = start; + return expression; + } + tokenizer.allowWhitespace(); + if ( !tokenizer.getStringMatch( ':' ) ) { + tokenizer.pos = start; + return expression; + } + tokenizer.allowWhitespace(); + ifFalse = tokenizer.getExpression(); + if ( !ifFalse ) { + tokenizer.pos = start; + return expression; + } + return { + t: types.CONDITIONAL, + o: [ + expression, + ifTrue, + ifFalse + ] + }; + }; + }( config_types, parse_Tokenizer_getExpression_getLogicalOr ); + + var parse_Tokenizer_getExpression__getExpression = function( getConditional ) { + + // The conditional operator is the lowest precedence operator (except yield, + // assignment operators, and commas, none of which are supported), so we + // start there. If it doesn't match, it 'falls through' to progressively + // higher precedence operators, until it eventually matches (or fails to + // match) a 'primary' - a literal or a reference. This way, the abstract syntax + // tree has everything in its proper place, i.e. 2 + 3 * 4 === 14, not 20. + return function() { + return getConditional( this ); + }; + }( parse_Tokenizer_getExpression_getConditional ); + + var parse_Tokenizer__Tokenizer = function( getMustache, getComment, getTag, getText, getExpression, allowWhitespace, getStringMatch ) { + + var Tokenizer; + Tokenizer = function( str, options ) { + var token; + this.str = str; + this.pos = 0; + this.delimiters = options.delimiters; + this.tripleDelimiters = options.tripleDelimiters; + this.interpolate = options.interpolate; + this.tokens = []; + while ( this.pos < this.str.length ) { + token = this.getToken(); + if ( token === null && this.remaining() ) { + this.fail(); + } + this.tokens.push( token ); + } + }; + Tokenizer.prototype = { + getToken: function() { + var token = this.getMustache() || this.getComment() || this.getTag() || this.getText(); + return token; + }, + getMustache: getMustache, + getComment: getComment, + getTag: getTag, + getText: getText, + getExpression: getExpression, + // utils + allowWhitespace: allowWhitespace, + getStringMatch: getStringMatch, + remaining: function() { + return this.str.substring( this.pos ); + }, + fail: function() { + var last20, next20; + last20 = this.str.substr( 0, this.pos ).substr( -20 ); + if ( last20.length === 20 ) { + last20 = '...' + last20; + } + next20 = this.remaining().substr( 0, 20 ); + if ( next20.length === 20 ) { + next20 = next20 + '...'; + } + throw new Error( 'Could not parse template: ' + ( last20 ? last20 + '<- ' : '' ) + 'failed at character ' + this.pos + ' ->' + next20 ); + }, + expected: function( thing ) { + var remaining = this.remaining().substr( 0, 40 ); + if ( remaining.length === 40 ) { + remaining += '...'; + } + throw new Error( 'Tokenizer failed: unexpected string "' + remaining + '" (expected ' + thing + ')' ); + } + }; + return Tokenizer; + }( parse_Tokenizer_getMustache__getMustache, parse_Tokenizer_getComment_getComment, parse_Tokenizer_getTag__getTag, parse_Tokenizer_getText__getText, parse_Tokenizer_getExpression__getExpression, parse_Tokenizer_utils_allowWhitespace, parse_Tokenizer_utils_getStringMatch ); + + var parse_tokenize = function( initOptions, stripHtmlComments, stripStandalones, stripCommentTokens, Tokenizer ) { + + return function( template, options ) { + var tokenizer, tokens; + options = options || {}; + if ( options.stripComments !== false ) { + template = stripHtmlComments( template ); + } + // TODO handle delimiters differently + tokenizer = new Tokenizer( template, { + delimiters: options.delimiters || initOptions.defaults.delimiters, + tripleDelimiters: options.tripleDelimiters || initOptions.defaults.tripleDelimiters, + interpolate: { + script: options.interpolateScripts !== false ? true : false, + style: options.interpolateStyles !== false ? true : false + } + } ); + // TODO and this... + tokens = tokenizer.tokens; + stripStandalones( tokens ); + stripCommentTokens( tokens ); + return tokens; + }; + }( config_initOptions, parse_utils_stripHtmlComments, parse_utils_stripStandalones, parse_utils_stripCommentTokens, parse_Tokenizer__Tokenizer ); + + var parse_Parser_getText_TextStub__TextStub = function( types ) { + + var TextStub, + // helpers + htmlEntities, controlCharacters, namedEntityPattern, hexEntityPattern, decimalEntityPattern, validateCode, decodeCharacterReferences, whitespace; + TextStub = function( token, preserveWhitespace ) { + this.text = preserveWhitespace ? token.value : token.value.replace( whitespace, ' ' ); + }; + TextStub.prototype = { + type: types.TEXT, + toJSON: function() { + // this will be used within HTML, so we need to decode things like & + return this.decoded || ( this.decoded = decodeCharacterReferences( this.text ) ); + }, + toString: function() { + // this will be used as straight text + return this.text; + } + }; + htmlEntities = { + quot: 34, + amp: 38, + apos: 39, + lt: 60, + gt: 62, + nbsp: 160, + iexcl: 161, + cent: 162, + pound: 163, + curren: 164, + yen: 165, + brvbar: 166, + sect: 167, + uml: 168, + copy: 169, + ordf: 170, + laquo: 171, + not: 172, + shy: 173, + reg: 174, + macr: 175, + deg: 176, + plusmn: 177, + sup2: 178, + sup3: 179, + acute: 180, + micro: 181, + para: 182, + middot: 183, + cedil: 184, + sup1: 185, + ordm: 186, + raquo: 187, + frac14: 188, + frac12: 189, + frac34: 190, + iquest: 191, + Agrave: 192, + Aacute: 193, + Acirc: 194, + Atilde: 195, + Auml: 196, + Aring: 197, + AElig: 198, + Ccedil: 199, + Egrave: 200, + Eacute: 201, + Ecirc: 202, + Euml: 203, + Igrave: 204, + Iacute: 205, + Icirc: 206, + Iuml: 207, + ETH: 208, + Ntilde: 209, + Ograve: 210, + Oacute: 211, + Ocirc: 212, + Otilde: 213, + Ouml: 214, + times: 215, + Oslash: 216, + Ugrave: 217, + Uacute: 218, + Ucirc: 219, + Uuml: 220, + Yacute: 221, + THORN: 222, + szlig: 223, + agrave: 224, + aacute: 225, + acirc: 226, + atilde: 227, + auml: 228, + aring: 229, + aelig: 230, + ccedil: 231, + egrave: 232, + eacute: 233, + ecirc: 234, + euml: 235, + igrave: 236, + iacute: 237, + icirc: 238, + iuml: 239, + eth: 240, + ntilde: 241, + ograve: 242, + oacute: 243, + ocirc: 244, + otilde: 245, + ouml: 246, + divide: 247, + oslash: 248, + ugrave: 249, + uacute: 250, + ucirc: 251, + uuml: 252, + yacute: 253, + thorn: 254, + yuml: 255, + OElig: 338, + oelig: 339, + Scaron: 352, + scaron: 353, + Yuml: 376, + fnof: 402, + circ: 710, + tilde: 732, + Alpha: 913, + Beta: 914, + Gamma: 915, + Delta: 916, + Epsilon: 917, + Zeta: 918, + Eta: 919, + Theta: 920, + Iota: 921, + Kappa: 922, + Lambda: 923, + Mu: 924, + Nu: 925, + Xi: 926, + Omicron: 927, + Pi: 928, + Rho: 929, + Sigma: 931, + Tau: 932, + Upsilon: 933, + Phi: 934, + Chi: 935, + Psi: 936, + Omega: 937, + alpha: 945, + beta: 946, + gamma: 947, + delta: 948, + epsilon: 949, + zeta: 950, + eta: 951, + theta: 952, + iota: 953, + kappa: 954, + lambda: 955, + mu: 956, + nu: 957, + xi: 958, + omicron: 959, + pi: 960, + rho: 961, + sigmaf: 962, + sigma: 963, + tau: 964, + upsilon: 965, + phi: 966, + chi: 967, + psi: 968, + omega: 969, + thetasym: 977, + upsih: 978, + piv: 982, + ensp: 8194, + emsp: 8195, + thinsp: 8201, + zwnj: 8204, + zwj: 8205, + lrm: 8206, + rlm: 8207, + ndash: 8211, + mdash: 8212, + lsquo: 8216, + rsquo: 8217, + sbquo: 8218, + ldquo: 8220, + rdquo: 8221, + bdquo: 8222, + dagger: 8224, + Dagger: 8225, + bull: 8226, + hellip: 8230, + permil: 8240, + prime: 8242, + Prime: 8243, + lsaquo: 8249, + rsaquo: 8250, + oline: 8254, + frasl: 8260, + euro: 8364, + image: 8465, + weierp: 8472, + real: 8476, + trade: 8482, + alefsym: 8501, + larr: 8592, + uarr: 8593, + rarr: 8594, + darr: 8595, + harr: 8596, + crarr: 8629, + lArr: 8656, + uArr: 8657, + rArr: 8658, + dArr: 8659, + hArr: 8660, + forall: 8704, + part: 8706, + exist: 8707, + empty: 8709, + nabla: 8711, + isin: 8712, + notin: 8713, + ni: 8715, + prod: 8719, + sum: 8721, + minus: 8722, + lowast: 8727, + radic: 8730, + prop: 8733, + infin: 8734, + ang: 8736, + and: 8743, + or: 8744, + cap: 8745, + cup: 8746, + 'int': 8747, + there4: 8756, + sim: 8764, + cong: 8773, + asymp: 8776, + ne: 8800, + equiv: 8801, + le: 8804, + ge: 8805, + sub: 8834, + sup: 8835, + nsub: 8836, + sube: 8838, + supe: 8839, + oplus: 8853, + otimes: 8855, + perp: 8869, + sdot: 8901, + lceil: 8968, + rceil: 8969, + lfloor: 8970, + rfloor: 8971, + lang: 9001, + rang: 9002, + loz: 9674, + spades: 9824, + clubs: 9827, + hearts: 9829, + diams: 9830 + }; + controlCharacters = [ + 8364, + 129, + 8218, + 402, + 8222, + 8230, + 8224, + 8225, + 710, + 8240, + 352, + 8249, + 338, + 141, + 381, + 143, + 144, + 8216, + 8217, + 8220, + 8221, + 8226, + 8211, + 8212, + 732, + 8482, + 353, + 8250, + 339, + 157, + 382, + 376 + ]; + namedEntityPattern = new RegExp( '&(' + Object.keys( htmlEntities ).join( '|' ) + ');?', 'g' ); + hexEntityPattern = /&#x([0-9]+);?/g; + decimalEntityPattern = /&#([0-9]+);?/g; + // some code points are verboten. If we were inserting HTML, the browser would replace the illegal + // code points with alternatives in some cases - since we're bypassing that mechanism, we need + // to replace them ourselves + // + // Source: http://en.wikipedia.org/wiki/Character_encodings_in_HTML#Illegal_characters + validateCode = function( code ) { + if ( !code ) { + return 65533; + } + // line feed becomes generic whitespace + if ( code === 10 ) { + return 32; + } + // ASCII range. (Why someone would use HTML entities for ASCII characters I don't know, but...) + if ( code < 128 ) { + return code; + } + // code points 128-159 are dealt with leniently by browsers, but they're incorrect. We need + // to correct the mistake or we'll end up with missing € signs and so on + if ( code <= 159 ) { + return controlCharacters[ code - 128 ]; + } + // basic multilingual plane + if ( code < 55296 ) { + return code; + } + // UTF-16 surrogate halves + if ( code <= 57343 ) { + return 65533; + } + // rest of the basic multilingual plane + if ( code <= 65535 ) { + return code; + } + // TODO it's... not exactly clear what should happen with code points over this value. The + // following seems to work. But I can't guarantee it works in China! + return 65533; + }; + decodeCharacterReferences = function( html ) { + var result; + // named entities + result = html.replace( namedEntityPattern, function( match, name ) { + if ( htmlEntities[ name ] ) { + return String.fromCharCode( htmlEntities[ name ] ); + } + return match; + } ); + // hex references + result = result.replace( hexEntityPattern, function( match, hex ) { + return String.fromCharCode( validateCode( parseInt( hex, 16 ) ) ); + } ); + // decimal references + result = result.replace( decimalEntityPattern, function( match, charCode ) { + return String.fromCharCode( validateCode( charCode ) ); + } ); + return result; + }; + whitespace = /\s+/g; + return TextStub; + }( config_types ); + + var parse_Parser_getText__getText = function( types, TextStub ) { + + return function( token, preserveWhitespace ) { + if ( token.type === types.TEXT ) { + this.pos += 1; + return new TextStub( token, preserveWhitespace ); + } + return null; + }; + }( config_types, parse_Parser_getText_TextStub__TextStub ); + + var parse_Parser_getComment_CommentStub__CommentStub = function( types ) { + + var CommentStub; + CommentStub = function( token ) { + this.content = token.content; + }; + CommentStub.prototype = { + toJSON: function() { + return { + t: types.COMMENT, + f: this.content + }; + }, + toString: function() { + return ''; + } + }; + return CommentStub; + }( config_types ); + + var parse_Parser_getComment__getComment = function( types, CommentStub ) { + + return function( token ) { + if ( token.type === types.COMMENT ) { + this.pos += 1; + return new CommentStub( token, this.preserveWhitespace ); + } + return null; + }; + }( config_types, parse_Parser_getComment_CommentStub__CommentStub ); + + var parse_Parser_getMustache_ExpressionStub = function( types, isObject ) { + + var ExpressionStub = function( token ) { + this.refs = []; + getRefs( token, this.refs ); + this.str = stringify( token, this.refs ); + }; + ExpressionStub.prototype = { + toJSON: function() { + if ( !this.json ) { + this.json = { + r: this.refs, + s: this.str + }; + } + return this.json; + } + }; + return ExpressionStub; + + function quoteStringLiteral( str ) { + return JSON.stringify( String( str ) ); + } + // TODO maybe refactor this? + function getRefs( token, refs ) { + var i, list; + if ( token.t === types.REFERENCE ) { + if ( refs.indexOf( token.n ) === -1 ) { + refs.unshift( token.n ); + } + } + list = token.o || token.m; + if ( list ) { + if ( isObject( list ) ) { + getRefs( list, refs ); + } else { + i = list.length; + while ( i-- ) { + getRefs( list[ i ], refs ); + } + } + } + if ( token.x ) { + getRefs( token.x, refs ); + } + if ( token.r ) { + getRefs( token.r, refs ); + } + if ( token.v ) { + getRefs( token.v, refs ); + } + } + + function stringify( token, refs ) { + var map = function( item ) { + return stringify( item, refs ); + }; + switch ( token.t ) { + case types.BOOLEAN_LITERAL: + case types.GLOBAL: + case types.NUMBER_LITERAL: + return token.v; + case types.STRING_LITERAL: + return quoteStringLiteral( token.v ); + case types.ARRAY_LITERAL: + return '[' + ( token.m ? token.m.map( map ).join( ',' ) : '' ) + ']'; + case types.OBJECT_LITERAL: + return '{' + ( token.m ? token.m.map( map ).join( ',' ) : '' ) + '}'; + case types.KEY_VALUE_PAIR: + return token.k + ':' + stringify( token.v, refs ); + case types.PREFIX_OPERATOR: + return ( token.s === 'typeof' ? 'typeof ' : token.s ) + stringify( token.o, refs ); + case types.INFIX_OPERATOR: + return stringify( token.o[ 0 ], refs ) + ( token.s.substr( 0, 2 ) === 'in' ? ' ' + token.s + ' ' : token.s ) + stringify( token.o[ 1 ], refs ); + case types.INVOCATION: + return stringify( token.x, refs ) + '(' + ( token.o ? token.o.map( map ).join( ',' ) : '' ) + ')'; + case types.BRACKETED: + return '(' + stringify( token.x, refs ) + ')'; + case types.MEMBER: + return stringify( token.x, refs ) + stringify( token.r, refs ); + case types.REFINEMENT: + return token.n ? '.' + token.n : '[' + stringify( token.x, refs ) + ']'; + case types.CONDITIONAL: + return stringify( token.o[ 0 ], refs ) + '?' + stringify( token.o[ 1 ], refs ) + ':' + stringify( token.o[ 2 ], refs ); + case types.REFERENCE: + return '${' + refs.indexOf( token.n ) + '}'; + default: + throw new Error( 'Could not stringify expression token. This error is unexpected' ); + } + } + }( config_types, utils_isObject ); + + var parse_Parser_getMustache_KeypathExpressionStub = function( types, ExpressionStub ) { + + var KeypathExpressionStub; + KeypathExpressionStub = function( token ) { + this.json = { + r: token.r, + m: token.m.map( jsonify ) + }; + }; + KeypathExpressionStub.prototype = { + toJSON: function() { + return this.json; + } + }; + return KeypathExpressionStub; + + function jsonify( member ) { + // Straightforward property, e.g. `foo.bar`? + if ( member.n ) { + return member.n; + } + // String or number literal, e.g. `foo["bar"]` or `foo[1]`? + if ( member.x.t === types.STRING_LITERAL || member.x.t === types.NUMBER_LITERAL ) { + return member.x.v; + } + // Straightforward reference, e.g. `foo[bar]`? + if ( member.x.t === types.REFERENCE ) { + return member.x; + } + // If none of the above, we need to process the AST + return new ExpressionStub( member.x ).toJSON(); + } + }( config_types, parse_Parser_getMustache_ExpressionStub ); + + var parse_Parser_getMustache_MustacheStub = function( types, KeypathExpressionStub, ExpressionStub ) { + + var MustacheStub = function( token, parser ) { + this.type = token.type === types.TRIPLE ? types.TRIPLE : token.mustacheType; + if ( token.ref ) { + this.ref = token.ref; + } + if ( token.keypathExpression ) { + this.keypathExpr = new KeypathExpressionStub( token.keypathExpression ); + } + if ( token.expression ) { + this.expr = new ExpressionStub( token.expression ); + } + parser.pos += 1; + }; + MustacheStub.prototype = { + toJSON: function() { + var json; + if ( this.json ) { + return this.json; + } + json = { + t: this.type + }; + if ( this.ref ) { + json.r = this.ref; + } + if ( this.keypathExpr ) { + json.kx = this.keypathExpr.toJSON(); + } + if ( this.expr ) { + json.x = this.expr.toJSON(); + } + this.json = json; + return json; + }, + toString: function() { + // mustaches cannot be stringified + return false; + } + }; + return MustacheStub; + }( config_types, parse_Parser_getMustache_KeypathExpressionStub, parse_Parser_getMustache_ExpressionStub ); + + var parse_Parser_utils_stringifyStubs = function( items ) { + var str = '', + itemStr, i, len; + if ( !items ) { + return ''; + } + for ( i = 0, len = items.length; i < len; i += 1 ) { + itemStr = items[ i ].toString(); + if ( itemStr === false ) { + return false; + } + str += itemStr; + } + return str; + }; + + var parse_Parser_utils_jsonifyStubs = function( stringifyStubs ) { + + return function( items, noStringify, topLevel ) { + var str, json; + if ( !topLevel && !noStringify ) { + str = stringifyStubs( items ); + if ( str !== false ) { + return str; + } + } + json = items.map( function( item ) { + return item.toJSON( noStringify ); + } ); + return json; + }; + }( parse_Parser_utils_stringifyStubs ); + + var parse_Parser_getMustache_SectionStub = function( types, normaliseKeypath, jsonifyStubs, KeypathExpressionStub, ExpressionStub ) { + + var SectionStub = function( firstToken, parser ) { + var next; + this.ref = firstToken.ref; + this.indexRef = firstToken.indexRef; + this.inverted = firstToken.mustacheType === types.INVERTED; + if ( firstToken.keypathExpression ) { + this.keypathExpr = new KeypathExpressionStub( firstToken.keypathExpression ); + } + if ( firstToken.expression ) { + this.expr = new ExpressionStub( firstToken.expression ); + } + parser.pos += 1; + this.items = []; + next = parser.next(); + while ( next ) { + if ( next.mustacheType === types.CLOSING ) { + validateClosing( this, next ); + parser.pos += 1; + break; + } + this.items.push( parser.getStub() ); + next = parser.next(); + } + }; + + function validateClosing( stub, token ) { + var opening = stub.ref, + closing = normaliseKeypath( token.ref.trim() ); + if ( !opening || !closing ) { + return; + } + if ( stub.indexRef ) { + opening += ':' + stub.indexRef; + } + if ( opening.substr( 0, closing.length ) !== closing ) { + throw new Error( 'Could not parse template: Illegal closing section {{/' + closing + '}}. Expected {{/' + stub.ref + '}}.' ); + } + } + SectionStub.prototype = { + toJSON: function( noStringify ) { + var json; + if ( this.json ) { + return this.json; + } + json = { + t: types.SECTION + }; + if ( this.ref ) { + json.r = this.ref; + } + if ( this.indexRef ) { + json.i = this.indexRef; + } + if ( this.inverted ) { + json.n = true; + } + if ( this.expr ) { + json.x = this.expr.toJSON(); + } + if ( this.keypathExpr ) { + json.kx = this.keypathExpr.toJSON(); + } + if ( this.items.length ) { + json.f = jsonifyStubs( this.items, noStringify ); + } + this.json = json; + return json; + }, + toString: function() { + // sections cannot be stringified + return false; + } + }; + return SectionStub; + }( config_types, utils_normaliseKeypath, parse_Parser_utils_jsonifyStubs, parse_Parser_getMustache_KeypathExpressionStub, parse_Parser_getMustache_ExpressionStub ); + + var parse_Parser_getMustache__getMustache = function( types, MustacheStub, SectionStub ) { + + return function( token ) { + if ( token.type === types.MUSTACHE || token.type === types.TRIPLE ) { + if ( token.mustacheType === types.SECTION || token.mustacheType === types.INVERTED ) { + return new SectionStub( token, this ); + } + return new MustacheStub( token, this ); + } + }; + }( config_types, parse_Parser_getMustache_MustacheStub, parse_Parser_getMustache_SectionStub ); + + var parse_Parser_getElement_ElementStub_utils_siblingsByTagName = { + li: [ 'li' ], + dt: [ + 'dt', + 'dd' + ], + dd: [ + 'dt', + 'dd' + ], + p: 'address article aside blockquote dir div dl fieldset footer form h1 h2 h3 h4 h5 h6 header hgroup hr menu nav ol p pre section table ul'.split( ' ' ), + rt: [ + 'rt', + 'rp' + ], + rp: [ + 'rp', + 'rt' + ], + optgroup: [ 'optgroup' ], + option: [ + 'option', + 'optgroup' + ], + thead: [ + 'tbody', + 'tfoot' + ], + tbody: [ + 'tbody', + 'tfoot' + ], + tr: [ 'tr' ], + td: [ + 'td', + 'th' + ], + th: [ + 'td', + 'th' + ] + }; + + var parse_Parser_getElement_ElementStub_utils_filterAttributes = function( isArray ) { + + return function( items ) { + var attrs, proxies, filtered, i, len, item; + filtered = {}; + attrs = []; + proxies = []; + len = items.length; + for ( i = 0; i < len; i += 1 ) { + item = items[ i ]; + // Transition? + if ( item.name === 'intro' ) { + if ( filtered.intro ) { + throw new Error( 'An element can only have one intro transition' ); + } + filtered.intro = item; + } else if ( item.name === 'outro' ) { + if ( filtered.outro ) { + throw new Error( 'An element can only have one outro transition' ); + } + filtered.outro = item; + } else if ( item.name === 'intro-outro' ) { + if ( filtered.intro || filtered.outro ) { + throw new Error( 'An element can only have one intro and one outro transition' ); + } + filtered.intro = item; + filtered.outro = deepClone( item ); + } else if ( item.name.substr( 0, 6 ) === 'proxy-' ) { + item.name = item.name.substring( 6 ); + proxies.push( item ); + } else if ( item.name.substr( 0, 3 ) === 'on-' ) { + item.name = item.name.substring( 3 ); + proxies.push( item ); + } else if ( item.name === 'decorator' ) { + filtered.decorator = item; + } else { + attrs.push( item ); + } + } + filtered.attrs = attrs; + filtered.proxies = proxies; + return filtered; + }; + + function deepClone( obj ) { + var result, key; + if ( typeof obj !== 'object' ) { + return obj; + } + if ( isArray( obj ) ) { + return obj.map( deepClone ); + } + result = {}; + for ( key in obj ) { + if ( obj.hasOwnProperty( key ) ) { + result[ key ] = deepClone( obj[ key ] ); + } + } + return result; + } + }( utils_isArray ); + + var parse_Parser_getElement_ElementStub_utils_processDirective = function( types, parseJSON ) { + + return function( directive ) { + var processed, tokens, token, colonIndex, throwError, directiveName, directiveArgs, parsed; + throwError = function() { + throw new Error( 'Illegal directive' ); + }; + if ( !directive.name || !directive.value ) { + throwError(); + } + processed = { + directiveType: directive.name + }; + tokens = directive.value; + directiveName = []; + directiveArgs = []; + while ( tokens.length ) { + token = tokens.shift(); + if ( token.type === types.TEXT ) { + colonIndex = token.value.indexOf( ':' ); + if ( colonIndex === -1 ) { + directiveName.push( token ); + } else { + // is the colon the first character? + if ( colonIndex ) { + // no + directiveName.push( { + type: types.TEXT, + value: token.value.substr( 0, colonIndex ) + } ); + } + // if there is anything after the colon in this token, treat + // it as the first token of the directiveArgs fragment + if ( token.value.length > colonIndex + 1 ) { + directiveArgs[ 0 ] = { + type: types.TEXT, + value: token.value.substring( colonIndex + 1 ) + }; + } + break; + } + } else { + directiveName.push( token ); + } + } + directiveArgs = directiveArgs.concat( tokens ); + if ( directiveName.length === 1 && directiveName[ 0 ].type === types.TEXT ) { + processed.name = directiveName[ 0 ].value; + } else { + processed.name = directiveName; + } + if ( directiveArgs.length ) { + if ( directiveArgs.length === 1 && directiveArgs[ 0 ].type === types.TEXT ) { + parsed = parseJSON( '[' + directiveArgs[ 0 ].value + ']' ); + processed.args = parsed ? parsed.value : directiveArgs[ 0 ].value; + } else { + processed.dynamicArgs = directiveArgs; + } + } + return processed; + }; + }( config_types, utils_parseJSON ); + + var parse_Parser_StringStub_StringParser = function( getText, getMustache ) { + + var StringParser; + StringParser = function( tokens, options ) { + // TODO what are the options? + var stub; + this.tokens = tokens || []; + this.pos = 0; + this.options = options; + this.result = []; + while ( stub = this.getStub() ) { + this.result.push( stub ); + } + }; + StringParser.prototype = { + getStub: function() { + var token = this.next(); + if ( !token ) { + return null; + } + return this.getText( token ) || this.getMustache( token ); + }, + getText: getText, + getMustache: getMustache, + next: function() { + return this.tokens[ this.pos ]; + } + }; + return StringParser; + }( parse_Parser_getText__getText, parse_Parser_getMustache__getMustache ); + + var parse_Parser_StringStub__StringStub = function( StringParser, stringifyStubs, jsonifyStubs ) { + + var StringStub; + StringStub = function( tokens ) { + var parser = new StringParser( tokens ); + this.stubs = parser.result; + }; + StringStub.prototype = { + toJSON: function( noStringify ) { + var json; + if ( this[ 'json_' + noStringify ] ) { + return this[ 'json_' + noStringify ]; + } + json = this[ 'json_' + noStringify ] = jsonifyStubs( this.stubs, noStringify ); + return json; + }, + toString: function() { + if ( this.str !== undefined ) { + return this.str; + } + this.str = stringifyStubs( this.stubs ); + return this.str; + } + }; + return StringStub; + }( parse_Parser_StringStub_StringParser, parse_Parser_utils_stringifyStubs, parse_Parser_utils_jsonifyStubs ); + + var parse_Parser_getElement_ElementStub_utils_jsonifyDirective = function( StringStub ) { + + return function( directive ) { + var result, name; + if ( typeof directive.name === 'string' ) { + if ( !directive.args && !directive.dynamicArgs ) { + return directive.name; + } + name = directive.name; + } else { + name = new StringStub( directive.name ).toJSON(); + } + result = { + n: name + }; + if ( directive.args ) { + result.a = directive.args; + return result; + } + if ( directive.dynamicArgs ) { + result.d = new StringStub( directive.dynamicArgs ).toJSON(); + } + return result; + }; + }( parse_Parser_StringStub__StringStub ); + + var parse_Parser_getElement_ElementStub_toJSON = function( types, jsonifyStubs, jsonifyDirective ) { + + return function( noStringify ) { + var json, name, value, proxy, i, len, attribute; + if ( this[ 'json_' + noStringify ] ) { + return this[ 'json_' + noStringify ]; + } + json = { + t: types.ELEMENT, + e: this.tag + }; + if ( this.doctype ) { + json.y = 1; + } + if ( this.attributes && this.attributes.length ) { + json.a = {}; + len = this.attributes.length; + for ( i = 0; i < len; i += 1 ) { + attribute = this.attributes[ i ]; + name = attribute.name; + if ( json.a[ name ] ) { + throw new Error( 'You cannot have multiple attributes with the same name' ); + } + // empty attributes (e.g. autoplay, checked) + if ( attribute.value === null ) { + value = null; + } else { + //value = jsonifyStubs( attribute.value, noStringify ); + value = attribute.value.toJSON( noStringify ); + } + json.a[ name ] = value; + } + } + if ( this.items && this.items.length ) { + json.f = jsonifyStubs( this.items, noStringify ); + } + if ( this.proxies && this.proxies.length ) { + json.v = {}; + len = this.proxies.length; + for ( i = 0; i < len; i += 1 ) { + proxy = this.proxies[ i ]; + json.v[ proxy.directiveType ] = jsonifyDirective( proxy ); + } + } + if ( this.intro ) { + json.t1 = jsonifyDirective( this.intro ); + } + if ( this.outro ) { + json.t2 = jsonifyDirective( this.outro ); + } + if ( this.decorator ) { + json.o = jsonifyDirective( this.decorator ); + } + this[ 'json_' + noStringify ] = json; + return json; + }; + }( config_types, parse_Parser_utils_jsonifyStubs, parse_Parser_getElement_ElementStub_utils_jsonifyDirective ); + + var parse_Parser_getElement_ElementStub_toString = function( stringifyStubs, voidElementNames ) { + + var htmlElements; + htmlElements = 'a abbr acronym address applet area b base basefont bdo big blockquote body br button caption center cite code col colgroup dd del dfn dir div dl dt em fieldset font form frame frameset h1 h2 h3 h4 h5 h6 head hr html i iframe img input ins isindex kbd label legend li link map menu meta noframes noscript object ol p param pre q s samp script select small span strike strong style sub sup textarea title tt u ul var article aside audio bdi canvas command data datagrid datalist details embed eventsource figcaption figure footer header hgroup keygen mark meter nav output progress ruby rp rt section source summary time track video wbr'.split( ' ' ); + return function() { + var str, i, len, attrStr, name, attrValueStr, fragStr, isVoid; + if ( this.str !== undefined ) { + return this.str; + } + // if this isn't an HTML element, it can't be stringified (since the only reason to stringify an + // element is to use with innerHTML, and SVG doesn't support that method. + // Note: table elements and select children are excluded from this, because IE (of course) + // fucks up when you use innerHTML with them + if ( htmlElements.indexOf( this.tag.toLowerCase() ) === -1 ) { + return this.str = false; + } + // do we have proxies or transitions or a decorator? if so we can't use innerHTML + if ( this.proxies || this.intro || this.outro || this.decorator ) { + return this.str = false; + } + // see if children can be stringified (i.e. don't contain mustaches) + fragStr = stringifyStubs( this.items ); + if ( fragStr === false ) { + return this.str = false; + } + // is this a void element? + isVoid = voidElementNames.indexOf( this.tag.toLowerCase() ) !== -1; + str = '<' + this.tag; + if ( this.attributes ) { + for ( i = 0, len = this.attributes.length; i < len; i += 1 ) { + name = this.attributes[ i ].name; + // does this look like a namespaced attribute? if so we can't stringify it + if ( name.indexOf( ':' ) !== -1 ) { + return this.str = false; + } + // if this element has an id attribute, it can't be stringified (since references are stored + // in ractive.nodes). Similarly, intro and outro transitions + if ( name === 'id' || name === 'intro' || name === 'outro' ) { + return this.str = false; + } + attrStr = ' ' + name; + // empty attributes + if ( this.attributes[ i ].value !== null ) { + attrValueStr = this.attributes[ i ].value.toString(); + if ( attrValueStr === false ) { + return this.str = false; + } + if ( attrValueStr !== '' ) { + attrStr += '='; + // does it need to be quoted? + if ( /[\s"'=<>`]/.test( attrValueStr ) ) { + attrStr += '"' + attrValueStr.replace( /"/g, '"' ) + '"'; + } else { + attrStr += attrValueStr; + } + } + } + str += attrStr; + } + } + // if this isn't a void tag, but is self-closing, add a solidus. Aaaaand, we're done + if ( this.selfClosing && !isVoid ) { + str += '/>'; + return this.str = str; + } + str += '>'; + // void element? we're done + if ( isVoid ) { + return this.str = str; + } + // if this has children, add them + str += fragStr; + str += ''; + return this.str = str; + }; + }( parse_Parser_utils_stringifyStubs, config_voidElementNames ); + + var parse_Parser_getElement_ElementStub__ElementStub = function( types, voidElementNames, warn, siblingsByTagName, filterAttributes, processDirective, toJSON, toString, StringStub ) { + + var ElementStub, + // helpers + allElementNames, closedByParentClose, onPattern, sanitize, leadingWhitespace = /^\s+/, + trailingWhitespace = /\s+$/; + ElementStub = function( firstToken, parser, preserveWhitespace ) { + var next, attrs, filtered, proxies, item, getFrag, lowerCaseTag; + parser.pos += 1; + getFrag = function( attr ) { + return { + name: attr.name, + value: attr.value ? new StringStub( attr.value ) : null + }; + }; + // enforce lower case tag names by default. HTML doesn't care. SVG does, so if we see an SVG tag + // that should be camelcased, camelcase it + this.tag = firstToken.name; + lowerCaseTag = firstToken.name.toLowerCase(); + if ( lowerCaseTag.substr( 0, 3 ) === 'rv-' ) { + warn( 'The "rv-" prefix for components has been deprecated. Support will be removed in a future version' ); + this.tag = this.tag.substring( 3 ); + } + // if this is a
 element, preserve whitespace within
+			preserveWhitespace = preserveWhitespace || lowerCaseTag === 'pre' || lowerCaseTag === 'style' || lowerCaseTag === 'script';
+			if ( firstToken.attrs ) {
+				filtered = filterAttributes( firstToken.attrs );
+				attrs = filtered.attrs;
+				proxies = filtered.proxies;
+				// remove event attributes (e.g. onclick='doSomething()') if we're sanitizing
+				if ( parser.options.sanitize && parser.options.sanitize.eventAttributes ) {
+					attrs = attrs.filter( sanitize );
+				}
+				if ( attrs.length ) {
+					this.attributes = attrs.map( getFrag );
+				}
+				// Process directives (proxy events, transitions, and decorators)
+				if ( proxies.length ) {
+					this.proxies = proxies.map( processDirective );
+				}
+				if ( filtered.intro ) {
+					this.intro = processDirective( filtered.intro );
+				}
+				if ( filtered.outro ) {
+					this.outro = processDirective( filtered.outro );
+				}
+				if ( filtered.decorator ) {
+					this.decorator = processDirective( filtered.decorator );
+				}
+			}
+			if ( firstToken.doctype ) {
+				this.doctype = true;
+			}
+			if ( firstToken.selfClosing ) {
+				this.selfClosing = true;
+			}
+			if ( voidElementNames.indexOf( lowerCaseTag ) !== -1 ) {
+				this.isVoid = true;
+			}
+			// if self-closing or a void element, close
+			if ( this.selfClosing || this.isVoid ) {
+				return;
+			}
+			this.siblings = siblingsByTagName[ lowerCaseTag ];
+			this.items = [];
+			next = parser.next();
+			while ( next ) {
+				// section closing mustache should also close this element, e.g.
+				// 
    {{#items}}
  • {{content}}{{/items}}
+ if ( next.mustacheType === types.CLOSING ) { + break; + } + if ( next.type === types.TAG ) { + // closing tag + if ( next.closing ) { + // it's a closing tag, which means this element is closed... + if ( next.name.toLowerCase() === lowerCaseTag ) { + parser.pos += 1; + } + break; + } else if ( this.siblings && this.siblings.indexOf( next.name.toLowerCase() ) !== -1 ) { + break; + } + } + this.items.push( parser.getStub( preserveWhitespace ) ); + next = parser.next(); + } + // if we're not preserving whitespace, we can eliminate inner leading and trailing whitespace + if ( !preserveWhitespace ) { + item = this.items[ 0 ]; + if ( item && item.type === types.TEXT ) { + item.text = item.text.replace( leadingWhitespace, '' ); + if ( !item.text ) { + this.items.shift(); + } + } + item = this.items[ this.items.length - 1 ]; + if ( item && item.type === types.TEXT ) { + item.text = item.text.replace( trailingWhitespace, '' ); + if ( !item.text ) { + this.items.pop(); + } + } + } + }; + ElementStub.prototype = { + toJSON: toJSON, + toString: toString + }; + allElementNames = 'a abbr acronym address applet area b base basefont bdo big blockquote body br button caption center cite code col colgroup dd del dfn dir div dl dt em fieldset font form frame frameset h1 h2 h3 h4 h5 h6 head hr html i iframe img input ins isindex kbd label legend li link map menu meta noframes noscript object ol p param pre q s samp script select small span strike strong style sub sup textarea title tt u ul var article aside audio bdi canvas command data datagrid datalist details embed eventsource figcaption figure footer header hgroup keygen mark meter nav output progress ruby rp rt section source summary time track video wbr'.split( ' ' ); + closedByParentClose = 'li dd rt rp optgroup option tbody tfoot tr td th'.split( ' ' ); + onPattern = /^on[a-zA-Z]/; + sanitize = function( attr ) { + var valid = !onPattern.test( attr.name ); + return valid; + }; + return ElementStub; + }( config_types, config_voidElementNames, utils_warn, parse_Parser_getElement_ElementStub_utils_siblingsByTagName, parse_Parser_getElement_ElementStub_utils_filterAttributes, parse_Parser_getElement_ElementStub_utils_processDirective, parse_Parser_getElement_ElementStub_toJSON, parse_Parser_getElement_ElementStub_toString, parse_Parser_StringStub__StringStub ); + + var parse_Parser_getElement__getElement = function( ElementStub ) { + + return function( token ) { + // sanitize + if ( this.options.sanitize && this.options.sanitize.elements ) { + if ( this.options.sanitize.elements.indexOf( token.name.toLowerCase() ) !== -1 ) { + return null; + } + } + return new ElementStub( token, this, this.preserveWhitespace ); + }; + }( parse_Parser_getElement_ElementStub__ElementStub ); + + var parse_Parser__Parser = function( getText, getComment, getMustache, getElement, jsonifyStubs ) { + + var Parser; + Parser = function( tokens, options ) { + var stub, stubs; + this.tokens = tokens || []; + this.pos = 0; + this.options = options; + this.preserveWhitespace = options.preserveWhitespace; + stubs = []; + while ( stub = this.getStub() ) { + stubs.push( stub ); + } + this.result = jsonifyStubs( stubs, options.noStringify, true ); + }; + Parser.prototype = { + getStub: function( preserveWhitespace ) { + var token = this.next(); + if ( !token ) { + return null; + } + return this.getText( token, this.preserveWhitespace || preserveWhitespace ) || this.getComment( token ) || this.getMustache( token ) || this.getElement( token ); + }, + getText: getText, + getComment: getComment, + getMustache: getMustache, + getElement: getElement, + next: function() { + return this.tokens[ this.pos ]; + } + }; + return Parser; + }( parse_Parser_getText__getText, parse_Parser_getComment__getComment, parse_Parser_getMustache__getMustache, parse_Parser_getElement__getElement, parse_Parser_utils_jsonifyStubs ); + + // Ractive.parse + // =============== + // + // Takes in a string, and returns an object representing the parsed template. + // A parsed template is an array of 1 or more 'descriptors', which in some + // cases have children. + // + // The format is optimised for size, not readability, however for reference the + // keys for each descriptor are as follows: + // + // * r - Reference, e.g. 'mustache' in {{mustache}} + // * t - Type code (e.g. 1 is text, 2 is interpolator...) + // * f - Fragment. Contains a descriptor's children + // * e - Element name + // * a - map of element Attributes, or proxy event/transition Arguments + // * d - Dynamic proxy event/transition arguments + // * n - indicates an iNverted section + // * i - Index reference, e.g. 'num' in {{#section:num}}content{{/section}} + // * v - eVent proxies (i.e. when user e.g. clicks on a node, fire proxy event) + // * x - eXpressions + // * s - String representation of an expression function + // * t1 - intro Transition + // * t2 - outro Transition + // * o - decOrator + // * y - is doctYpe + var parse__parse = function( tokenize, types, Parser ) { + + var parse, onlyWhitespace, inlinePartialStart, inlinePartialEnd, parseCompoundTemplate; + onlyWhitespace = /^\s*$/; + inlinePartialStart = //; + inlinePartialEnd = //; + parse = function( template, options ) { + var tokens, json, token; + options = options || {}; + // does this template include inline partials? + if ( inlinePartialStart.test( template ) ) { + return parseCompoundTemplate( template, options ); + } + if ( options.sanitize === true ) { + options.sanitize = { + // blacklist from https://code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/lang/html/html4-elements-whitelist.json + elements: 'applet base basefont body frame frameset head html isindex link meta noframes noscript object param script style title'.split( ' ' ), + eventAttributes: true + }; + } + tokens = tokenize( template, options ); + if ( !options.preserveWhitespace ) { + // remove first token if it only contains whitespace + token = tokens[ 0 ]; + if ( token && token.type === types.TEXT && onlyWhitespace.test( token.value ) ) { + tokens.shift(); + } + // ditto last token + token = tokens[ tokens.length - 1 ]; + if ( token && token.type === types.TEXT && onlyWhitespace.test( token.value ) ) { + tokens.pop(); + } + } + json = new Parser( tokens, options ).result; + if ( typeof json === 'string' ) { + // If we return it as a string, Ractive will attempt to reparse it! + // Instead we wrap it in an array. Ractive knows what to do then + return [ json ]; + } + return json; + }; + parseCompoundTemplate = function( template, options ) { + var mainTemplate, remaining, partials, name, startMatch, endMatch; + partials = {}; + mainTemplate = ''; + remaining = template; + while ( startMatch = inlinePartialStart.exec( remaining ) ) { + name = startMatch[ 1 ]; + mainTemplate += remaining.substr( 0, startMatch.index ); + remaining = remaining.substring( startMatch.index + startMatch[ 0 ].length ); + endMatch = inlinePartialEnd.exec( remaining ); + if ( !endMatch || endMatch[ 1 ] !== name ) { + throw new Error( 'Inline partials must have a closing delimiter, and cannot be nested' ); + } + partials[ name ] = parse( remaining.substr( 0, endMatch.index ), options ); + remaining = remaining.substring( endMatch.index + endMatch[ 0 ].length ); + } + return { + main: parse( mainTemplate, options ), + partials: partials + }; + }; + return parse; + }( parse_tokenize, config_types, parse_Parser__Parser ); + + var render_DomFragment_Partial_deIndent = function() { + + var empty = /^\s*$/, + leadingWhitespace = /^\s*/; + return function( str ) { + var lines, firstLine, lastLine, minIndent; + lines = str.split( '\n' ); + // remove first and last line, if they only contain whitespace + firstLine = lines[ 0 ]; + if ( firstLine !== undefined && empty.test( firstLine ) ) { + lines.shift(); + } + lastLine = lines[ lines.length - 1 ]; + if ( lastLine !== undefined && empty.test( lastLine ) ) { + lines.pop(); + } + minIndent = lines.reduce( reducer, null ); + if ( minIndent ) { + str = lines.map( function( line ) { + return line.replace( minIndent, '' ); + } ).join( '\n' ); + } + return str; + }; + + function reducer( previous, line ) { + var lineIndent = leadingWhitespace.exec( line )[ 0 ]; + if ( previous === null || lineIndent.length < previous.length ) { + return lineIndent; + } + return previous; + } + }(); + + var render_DomFragment_Partial_getPartialDescriptor = function( errors, isClient, warn, isObject, partials, parse, deIndent ) { + + var getPartialDescriptor, registerPartial, getPartialFromRegistry, unpack; + getPartialDescriptor = function( root, name ) { + var el, partial, errorMessage; + // If the partial was specified on this instance, great + if ( partial = getPartialFromRegistry( root, name ) ) { + return partial; + } + // Does it exist on the page as a script tag? + if ( isClient ) { + el = document.getElementById( name ); + if ( el && el.tagName === 'SCRIPT' ) { + if ( !parse ) { + throw new Error( errors.missingParser ); + } + registerPartial( parse( deIndent( el.text ), root.parseOptions ), name, partials ); + } + } + partial = partials[ name ]; + // No match? Return an empty array + if ( !partial ) { + errorMessage = 'Could not find descriptor for partial "' + name + '"'; + if ( root.debug ) { + throw new Error( errorMessage ); + } else { + warn( errorMessage ); + } + return []; + } + return unpack( partial ); + }; + getPartialFromRegistry = function( ractive, name ) { + var partial; + if ( ractive.partials[ name ] ) { + // If this was added manually to the registry, but hasn't been parsed, + // parse it now + if ( typeof ractive.partials[ name ] === 'string' ) { + if ( !parse ) { + throw new Error( errors.missingParser ); + } + partial = parse( ractive.partials[ name ], ractive.parseOptions ); + registerPartial( partial, name, ractive.partials ); + } + return unpack( ractive.partials[ name ] ); + } + }; + registerPartial = function( partial, name, registry ) { + var key; + if ( isObject( partial ) ) { + registry[ name ] = partial.main; + for ( key in partial.partials ) { + if ( partial.partials.hasOwnProperty( key ) ) { + registry[ key ] = partial.partials[ key ]; + } + } + } else { + registry[ name ] = partial; + } + }; + unpack = function( partial ) { + // Unpack string, if necessary + if ( partial.length === 1 && typeof partial[ 0 ] === 'string' ) { + return partial[ 0 ]; + } + return partial; + }; + return getPartialDescriptor; + }( config_errors, config_isClient, utils_warn, utils_isObject, registries_partials, parse__parse, render_DomFragment_Partial_deIndent ); + + var render_DomFragment_Partial_applyIndent = function( string, indent ) { + var indented; + if ( !indent ) { + return string; + } + indented = string.split( '\n' ).map( function( line, notFirstLine ) { + return notFirstLine ? indent + line : line; + } ).join( '\n' ); + return indented; + }; + + var render_DomFragment_Partial__Partial = function( types, getPartialDescriptor, applyIndent, circular ) { + + var DomPartial, DomFragment; + circular.push( function() { + DomFragment = circular.DomFragment; + } ); + DomPartial = function( options, docFrag ) { + var parentFragment = this.parentFragment = options.parentFragment, + descriptor; + this.type = types.PARTIAL; + this.name = options.descriptor.r; + this.index = options.index; + if ( !options.descriptor.r ) { + // TODO support dynamic partial switching + throw new Error( 'Partials must have a static reference (no expressions). This may change in a future version of Ractive.' ); + } + descriptor = getPartialDescriptor( parentFragment.root, options.descriptor.r ); + this.fragment = new DomFragment( { + descriptor: descriptor, + root: parentFragment.root, + pNode: parentFragment.pNode, + owner: this + } ); + if ( docFrag ) { + docFrag.appendChild( this.fragment.docFrag ); + } + }; + DomPartial.prototype = { + firstNode: function() { + return this.fragment.firstNode(); + }, + findNextNode: function() { + return this.parentFragment.findNextNode( this ); + }, + detach: function() { + return this.fragment.detach(); + }, + reassign: function( indexRef, newIndex, oldKeypath, newKeypath ) { + return this.fragment.reassign( indexRef, newIndex, oldKeypath, newKeypath ); + }, + teardown: function( destroy ) { + this.fragment.teardown( destroy ); + }, + toString: function() { + var string, previousItem, lastLine, match; + string = this.fragment.toString(); + previousItem = this.parentFragment.items[ this.index - 1 ]; + if ( !previousItem || previousItem.type !== types.TEXT ) { + return string; + } + lastLine = previousItem.descriptor.split( '\n' ).pop(); + if ( match = /^\s+$/.exec( lastLine ) ) { + return applyIndent( string, match[ 0 ] ); + } + return string; + }, + find: function( selector ) { + return this.fragment.find( selector ); + }, + findAll: function( selector, query ) { + return this.fragment.findAll( selector, query ); + }, + findComponent: function( selector ) { + return this.fragment.findComponent( selector ); + }, + findAllComponents: function( selector, query ) { + return this.fragment.findAllComponents( selector, query ); + } + }; + return DomPartial; + }( config_types, render_DomFragment_Partial_getPartialDescriptor, render_DomFragment_Partial_applyIndent, circular ); + + var render_DomFragment_Component_initialise_createModel_ComponentParameter = function( runloop, StringFragment ) { + + var ComponentParameter = function( component, key, value ) { + this.parentFragment = component.parentFragment; + this.component = component; + this.key = key; + this.fragment = new StringFragment( { + descriptor: value, + root: component.root, + owner: this + } ); + this.selfUpdating = this.fragment.isSimple(); + this.value = this.fragment.getValue(); + }; + ComponentParameter.prototype = { + bubble: function() { + // If there's a single item, we can update the component immediately... + if ( this.selfUpdating ) { + this.update(); + } else if ( !this.deferred && this.ready ) { + runloop.addAttribute( this ); + this.deferred = true; + } + }, + update: function() { + var value = this.fragment.getValue(); + this.component.instance.set( this.key, value ); + this.value = value; + }, + teardown: function() { + this.fragment.teardown(); + } + }; + return ComponentParameter; + }( global_runloop, render_StringFragment__StringFragment ); + + var render_DomFragment_Component_initialise_createModel__createModel = function( types, parseJSON, resolveRef, get, ComponentParameter ) { + + return function( component, defaultData, attributes, toBind ) { + var data, key, value; + data = {}; + // some parameters, e.g. foo="The value is {{bar}}", are 'complex' - in + // other words, we need to construct a string fragment to watch + // when they change. We store these so they can be torn down later + component.complexParameters = []; + for ( key in attributes ) { + if ( attributes.hasOwnProperty( key ) ) { + value = getValue( component, key, attributes[ key ], toBind ); + if ( value !== undefined || defaultData[ key ] === undefined ) { + data[ key ] = value; + } + } + } + return data; + }; + + function getValue( component, key, descriptor, toBind ) { + var parameter, parsed, parentInstance, parentFragment, keypath, indexRef; + parentInstance = component.root; + parentFragment = component.parentFragment; + // If this is a static value, great + if ( typeof descriptor === 'string' ) { + parsed = parseJSON( descriptor ); + return parsed ? parsed.value : descriptor; + } + // If null, we treat it as a boolean attribute (i.e. true) + if ( descriptor === null ) { + return true; + } + // If a regular interpolator, we bind to it + if ( descriptor.length === 1 && descriptor[ 0 ].t === types.INTERPOLATOR && descriptor[ 0 ].r ) { + // Is it an index reference? + if ( parentFragment.indexRefs && parentFragment.indexRefs[ indexRef = descriptor[ 0 ].r ] !== undefined ) { + component.indexRefBindings[ indexRef ] = key; + return parentFragment.indexRefs[ indexRef ]; + } + // TODO what about references that resolve late? Should these be considered? + keypath = resolveRef( parentInstance, descriptor[ 0 ].r, parentFragment ) || descriptor[ 0 ].r; + // We need to set up bindings between parent and child, but + // we can't do it yet because the child instance doesn't exist + // yet - so we make a note instead + toBind.push( { + childKeypath: key, + parentKeypath: keypath + } ); + return get( parentInstance, keypath ); + } + // We have a 'complex parameter' - we need to create a full-blown string + // fragment in order to evaluate and observe its value + parameter = new ComponentParameter( component, key, descriptor ); + component.complexParameters.push( parameter ); + return parameter.value; + } + }( config_types, utils_parseJSON, shared_resolveRef, shared_get__get, render_DomFragment_Component_initialise_createModel_ComponentParameter ); + + var render_DomFragment_Component_initialise_createInstance = function() { + + return function( component, Component, data, docFrag, contentDescriptor ) { + var instance, parentFragment, partials, root, adapt; + parentFragment = component.parentFragment; + root = component.root; + // Make contents available as a {{>content}} partial + partials = { + content: contentDescriptor || [] + }; + // Use component default adaptors AND inherit parent adaptors. + adapt = combineAdaptors( root, Component.defaults.adapt, Component.adaptors ); + instance = new Component( { + el: parentFragment.pNode, + append: true, + data: data, + partials: partials, + magic: root.magic || Component.defaults.magic, + modifyArrays: root.modifyArrays, + _parent: root, + _component: component, + adapt: adapt + } ); + if ( docFrag ) { + // The component may be in the wrong place! This is because we + // are still populating the document fragment that will be appended + // to its parent node. So even though the component is *already* + // a child of the parent node, we need to detach it, then insert + // it into said document fragment, so that order is maintained + // (both figuratively and literally). + instance.insert( docFrag ); + // (After inserting, we need to reset the node reference) + instance.fragment.pNode = instance.el = parentFragment.pNode; + } + return instance; + }; + + function combineAdaptors( root, defaultAdapt ) { + var adapt, len, i; + // Parent adaptors should take precedence, so they go first + if ( root.adapt.length ) { + adapt = root.adapt.map( function( stringOrObject ) { + if ( typeof stringOrObject === 'object' ) { + return stringOrObject; + } + return root.adaptors[ stringOrObject ] || stringOrObject; + } ); + } else { + adapt = []; + } + // If the component has any adaptors that aren't already included, + // include them now + if ( len = defaultAdapt.length ) { + for ( i = 0; i < len; i += 1 ) { + if ( adapt.indexOf( defaultAdapt[ i ] ) === -1 ) { + adapt.push( defaultAdapt[ i ] ); + } + } + } + return adapt; + } + }(); + + var render_DomFragment_Component_initialise_createBindings = function( createComponentBinding, get, set ) { + + return function createInitialComponentBindings( component, toBind ) { + toBind.forEach( function createInitialComponentBinding( pair ) { + var childValue, parentValue; + createComponentBinding( component, component.root, pair.parentKeypath, pair.childKeypath ); + childValue = get( component.instance, pair.childKeypath ); + parentValue = get( component.root, pair.parentKeypath ); + if ( childValue !== undefined && parentValue === undefined ) { + set( component.root, pair.parentKeypath, childValue ); + } + } ); + }; + }( shared_createComponentBinding, shared_get__get, shared_set ); + + var render_DomFragment_Component_initialise_propagateEvents = function( warn ) { + + // TODO how should event arguments be handled? e.g. + // + // The event 'bar' will be fired on the parent instance + // when 'foo' fires on the child, but the 1,2,3 arguments + // will be lost + var errorMessage = 'Components currently only support simple events - you cannot include arguments. Sorry!'; + return function( component, eventsDescriptor ) { + var eventName; + for ( eventName in eventsDescriptor ) { + if ( eventsDescriptor.hasOwnProperty( eventName ) ) { + propagateEvent( component.instance, component.root, eventName, eventsDescriptor[ eventName ] ); + } + } + }; + + function propagateEvent( childInstance, parentInstance, eventName, proxyEventName ) { + if ( typeof proxyEventName !== 'string' ) { + if ( parentInstance.debug ) { + throw new Error( errorMessage ); + } else { + warn( errorMessage ); + return; + } + } + childInstance.on( eventName, function() { + var args = Array.prototype.slice.call( arguments ); + args.unshift( proxyEventName ); + parentInstance.fire.apply( parentInstance, args ); + } ); + } + }( utils_warn ); + + var render_DomFragment_Component_initialise_updateLiveQueries = function( component ) { + var ancestor, query; + // If there's a live query for this component type, add it + ancestor = component.root; + while ( ancestor ) { + if ( query = ancestor._liveComponentQueries[ component.name ] ) { + query.push( component.instance ); + } + ancestor = ancestor._parent; + } + }; + + var render_DomFragment_Component_initialise__initialise = function( types, warn, createModel, createInstance, createBindings, propagateEvents, updateLiveQueries ) { + + return function initialiseComponent( component, options, docFrag ) { + var parentFragment, root, Component, data, toBind; + parentFragment = component.parentFragment = options.parentFragment; + root = parentFragment.root; + component.root = root; + component.type = types.COMPONENT; + component.name = options.descriptor.e; + component.index = options.index; + component.indexRefBindings = {}; + component.bindings = []; + // get the component constructor + Component = root.components[ options.descriptor.e ]; + if ( !Component ) { + throw new Error( 'Component "' + options.descriptor.e + '" not found' ); + } + // First, we need to create a model for the component - e.g. if we + // encounter then we need to create a widget + // with `data: { foo: 'bar' }`. + // + // This may involve setting up some bindings, but we can't do it + // yet so we take some notes instead + toBind = []; + data = createModel( component, Component.data || {}, options.descriptor.a, toBind ); + createInstance( component, Component, data, docFrag, options.descriptor.f ); + createBindings( component, toBind ); + propagateEvents( component, options.descriptor.v ); + // intro, outro and decorator directives have no effect + if ( options.descriptor.t1 || options.descriptor.t2 || options.descriptor.o ) { + warn( 'The "intro", "outro" and "decorator" directives have no effect on components' ); + } + updateLiveQueries( component ); + }; + }( config_types, utils_warn, render_DomFragment_Component_initialise_createModel__createModel, render_DomFragment_Component_initialise_createInstance, render_DomFragment_Component_initialise_createBindings, render_DomFragment_Component_initialise_propagateEvents, render_DomFragment_Component_initialise_updateLiveQueries ); + + var render_DomFragment_Component__Component = function( initialise, getNewKeypath ) { + + var DomComponent = function( options, docFrag ) { + initialise( this, options, docFrag ); + }; + DomComponent.prototype = { + firstNode: function() { + return this.instance.fragment.firstNode(); + }, + findNextNode: function() { + return this.parentFragment.findNextNode( this ); + }, + detach: function() { + return this.instance.fragment.detach(); + }, + teardown: function( destroy ) { + while ( this.complexParameters.length ) { + this.complexParameters.pop().teardown(); + } + while ( this.bindings.length ) { + this.bindings.pop().teardown(); + } + removeFromLiveComponentQueries( this ); + // Add this flag so that we don't unnecessarily destroy the component's nodes + this.shouldDestroy = destroy; + this.instance.teardown(); + }, + reassign: function( indexRef, newIndex, oldKeypath, newKeypath ) { + var childInstance = this.instance, + parentInstance = childInstance._parent, + indexRefAlias, query; + this.bindings.forEach( function( binding ) { + var updated; + if ( binding.root !== parentInstance ) { + return; + } + if ( binding.keypath === indexRef ) { + childInstance.set( binding.otherKeypath, newIndex ); + } + if ( updated = getNewKeypath( binding.keypath, oldKeypath, newKeypath ) ) { + binding.reassign( updated ); + } + } ); + if ( indexRefAlias = this.indexRefBindings[ indexRef ] ) { + childInstance.set( indexRefAlias, newIndex ); + } + if ( query = this.root._liveComponentQueries[ this.name ] ) { + query._makeDirty(); + } + }, + toString: function() { + return this.instance.fragment.toString(); + }, + find: function( selector ) { + return this.instance.fragment.find( selector ); + }, + findAll: function( selector, query ) { + return this.instance.fragment.findAll( selector, query ); + }, + findComponent: function( selector ) { + if ( !selector || selector === this.name ) { + return this.instance; + } + if ( this.instance.fragment ) { + return this.instance.fragment.findComponent( selector ); + } + return null; + }, + findAllComponents: function( selector, query ) { + query._test( this, true ); + if ( this.instance.fragment ) { + this.instance.fragment.findAllComponents( selector, query ); + } + } + }; + return DomComponent; + + function removeFromLiveComponentQueries( component ) { + var instance, query; + instance = component.root; + do { + if ( query = instance._liveComponentQueries[ component.name ] ) { + query._remove( component ); + } + } while ( instance = instance._parent ); + } + }( render_DomFragment_Component_initialise__initialise, render_shared_utils_getNewKeypath ); + + var render_DomFragment_Comment = function( types, detach ) { + + var DomComment = function( options, docFrag ) { + this.type = types.COMMENT; + this.descriptor = options.descriptor; + if ( docFrag ) { + this.node = document.createComment( options.descriptor.f ); + docFrag.appendChild( this.node ); + } + }; + DomComment.prototype = { + detach: detach, + teardown: function( destroy ) { + if ( destroy ) { + this.detach(); + } + }, + firstNode: function() { + return this.node; + }, + toString: function() { + return ''; + } + }; + return DomComment; + }( config_types, render_DomFragment_shared_detach ); + + var render_DomFragment__DomFragment = function( types, matches, Fragment, insertHtml, Text, Interpolator, Section, Triple, Element, Partial, Component, Comment, circular ) { + + var DomFragment = function( options ) { + if ( options.pNode ) { + this.docFrag = document.createDocumentFragment(); + } + // if we have an HTML string, our job is easy. + if ( typeof options.descriptor === 'string' ) { + this.html = options.descriptor; + if ( this.docFrag ) { + this.nodes = insertHtml( this.html, options.pNode.tagName, options.pNode.namespaceURI, this.docFrag ); + } + } else { + // otherwise we need to make a proper fragment + Fragment.init( this, options ); + } + }; + DomFragment.prototype = { + reassign: Fragment.reassign, + detach: function() { + var len, i; + if ( this.docFrag ) { + // if this was built from HTML, we just need to remove the nodes + if ( this.nodes ) { + len = this.nodes.length; + for ( i = 0; i < len; i += 1 ) { + this.docFrag.appendChild( this.nodes[ i ] ); + } + } else if ( this.items ) { + len = this.items.length; + for ( i = 0; i < len; i += 1 ) { + this.docFrag.appendChild( this.items[ i ].detach() ); + } + } + return this.docFrag; + } + }, + createItem: function( options ) { + if ( typeof options.descriptor === 'string' ) { + return new Text( options, this.docFrag ); + } + switch ( options.descriptor.t ) { + case types.INTERPOLATOR: + return new Interpolator( options, this.docFrag ); + case types.SECTION: + return new Section( options, this.docFrag ); + case types.TRIPLE: + return new Triple( options, this.docFrag ); + case types.ELEMENT: + if ( this.root.components[ options.descriptor.e ] ) { + return new Component( options, this.docFrag ); + } + return new Element( options, this.docFrag ); + case types.PARTIAL: + return new Partial( options, this.docFrag ); + case types.COMMENT: + return new Comment( options, this.docFrag ); + default: + throw new Error( 'Something very strange happened. Please file an issue at https://github.com/RactiveJS/Ractive/issues. Thanks!' ); + } + }, + teardown: function( destroy ) { + var node; + // if this was built from HTML, we just need to remove the nodes + if ( this.nodes && destroy ) { + while ( node = this.nodes.pop() ) { + node.parentNode.removeChild( node ); + } + } else if ( this.items ) { + while ( this.items.length ) { + this.items.pop().teardown( destroy ); + } + } + this.nodes = this.items = this.docFrag = null; + }, + firstNode: function() { + if ( this.items && this.items[ 0 ] ) { + return this.items[ 0 ].firstNode(); + } else if ( this.nodes ) { + return this.nodes[ 0 ] || null; + } + return null; + }, + findNextNode: function( item ) { + var index = item.index; + if ( this.items[ index + 1 ] ) { + return this.items[ index + 1 ].firstNode(); + } + // if this is the root fragment, and there are no more items, + // it means we're at the end... + if ( this.owner === this.root ) { + if ( !this.owner.component ) { + return null; + } + // ...unless this is a component + return this.owner.component.findNextNode(); + } + return this.owner.findNextNode( this ); + }, + toString: function() { + var html, i, len, item; + if ( this.html ) { + return this.html; + } + html = ''; + if ( !this.items ) { + return html; + } + len = this.items.length; + for ( i = 0; i < len; i += 1 ) { + item = this.items[ i ]; + html += item.toString(); + } + return html; + }, + find: function( selector ) { + var i, len, item, node, queryResult; + if ( this.nodes ) { + len = this.nodes.length; + for ( i = 0; i < len; i += 1 ) { + node = this.nodes[ i ]; + // we only care about elements + if ( node.nodeType !== 1 ) { + continue; + } + if ( matches( node, selector ) ) { + return node; + } + if ( queryResult = node.querySelector( selector ) ) { + return queryResult; + } + } + return null; + } + if ( this.items ) { + len = this.items.length; + for ( i = 0; i < len; i += 1 ) { + item = this.items[ i ]; + if ( item.find && ( queryResult = item.find( selector ) ) ) { + return queryResult; + } + } + return null; + } + }, + findAll: function( selector, query ) { + var i, len, item, node, queryAllResult, numNodes, j; + if ( this.nodes ) { + len = this.nodes.length; + for ( i = 0; i < len; i += 1 ) { + node = this.nodes[ i ]; + // we only care about elements + if ( node.nodeType !== 1 ) { + continue; + } + if ( matches( node, selector ) ) { + query.push( node ); + } + if ( queryAllResult = node.querySelectorAll( selector ) ) { + numNodes = queryAllResult.length; + for ( j = 0; j < numNodes; j += 1 ) { + query.push( queryAllResult[ j ] ); + } + } + } + } else if ( this.items ) { + len = this.items.length; + for ( i = 0; i < len; i += 1 ) { + item = this.items[ i ]; + if ( item.findAll ) { + item.findAll( selector, query ); + } + } + } + return query; + }, + findComponent: function( selector ) { + var len, i, item, queryResult; + if ( this.items ) { + len = this.items.length; + for ( i = 0; i < len; i += 1 ) { + item = this.items[ i ]; + if ( item.findComponent && ( queryResult = item.findComponent( selector ) ) ) { + return queryResult; + } + } + return null; + } + }, + findAllComponents: function( selector, query ) { + var i, len, item; + if ( this.items ) { + len = this.items.length; + for ( i = 0; i < len; i += 1 ) { + item = this.items[ i ]; + if ( item.findAllComponents ) { + item.findAllComponents( selector, query ); + } + } + } + return query; + } + }; + circular.DomFragment = DomFragment; + return DomFragment; + }( config_types, utils_matches, render_shared_Fragment__Fragment, render_DomFragment_shared_insertHtml, render_DomFragment_Text, render_DomFragment_Interpolator, render_DomFragment_Section__Section, render_DomFragment_Triple, render_DomFragment_Element__Element, render_DomFragment_Partial__Partial, render_DomFragment_Component__Component, render_DomFragment_Comment, circular ); + + var Ractive_prototype_render = function( runloop, css, DomFragment ) { + + return function Ractive_prototype_render( target, callback ) { + this._rendering = true; + runloop.start( this, callback ); + // This method is part of the API for one reason only - so that it can be + // overwritten by components that don't want to use the templating system + // (e.g. canvas-based components). It shouldn't be called outside of the + // initialisation sequence! + if ( !this._initing ) { + throw new Error( 'You cannot call ractive.render() directly!' ); + } + // Add CSS, if applicable + if ( this.constructor.css ) { + css.add( this.constructor ); + } + // Render our *root fragment* + this.fragment = new DomFragment( { + descriptor: this.template, + root: this, + owner: this, + // saves doing `if ( this.parent ) { /*...*/ }` later on + pNode: target + } ); + if ( target ) { + target.appendChild( this.fragment.docFrag ); + } + // If this is *isn't* a child of a component that's in the process of rendering, + // it should call any `init()` methods at this point + if ( !this._parent || !this._parent._rendering ) { + initChildren( this ); + } + delete this._rendering; + runloop.end(); + }; + + function initChildren( instance ) { + var child; + while ( child = instance._childInitQueue.pop() ) { + if ( child.instance.init ) { + child.instance.init( child.options ); + } + // now do the same for grandchildren, etc + initChildren( child.instance ); + } + } + }( global_runloop, global_css, render_DomFragment__DomFragment ); + + var Ractive_prototype_renderHTML = function( warn ) { + + return function() { + // TODO remove this method in a future version! + warn( 'renderHTML() has been deprecated and will be removed in a future version. Please use toHTML() instead' ); + return this.toHTML(); + }; + }( utils_warn ); + + var Ractive_prototype_reset = function( Promise, runloop, clearCache, notifyDependants ) { + + return function( data, callback ) { + var promise, fulfilPromise, wrapper; + if ( typeof data === 'function' ) { + callback = data; + data = {}; + } else { + data = data || {}; + } + if ( typeof data !== 'object' ) { + throw new Error( 'The reset method takes either no arguments, or an object containing new data' ); + } + promise = new Promise( function( fulfil ) { + fulfilPromise = fulfil; + } ); + if ( callback ) { + promise.then( callback ); + } + runloop.start( this, fulfilPromise ); + // If the root object is wrapped, try and use the wrapper's reset value + if ( ( wrapper = this._wrapped[ '' ] ) && wrapper.reset ) { + if ( wrapper.reset( data ) === false ) { + // reset was rejected, we need to replace the object + this.data = data; + } + } else { + this.data = data; + } + clearCache( this, '' ); + notifyDependants( this, '' ); + runloop.end(); + this.fire( 'reset', data ); + return promise; + }; + }( utils_Promise, global_runloop, shared_clearCache, shared_notifyDependants ); + + var Ractive_prototype_set = function( runloop, isObject, normaliseKeypath, Promise, set ) { + + return function Ractive_prototype_set( keypath, value, callback ) { + var map, promise, fulfilPromise; + promise = new Promise( function( fulfil ) { + fulfilPromise = fulfil; + } ); + runloop.start( this, fulfilPromise ); + // Set multiple keypaths in one go + if ( isObject( keypath ) ) { + map = keypath; + callback = value; + for ( keypath in map ) { + if ( map.hasOwnProperty( keypath ) ) { + value = map[ keypath ]; + keypath = normaliseKeypath( keypath ); + set( this, keypath, value ); + } + } + } else { + keypath = normaliseKeypath( keypath ); + set( this, keypath, value ); + } + runloop.end(); + if ( callback ) { + promise.then( callback.bind( this ) ); + } + return promise; + }; + }( global_runloop, utils_isObject, utils_normaliseKeypath, utils_Promise, shared_set ); + + var Ractive_prototype_subtract = function( add ) { + + return function( keypath, d ) { + return add( this, keypath, d === undefined ? -1 : -d ); + }; + }( Ractive_prototype_shared_add ); + + // Teardown. This goes through the root fragment and all its children, removing observers + // and generally cleaning up after itself + var Ractive_prototype_teardown = function( types, css, runloop, Promise, clearCache ) { + + return function( callback ) { + var keypath, promise, fulfilPromise, shouldDestroy, originalCallback, fragment, nearestDetachingElement, unresolvedImplicitDependency; + this.fire( 'teardown' ); + // If this is a component, and the component isn't marked for destruction, + // don't detach nodes from the DOM unnecessarily + shouldDestroy = !this.component || this.component.shouldDestroy; + if ( this.constructor.css ) { + // We need to find the nearest detaching element. When it gets removed + // from the DOM, it's safe to remove our CSS + if ( shouldDestroy ) { + originalCallback = callback; + callback = function() { + if ( originalCallback ) { + originalCallback.call( this ); + } + css.remove( this.constructor ); + }; + } else { + fragment = this.component.parentFragment; + do { + if ( fragment.owner.type !== types.ELEMENT ) { + continue; + } + if ( fragment.owner.willDetach ) { + nearestDetachingElement = fragment.owner; + } + } while ( !nearestDetachingElement && ( fragment = fragment.parent ) ); + if ( !nearestDetachingElement ) { + throw new Error( 'A component is being torn down but doesn\'t have a nearest detaching element... this shouldn\'t happen!' ); + } + nearestDetachingElement.cssDetachQueue.push( this.constructor ); + } + } + promise = new Promise( function( fulfil ) { + fulfilPromise = fulfil; + } ); + runloop.start( this, fulfilPromise ); + this.fragment.teardown( shouldDestroy ); + // Cancel any animations in progress + while ( this._animations[ 0 ] ) { + this._animations[ 0 ].stop(); + } + // Clear cache - this has the side-effect of unregistering keypaths from modified arrays. + for ( keypath in this._cache ) { + clearCache( this, keypath ); + } + // Teardown any failed lookups - we don't need them to resolve any more + while ( unresolvedImplicitDependency = this._unresolvedImplicitDependencies.pop() ) { + unresolvedImplicitDependency.teardown(); + } + runloop.end(); + if ( callback ) { + promise.then( callback.bind( this ) ); + } + return promise; + }; + }( config_types, global_css, global_runloop, utils_Promise, shared_clearCache ); + + var Ractive_prototype_toHTML = function() { + return this.fragment.toString(); + }; + + var Ractive_prototype_toggle = function( keypath, callback ) { + var value; + if ( typeof keypath !== 'string' ) { + if ( this.debug ) { + throw new Error( 'Bad arguments' ); + } + return; + } + value = this.get( keypath ); + return this.set( keypath, !value, callback ); + }; + + var Ractive_prototype_update = function( runloop, Promise, clearCache, notifyDependants ) { + + return function( keypath, callback ) { + var promise, fulfilPromise; + if ( typeof keypath === 'function' ) { + callback = keypath; + keypath = ''; + } else { + keypath = keypath || ''; + } + promise = new Promise( function( fulfil ) { + fulfilPromise = fulfil; + } ); + runloop.start( this, fulfilPromise ); + clearCache( this, keypath ); + notifyDependants( this, keypath ); + runloop.end(); + this.fire( 'update', keypath ); + if ( callback ) { + promise.then( callback.bind( this ) ); + } + return promise; + }; + }( global_runloop, utils_Promise, shared_clearCache, shared_notifyDependants ); + + var Ractive_prototype_updateModel = function( getValueFromCheckboxes, arrayContentsMatch, isEqual ) { + + return function Ractive_prototype_updateModel( keypath, cascade ) { + var values, deferredCheckboxes, i; + if ( typeof keypath !== 'string' ) { + keypath = ''; + cascade = true; + } + consolidateChangedValues( this, keypath, values = {}, deferredCheckboxes = [], cascade ); + if ( i = deferredCheckboxes.length ) { + while ( i-- ) { + keypath = deferredCheckboxes[ i ]; + values[ keypath ] = getValueFromCheckboxes( this, keypath ); + } + } + this.set( values ); + }; + + function consolidateChangedValues( ractive, keypath, values, deferredCheckboxes, cascade ) { + var bindings, childDeps, i, binding, oldValue, newValue; + bindings = ractive._twowayBindings[ keypath ]; + if ( bindings ) { + i = bindings.length; + while ( i-- ) { + binding = bindings[ i ]; + // special case - radio name bindings + if ( binding.radioName && !binding.node.checked ) { + continue; + } + // special case - checkbox name bindings + if ( binding.checkboxName ) { + if ( binding.changed() && deferredCheckboxes[ keypath ] !== true ) { + // we will need to see which checkboxes with the same name are checked, + // but we only want to do so once + deferredCheckboxes[ keypath ] = true; + // for quick lookup without indexOf + deferredCheckboxes.push( keypath ); + } + continue; + } + oldValue = binding.attr.value; + newValue = binding.value(); + if ( arrayContentsMatch( oldValue, newValue ) ) { + continue; + } + if ( !isEqual( oldValue, newValue ) ) { + values[ keypath ] = newValue; + } + } + } + if ( !cascade ) { + return; + } + // cascade + childDeps = ractive._depsMap[ keypath ]; + if ( childDeps ) { + i = childDeps.length; + while ( i-- ) { + consolidateChangedValues( ractive, childDeps[ i ], values, deferredCheckboxes, cascade ); + } + } + } + }( shared_getValueFromCheckboxes, utils_arrayContentsMatch, utils_isEqual ); + + var Ractive_prototype__prototype = function( add, animate, detach, find, findAll, findAllComponents, findComponent, fire, get, insert, merge, observe, off, on, render, renderHTML, reset, set, subtract, teardown, toHTML, toggle, update, updateModel ) { + + return { + add: add, + animate: animate, + detach: detach, + find: find, + findAll: findAll, + findAllComponents: findAllComponents, + findComponent: findComponent, + fire: fire, + get: get, + insert: insert, + merge: merge, + observe: observe, + off: off, + on: on, + render: render, + renderHTML: renderHTML, + reset: reset, + set: set, + subtract: subtract, + teardown: teardown, + toHTML: toHTML, + toggle: toggle, + update: update, + updateModel: updateModel + }; + }( Ractive_prototype_add, Ractive_prototype_animate__animate, Ractive_prototype_detach, Ractive_prototype_find, Ractive_prototype_findAll, Ractive_prototype_findAllComponents, Ractive_prototype_findComponent, Ractive_prototype_fire, Ractive_prototype_get, Ractive_prototype_insert, Ractive_prototype_merge__merge, Ractive_prototype_observe__observe, Ractive_prototype_off, Ractive_prototype_on, Ractive_prototype_render, Ractive_prototype_renderHTML, Ractive_prototype_reset, Ractive_prototype_set, Ractive_prototype_subtract, Ractive_prototype_teardown, Ractive_prototype_toHTML, Ractive_prototype_toggle, Ractive_prototype_update, Ractive_prototype_updateModel ); + + var registries_components = {}; + + // These are a subset of the easing equations found at + // https://raw.github.com/danro/easing-js - license info + // follows: + // -------------------------------------------------- + // easing.js v0.5.4 + // Generic set of easing functions with AMD support + // https://github.com/danro/easing-js + // This code may be freely distributed under the MIT license + // http://danro.mit-license.org/ + // -------------------------------------------------- + // All functions adapted from Thomas Fuchs & Jeremy Kahn + // Easing Equations (c) 2003 Robert Penner, BSD license + // https://raw.github.com/danro/easing-js/master/LICENSE + // -------------------------------------------------- + // In that library, the functions named easeIn, easeOut, and + // easeInOut below are named easeInCubic, easeOutCubic, and + // (you guessed it) easeInOutCubic. + // + // You can add additional easing functions to this list, and they + // will be globally available. + var registries_easing = { + linear: function( pos ) { + return pos; + }, + easeIn: function( pos ) { + return Math.pow( pos, 3 ); + }, + easeOut: function( pos ) { + return Math.pow( pos - 1, 3 ) + 1; + }, + easeInOut: function( pos ) { + if ( ( pos /= 0.5 ) < 1 ) { + return 0.5 * Math.pow( pos, 3 ); + } + return 0.5 * ( Math.pow( pos - 2, 3 ) + 2 ); + } + }; + + var utils_getGuid = function() { + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace( /[xy]/g, function( c ) { + var r, v; + r = Math.random() * 16 | 0; + v = c == 'x' ? r : r & 3 | 8; + return v.toString( 16 ); + } ); + }; + + var utils_extend = function( target ) { + var prop, source, sources = Array.prototype.slice.call( arguments, 1 ); + while ( source = sources.shift() ) { + for ( prop in source ) { + if ( source.hasOwnProperty( prop ) ) { + target[ prop ] = source[ prop ]; + } + } + } + return target; + }; + + var config_registries = [ + 'adaptors', + 'components', + 'decorators', + 'easing', + 'events', + 'interpolators', + 'partials', + 'transitions', + 'data' + ]; + + var extend_utils_transformCss = function() { + + var selectorsPattern = /(?:^|\})?\s*([^\{\}]+)\s*\{/g, + commentsPattern = /\/\*.*?\*\//g, + selectorUnitPattern = /((?:(?:\[[^\]+]\])|(?:[^\s\+\>\~:]))+)((?::[^\s\+\>\~]+)?\s*[\s\+\>\~]?)\s*/g; + return function transformCss( css, guid ) { + var transformed, addGuid; + addGuid = function( selector ) { + var selectorUnits, match, unit, dataAttr, base, prepended, appended, i, transformed = []; + selectorUnits = []; + while ( match = selectorUnitPattern.exec( selector ) ) { + selectorUnits.push( { + str: match[ 0 ], + base: match[ 1 ], + modifiers: match[ 2 ] + } ); + } + // For each simple selector within the selector, we need to create a version + // that a) combines with the guid, and b) is inside the guid + dataAttr = '[data-rvcguid="' + guid + '"]'; + base = selectorUnits.map( extractString ); + i = selectorUnits.length; + while ( i-- ) { + appended = base.slice(); + // Pseudo-selectors should go after the attribute selector + unit = selectorUnits[ i ]; + appended[ i ] = unit.base + dataAttr + unit.modifiers || ''; + prepended = base.slice(); + prepended[ i ] = dataAttr + ' ' + prepended[ i ]; + transformed.push( appended.join( ' ' ), prepended.join( ' ' ) ); + } + return transformed.join( ', ' ); + }; + transformed = css.replace( commentsPattern, '' ).replace( selectorsPattern, function( match, $1 ) { + var selectors, transformed; + selectors = $1.split( ',' ).map( trim ); + transformed = selectors.map( addGuid ).join( ', ' ) + ' '; + return match.replace( $1, transformed ); + } ); + return transformed; + }; + + function trim( str ) { + if ( str.trim ) { + return str.trim(); + } + return str.replace( /^\s+/, '' ).replace( /\s+$/, '' ); + } + + function extractString( unit ) { + return unit.str; + } + }(); + + var extend_inheritFromParent = function( registries, create, defineProperty, transformCss ) { + + // This is where we inherit class-level options, such as `modifyArrays` + // or `append` or `twoway`, and registries such as `partials` + return function( Child, Parent ) { + registries.forEach( function( property ) { + if ( Parent[ property ] ) { + Child[ property ] = create( Parent[ property ] ); + } + } ); + defineProperty( Child, 'defaults', { + value: create( Parent.defaults ) + } ); + // Special case - CSS + if ( Parent.css ) { + defineProperty( Child, 'css', { + value: Parent.defaults.noCssTransform ? Parent.css : transformCss( Parent.css, Child._guid ) + } ); + } + }; + }( config_registries, utils_create, utils_defineProperty, extend_utils_transformCss ); + + var extend_wrapMethod = function( method, superMethod ) { + if ( /_super/.test( method ) ) { + return function() { + var _super = this._super, + result; + this._super = superMethod; + result = method.apply( this, arguments ); + this._super = _super; + return result; + }; + } else { + return method; + } + }; + + var extend_utils_augment = function( target, source ) { + var key; + for ( key in source ) { + if ( source.hasOwnProperty( key ) ) { + target[ key ] = source[ key ]; + } + } + return target; + }; + + var extend_inheritFromChildProps = function( initOptions, registries, defineProperty, wrapMethod, augment, transformCss ) { + + var blacklisted = {}; + registries.concat( initOptions.keys ).forEach( function( property ) { + blacklisted[ property ] = true; + } ); + // This is where we augment the class-level options (inherited from + // Parent) with the values passed to Parent.extend() + return function( Child, childProps ) { + var key, member; + registries.forEach( function( property ) { + var value = childProps[ property ]; + if ( value ) { + if ( Child[ property ] ) { + augment( Child[ property ], value ); + } else { + Child[ property ] = value; + } + } + } ); + initOptions.keys.forEach( function( key ) { + var value = childProps[ key ]; + if ( value !== undefined ) { + // we may need to wrap a function (e.g. the `complete` option) + if ( typeof value === 'function' && typeof Child[ key ] === 'function' ) { + Child.defaults[ key ] = wrapMethod( value, Child[ key ] ); + } else { + Child.defaults[ key ] = childProps[ key ]; + } + } + } ); + for ( key in childProps ) { + if ( !blacklisted[ key ] && childProps.hasOwnProperty( key ) ) { + member = childProps[ key ]; + // if this is a method that overwrites a prototype method, we may need + // to wrap it + if ( typeof member === 'function' && typeof Child.prototype[ key ] === 'function' ) { + Child.prototype[ key ] = wrapMethod( member, Child.prototype[ key ] ); + } else { + Child.prototype[ key ] = member; + } + } + } + // Special case - CSS + if ( childProps.css ) { + defineProperty( Child, 'css', { + value: Child.defaults.noCssTransform ? childProps.css : transformCss( childProps.css, Child._guid ) + } ); + } + }; + }( config_initOptions, config_registries, utils_defineProperty, extend_wrapMethod, extend_utils_augment, extend_utils_transformCss ); + + var extend_extractInlinePartials = function( isObject, augment ) { + + return function( Child, childProps ) { + // does our template contain inline partials? + if ( isObject( Child.defaults.template ) ) { + if ( !Child.partials ) { + Child.partials = {}; + } + // get those inline partials + augment( Child.partials, Child.defaults.template.partials ); + // but we also need to ensure that any explicit partials override inline ones + if ( childProps.partials ) { + augment( Child.partials, childProps.partials ); + } + // move template to where it belongs + Child.defaults.template = Child.defaults.template.main; + } + }; + }( utils_isObject, extend_utils_augment ); + + var extend_conditionallyParseTemplate = function( errors, isClient, parse ) { + + return function( Child ) { + var templateEl; + if ( typeof Child.defaults.template === 'string' ) { + if ( !parse ) { + throw new Error( errors.missingParser ); + } + if ( Child.defaults.template.charAt( 0 ) === '#' && isClient ) { + templateEl = document.getElementById( Child.defaults.template.substring( 1 ) ); + if ( templateEl && templateEl.tagName === 'SCRIPT' ) { + Child.defaults.template = parse( templateEl.innerHTML, Child ); + } else { + throw new Error( 'Could not find template element (' + Child.defaults.template + ')' ); + } + } else { + Child.defaults.template = parse( Child.defaults.template, Child.defaults ); + } + } + }; + }( config_errors, config_isClient, parse__parse ); + + var extend_conditionallyParsePartials = function( errors, parse ) { + + return function( Child ) { + var key; + // Parse partials, if necessary + if ( Child.partials ) { + for ( key in Child.partials ) { + if ( Child.partials.hasOwnProperty( key ) && typeof Child.partials[ key ] === 'string' ) { + if ( !parse ) { + throw new Error( errors.missingParser ); + } + Child.partials[ key ] = parse( Child.partials[ key ], Child ); + } + } + } + }; + }( config_errors, parse__parse ); + + var Ractive_initialise_computations_getComputationSignature = function() { + + var pattern = /\$\{([^\}]+)\}/g; + return function( signature ) { + if ( typeof signature === 'function' ) { + return { + get: signature + }; + } + if ( typeof signature === 'string' ) { + return { + get: createFunctionFromString( signature ) + }; + } + if ( typeof signature === 'object' && typeof signature.get === 'string' ) { + signature = { + get: createFunctionFromString( signature.get ), + set: signature.set + }; + } + return signature; + }; + + function createFunctionFromString( signature ) { + var functionBody = 'var __ractive=this;return(' + signature.replace( pattern, function( match, keypath ) { + return '__ractive.get("' + keypath + '")'; + } ) + ')'; + return new Function( functionBody ); + } + }(); + + var Ractive_initialise_computations_Watcher = function( isEqual, registerDependant, unregisterDependant ) { + + var Watcher = function( computation, keypath ) { + this.root = computation.ractive; + this.keypath = keypath; + this.priority = 0; + this.computation = computation; + registerDependant( this ); + }; + Watcher.prototype = { + update: function() { + var value; + value = this.root.get( this.keypath ); + if ( !isEqual( value, this.value ) ) { + this.computation.bubble(); + } + }, + teardown: function() { + unregisterDependant( this ); + } + }; + return Watcher; + }( utils_isEqual, shared_registerDependant, shared_unregisterDependant ); + + var Ractive_initialise_computations_Computation = function( warn, runloop, set, Watcher ) { + + var Computation = function( ractive, key, signature ) { + this.ractive = ractive; + this.key = key; + this.getter = signature.get; + this.setter = signature.set; + this.watchers = []; + this.update(); + }; + Computation.prototype = { + set: function( value ) { + if ( this.setting ) { + this.value = value; + return; + } + if ( !this.setter ) { + throw new Error( 'Computed properties without setters are read-only in the current version' ); + } + this.setter.call( this.ractive, value ); + }, + update: function() { + var ractive, originalCaptured, result, errored; + ractive = this.ractive; + originalCaptured = ractive._captured; + if ( !originalCaptured ) { + ractive._captured = []; + } + try { + result = this.getter.call( ractive ); + } catch ( err ) { + if ( ractive.debug ) { + warn( 'Failed to compute "' + this.key + '": ' + err.message || err ); + } + errored = true; + } + diff( this, this.watchers, ractive._captured ); + // reset + ractive._captured = originalCaptured; + if ( !errored ) { + this.setting = true; + this.value = result; + set( ractive, this.key, result ); + this.setting = false; + } + this.deferred = false; + }, + bubble: function() { + if ( this.watchers.length <= 1 ) { + this.update(); + } else if ( !this.deferred ) { + runloop.addComputation( this ); + this.deferred = true; + } + } + }; + + function diff( computation, watchers, newDependencies ) { + var i, watcher, keypath; + // remove dependencies that are no longer used + i = watchers.length; + while ( i-- ) { + watcher = watchers[ i ]; + if ( !newDependencies[ watcher.keypath ] ) { + watchers.splice( i, 1 ); + watchers[ watcher.keypath ] = null; + watcher.teardown(); + } + } + // create references for any new dependencies + i = newDependencies.length; + while ( i-- ) { + keypath = newDependencies[ i ]; + if ( !watchers[ keypath ] ) { + watcher = new Watcher( computation, keypath ); + watchers.push( watchers[ keypath ] = watcher ); + } + } + } + return Computation; + }( utils_warn, global_runloop, shared_set, Ractive_initialise_computations_Watcher ); + + var Ractive_initialise_computations_createComputations = function( getComputationSignature, Computation ) { + + return function createComputations( ractive, computed ) { + var key, signature; + for ( key in computed ) { + signature = getComputationSignature( computed[ key ] ); + ractive._computations[ key ] = new Computation( ractive, key, signature ); + } + }; + }( Ractive_initialise_computations_getComputationSignature, Ractive_initialise_computations_Computation ); + + var Ractive_initialise = function( isClient, errors, initOptions, registries, warn, create, extend, fillGaps, defineProperties, getElement, isObject, isArray, getGuid, Promise, magicAdaptor, parse, createComputations ) { + + var flags = [ + 'adapt', + 'modifyArrays', + 'magic', + 'twoway', + 'lazy', + 'debug', + 'isolated' + ]; + return function initialiseRactiveInstance( ractive, options ) { + var defaults, template, templateEl, parsedTemplate, promise, fulfilPromise, computed; + if ( isArray( options.adaptors ) ) { + warn( 'The `adaptors` option, to indicate which adaptors should be used with a given Ractive instance, has been deprecated in favour of `adapt`. See [TODO] for more information' ); + options.adapt = options.adaptors; + delete options.adaptors; + } + // Options + // ------- + defaults = ractive.constructor.defaults; + initOptions.keys.forEach( function( key ) { + if ( options[ key ] === undefined ) { + options[ key ] = defaults[ key ]; + } + } ); + // options + flags.forEach( function( flag ) { + ractive[ flag ] = options[ flag ]; + } ); + // special cases + if ( typeof ractive.adapt === 'string' ) { + ractive.adapt = [ ractive.adapt ]; + } + if ( ractive.magic && !magicAdaptor ) { + throw new Error( 'Getters and setters (magic mode) are not supported in this browser' ); + } + // Initialisation + // -------------- + // We use Object.defineProperties (where possible) as these should be read-only + defineProperties( ractive, { + _initing: { + value: true, + writable: true + }, + // Generate a unique identifier, for places where you'd use a weak map if it + // existed + _guid: { + value: getGuid() + }, + // events + _subs: { + value: create( null ), + configurable: true + }, + // cache + _cache: { + value: {} + }, + // we need to be able to use hasOwnProperty, so can't inherit from null + _cacheMap: { + value: create( null ) + }, + // dependency graph + _deps: { + value: [] + }, + _depsMap: { + value: create( null ) + }, + _patternObservers: { + value: [] + }, + // Keep a list of used evaluators, so we don't duplicate them + _evaluators: { + value: create( null ) + }, + // Computed properties + _computations: { + value: create( null ) + }, + // two-way bindings + _twowayBindings: { + value: {} + }, + // animations (so we can stop any in progress at teardown) + _animations: { + value: [] + }, + // nodes registry + nodes: { + value: {} + }, + // property wrappers + _wrapped: { + value: create( null ) + }, + // live queries + _liveQueries: { + value: [] + }, + _liveComponentQueries: { + value: [] + }, + // components to init at the end of a mutation + _childInitQueue: { + value: [] + }, + // data changes + _changes: { + value: [] + }, + // failed lookups, when we try to access data from ancestor scopes + _unresolvedImplicitDependencies: { + value: [] + } + } ); + // If this is a component, store a reference to the parent + if ( options._parent && options._component ) { + defineProperties( ractive, { + _parent: { + value: options._parent + }, + component: { + value: options._component + } + } ); + // And store a reference to the instance on the component + options._component.instance = ractive; + } + if ( options.el ) { + ractive.el = getElement( options.el ); + if ( !ractive.el && ractive.debug ) { + throw new Error( 'Could not find container element' ); + } + } + // Create local registry objects, with the global registries as prototypes + if ( options.eventDefinitions ) { + // TODO remove support + warn( 'ractive.eventDefinitions has been deprecated in favour of ractive.events. Support will be removed in future versions' ); + options.events = options.eventDefinitions; + } + registries.forEach( function( registry ) { + if ( ractive.constructor[ registry ] ) { + ractive[ registry ] = extend( create( ractive.constructor[ registry ] ), options[ registry ] ); + } else if ( options[ registry ] ) { + ractive[ registry ] = options[ registry ]; + } + } ); + // Special case + if ( !ractive.data ) { + ractive.data = {}; + } + // Set up any computed values + computed = defaults.computed ? extend( create( defaults.computed ), options.computed ) : options.computed; + if ( computed ) { + createComputations( ractive, computed ); + } + // Parse template, if necessary + template = options.template; + if ( typeof template === 'string' ) { + if ( !parse ) { + throw new Error( errors.missingParser ); + } + if ( template.charAt( 0 ) === '#' && isClient ) { + // assume this is an ID of a + + +
+ «

NAME_HERE

+
+ +
+

loading individual Ractive.js source files... please wait

+
+ + + + + + + + + + diff --git a/sandbox/_sandbox.css b/sandbox/_sandbox.css new file mode 100644 index 0000000000..1334e97bd3 --- /dev/null +++ b/sandbox/_sandbox.css @@ -0,0 +1,87 @@ +body { + font-family: 'Helvetica Neue', Arial, sans-serif; + font-weight: 200; + color: #555; + line-height: 1.5; +} + +h1, h2, h3, h4, h5, h6 { + font-weight: 200; +} + +a { + color: #729d34; +} + +code { + background-color: #f9f9f9; + border: 1px solid #f4f4f4; + padding: 0.1em; + position: relative; + bottom: 0.1em; +} + +a:link, a:visited { + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +header { + padding: 1em; + border-bottom: 1px solid #eee; +} + +header a { + display: inline-block; + font-size: 2em; + margin: 0 0.5em 0 0; +} + +header h1 { + display: inline-block; + margin: 0; +} + +main { + display: block; + min-height: 400px; + padding: 1em; +} + +.loading { + color: #aaa; +} + +footer { + padding: 1em; + border-top: 1px solid #eee; + text-align: center; +} + +footer a { + position: relative; + margin: 0 1.5em 0 0; +} + +footer a:after { + position: absolute; + right: -1em; + content: '\2022'; + color: #aaa; +} + +footer a:last-child { + margin: 0; +} + +footer a:last-child:after { + content: ''; +} + +/* IE8... */ +header, main, footer { + display: block; +} \ No newline at end of file diff --git a/sandbox/require.js b/sandbox/require.js new file mode 100644 index 0000000000..56bfc19844 --- /dev/null +++ b/sandbox/require.js @@ -0,0 +1,2054 @@ +/** vim: et:ts=4:sw=4:sts=4 + * @license RequireJS 2.1.9 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved. + * Available via the MIT or new BSD license. + * see: http://github.com/jrburke/requirejs for details + */ +//Not using strict: uneven strict support in browsers, #392, and causes +//problems with requirejs.exec()/transpiler plugins that may not be strict. +/*jslint regexp: true, nomen: true, sloppy: true */ +/*global window, navigator, document, importScripts, setTimeout, opera */ + +var requirejs, require, define; +(function (global) { + var req, s, head, baseElement, dataMain, src, + interactiveScript, currentlyAddingScript, mainScript, subPath, + version = '2.1.9', + commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg, + cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g, + jsSuffixRegExp = /\.js$/, + currDirRegExp = /^\.\//, + op = Object.prototype, + ostring = op.toString, + hasOwn = op.hasOwnProperty, + ap = Array.prototype, + apsp = ap.splice, + isBrowser = !!(typeof window !== 'undefined' && typeof navigator !== 'undefined' && window.document), + isWebWorker = !isBrowser && typeof importScripts !== 'undefined', + //PS3 indicates loaded and complete, but need to wait for complete + //specifically. Sequence is 'loading', 'loaded', execution, + // then 'complete'. The UA check is unfortunate, but not sure how + //to feature test w/o causing perf issues. + readyRegExp = isBrowser && navigator.platform === 'PLAYSTATION 3' ? + /^complete$/ : /^(complete|loaded)$/, + defContextName = '_', + //Oh the tragedy, detecting opera. See the usage of isOpera for reason. + isOpera = typeof opera !== 'undefined' && opera.toString() === '[object Opera]', + contexts = {}, + cfg = {}, + globalDefQueue = [], + useInteractive = false; + + function isFunction(it) { + return ostring.call(it) === '[object Function]'; + } + + function isArray(it) { + return ostring.call(it) === '[object Array]'; + } + + /** + * Helper function for iterating over an array. If the func returns + * a true value, it will break out of the loop. + */ + function each(ary, func) { + if (ary) { + var i; + for (i = 0; i < ary.length; i += 1) { + if (ary[i] && func(ary[i], i, ary)) { + break; + } + } + } + } + + /** + * Helper function for iterating over an array backwards. If the func + * returns a true value, it will break out of the loop. + */ + function eachReverse(ary, func) { + if (ary) { + var i; + for (i = ary.length - 1; i > -1; i -= 1) { + if (ary[i] && func(ary[i], i, ary)) { + break; + } + } + } + } + + function hasProp(obj, prop) { + return hasOwn.call(obj, prop); + } + + function getOwn(obj, prop) { + return hasProp(obj, prop) && obj[prop]; + } + + /** + * Cycles over properties in an object and calls a function for each + * property value. If the function returns a truthy value, then the + * iteration is stopped. + */ + function eachProp(obj, func) { + var prop; + for (prop in obj) { + if (hasProp(obj, prop)) { + if (func(obj[prop], prop)) { + break; + } + } + } + } + + /** + * Simple function to mix in properties from source into target, + * but only if target does not already have a property of the same name. + */ + function mixin(target, source, force, deepStringMixin) { + if (source) { + eachProp(source, function (value, prop) { + if (force || !hasProp(target, prop)) { + if (deepStringMixin && typeof value !== 'string') { + if (!target[prop]) { + target[prop] = {}; + } + mixin(target[prop], value, force, deepStringMixin); + } else { + target[prop] = value; + } + } + }); + } + return target; + } + + //Similar to Function.prototype.bind, but the 'this' object is specified + //first, since it is easier to read/figure out what 'this' will be. + function bind(obj, fn) { + return function () { + return fn.apply(obj, arguments); + }; + } + + function scripts() { + return document.getElementsByTagName('script'); + } + + function defaultOnError(err) { + throw err; + } + + //Allow getting a global that expressed in + //dot notation, like 'a.b.c'. + function getGlobal(value) { + if (!value) { + return value; + } + var g = global; + each(value.split('.'), function (part) { + g = g[part]; + }); + return g; + } + + /** + * Constructs an error with a pointer to an URL with more information. + * @param {String} id the error ID that maps to an ID on a web page. + * @param {String} message human readable error. + * @param {Error} [err] the original error, if there is one. + * + * @returns {Error} + */ + function makeError(id, msg, err, requireModules) { + var e = new Error(msg + '\nhttp://requirejs.org/docs/errors.html#' + id); + e.requireType = id; + e.requireModules = requireModules; + if (err) { + e.originalError = err; + } + return e; + } + + if (typeof define !== 'undefined') { + //If a define is already in play via another AMD loader, + //do not overwrite. + return; + } + + if (typeof requirejs !== 'undefined') { + if (isFunction(requirejs)) { + //Do not overwrite and existing requirejs instance. + return; + } + cfg = requirejs; + requirejs = undefined; + } + + //Allow for a require config object + if (typeof require !== 'undefined' && !isFunction(require)) { + //assume it is a config object. + cfg = require; + require = undefined; + } + + function newContext(contextName) { + var inCheckLoaded, Module, context, handlers, + checkLoadedTimeoutId, + config = { + //Defaults. Do not set a default for map + //config to speed up normalize(), which + //will run faster if there is no default. + waitSeconds: 7, + baseUrl: './', + paths: {}, + pkgs: {}, + shim: {}, + config: {} + }, + registry = {}, + //registry of just enabled modules, to speed + //cycle breaking code when lots of modules + //are registered, but not activated. + enabledRegistry = {}, + undefEvents = {}, + defQueue = [], + defined = {}, + urlFetched = {}, + requireCounter = 1, + unnormalizedCounter = 1; + + /** + * Trims the . and .. from an array of path segments. + * It will keep a leading path segment if a .. will become + * the first path segment, to help with module name lookups, + * which act like paths, but can be remapped. But the end result, + * all paths that use this function should look normalized. + * NOTE: this method MODIFIES the input array. + * @param {Array} ary the array of path segments. + */ + function trimDots(ary) { + var i, part; + for (i = 0; ary[i]; i += 1) { + part = ary[i]; + if (part === '.') { + ary.splice(i, 1); + i -= 1; + } else if (part === '..') { + if (i === 1 && (ary[2] === '..' || ary[0] === '..')) { + //End of the line. Keep at least one non-dot + //path segment at the front so it can be mapped + //correctly to disk. Otherwise, there is likely + //no path mapping for a path starting with '..'. + //This can still fail, but catches the most reasonable + //uses of .. + break; + } else if (i > 0) { + ary.splice(i - 1, 2); + i -= 2; + } + } + } + } + + /** + * Given a relative module name, like ./something, normalize it to + * a real name that can be mapped to a path. + * @param {String} name the relative name + * @param {String} baseName a real name that the name arg is relative + * to. + * @param {Boolean} applyMap apply the map config to the value. Should + * only be done if this normalization is for a dependency ID. + * @returns {String} normalized name + */ + function normalize(name, baseName, applyMap) { + var pkgName, pkgConfig, mapValue, nameParts, i, j, nameSegment, + foundMap, foundI, foundStarMap, starI, + baseParts = baseName && baseName.split('/'), + normalizedBaseParts = baseParts, + map = config.map, + starMap = map && map['*']; + + //Adjust any relative paths. + if (name && name.charAt(0) === '.') { + //If have a base name, try to normalize against it, + //otherwise, assume it is a top-level require that will + //be relative to baseUrl in the end. + if (baseName) { + if (getOwn(config.pkgs, baseName)) { + //If the baseName is a package name, then just treat it as one + //name to concat the name with. + normalizedBaseParts = baseParts = [baseName]; + } else { + //Convert baseName to array, and lop off the last part, + //so that . matches that 'directory' and not name of the baseName's + //module. For instance, baseName of 'one/two/three', maps to + //'one/two/three.js', but we want the directory, 'one/two' for + //this normalization. + normalizedBaseParts = baseParts.slice(0, baseParts.length - 1); + } + + name = normalizedBaseParts.concat(name.split('/')); + trimDots(name); + + //Some use of packages may use a . path to reference the + //'main' module name, so normalize for that. + pkgConfig = getOwn(config.pkgs, (pkgName = name[0])); + name = name.join('/'); + if (pkgConfig && name === pkgName + '/' + pkgConfig.main) { + name = pkgName; + } + } else if (name.indexOf('./') === 0) { + // No baseName, so this is ID is resolved relative + // to baseUrl, pull off the leading dot. + name = name.substring(2); + } + } + + //Apply map config if available. + if (applyMap && map && (baseParts || starMap)) { + nameParts = name.split('/'); + + for (i = nameParts.length; i > 0; i -= 1) { + nameSegment = nameParts.slice(0, i).join('/'); + + if (baseParts) { + //Find the longest baseName segment match in the config. + //So, do joins on the biggest to smallest lengths of baseParts. + for (j = baseParts.length; j > 0; j -= 1) { + mapValue = getOwn(map, baseParts.slice(0, j).join('/')); + + //baseName segment has config, find if it has one for + //this name. + if (mapValue) { + mapValue = getOwn(mapValue, nameSegment); + if (mapValue) { + //Match, update name to the new value. + foundMap = mapValue; + foundI = i; + break; + } + } + } + } + + if (foundMap) { + break; + } + + //Check for a star map match, but just hold on to it, + //if there is a shorter segment match later in a matching + //config, then favor over this star map. + if (!foundStarMap && starMap && getOwn(starMap, nameSegment)) { + foundStarMap = getOwn(starMap, nameSegment); + starI = i; + } + } + + if (!foundMap && foundStarMap) { + foundMap = foundStarMap; + foundI = starI; + } + + if (foundMap) { + nameParts.splice(0, foundI, foundMap); + name = nameParts.join('/'); + } + } + + return name; + } + + function removeScript(name) { + if (isBrowser) { + each(scripts(), function (scriptNode) { + if (scriptNode.getAttribute('data-requiremodule') === name && + scriptNode.getAttribute('data-requirecontext') === context.contextName) { + scriptNode.parentNode.removeChild(scriptNode); + return true; + } + }); + } + } + + function hasPathFallback(id) { + var pathConfig = getOwn(config.paths, id); + if (pathConfig && isArray(pathConfig) && pathConfig.length > 1) { + //Pop off the first array value, since it failed, and + //retry + pathConfig.shift(); + context.require.undef(id); + context.require([id]); + return true; + } + } + + //Turns a plugin!resource to [plugin, resource] + //with the plugin being undefined if the name + //did not have a plugin prefix. + function splitPrefix(name) { + var prefix, + index = name ? name.indexOf('!') : -1; + if (index > -1) { + prefix = name.substring(0, index); + name = name.substring(index + 1, name.length); + } + return [prefix, name]; + } + + /** + * Creates a module mapping that includes plugin prefix, module + * name, and path. If parentModuleMap is provided it will + * also normalize the name via require.normalize() + * + * @param {String} name the module name + * @param {String} [parentModuleMap] parent module map + * for the module name, used to resolve relative names. + * @param {Boolean} isNormalized: is the ID already normalized. + * This is true if this call is done for a define() module ID. + * @param {Boolean} applyMap: apply the map config to the ID. + * Should only be true if this map is for a dependency. + * + * @returns {Object} + */ + function makeModuleMap(name, parentModuleMap, isNormalized, applyMap) { + var url, pluginModule, suffix, nameParts, + prefix = null, + parentName = parentModuleMap ? parentModuleMap.name : null, + originalName = name, + isDefine = true, + normalizedName = ''; + + //If no name, then it means it is a require call, generate an + //internal name. + if (!name) { + isDefine = false; + name = '_@r' + (requireCounter += 1); + } + + nameParts = splitPrefix(name); + prefix = nameParts[0]; + name = nameParts[1]; + + if (prefix) { + prefix = normalize(prefix, parentName, applyMap); + pluginModule = getOwn(defined, prefix); + } + + //Account for relative paths if there is a base name. + if (name) { + if (prefix) { + if (pluginModule && pluginModule.normalize) { + //Plugin is loaded, use its normalize method. + normalizedName = pluginModule.normalize(name, function (name) { + return normalize(name, parentName, applyMap); + }); + } else { + normalizedName = normalize(name, parentName, applyMap); + } + } else { + //A regular module. + normalizedName = normalize(name, parentName, applyMap); + + //Normalized name may be a plugin ID due to map config + //application in normalize. The map config values must + //already be normalized, so do not need to redo that part. + nameParts = splitPrefix(normalizedName); + prefix = nameParts[0]; + normalizedName = nameParts[1]; + isNormalized = true; + + url = context.nameToUrl(normalizedName); + } + } + + //If the id is a plugin id that cannot be determined if it needs + //normalization, stamp it with a unique ID so two matching relative + //ids that may conflict can be separate. + suffix = prefix && !pluginModule && !isNormalized ? + '_unnormalized' + (unnormalizedCounter += 1) : + ''; + + return { + prefix: prefix, + name: normalizedName, + parentMap: parentModuleMap, + unnormalized: !!suffix, + url: url, + originalName: originalName, + isDefine: isDefine, + id: (prefix ? + prefix + '!' + normalizedName : + normalizedName) + suffix + }; + } + + function getModule(depMap) { + var id = depMap.id, + mod = getOwn(registry, id); + + if (!mod) { + mod = registry[id] = new context.Module(depMap); + } + + return mod; + } + + function on(depMap, name, fn) { + var id = depMap.id, + mod = getOwn(registry, id); + + if (hasProp(defined, id) && + (!mod || mod.defineEmitComplete)) { + if (name === 'defined') { + fn(defined[id]); + } + } else { + mod = getModule(depMap); + if (mod.error && name === 'error') { + fn(mod.error); + } else { + mod.on(name, fn); + } + } + } + + function onError(err, errback) { + var ids = err.requireModules, + notified = false; + + if (errback) { + errback(err); + } else { + each(ids, function (id) { + var mod = getOwn(registry, id); + if (mod) { + //Set error on module, so it skips timeout checks. + mod.error = err; + if (mod.events.error) { + notified = true; + mod.emit('error', err); + } + } + }); + + if (!notified) { + req.onError(err); + } + } + } + + /** + * Internal method to transfer globalQueue items to this context's + * defQueue. + */ + function takeGlobalQueue() { + //Push all the globalDefQueue items into the context's defQueue + if (globalDefQueue.length) { + //Array splice in the values since the context code has a + //local var ref to defQueue, so cannot just reassign the one + //on context. + apsp.apply(defQueue, + [defQueue.length - 1, 0].concat(globalDefQueue)); + globalDefQueue = []; + } + } + + handlers = { + 'require': function (mod) { + if (mod.require) { + return mod.require; + } else { + return (mod.require = context.makeRequire(mod.map)); + } + }, + 'exports': function (mod) { + mod.usingExports = true; + if (mod.map.isDefine) { + if (mod.exports) { + return mod.exports; + } else { + return (mod.exports = defined[mod.map.id] = {}); + } + } + }, + 'module': function (mod) { + if (mod.module) { + return mod.module; + } else { + return (mod.module = { + id: mod.map.id, + uri: mod.map.url, + config: function () { + var c, + pkg = getOwn(config.pkgs, mod.map.id); + // For packages, only support config targeted + // at the main module. + c = pkg ? getOwn(config.config, mod.map.id + '/' + pkg.main) : + getOwn(config.config, mod.map.id); + return c || {}; + }, + exports: defined[mod.map.id] + }); + } + } + }; + + function cleanRegistry(id) { + //Clean up machinery used for waiting modules. + delete registry[id]; + delete enabledRegistry[id]; + } + + function breakCycle(mod, traced, processed) { + var id = mod.map.id; + + if (mod.error) { + mod.emit('error', mod.error); + } else { + traced[id] = true; + each(mod.depMaps, function (depMap, i) { + var depId = depMap.id, + dep = getOwn(registry, depId); + + //Only force things that have not completed + //being defined, so still in the registry, + //and only if it has not been matched up + //in the module already. + if (dep && !mod.depMatched[i] && !processed[depId]) { + if (getOwn(traced, depId)) { + mod.defineDep(i, defined[depId]); + mod.check(); //pass false? + } else { + breakCycle(dep, traced, processed); + } + } + }); + processed[id] = true; + } + } + + function checkLoaded() { + var map, modId, err, usingPathFallback, + waitInterval = config.waitSeconds * 1000, + //It is possible to disable the wait interval by using waitSeconds of 0. + expired = waitInterval && (context.startTime + waitInterval) < new Date().getTime(), + noLoads = [], + reqCalls = [], + stillLoading = false, + needCycleCheck = true; + + //Do not bother if this call was a result of a cycle break. + if (inCheckLoaded) { + return; + } + + inCheckLoaded = true; + + //Figure out the state of all the modules. + eachProp(enabledRegistry, function (mod) { + map = mod.map; + modId = map.id; + + //Skip things that are not enabled or in error state. + if (!mod.enabled) { + return; + } + + if (!map.isDefine) { + reqCalls.push(mod); + } + + if (!mod.error) { + //If the module should be executed, and it has not + //been inited and time is up, remember it. + if (!mod.inited && expired) { + if (hasPathFallback(modId)) { + usingPathFallback = true; + stillLoading = true; + } else { + noLoads.push(modId); + removeScript(modId); + } + } else if (!mod.inited && mod.fetched && map.isDefine) { + stillLoading = true; + if (!map.prefix) { + //No reason to keep looking for unfinished + //loading. If the only stillLoading is a + //plugin resource though, keep going, + //because it may be that a plugin resource + //is waiting on a non-plugin cycle. + return (needCycleCheck = false); + } + } + } + }); + + if (expired && noLoads.length) { + //If wait time expired, throw error of unloaded modules. + err = makeError('timeout', 'Load timeout for modules: ' + noLoads, null, noLoads); + err.contextName = context.contextName; + return onError(err); + } + + //Not expired, check for a cycle. + if (needCycleCheck) { + each(reqCalls, function (mod) { + breakCycle(mod, {}, {}); + }); + } + + //If still waiting on loads, and the waiting load is something + //other than a plugin resource, or there are still outstanding + //scripts, then just try back later. + if ((!expired || usingPathFallback) && stillLoading) { + //Something is still waiting to load. Wait for it, but only + //if a timeout is not already in effect. + if ((isBrowser || isWebWorker) && !checkLoadedTimeoutId) { + checkLoadedTimeoutId = setTimeout(function () { + checkLoadedTimeoutId = 0; + checkLoaded(); + }, 50); + } + } + + inCheckLoaded = false; + } + + Module = function (map) { + this.events = getOwn(undefEvents, map.id) || {}; + this.map = map; + this.shim = getOwn(config.shim, map.id); + this.depExports = []; + this.depMaps = []; + this.depMatched = []; + this.pluginMaps = {}; + this.depCount = 0; + + /* this.exports this.factory + this.depMaps = [], + this.enabled, this.fetched + */ + }; + + Module.prototype = { + init: function (depMaps, factory, errback, options) { + options = options || {}; + + //Do not do more inits if already done. Can happen if there + //are multiple define calls for the same module. That is not + //a normal, common case, but it is also not unexpected. + if (this.inited) { + return; + } + + this.factory = factory; + + if (errback) { + //Register for errors on this module. + this.on('error', errback); + } else if (this.events.error) { + //If no errback already, but there are error listeners + //on this module, set up an errback to pass to the deps. + errback = bind(this, function (err) { + this.emit('error', err); + }); + } + + //Do a copy of the dependency array, so that + //source inputs are not modified. For example + //"shim" deps are passed in here directly, and + //doing a direct modification of the depMaps array + //would affect that config. + this.depMaps = depMaps && depMaps.slice(0); + + this.errback = errback; + + //Indicate this module has be initialized + this.inited = true; + + this.ignore = options.ignore; + + //Could have option to init this module in enabled mode, + //or could have been previously marked as enabled. However, + //the dependencies are not known until init is called. So + //if enabled previously, now trigger dependencies as enabled. + if (options.enabled || this.enabled) { + //Enable this module and dependencies. + //Will call this.check() + this.enable(); + } else { + this.check(); + } + }, + + defineDep: function (i, depExports) { + //Because of cycles, defined callback for a given + //export can be called more than once. + if (!this.depMatched[i]) { + this.depMatched[i] = true; + this.depCount -= 1; + this.depExports[i] = depExports; + } + }, + + fetch: function () { + if (this.fetched) { + return; + } + this.fetched = true; + + context.startTime = (new Date()).getTime(); + + var map = this.map; + + //If the manager is for a plugin managed resource, + //ask the plugin to load it now. + if (this.shim) { + context.makeRequire(this.map, { + enableBuildCallback: true + })(this.shim.deps || [], bind(this, function () { + return map.prefix ? this.callPlugin() : this.load(); + })); + } else { + //Regular dependency. + return map.prefix ? this.callPlugin() : this.load(); + } + }, + + load: function () { + var url = this.map.url; + + //Regular dependency. + if (!urlFetched[url]) { + urlFetched[url] = true; + context.load(this.map.id, url); + } + }, + + /** + * Checks if the module is ready to define itself, and if so, + * define it. + */ + check: function () { + if (!this.enabled || this.enabling) { + return; + } + + var err, cjsModule, + id = this.map.id, + depExports = this.depExports, + exports = this.exports, + factory = this.factory; + + if (!this.inited) { + this.fetch(); + } else if (this.error) { + this.emit('error', this.error); + } else if (!this.defining) { + //The factory could trigger another require call + //that would result in checking this module to + //define itself again. If already in the process + //of doing that, skip this work. + this.defining = true; + + if (this.depCount < 1 && !this.defined) { + if (isFunction(factory)) { + //If there is an error listener, favor passing + //to that instead of throwing an error. However, + //only do it for define()'d modules. require + //errbacks should not be called for failures in + //their callbacks (#699). However if a global + //onError is set, use that. + if ((this.events.error && this.map.isDefine) || + req.onError !== defaultOnError) { + try { + exports = context.execCb(id, factory, depExports, exports); + } catch (e) { + err = e; + } + } else { + exports = context.execCb(id, factory, depExports, exports); + } + + if (this.map.isDefine) { + //If setting exports via 'module' is in play, + //favor that over return value and exports. After that, + //favor a non-undefined return value over exports use. + cjsModule = this.module; + if (cjsModule && + cjsModule.exports !== undefined && + //Make sure it is not already the exports value + cjsModule.exports !== this.exports) { + exports = cjsModule.exports; + } else if (exports === undefined && this.usingExports) { + //exports already set the defined value. + exports = this.exports; + } + } + + if (err) { + err.requireMap = this.map; + err.requireModules = this.map.isDefine ? [this.map.id] : null; + err.requireType = this.map.isDefine ? 'define' : 'require'; + return onError((this.error = err)); + } + + } else { + //Just a literal value + exports = factory; + } + + this.exports = exports; + + if (this.map.isDefine && !this.ignore) { + defined[id] = exports; + + if (req.onResourceLoad) { + req.onResourceLoad(context, this.map, this.depMaps); + } + } + + //Clean up + cleanRegistry(id); + + this.defined = true; + } + + //Finished the define stage. Allow calling check again + //to allow define notifications below in the case of a + //cycle. + this.defining = false; + + if (this.defined && !this.defineEmitted) { + this.defineEmitted = true; + this.emit('defined', this.exports); + this.defineEmitComplete = true; + } + + } + }, + + callPlugin: function () { + var map = this.map, + id = map.id, + //Map already normalized the prefix. + pluginMap = makeModuleMap(map.prefix); + + //Mark this as a dependency for this plugin, so it + //can be traced for cycles. + this.depMaps.push(pluginMap); + + on(pluginMap, 'defined', bind(this, function (plugin) { + var load, normalizedMap, normalizedMod, + name = this.map.name, + parentName = this.map.parentMap ? this.map.parentMap.name : null, + localRequire = context.makeRequire(map.parentMap, { + enableBuildCallback: true + }); + + //If current map is not normalized, wait for that + //normalized name to load instead of continuing. + if (this.map.unnormalized) { + //Normalize the ID if the plugin allows it. + if (plugin.normalize) { + name = plugin.normalize(name, function (name) { + return normalize(name, parentName, true); + }) || ''; + } + + //prefix and name should already be normalized, no need + //for applying map config again either. + normalizedMap = makeModuleMap(map.prefix + '!' + name, + this.map.parentMap); + on(normalizedMap, + 'defined', bind(this, function (value) { + this.init([], function () { return value; }, null, { + enabled: true, + ignore: true + }); + })); + + normalizedMod = getOwn(registry, normalizedMap.id); + if (normalizedMod) { + //Mark this as a dependency for this plugin, so it + //can be traced for cycles. + this.depMaps.push(normalizedMap); + + if (this.events.error) { + normalizedMod.on('error', bind(this, function (err) { + this.emit('error', err); + })); + } + normalizedMod.enable(); + } + + return; + } + + load = bind(this, function (value) { + this.init([], function () { return value; }, null, { + enabled: true + }); + }); + + load.error = bind(this, function (err) { + this.inited = true; + this.error = err; + err.requireModules = [id]; + + //Remove temp unnormalized modules for this module, + //since they will never be resolved otherwise now. + eachProp(registry, function (mod) { + if (mod.map.id.indexOf(id + '_unnormalized') === 0) { + cleanRegistry(mod.map.id); + } + }); + + onError(err); + }); + + //Allow plugins to load other code without having to know the + //context or how to 'complete' the load. + load.fromText = bind(this, function (text, textAlt) { + /*jslint evil: true */ + var moduleName = map.name, + moduleMap = makeModuleMap(moduleName), + hasInteractive = useInteractive; + + //As of 2.1.0, support just passing the text, to reinforce + //fromText only being called once per resource. Still + //support old style of passing moduleName but discard + //that moduleName in favor of the internal ref. + if (textAlt) { + text = textAlt; + } + + //Turn off interactive script matching for IE for any define + //calls in the text, then turn it back on at the end. + if (hasInteractive) { + useInteractive = false; + } + + //Prime the system by creating a module instance for + //it. + getModule(moduleMap); + + //Transfer any config to this other module. + if (hasProp(config.config, id)) { + config.config[moduleName] = config.config[id]; + } + + try { + req.exec(text); + } catch (e) { + return onError(makeError('fromtexteval', + 'fromText eval for ' + id + + ' failed: ' + e, + e, + [id])); + } + + if (hasInteractive) { + useInteractive = true; + } + + //Mark this as a dependency for the plugin + //resource + this.depMaps.push(moduleMap); + + //Support anonymous modules. + context.completeLoad(moduleName); + + //Bind the value of that module to the value for this + //resource ID. + localRequire([moduleName], load); + }); + + //Use parentName here since the plugin's name is not reliable, + //could be some weird string with no path that actually wants to + //reference the parentName's path. + plugin.load(map.name, localRequire, load, config); + })); + + context.enable(pluginMap, this); + this.pluginMaps[pluginMap.id] = pluginMap; + }, + + enable: function () { + enabledRegistry[this.map.id] = this; + this.enabled = true; + + //Set flag mentioning that the module is enabling, + //so that immediate calls to the defined callbacks + //for dependencies do not trigger inadvertent load + //with the depCount still being zero. + this.enabling = true; + + //Enable each dependency + each(this.depMaps, bind(this, function (depMap, i) { + var id, mod, handler; + + if (typeof depMap === 'string') { + //Dependency needs to be converted to a depMap + //and wired up to this module. + depMap = makeModuleMap(depMap, + (this.map.isDefine ? this.map : this.map.parentMap), + false, + !this.skipMap); + this.depMaps[i] = depMap; + + handler = getOwn(handlers, depMap.id); + + if (handler) { + this.depExports[i] = handler(this); + return; + } + + this.depCount += 1; + + on(depMap, 'defined', bind(this, function (depExports) { + this.defineDep(i, depExports); + this.check(); + })); + + if (this.errback) { + on(depMap, 'error', bind(this, this.errback)); + } + } + + id = depMap.id; + mod = registry[id]; + + //Skip special modules like 'require', 'exports', 'module' + //Also, don't call enable if it is already enabled, + //important in circular dependency cases. + if (!hasProp(handlers, id) && mod && !mod.enabled) { + context.enable(depMap, this); + } + })); + + //Enable each plugin that is used in + //a dependency + eachProp(this.pluginMaps, bind(this, function (pluginMap) { + var mod = getOwn(registry, pluginMap.id); + if (mod && !mod.enabled) { + context.enable(pluginMap, this); + } + })); + + this.enabling = false; + + this.check(); + }, + + on: function (name, cb) { + var cbs = this.events[name]; + if (!cbs) { + cbs = this.events[name] = []; + } + cbs.push(cb); + }, + + emit: function (name, evt) { + each(this.events[name], function (cb) { + cb(evt); + }); + if (name === 'error') { + //Now that the error handler was triggered, remove + //the listeners, since this broken Module instance + //can stay around for a while in the registry. + delete this.events[name]; + } + } + }; + + function callGetModule(args) { + //Skip modules already defined. + if (!hasProp(defined, args[0])) { + getModule(makeModuleMap(args[0], null, true)).init(args[1], args[2]); + } + } + + function removeListener(node, func, name, ieName) { + //Favor detachEvent because of IE9 + //issue, see attachEvent/addEventListener comment elsewhere + //in this file. + if (node.detachEvent && !isOpera) { + //Probably IE. If not it will throw an error, which will be + //useful to know. + if (ieName) { + node.detachEvent(ieName, func); + } + } else { + node.removeEventListener(name, func, false); + } + } + + /** + * Given an event from a script node, get the requirejs info from it, + * and then removes the event listeners on the node. + * @param {Event} evt + * @returns {Object} + */ + function getScriptData(evt) { + //Using currentTarget instead of target for Firefox 2.0's sake. Not + //all old browsers will be supported, but this one was easy enough + //to support and still makes sense. + var node = evt.currentTarget || evt.srcElement; + + //Remove the listeners once here. + removeListener(node, context.onScriptLoad, 'load', 'onreadystatechange'); + removeListener(node, context.onScriptError, 'error'); + + return { + node: node, + id: node && node.getAttribute('data-requiremodule') + }; + } + + function intakeDefines() { + var args; + + //Any defined modules in the global queue, intake them now. + takeGlobalQueue(); + + //Make sure any remaining defQueue items get properly processed. + while (defQueue.length) { + args = defQueue.shift(); + if (args[0] === null) { + return onError(makeError('mismatch', 'Mismatched anonymous define() module: ' + args[args.length - 1])); + } else { + //args are id, deps, factory. Should be normalized by the + //define() function. + callGetModule(args); + } + } + } + + context = { + config: config, + contextName: contextName, + registry: registry, + defined: defined, + urlFetched: urlFetched, + defQueue: defQueue, + Module: Module, + makeModuleMap: makeModuleMap, + nextTick: req.nextTick, + onError: onError, + + /** + * Set a configuration for the context. + * @param {Object} cfg config object to integrate. + */ + configure: function (cfg) { + //Make sure the baseUrl ends in a slash. + if (cfg.baseUrl) { + if (cfg.baseUrl.charAt(cfg.baseUrl.length - 1) !== '/') { + cfg.baseUrl += '/'; + } + } + + //Save off the paths and packages since they require special processing, + //they are additive. + var pkgs = config.pkgs, + shim = config.shim, + objs = { + paths: true, + config: true, + map: true + }; + + eachProp(cfg, function (value, prop) { + if (objs[prop]) { + if (prop === 'map') { + if (!config.map) { + config.map = {}; + } + mixin(config[prop], value, true, true); + } else { + mixin(config[prop], value, true); + } + } else { + config[prop] = value; + } + }); + + //Merge shim + if (cfg.shim) { + eachProp(cfg.shim, function (value, id) { + //Normalize the structure + if (isArray(value)) { + value = { + deps: value + }; + } + if ((value.exports || value.init) && !value.exportsFn) { + value.exportsFn = context.makeShimExports(value); + } + shim[id] = value; + }); + config.shim = shim; + } + + //Adjust packages if necessary. + if (cfg.packages) { + each(cfg.packages, function (pkgObj) { + var location; + + pkgObj = typeof pkgObj === 'string' ? { name: pkgObj } : pkgObj; + location = pkgObj.location; + + //Create a brand new object on pkgs, since currentPackages can + //be passed in again, and config.pkgs is the internal transformed + //state for all package configs. + pkgs[pkgObj.name] = { + name: pkgObj.name, + location: location || pkgObj.name, + //Remove leading dot in main, so main paths are normalized, + //and remove any trailing .js, since different package + //envs have different conventions: some use a module name, + //some use a file name. + main: (pkgObj.main || 'main') + .replace(currDirRegExp, '') + .replace(jsSuffixRegExp, '') + }; + }); + + //Done with modifications, assing packages back to context config + config.pkgs = pkgs; + } + + //If there are any "waiting to execute" modules in the registry, + //update the maps for them, since their info, like URLs to load, + //may have changed. + eachProp(registry, function (mod, id) { + //If module already has init called, since it is too + //late to modify them, and ignore unnormalized ones + //since they are transient. + if (!mod.inited && !mod.map.unnormalized) { + mod.map = makeModuleMap(id); + } + }); + + //If a deps array or a config callback is specified, then call + //require with those args. This is useful when require is defined as a + //config object before require.js is loaded. + if (cfg.deps || cfg.callback) { + context.require(cfg.deps || [], cfg.callback); + } + }, + + makeShimExports: function (value) { + function fn() { + var ret; + if (value.init) { + ret = value.init.apply(global, arguments); + } + return ret || (value.exports && getGlobal(value.exports)); + } + return fn; + }, + + makeRequire: function (relMap, options) { + options = options || {}; + + function localRequire(deps, callback, errback) { + var id, map, requireMod; + + if (options.enableBuildCallback && callback && isFunction(callback)) { + callback.__requireJsBuild = true; + } + + if (typeof deps === 'string') { + if (isFunction(callback)) { + //Invalid call + return onError(makeError('requireargs', 'Invalid require call'), errback); + } + + //If require|exports|module are requested, get the + //value for them from the special handlers. Caveat: + //this only works while module is being defined. + if (relMap && hasProp(handlers, deps)) { + return handlers[deps](registry[relMap.id]); + } + + //Synchronous access to one module. If require.get is + //available (as in the Node adapter), prefer that. + if (req.get) { + return req.get(context, deps, relMap, localRequire); + } + + //Normalize module name, if it contains . or .. + map = makeModuleMap(deps, relMap, false, true); + id = map.id; + + if (!hasProp(defined, id)) { + return onError(makeError('notloaded', 'Module name "' + + id + + '" has not been loaded yet for context: ' + + contextName + + (relMap ? '' : '. Use require([])'))); + } + return defined[id]; + } + + //Grab defines waiting in the global queue. + intakeDefines(); + + //Mark all the dependencies as needing to be loaded. + context.nextTick(function () { + //Some defines could have been added since the + //require call, collect them. + intakeDefines(); + + requireMod = getModule(makeModuleMap(null, relMap)); + + //Store if map config should be applied to this require + //call for dependencies. + requireMod.skipMap = options.skipMap; + + requireMod.init(deps, callback, errback, { + enabled: true + }); + + checkLoaded(); + }); + + return localRequire; + } + + mixin(localRequire, { + isBrowser: isBrowser, + + /** + * Converts a module name + .extension into an URL path. + * *Requires* the use of a module name. It does not support using + * plain URLs like nameToUrl. + */ + toUrl: function (moduleNamePlusExt) { + var ext, + index = moduleNamePlusExt.lastIndexOf('.'), + segment = moduleNamePlusExt.split('/')[0], + isRelative = segment === '.' || segment === '..'; + + //Have a file extension alias, and it is not the + //dots from a relative path. + if (index !== -1 && (!isRelative || index > 1)) { + ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length); + moduleNamePlusExt = moduleNamePlusExt.substring(0, index); + } + + return context.nameToUrl(normalize(moduleNamePlusExt, + relMap && relMap.id, true), ext, true); + }, + + defined: function (id) { + return hasProp(defined, makeModuleMap(id, relMap, false, true).id); + }, + + specified: function (id) { + id = makeModuleMap(id, relMap, false, true).id; + return hasProp(defined, id) || hasProp(registry, id); + } + }); + + //Only allow undef on top level require calls + if (!relMap) { + localRequire.undef = function (id) { + //Bind any waiting define() calls to this context, + //fix for #408 + takeGlobalQueue(); + + var map = makeModuleMap(id, relMap, true), + mod = getOwn(registry, id); + + removeScript(id); + + delete defined[id]; + delete urlFetched[map.url]; + delete undefEvents[id]; + + if (mod) { + //Hold on to listeners in case the + //module will be attempted to be reloaded + //using a different config. + if (mod.events.defined) { + undefEvents[id] = mod.events; + } + + cleanRegistry(id); + } + }; + } + + return localRequire; + }, + + /** + * Called to enable a module if it is still in the registry + * awaiting enablement. A second arg, parent, the parent module, + * is passed in for context, when this method is overriden by + * the optimizer. Not shown here to keep code compact. + */ + enable: function (depMap) { + var mod = getOwn(registry, depMap.id); + if (mod) { + getModule(depMap).enable(); + } + }, + + /** + * Internal method used by environment adapters to complete a load event. + * A load event could be a script load or just a load pass from a synchronous + * load call. + * @param {String} moduleName the name of the module to potentially complete. + */ + completeLoad: function (moduleName) { + var found, args, mod, + shim = getOwn(config.shim, moduleName) || {}, + shExports = shim.exports; + + takeGlobalQueue(); + + while (defQueue.length) { + args = defQueue.shift(); + if (args[0] === null) { + args[0] = moduleName; + //If already found an anonymous module and bound it + //to this name, then this is some other anon module + //waiting for its completeLoad to fire. + if (found) { + break; + } + found = true; + } else if (args[0] === moduleName) { + //Found matching define call for this script! + found = true; + } + + callGetModule(args); + } + + //Do this after the cycle of callGetModule in case the result + //of those calls/init calls changes the registry. + mod = getOwn(registry, moduleName); + + if (!found && !hasProp(defined, moduleName) && mod && !mod.inited) { + if (config.enforceDefine && (!shExports || !getGlobal(shExports))) { + if (hasPathFallback(moduleName)) { + return; + } else { + return onError(makeError('nodefine', + 'No define call for ' + moduleName, + null, + [moduleName])); + } + } else { + //A script that does not call define(), so just simulate + //the call for it. + callGetModule([moduleName, (shim.deps || []), shim.exportsFn]); + } + } + + checkLoaded(); + }, + + /** + * Converts a module name to a file path. Supports cases where + * moduleName may actually be just an URL. + * Note that it **does not** call normalize on the moduleName, + * it is assumed to have already been normalized. This is an + * internal API, not a public one. Use toUrl for the public API. + */ + nameToUrl: function (moduleName, ext, skipExt) { + var paths, pkgs, pkg, pkgPath, syms, i, parentModule, url, + parentPath; + + //If a colon is in the URL, it indicates a protocol is used and it is just + //an URL to a file, or if it starts with a slash, contains a query arg (i.e. ?) + //or ends with .js, then assume the user meant to use an url and not a module id. + //The slash is important for protocol-less URLs as well as full paths. + if (req.jsExtRegExp.test(moduleName)) { + //Just a plain path, not module name lookup, so just return it. + //Add extension if it is included. This is a bit wonky, only non-.js things pass + //an extension, this method probably needs to be reworked. + url = moduleName + (ext || ''); + } else { + //A module that needs to be converted to a path. + paths = config.paths; + pkgs = config.pkgs; + + syms = moduleName.split('/'); + //For each module name segment, see if there is a path + //registered for it. Start with most specific name + //and work up from it. + for (i = syms.length; i > 0; i -= 1) { + parentModule = syms.slice(0, i).join('/'); + pkg = getOwn(pkgs, parentModule); + parentPath = getOwn(paths, parentModule); + if (parentPath) { + //If an array, it means there are a few choices, + //Choose the one that is desired + if (isArray(parentPath)) { + parentPath = parentPath[0]; + } + syms.splice(0, i, parentPath); + break; + } else if (pkg) { + //If module name is just the package name, then looking + //for the main module. + if (moduleName === pkg.name) { + pkgPath = pkg.location + '/' + pkg.main; + } else { + pkgPath = pkg.location; + } + syms.splice(0, i, pkgPath); + break; + } + } + + //Join the path parts together, then figure out if baseUrl is needed. + url = syms.join('/'); + url += (ext || (/^data\:|\?/.test(url) || skipExt ? '' : '.js')); + url = (url.charAt(0) === '/' || url.match(/^[\w\+\.\-]+:/) ? '' : config.baseUrl) + url; + } + + return config.urlArgs ? url + + ((url.indexOf('?') === -1 ? '?' : '&') + + config.urlArgs) : url; + }, + + //Delegates to req.load. Broken out as a separate function to + //allow overriding in the optimizer. + load: function (id, url) { + req.load(context, id, url); + }, + + /** + * Executes a module callback function. Broken out as a separate function + * solely to allow the build system to sequence the files in the built + * layer in the right sequence. + * + * @private + */ + execCb: function (name, callback, args, exports) { + return callback.apply(exports, args); + }, + + /** + * callback for script loads, used to check status of loading. + * + * @param {Event} evt the event from the browser for the script + * that was loaded. + */ + onScriptLoad: function (evt) { + //Using currentTarget instead of target for Firefox 2.0's sake. Not + //all old browsers will be supported, but this one was easy enough + //to support and still makes sense. + if (evt.type === 'load' || + (readyRegExp.test((evt.currentTarget || evt.srcElement).readyState))) { + //Reset interactive script so a script node is not held onto for + //to long. + interactiveScript = null; + + //Pull out the name of the module and the context. + var data = getScriptData(evt); + context.completeLoad(data.id); + } + }, + + /** + * Callback for script errors. + */ + onScriptError: function (evt) { + var data = getScriptData(evt); + if (!hasPathFallback(data.id)) { + return onError(makeError('scripterror', 'Script error for: ' + data.id, evt, [data.id])); + } + } + }; + + context.require = context.makeRequire(); + return context; + } + + /** + * Main entry point. + * + * If the only argument to require is a string, then the module that + * is represented by that string is fetched for the appropriate context. + * + * If the first argument is an array, then it will be treated as an array + * of dependency string names to fetch. An optional function callback can + * be specified to execute when all of those dependencies are available. + * + * Make a local req variable to help Caja compliance (it assumes things + * on a require that are not standardized), and to give a short + * name for minification/local scope use. + */ + req = requirejs = function (deps, callback, errback, optional) { + + //Find the right context, use default + var context, config, + contextName = defContextName; + + // Determine if have config object in the call. + if (!isArray(deps) && typeof deps !== 'string') { + // deps is a config object + config = deps; + if (isArray(callback)) { + // Adjust args if there are dependencies + deps = callback; + callback = errback; + errback = optional; + } else { + deps = []; + } + } + + if (config && config.context) { + contextName = config.context; + } + + context = getOwn(contexts, contextName); + if (!context) { + context = contexts[contextName] = req.s.newContext(contextName); + } + + if (config) { + context.configure(config); + } + + return context.require(deps, callback, errback); + }; + + /** + * Support require.config() to make it easier to cooperate with other + * AMD loaders on globally agreed names. + */ + req.config = function (config) { + return req(config); + }; + + /** + * Execute something after the current tick + * of the event loop. Override for other envs + * that have a better solution than setTimeout. + * @param {Function} fn function to execute later. + */ + req.nextTick = typeof setTimeout !== 'undefined' ? function (fn) { + setTimeout(fn, 4); + } : function (fn) { fn(); }; + + /** + * Export require as a global, but only if it does not already exist. + */ + if (!require) { + require = req; + } + + req.version = version; + + //Used to filter out dependencies that are already paths. + req.jsExtRegExp = /^\/|:|\?|\.js$/; + req.isBrowser = isBrowser; + s = req.s = { + contexts: contexts, + newContext: newContext + }; + + //Create default context. + req({}); + + //Exports some context-sensitive methods on global require. + each([ + 'toUrl', + 'undef', + 'defined', + 'specified' + ], function (prop) { + //Reference from contexts instead of early binding to default context, + //so that during builds, the latest instance of the default context + //with its config gets used. + req[prop] = function () { + var ctx = contexts[defContextName]; + return ctx.require[prop].apply(ctx, arguments); + }; + }); + + if (isBrowser) { + head = s.head = document.getElementsByTagName('head')[0]; + //If BASE tag is in play, using appendChild is a problem for IE6. + //When that browser dies, this can be removed. Details in this jQuery bug: + //http://dev.jquery.com/ticket/2709 + baseElement = document.getElementsByTagName('base')[0]; + if (baseElement) { + head = s.head = baseElement.parentNode; + } + } + + /** + * Any errors that require explicitly generates will be passed to this + * function. Intercept/override it if you want custom error handling. + * @param {Error} err the error object. + */ + req.onError = defaultOnError; + + /** + * Creates the node for the load command. Only used in browser envs. + */ + req.createNode = function (config, moduleName, url) { + var node = config.xhtml ? + document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') : + document.createElement('script'); + node.type = config.scriptType || 'text/javascript'; + node.charset = 'utf-8'; + node.async = true; + return node; + }; + + /** + * Does the request to load a module for the browser case. + * Make this a separate function to allow other environments + * to override it. + * + * @param {Object} context the require context to find state. + * @param {String} moduleName the name of the module. + * @param {Object} url the URL to the module. + */ + req.load = function (context, moduleName, url) { + var config = (context && context.config) || {}, + node; + if (isBrowser) { + //In the browser so use a script tag + node = req.createNode(config, moduleName, url); + + node.setAttribute('data-requirecontext', context.contextName); + node.setAttribute('data-requiremodule', moduleName); + + //Set up load listener. Test attachEvent first because IE9 has + //a subtle issue in its addEventListener and script onload firings + //that do not match the behavior of all other browsers with + //addEventListener support, which fire the onload event for a + //script right after the script execution. See: + //https://connect.microsoft.com/IE/feedback/details/648057/script-onload-event-is-not-fired-immediately-after-script-execution + //UNFORTUNATELY Opera implements attachEvent but does not follow the script + //script execution mode. + if (node.attachEvent && + //Check if node.attachEvent is artificially added by custom script or + //natively supported by browser + //read https://github.com/jrburke/requirejs/issues/187 + //if we can NOT find [native code] then it must NOT natively supported. + //in IE8, node.attachEvent does not have toString() + //Note the test for "[native code" with no closing brace, see: + //https://github.com/jrburke/requirejs/issues/273 + !(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code') < 0) && + !isOpera) { + //Probably IE. IE (at least 6-8) do not fire + //script onload right after executing the script, so + //we cannot tie the anonymous define call to a name. + //However, IE reports the script as being in 'interactive' + //readyState at the time of the define call. + useInteractive = true; + + node.attachEvent('onreadystatechange', context.onScriptLoad); + //It would be great to add an error handler here to catch + //404s in IE9+. However, onreadystatechange will fire before + //the error handler, so that does not help. If addEventListener + //is used, then IE will fire error before load, but we cannot + //use that pathway given the connect.microsoft.com issue + //mentioned above about not doing the 'script execute, + //then fire the script load event listener before execute + //next script' that other browsers do. + //Best hope: IE10 fixes the issues, + //and then destroys all installs of IE 6-9. + //node.attachEvent('onerror', context.onScriptError); + } else { + node.addEventListener('load', context.onScriptLoad, false); + node.addEventListener('error', context.onScriptError, false); + } + node.src = url; + + //For some cache cases in IE 6-8, the script executes before the end + //of the appendChild execution, so to tie an anonymous define + //call to the module name (which is stored on the node), hold on + //to a reference to this node, but clear after the DOM insertion. + currentlyAddingScript = node; + if (baseElement) { + head.insertBefore(node, baseElement); + } else { + head.appendChild(node); + } + currentlyAddingScript = null; + + return node; + } else if (isWebWorker) { + try { + //In a web worker, use importScripts. This is not a very + //efficient use of importScripts, importScripts will block until + //its script is downloaded and evaluated. However, if web workers + //are in play, the expectation that a build has been done so that + //only one script needs to be loaded anyway. This may need to be + //reevaluated if other use cases become common. + importScripts(url); + + //Account for anonymous modules + context.completeLoad(moduleName); + } catch (e) { + context.onError(makeError('importscripts', + 'importScripts failed for ' + + moduleName + ' at ' + url, + e, + [moduleName])); + } + } + }; + + function getInteractiveScript() { + if (interactiveScript && interactiveScript.readyState === 'interactive') { + return interactiveScript; + } + + eachReverse(scripts(), function (script) { + if (script.readyState === 'interactive') { + return (interactiveScript = script); + } + }); + return interactiveScript; + } + + //Look for a data-main script attribute, which could also adjust the baseUrl. + if (isBrowser && !cfg.skipDataMain) { + //Figure out baseUrl. Get it from the script tag with require.js in it. + eachReverse(scripts(), function (script) { + //Set the 'head' where we can append children by + //using the script's parent. + if (!head) { + head = script.parentNode; + } + + //Look for a data-main attribute to set main script for the page + //to load. If it is there, the path to data main becomes the + //baseUrl, if it is not already set. + dataMain = script.getAttribute('data-main'); + if (dataMain) { + //Preserve dataMain in case it is a path (i.e. contains '?') + mainScript = dataMain; + + //Set final baseUrl if there is not already an explicit one. + if (!cfg.baseUrl) { + //Pull off the directory of data-main for use as the + //baseUrl. + src = mainScript.split('/'); + mainScript = src.pop(); + subPath = src.length ? src.join('/') + '/' : './'; + + cfg.baseUrl = subPath; + } + + //Strip off any trailing .js since mainScript is now + //like a module name. + mainScript = mainScript.replace(jsSuffixRegExp, ''); + + //If mainScript is still a path, fall back to dataMain + if (req.jsExtRegExp.test(mainScript)) { + mainScript = dataMain; + } + + //Put the data-main script in the files to load. + cfg.deps = cfg.deps ? cfg.deps.concat(mainScript) : [mainScript]; + + return true; + } + }); + } + + /** + * The function that handles definitions of modules. Differs from + * require() in that a string for the module should be the first argument, + * and the function to execute after dependencies are loaded should + * return a value to define the module corresponding to the first argument's + * name. + */ + define = function (name, deps, callback) { + var node, context; + + //Allow for anonymous modules + if (typeof name !== 'string') { + //Adjust args appropriately + callback = deps; + deps = name; + name = null; + } + + //This module may not have dependencies + if (!isArray(deps)) { + callback = deps; + deps = null; + } + + //If no name, and callback is a function, then figure out if it a + //CommonJS thing with dependencies. + if (!deps && isFunction(callback)) { + deps = []; + //Remove comments from the callback string, + //look for require calls, and pull them into the dependencies, + //but only if there are function args. + if (callback.length) { + callback + .toString() + .replace(commentRegExp, '') + .replace(cjsRequireRegExp, function (match, dep) { + deps.push(dep); + }); + + //May be a CommonJS thing even without require calls, but still + //could use exports, and module. Avoid doing exports and module + //work though if it just needs require. + //REQUIRES the function to expect the CommonJS variables in the + //order listed below. + deps = (callback.length === 1 ? ['require'] : ['require', 'exports', 'module']).concat(deps); + } + } + + //If in IE 6-8 and hit an anonymous define() call, do the interactive + //work. + if (useInteractive) { + node = currentlyAddingScript || getInteractiveScript(); + if (node) { + if (!name) { + name = node.getAttribute('data-requiremodule'); + } + context = contexts[node.getAttribute('data-requirecontext')]; + } + } + + //Always save off evaluating the def call until the script onload handler. + //This allows multiple modules to be in a file without prematurely + //tracing dependencies, and allows for anonymous module support, + //where the module name is not known until the script onload event + //occurs. If no context, use the global queue, and get it processed + //in the onscript load callback. + (context ? context.defQueue : globalDefQueue).push([name, deps, callback]); + }; + + define.amd = { + jQuery: true + }; + + + /** + * Executes the text. Normally just uses eval, but can be modified + * to use a better, environment-specific call. Only used for transpiling + * loader plugins, not for plain JS modules. + * @param {String} text the text to execute/evaluate. + */ + req.exec = function (text) { + /*jslint evil: true */ + return eval(text); + }; + + //Set up with config info. + req(cfg); +}(this)); \ No newline at end of file diff --git a/sandbox/sample/index.html b/sandbox/sample/index.html new file mode 100644 index 0000000000..17f2d545db --- /dev/null +++ b/sandbox/sample/index.html @@ -0,0 +1,66 @@ + + + + + + SAMPLE | Ractive.js sandbox + + + + + + + + +
+ «

SAMPLE

+
+ +
+

loading individual Ractive.js source files... please wait

+
+ + + + + + + + + + diff --git a/scripts/deploy-edge-to-cdn.sh b/scripts/deploy-edge-to-cdn.sh new file mode 100644 index 0000000000..3b53539bc6 --- /dev/null +++ b/scripts/deploy-edge-to-cdn.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +# deploy script based on https://medium.com/philosophy-logic/53a8270e87db +if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then + echo "Deploying edge version to CDN..." + + git clone https://github.com/RactiveJS/cdn.ractivejs.org.git cdn + git checkout -b gh-pages origin/gh-pages + + rm -r cdn/edge + cp -r build/ cdn/edge + + ( cd cdn + + git config user.name "Travis-CI" + git config user.email "richard.a.harris+travis@gmail.com" + git add . + git commit -m "Updated edge version" + + git push "https://${GH_TOKEN}@${GH_REF}" + ) +fi diff --git a/src/Ractive.js b/src/Ractive.js index eb7b883997..8377ad1d5a 100644 --- a/src/Ractive.js +++ b/src/Ractive.js @@ -1,15 +1,8 @@ -define([ 'Ractive/_Ractive', 'circular' ], function ( Ractive, circular ) { +define([ 'Ractive/_Ractive', 'circular', 'legacy' ], function ( Ractive, circular ) { 'use strict'; - // Internet Explorer derp. Methods that should be attached to Node.prototype - // are instead attached to HTMLElement.prototype, which means SVG elements - // can't use them. Remember kids, friends don't let friends use IE. - // - // This is here, rather than in legacy.js, because it affects IE9. - if ( typeof window !== 'undefined' && window.Node && !window.Node.prototype.contains && window.HTMLElement && window.HTMLElement.prototype.contains ) { - window.Node.prototype.contains = window.HTMLElement.prototype.contains; - } + var FUNCTION = 'function'; // Certain modules have circular dependencies. If we were bundling a // module loader, e.g. almond.js, this wouldn't be a problem, but we're @@ -20,6 +13,34 @@ define([ 'Ractive/_Ractive', 'circular' ], function ( Ractive, circular ) { circular.pop()(); } + + // Ractive.js makes liberal use of things like Array.prototype.indexOf. In + // older browsers, these are made available via a shim - here, we do a quick + // pre-flight check to make sure that either a) we're not in a shit browser, + // or b) we're using a Ractive-legacy.js build + if ( + typeof Date.now !== FUNCTION || + typeof String.prototype.trim !== FUNCTION || + typeof Object.keys !== FUNCTION || + typeof Array.prototype.indexOf !== FUNCTION || + typeof Array.prototype.forEach !== FUNCTION || + typeof Array.prototype.map !== FUNCTION || + typeof Array.prototype.filter !== FUNCTION || + ( typeof window !== 'undefined' && typeof window.addEventListener !== FUNCTION ) + ) { + throw new Error( 'It looks like you\'re attempting to use Ractive.js in an older browser. You\'ll need to use one of the \'legacy builds\' in order to continue - see http://docs.ractivejs.org/latest/legacy-builds for more information.' ); + } + + + // Internet Explorer derp. Methods that should be attached to Node.prototype + // are instead attached to HTMLElement.prototype, which means SVG elements + // can't use them. Remember kids, friends don't let friends use IE. + // + // This is here, rather than in legacy.js, because it affects IE9. + if ( typeof window !== 'undefined' && window.Node && !window.Node.prototype.contains && window.HTMLElement && window.HTMLElement.prototype.contains ) { + window.Node.prototype.contains = window.HTMLElement.prototype.contains; + } + return Ractive; -}); \ No newline at end of file +}); diff --git a/src/Ractive/_Ractive.js b/src/Ractive/_Ractive.js index 8004ac9186..3f233bbf7f 100644 --- a/src/Ractive/_Ractive.js +++ b/src/Ractive/_Ractive.js @@ -1,24 +1,30 @@ define([ + 'config/initOptions', 'config/svg', - 'utils/create', 'utils/defineProperties', 'Ractive/prototype/_prototype', 'registries/partials', 'registries/adaptors', + 'registries/components', 'registries/easing', + 'registries/interpolators', + 'utils/Promise', 'extend/_extend', 'parse/_parse', 'Ractive/initialise', 'circular' ], function ( + initOptions, svg, - create, defineProperties, - prototype, + proto, partialRegistry, adaptorRegistry, + componentsRegistry, easingRegistry, - Ractive_extend, + interpolatorsRegistry, + Promise, + extend, parse, initialise, circular @@ -30,27 +36,30 @@ define([ initialise( this, options ); }; + Ractive.prototype = proto; + // Read-only properties defineProperties( Ractive, { - // Prototype methods - prototype: { value: prototype }, - // Shared properties partials: { value: partialRegistry }, // Plugins - adaptors: { value: adaptorRegistry }, - easing: { value: easingRegistry }, - transitions: { value: {} }, - events: { value: {} }, - components: { value: {} }, - decorators: { value: {} }, + adaptors: { value: adaptorRegistry }, + easing: { value: easingRegistry }, + transitions: { value: {} }, + events: { value: {} }, + components: { value: componentsRegistry }, + decorators: { value: {} }, + interpolators: { value: interpolatorsRegistry }, + + // Default options + defaults: { value: initOptions.defaults }, // Support svg: { value: svg }, - VERSION: { value: '<%= version %>' } + VERSION: { value: '<%= pkg.version %>' } }); // TODO deprecated @@ -58,14 +67,14 @@ define([ Ractive.prototype.constructor = Ractive; - Ractive.delimiters = [ '{{', '}}' ]; - Ractive.tripleDelimiters = [ '{{{', '}}}' ]; + // Namespaced constructors + Ractive.Promise = Promise; // Static methods - Ractive.extend = Ractive_extend; + Ractive.extend = extend; Ractive.parse = parse; circular.Ractive = Ractive; return Ractive; -}); \ No newline at end of file +}); diff --git a/src/Ractive/initialise.js b/src/Ractive/initialise.js index 72e414fb0d..dcfce0dec7 100644 --- a/src/Ractive/initialise.js +++ b/src/Ractive/initialise.js @@ -1,67 +1,76 @@ define([ 'config/isClient', 'config/errors', + 'config/initOptions', + 'config/registries', 'utils/warn', 'utils/create', 'utils/extend', - 'utils/defineProperty', + 'utils/fillGaps', 'utils/defineProperties', 'utils/getElement', 'utils/isObject', - 'Ractive/prototype/get/magicAdaptor', - 'parse/_parse' + 'utils/isArray', + 'utils/getGuid', + 'utils/Promise', + 'shared/get/magicAdaptor', + 'parse/_parse', + 'Ractive/initialise/computations/createComputations' ], function ( isClient, errors, + initOptions, + registries, warn, create, extend, - defineProperty, + fillGaps, defineProperties, getElement, isObject, + isArray, + getGuid, + Promise, magicAdaptor, - parse + parse, + createComputations ) { 'use strict'; - var getObject, getArray, defaultOptions, registries; + var flags = [ 'adapt', 'modifyArrays', 'magic', 'twoway', 'lazy', 'debug', 'isolated' ]; - getObject = function () { return {}; }; - getArray = function () { return []; }; + return function initialiseRactiveInstance ( ractive, options ) { - defaultOptions = create( null ); + var defaults, template, templateEl, parsedTemplate, promise, fulfilPromise, computed; - defineProperties( defaultOptions, { - preserveWhitespace: { enumerable: true, value: false }, - append: { enumerable: true, value: false }, - twoway: { enumerable: true, value: true }, - modifyArrays: { enumerable: true, value: true }, - data: { enumerable: true, value: getObject }, - lazy: { enumerable: true, value: false }, - debug: { enumerable: true, value: false }, - transitions: { enumerable: true, value: getObject }, - decorators: { enumerable: true, value: getObject }, - events: { enumerable: true, value: getObject }, - noIntro: { enumerable: true, value: false }, - transitionsEnabled: { enumerable: true, value: true }, - magic: { enumerable: true, value: false }, - adaptors: { enumerable: true, value: getArray } - }); - - registries = [ 'components', 'decorators', 'events', 'partials', 'transitions', 'data' ]; - - return function ( ractive, options ) { - - var key, template, templateEl, parsedTemplate; + if ( isArray( options.adaptors ) ) { + warn( 'The `adaptors` option, to indicate which adaptors should be used with a given Ractive instance, has been deprecated in favour of `adapt`. See [TODO] for more information' ); + options.adapt = options.adaptors; + delete options.adaptors; + } // Options // ------- - for ( key in defaultOptions ) { + defaults = ractive.constructor.defaults; + initOptions.keys.forEach( function ( key ) { if ( options[ key ] === undefined ) { - options[ key ] = ( typeof defaultOptions[ key ] === 'function' ? defaultOptions[ key ]() : defaultOptions[ key ] ); + options[ key ] = defaults[ key ]; } + }); + + // options + flags.forEach( function ( flag ) { + ractive[ flag ] = options[ flag ]; + }); + + // special cases + if ( typeof ractive.adapt === 'string' ) { + ractive.adapt = [ ractive.adapt ]; + } + + if ( ractive.magic && !magicAdaptor ) { + throw new Error( 'Getters and setters (magic mode) are not supported in this browser' ); } @@ -74,15 +83,7 @@ define([ // Generate a unique identifier, for places where you'd use a weak map if it // existed - _guid: { - value: 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { - var r, v; - - r = Math.random()*16|0; - v = ( c == 'x' ? r : (r&0x3|0x8) ); - return v.toString(16); - }) - }, + _guid: { value: getGuid() }, // events _subs: { value: create( null ), configurable: true }, @@ -97,21 +98,15 @@ define([ _patternObservers: { value: [] }, - // unresolved dependants - _pendingResolution: { value: [] }, - - // Create arrays for deferred attributes and evaluators etc - _deferred: { value: {} }, - // Keep a list of used evaluators, so we don't duplicate them _evaluators: { value: create( null ) }, + // Computed properties + _computations: { value: create( null ) }, + // two-way bindings _twowayBindings: { value: {} }, - // transition manager - _transitionManager: { value: null, writable: true }, - // animations (so we can stop any in progress at teardown) _animations: { value: [] }, @@ -123,39 +118,27 @@ define([ // live queries _liveQueries: { value: [] }, - _liveComponentQueries: { value: [] } - }); + _liveComponentQueries: { value: [] }, - defineProperties( ractive._deferred, { - attrs: { value: [] }, - evals: { value: [] }, - selectValues: { value: [] }, - checkboxes: { value: [] }, - radios: { value: [] }, - observers: { value: [] }, - transitions: { value: [] }, - liveQueries: { value: [] }, - decorators: { value: [] }, - focusable: { value: null, writable: true } - }); + // components to init at the end of a mutation + _childInitQueue: { value: [] }, - // options - ractive.adaptors = options.adaptors; - ractive.modifyArrays = options.modifyArrays; - ractive.magic = options.magic; - ractive.twoway = options.twoway; - ractive.lazy = options.lazy; - ractive.debug = options.debug; + // data changes + _changes: { value: [] }, - if ( ractive.magic && !magicAdaptor ) { - throw new Error( 'Getters and setters (magic mode) are not supported in this browser' ); - } + // failed lookups, when we try to access data from ancestor scopes + _unresolvedImplicitDependencies: { value: [] } + }); // If this is a component, store a reference to the parent - if ( options._parent ) { - defineProperty( ractive, '_parent', { - value: options._parent + if ( options._parent && options._component ) { + defineProperties( ractive, { + _parent: { value: options._parent }, + component: { value: options._component } }); + + // And store a reference to the instance on the component + options._component.instance = ractive; } if ( options.el ) { @@ -174,12 +157,26 @@ define([ registries.forEach( function ( registry ) { if ( ractive.constructor[ registry ] ) { - ractive[ registry ] = extend( create( ractive.constructor[ registry ] || {} ), options[ registry ] ); + ractive[ registry ] = extend( create( ractive.constructor[ registry ] ), options[ registry ] ); } else if ( options[ registry ] ) { ractive[ registry ] = options[ registry ]; } }); + // Special case + if ( !ractive.data ) { + ractive.data = {}; + } + + // Set up any computed values + computed = defaults.computed + ? extend( create( defaults.computed ), options.computed ) + : options.computed; + + if ( computed ) { + createComputations( ractive, computed ); + } + // Parse template, if necessary @@ -211,7 +208,7 @@ define([ // deal with compound template if ( isObject( parsedTemplate ) ) { - extend( ractive.partials, parsedTemplate.partials ); + fillGaps( ractive.partials, parsedTemplate.partials ); parsedTemplate = parsedTemplate.main; } @@ -246,7 +243,12 @@ define([ ractive.el.innerHTML = ''; } - ractive.render( ractive.el, options.complete ); + promise = new Promise( function ( fulfil ) { fulfilPromise = fulfil; }); + ractive.render( ractive.el, fulfilPromise ); + + if ( options.complete ) { + promise.then( options.complete.bind( ractive ) ); + } // reset transitionsEnabled ractive.transitionsEnabled = options.transitionsEnabled; @@ -255,4 +257,4 @@ define([ ractive._initing = false; }; -}); \ No newline at end of file +}); diff --git a/src/Ractive/initialise/computations/Computation.js b/src/Ractive/initialise/computations/Computation.js new file mode 100644 index 0000000000..1d66726497 --- /dev/null +++ b/src/Ractive/initialise/computations/Computation.js @@ -0,0 +1,118 @@ +define([ + 'utils/warn', + 'global/runloop', + 'shared/set', + 'Ractive/initialise/computations/Watcher' +], function ( + warn, + runloop, + set, + Watcher +) { + + 'use strict'; + + var Computation = function ( ractive, key, signature ) { + this.ractive = ractive; + this.key = key; + + this.getter = signature.get; + this.setter = signature.set; + + this.watchers = []; + + this.update(); + }; + + Computation.prototype = { + set: function ( value ) { + if ( this.setting ) { + this.value = value; + return; + } + + if ( !this.setter ) { + throw new Error( 'Computed properties without setters are read-only in the current version' ); + } + + this.setter.call( this.ractive, value ); + }, + + update: function () { + var ractive, originalCaptured, result, errored; + + ractive = this.ractive; + originalCaptured = ractive._captured; + + if ( !originalCaptured ) { + ractive._captured = []; + } + + try { + result = this.getter.call( ractive ); + } catch ( err ) { + if ( ractive.debug ) { + warn( 'Failed to compute "' + this.key + '": ' + err.message || err ); + } + + errored = true; + } + + diff( this, this.watchers, ractive._captured ); + + // reset + ractive._captured = originalCaptured; + + if ( !errored ) { + this.setting = true; + this.value = result; + set( ractive, this.key, result ); + this.setting = false; + } + + this.deferred = false; + }, + + bubble: function () { + if ( this.watchers.length <= 1 ) { + this.update(); + } + + else if ( !this.deferred ) { + runloop.addComputation( this ); + this.deferred = true; + } + } + }; + + function diff ( computation, watchers, newDependencies ) { + var i, watcher, keypath; + + // remove dependencies that are no longer used + i = watchers.length; + while ( i-- ) { + watcher = watchers[i]; + + if ( !newDependencies[ watcher.keypath ] ) { + watchers.splice( i, 1 ); + watchers[ watcher.keypath ] = null; + + watcher.teardown(); + } + } + + // create references for any new dependencies + i = newDependencies.length; + while ( i-- ) { + keypath = newDependencies[i]; + + if ( !watchers[ keypath ] ) { + watcher = new Watcher( computation, keypath ); + watchers.push( watchers[ keypath ] = watcher ); + } + } + } + + return Computation; + +}); diff --git a/src/Ractive/initialise/computations/Watcher.js b/src/Ractive/initialise/computations/Watcher.js new file mode 100644 index 0000000000..56664cc3e3 --- /dev/null +++ b/src/Ractive/initialise/computations/Watcher.js @@ -0,0 +1,41 @@ +define([ + 'utils/isEqual', + 'shared/registerDependant', + 'shared/unregisterDependant' +], function ( + isEqual, + registerDependant, + unregisterDependant +) { + + 'use strict'; + + var Watcher = function ( computation, keypath ) { + this.root = computation.ractive; + this.keypath = keypath; + this.priority = 0; + + this.computation = computation; + + registerDependant( this ); + }; + + Watcher.prototype = { + update: function () { + var value; + + value = this.root.get( this.keypath ); + + if ( !isEqual( value, this.value ) ) { + this.computation.bubble(); + } + }, + + teardown: function () { + unregisterDependant( this ); + } + }; + + return Watcher; + +}); diff --git a/src/Ractive/initialise/computations/createComputations.js b/src/Ractive/initialise/computations/createComputations.js new file mode 100644 index 0000000000..2c341733f9 --- /dev/null +++ b/src/Ractive/initialise/computations/createComputations.js @@ -0,0 +1,20 @@ +define([ + 'Ractive/initialise/computations/getComputationSignature', + 'Ractive/initialise/computations/Computation' +], function ( + getComputationSignature, + Computation +) { + + 'use strict'; + + return function createComputations ( ractive, computed ) { + var key, signature; + + for ( key in computed ) { + signature = getComputationSignature( computed[ key ] ); + ractive._computations[ key ] = new Computation( ractive, key, signature ); + } + }; + +}); diff --git a/src/Ractive/initialise/computations/getComputationSignature.js b/src/Ractive/initialise/computations/getComputationSignature.js new file mode 100644 index 0000000000..c009da68d9 --- /dev/null +++ b/src/Ractive/initialise/computations/getComputationSignature.js @@ -0,0 +1,36 @@ +define( function () { + + 'use strict'; + + var pattern = /\$\{([^\}]+)\}/g; + + return function ( signature ) { + if ( typeof signature === 'function' ) { + return { get: signature }; + } + + if ( typeof signature === 'string' ) { + return { + get: createFunctionFromString( signature ) + }; + } + + if ( typeof signature === 'object' && typeof signature.get === 'string' ) { + signature = { + get: createFunctionFromString( signature.get ), + set: signature.set + }; + } + + return signature; + }; + + function createFunctionFromString ( signature ) { + var functionBody = 'var __ractive=this;return(' + signature.replace( pattern, function ( match, keypath ) { + return '__ractive.get("' + keypath + '")'; + }) + ')'; + + return new Function ( functionBody ); + } + +}); diff --git a/src/Ractive/prototype/_prototype.js b/src/Ractive/prototype/_prototype.js index 4ba7bbc521..4f11fc839f 100644 --- a/src/Ractive/prototype/_prototype.js +++ b/src/Ractive/prototype/_prototype.js @@ -1,79 +1,82 @@ define([ - 'Ractive/prototype/get/_get', - 'Ractive/prototype/set', - 'Ractive/prototype/update', - 'Ractive/prototype/updateModel', + 'Ractive/prototype/add', 'Ractive/prototype/animate/_animate', - 'Ractive/prototype/on', - 'Ractive/prototype/off', - 'Ractive/prototype/observe/_observe', - 'Ractive/prototype/fire', + 'Ractive/prototype/detach', 'Ractive/prototype/find', 'Ractive/prototype/findAll', - 'Ractive/prototype/findComponent', 'Ractive/prototype/findAllComponents', + 'Ractive/prototype/findComponent', + 'Ractive/prototype/fire', + 'Ractive/prototype/get', + 'Ractive/prototype/insert', + 'Ractive/prototype/merge/_merge', + 'Ractive/prototype/observe/_observe', + 'Ractive/prototype/off', + 'Ractive/prototype/on', 'Ractive/prototype/render', 'Ractive/prototype/renderHTML', - 'Ractive/prototype/toHTML', - 'Ractive/prototype/teardown', - 'Ractive/prototype/add', + 'Ractive/prototype/reset', + 'Ractive/prototype/set', 'Ractive/prototype/subtract', + 'Ractive/prototype/teardown', + 'Ractive/prototype/toHTML', 'Ractive/prototype/toggle', - 'Ractive/prototype/merge/_merge', - 'Ractive/prototype/detach', - 'Ractive/prototype/insert' + 'Ractive/prototype/update', + 'Ractive/prototype/updateModel' ], function ( - get, - set, - update, - updateModel, + add, animate, - on, - off, - observe, - fire, + detach, find, findAll, - findComponent, findAllComponents, + findComponent, + fire, + get, + insert, + merge, + observe, + off, + on, render, renderHTML, - toHTML, - teardown, - add, + reset, + set, subtract, + teardown, + toHTML, toggle, - merge, - detach, - insert + update, + updateModel ) { 'use strict'; return { - get: get, - set: set, - update: update, - updateModel: updateModel, + add: add, animate: animate, - on: on, - off: off, - observe: observe, - fire: fire, + detach: detach, find: find, findAll: findAll, - findComponent: findComponent, findAllComponents: findAllComponents, - renderHTML: renderHTML, - toHTML: toHTML, + findComponent: findComponent, + fire: fire, + get: get, + insert: insert, + merge: merge, + observe: observe, + off: off, + on: on, render: render, - teardown: teardown, - add: add, + renderHTML: renderHTML, + reset: reset, + set: set, subtract: subtract, + teardown: teardown, + toHTML: toHTML, toggle: toggle, - merge: merge, - detach: detach, - insert: insert + update: update, + updateModel: updateModel }; -}); \ No newline at end of file +}); diff --git a/src/Ractive/prototype/add.js b/src/Ractive/prototype/add.js index a4c87bea70..dff4af052b 100644 --- a/src/Ractive/prototype/add.js +++ b/src/Ractive/prototype/add.js @@ -3,7 +3,7 @@ define([ 'Ractive/prototype/shared/add' ], function ( add ) { 'use strict'; return function ( keypath, d ) { - add( this, keypath, ( d === undefined ? 1 : d ) ); + return add( this, keypath, ( d === undefined ? 1 : +d ) ); }; -}); \ No newline at end of file +}); diff --git a/src/Ractive/prototype/animate/Animation.js b/src/Ractive/prototype/animate/Animation.js index 9c1e5d4260..d0fc3657dd 100755 --- a/src/Ractive/prototype/animate/Animation.js +++ b/src/Ractive/prototype/animate/Animation.js @@ -1,9 +1,13 @@ define([ 'utils/warn', - 'shared/interpolate' + 'global/runloop', + 'shared/interpolate', + 'shared/set' ], function ( warn, - interpolate + runloop, + interpolate, + set ) { 'use strict'; @@ -20,7 +24,7 @@ define([ } } - this.interpolator = interpolate( this.from, this.to ); + this.interpolator = interpolate( this.from, this.to, this.root, this.interpolator ); this.running = true; }; @@ -36,16 +40,16 @@ define([ if ( elapsed >= this.duration ) { if ( keypath !== null ) { - this.root.set( keypath, this.to ); + runloop.start( this.root ); + set( this.root, keypath, this.to ); + runloop.end(); } if ( this.step ) { this.step( 1, this.to ); } - if ( this.complete ) { - this.complete( 1, this.to ); - } + this.complete( this.to ); index = this.root._animations.indexOf( this ); @@ -64,7 +68,9 @@ define([ if ( keypath !== null ) { value = this.interpolator( t ); - this.root.set( keypath, value ); + runloop.start( this.root ); + set( this.root, keypath, value ); + runloop.end(); } if ( this.step ) { @@ -95,4 +101,4 @@ define([ return Animation; -}); \ No newline at end of file +}); diff --git a/src/Ractive/prototype/animate/_animate.js b/src/Ractive/prototype/animate/_animate.js index 0650f5f404..7c6c1f83ba 100755 --- a/src/Ractive/prototype/animate/_animate.js +++ b/src/Ractive/prototype/animate/_animate.js @@ -1,27 +1,33 @@ define([ 'utils/isEqual', - 'Ractive/prototype/animate/animations', - 'Ractive/prototype/animate/Animation', - 'registries/easing' + 'utils/Promise', + 'utils/normaliseKeypath', + 'shared/animations', + 'shared/get/_get', + 'Ractive/prototype/animate/Animation' ], function ( isEqual, + Promise, + normaliseKeypath, animations, - Animation, - easingRegistry + get, + Animation ) { 'use strict'; - var noAnimation = { - stop: function () {} + var noop = function () {}, noAnimation = { + stop: noop }; return function ( keypath, to, options ) { - var k, + var promise, + fulfilPromise, + k, animation, animations, easing, @@ -34,6 +40,8 @@ function ( dummy, dummyOptions; + promise = new Promise( function ( fulfil ) { fulfilPromise = fulfil; }); + // animate multiple keypaths if ( typeof keypath === 'object' ) { options = to || {}; @@ -74,13 +82,10 @@ function ( if ( step ) { options.step = collectValue; } - - if ( complete ) { - options.complete = collectValue; - } } - animations[ animations.length ] = animate( this, k, keypath[k], options ); + options.complete = complete ? collectValue : noop; + animations.push( animate( this, k, keypath[k], options ) ); } } @@ -97,18 +102,23 @@ function ( } if ( complete ) { - dummyOptions.complete = function ( t ) { + promise.then( function ( t ) { complete( t, currentValues ); - }; + }); } - animations[ animations.length ] = dummy = animate( this, null, null, dummyOptions ); + dummyOptions.complete = fulfilPromise; + + dummy = animate( this, null, null, dummyOptions ); + animations.push( dummy ); } return { stop: function () { - while ( animations.length ) { - animations.pop().stop(); + var animation; + + while ( animation = animations.pop() ) { + animation.stop(); } if ( dummy ) { @@ -121,20 +131,28 @@ function ( // animate a single keypath options = options || {}; + if ( options.complete ) { + promise.then( options.complete ); + } + + options.complete = fulfilPromise; animation = animate( this, keypath, to, options ); - return { - stop: function () { - animation.stop(); - } + promise.stop = function () { + animation.stop(); }; + return promise; }; function animate ( root, keypath, to, options ) { var easing, duration, animation, from; + if ( keypath ) { + keypath = normaliseKeypath( keypath ); + } + if ( keypath !== null ) { - from = root.get( keypath ); + from = get( root, keypath ); } // cancel any existing animation @@ -144,7 +162,7 @@ function ( // don't bother animating values that stay the same if ( isEqual( from, to ) ) { if ( options.complete ) { - options.complete( 1, options.to ); + options.complete( options.to ); } return noAnimation; @@ -157,13 +175,7 @@ function ( } else { - if ( root.easing && root.easing[ options.easing ] ) { - // use instance easing function first - easing = root.easing[ options.easing ]; - } else { - // fallback to global easing functions - easing = easingRegistry[ options.easing ]; - } + easing = root.easing[ options.easing ]; } if ( typeof easing !== 'function' ) { @@ -182,6 +194,7 @@ function ( root: root, duration: duration, easing: easing, + interpolator: options.interpolator, // TODO wrap callbacks if necessary, to use instance as context step: options.step, @@ -189,9 +202,9 @@ function ( }); animations.add( animation ); - root._animations[ root._animations.length ] = animation; + root._animations.push( animation ); return animation; } -}); \ No newline at end of file +}); diff --git a/src/Ractive/prototype/detach.js b/src/Ractive/prototype/detach.js index 9eff0248d3..610ee45edc 100644 --- a/src/Ractive/prototype/detach.js +++ b/src/Ractive/prototype/detach.js @@ -6,4 +6,4 @@ define( function () { return this.fragment.detach(); }; -}); \ No newline at end of file +}); diff --git a/src/Ractive/prototype/find.js b/src/Ractive/prototype/find.js index 5854fa3b25..aca7184c13 100755 --- a/src/Ractive/prototype/find.js +++ b/src/Ractive/prototype/find.js @@ -10,4 +10,4 @@ define( function () { return this.fragment.find( selector ); }; -}); \ No newline at end of file +}); diff --git a/src/Ractive/prototype/findAll.js b/src/Ractive/prototype/findAll.js index 43a498f158..b92fc274b2 100755 --- a/src/Ractive/prototype/findAll.js +++ b/src/Ractive/prototype/findAll.js @@ -1,12 +1,6 @@ define([ - 'utils/warn', - 'utils/matches', - 'utils/defineProperties', 'Ractive/prototype/shared/makeQuery/_makeQuery' ], function ( - warn, - matches, - defineProperties, makeQuery ) { @@ -43,4 +37,4 @@ define([ return query; }; -}); \ No newline at end of file +}); diff --git a/src/Ractive/prototype/findAllComponents.js b/src/Ractive/prototype/findAllComponents.js index 885bd0d2d1..c0712ce5cd 100644 --- a/src/Ractive/prototype/findAllComponents.js +++ b/src/Ractive/prototype/findAllComponents.js @@ -1,12 +1,6 @@ define([ - 'utils/warn', - 'utils/matches', - 'utils/defineProperties', 'Ractive/prototype/shared/makeQuery/_makeQuery' ], function ( - warn, - matches, - defineProperties, makeQuery ) { @@ -39,4 +33,4 @@ define([ return query; }; -}); \ No newline at end of file +}); diff --git a/src/Ractive/prototype/findComponent.js b/src/Ractive/prototype/findComponent.js index a7e5138922..258cf60b8d 100644 --- a/src/Ractive/prototype/findComponent.js +++ b/src/Ractive/prototype/findComponent.js @@ -10,4 +10,4 @@ define([ return this.fragment.findComponent( selector ); }; -}); \ No newline at end of file +}); diff --git a/src/Ractive/prototype/fire.js b/src/Ractive/prototype/fire.js index 461c7ac61e..8b474beb7c 100755 --- a/src/Ractive/prototype/fire.js +++ b/src/Ractive/prototype/fire.js @@ -16,4 +16,4 @@ define( function () { } }; -}); \ No newline at end of file +}); diff --git a/src/Ractive/prototype/get.js b/src/Ractive/prototype/get.js new file mode 100644 index 0000000000..357a46202b --- /dev/null +++ b/src/Ractive/prototype/get.js @@ -0,0 +1,38 @@ +define([ + 'utils/normaliseKeypath', + 'shared/get/_get', + 'shared/get/UnresolvedImplicitDependency' +], function ( + normaliseKeypath, + get, + UnresolvedImplicitDependency +) { + + 'use strict'; + + var options = { isTopLevel: true }; + + return function Ractive_prototype_get ( keypath ) { + var value; + + keypath = normaliseKeypath( keypath ); + + value = get( this, keypath, options ); + + // capture the dependency, if we're inside an evaluator + if ( this._captured && ( this._captured[ keypath ] !== true ) ) { + this._captured.push( keypath ); + this._captured[ keypath ] = true; + + // if we couldn't resolve the keypath, we need to make it as a failed + // lookup, so that the evaluator updates correctly once we CAN + // resolve the keypath + if ( value === undefined && ( this._unresolvedImplicitDependencies[ keypath ] !== true ) ) { + new UnresolvedImplicitDependency( this, keypath ); + } + } + + return value; + }; + +}); diff --git a/src/Ractive/prototype/get/_get.js b/src/Ractive/prototype/get/_get.js deleted file mode 100644 index ebc1e500e2..0000000000 --- a/src/Ractive/prototype/get/_get.js +++ /dev/null @@ -1,109 +0,0 @@ -define([ - 'utils/normaliseKeypath', - 'registries/adaptors', - 'shared/adaptIfNecessary' -], function ( - normaliseKeypath, - adaptorRegistry, - adaptIfNecessary -) { - - 'use strict'; - - var get, _get, retrieve; - - - // all the logic sits in a private function, so we can do _get even when - // ractive.get() has been overridden (i.e. by an evaluator, to do intercepts) - get = function ( keypath ) { - // capture the dependency, if we're inside an evaluator - if ( this._captured && !this._captured[ keypath ] ) { - this._captured.push( keypath ); - this._captured[ keypath ] = true; - } - - return _get( this, keypath ); - }; - - _get = function ( ractive, keypath ) { - var cache, - cached, - value, - wrapped, - evaluator; - - // Normalise the keypath (i.e. list[0].foo -> list.0.foo) - keypath = normaliseKeypath( keypath ); - - cache = ractive._cache; - - if ( ( cached = cache[ keypath ] ) !== undefined ) { - return cached; - } - - // Is this a wrapped property? - if ( wrapped = ractive._wrapped[ keypath ] ) { - value = wrapped.value; - } - - // Is it the root? - else if ( !keypath ) { - adaptIfNecessary( ractive, '', ractive.data ); - value = ractive.data; - } - - // Is this an uncached evaluator value? - else if ( evaluator = ractive._evaluators[ keypath ] ) { - value = evaluator.value; - } - - // No? Then we need to retrieve the value one key at a time - else { - value = retrieve( ractive, keypath ); - } - - cache[ keypath ] = value; - return value; - }; - - - retrieve = function ( ractive, keypath ) { - var keys, key, parentKeypath, parentValue, cacheMap, value, wrapped; - - keys = keypath.split( '.' ); - key = keys.pop(); - parentKeypath = keys.join( '.' ); - - parentValue = _get( ractive, parentKeypath ); - - if ( wrapped = ractive._wrapped[ parentKeypath ] ) { - parentValue = wrapped.get(); - } - - if ( parentValue === null || parentValue === undefined ) { - return; - } - - // update cache map - if ( !( cacheMap = ractive._cacheMap[ parentKeypath ] ) ) { - ractive._cacheMap[ parentKeypath ] = [ keypath ]; - } else { - if ( cacheMap.indexOf( keypath ) === -1 ) { - cacheMap[ cacheMap.length ] = keypath; - } - } - - value = parentValue[ key ]; - - - // Do we have an adaptor for this value? - adaptIfNecessary( ractive, keypath, value ); - - // Update cache - ractive._cache[ keypath ] = value; - return value; - }; - - return get; - -}); \ No newline at end of file diff --git a/src/Ractive/prototype/get/arrayAdaptor.js b/src/Ractive/prototype/get/arrayAdaptor.js deleted file mode 100644 index c860208e00..0000000000 --- a/src/Ractive/prototype/get/arrayAdaptor.js +++ /dev/null @@ -1,342 +0,0 @@ -define([ - 'config/types', - 'utils/defineProperty', - 'utils/isArray', - 'shared/clearCache', - 'shared/preDomUpdate', - 'shared/postDomUpdate', - 'shared/makeTransitionManager', - 'shared/notifyDependants' -], function ( - types, - defineProperty, - isArray, - clearCache, - preDomUpdate, - postDomUpdate, - makeTransitionManager, - notifyDependants -) { - - 'use strict'; - - var arrayAdaptor, - - // helpers - notifyArrayDependants, - ArrayWrapper, - patchArrayMethods, - unpatchArrayMethods, - patchedArrayProto, - testObj, - mutatorMethods, - noop, - errorMessage; - - - arrayAdaptor = { - filter: function ( object ) { - // wrap the array if a) b) it's an array, and b) either it hasn't been wrapped already, - // or the array didn't trigger the get() itself - return isArray( object ) && ( !object._ractive || !object._ractive.setting ); - }, - wrap: function ( ractive, array, keypath ) { - return new ArrayWrapper( ractive, array, keypath ); - } - }; - - ArrayWrapper = function ( ractive, array, keypath ) { - this.root = ractive; - this.value = array; - this.keypath = keypath; - - // if this array hasn't already been ractified, ractify it - if ( !array._ractive ) { - - // define a non-enumerable _ractive property to store the wrappers - defineProperty( array, '_ractive', { - value: { - wrappers: [], - instances: [], - setting: false - }, - configurable: true - }); - - patchArrayMethods( array ); - } - - // store the ractive instance, so we can handle transitions later - if ( !array._ractive.instances[ ractive._guid ] ) { - array._ractive.instances[ ractive._guid ] = 0; - array._ractive.instances.push( ractive ); - } - - array._ractive.instances[ ractive._guid ] += 1; - array._ractive.wrappers.push( this ); - }; - - ArrayWrapper.prototype = { - get: function () { - return this.value; - }, - teardown: function () { - var array, storage, wrappers, instances, index; - - array = this.value; - storage = array._ractive; - wrappers = storage.wrappers; - instances = storage.instances; - - // if teardown() was invoked because we're clearing the cache as a result of - // a change that the array itself triggered, we can save ourselves the teardown - // and immediate setup - if ( storage.setting ) { - return false; // so that we don't remove it from this.root._wrapped - } - - index = wrappers.indexOf( this ); - if ( index === -1 ) { - throw new Error( errorMessage ); - } - - wrappers.splice( index, 1 ); - - // if nothing else depends on this array, we can revert it to its - // natural state - if ( !wrappers.length ) { - delete array._ractive; - unpatchArrayMethods( this.value ); - } - - else { - // remove ractive instance if possible - instances[ this.root._guid ] -= 1; - if ( !instances[ this.root._guid ] ) { - index = instances.indexOf( this.root ); - - if ( index === -1 ) { - throw new Error( errorMessage ); - } - - instances.splice( index, 1 ); - } - } - } - }; - - - notifyArrayDependants = function ( array, methodName, args ) { - var notifyKeypathDependants, - queueDependants, - wrappers, - wrapper, - i; - - notifyKeypathDependants = function ( root, keypath ) { - var depsByKeypath, deps, keys, upstreamQueue, smartUpdateQueue, dumbUpdateQueue, i, changed, start, end, childKeypath, lengthUnchanged; - - // If this is a sort or reverse, we just do root.set()... - if ( methodName === 'sort' || methodName === 'reverse' ) { - root.set( keypath, array ); - return; - } - - // ...otherwise we do a smart update whereby elements are added/removed - // in the right place. But we do need to clear the cache - clearCache( root, keypath ); - - // Find dependants. If any are DOM sections, we do a smart update - // rather than a ractive.set() blunderbuss - smartUpdateQueue = []; - dumbUpdateQueue = []; - - for ( i=0; i 2 ) && args[1] ) { - changed = Math.min( args[1], args.length - 2 ); - start = args[0]; - end = start + changed; - - if ( args[1] === ( args.length - 2 ) ) { - lengthUnchanged = true; - } - - for ( i=start; i 1 ) { - keys.pop(); - upstreamKeypath = keys.join( '.' ); - - if ( !upstreamChanges[ upstreamKeypath ] ) { - upstreamChanges[ upstreamChanges.length ] = upstreamKeypath; - upstreamChanges[ upstreamKeypath ] = true; - } - } - } - - return upstreamChanges; - }; - - - resetWrapped = function ( ractive, keypath, value, wrapped, changes ) { - var previous, cached, cacheMap, i; - - previous = wrapped.get(); - - if ( !isEqual( previous, value ) ) { - if ( wrapped.reset( value ) === false ) { - return false; - } - } - - value = wrapped.get(); - cached = ractive._cache[ keypath ]; - - if ( !isEqual( cached, value ) ) { - ractive._cache[ keypath ] = value; - - // Clear downstream keypaths only. Otherwise this wrapper will be torn down! - // TODO is there a way to intelligently detect whether a wrapper should be - // torn down? - cacheMap = ractive._cacheMap[ keypath ]; - - if ( cacheMap ) { - i = cacheMap.length; - while ( i-- ) { - clearCache( ractive, cacheMap[i] ); - } - } - - changes[ changes.length ] = keypath; - } - }; - - return set; - -}); \ No newline at end of file +}); diff --git a/src/Ractive/prototype/shared/add.js b/src/Ractive/prototype/shared/add.js index b6e99d8b42..db24705797 100644 --- a/src/Ractive/prototype/shared/add.js +++ b/src/Ractive/prototype/shared/add.js @@ -1,4 +1,8 @@ -define([ 'utils/isNumeric' ], function ( isNumeric ) { +define([ + 'utils/isNumeric' +], function ( + isNumeric +) { 'use strict'; @@ -6,26 +10,16 @@ define([ 'utils/isNumeric' ], function ( isNumeric ) { var value; if ( typeof keypath !== 'string' || !isNumeric( d ) ) { - if ( root.debug ) { - throw new Error( 'Bad arguments' ); - } - return; + throw new Error( 'Bad arguments' ); } - value = root.get( keypath ); - - if ( value === undefined ) { - value = 0; - } + value = +root.get( keypath ) || 0; if ( !isNumeric( value ) ) { - if ( root.debug ) { - throw new Error( 'Cannot add to a non-numeric value' ); - } - return; + throw new Error( 'Cannot add to a non-numeric value' ); } - root.set( keypath, value + d ); + return root.set( keypath, value + d ); }; -}); \ No newline at end of file +}); diff --git a/src/Ractive/prototype/shared/makeQuery/_makeQuery.js b/src/Ractive/prototype/shared/makeQuery/_makeQuery.js index 518e31df6f..d1b395d90c 100644 --- a/src/Ractive/prototype/shared/makeQuery/_makeQuery.js +++ b/src/Ractive/prototype/shared/makeQuery/_makeQuery.js @@ -17,9 +17,7 @@ define([ 'use strict'; return function ( ractive, selector, live, isComponentQuery ) { - var query; - - query = []; + var query = []; defineProperties( query, { selector: { value: selector }, @@ -47,4 +45,4 @@ define([ return query; }; -}); \ No newline at end of file +}); diff --git a/src/Ractive/prototype/shared/makeQuery/cancel.js b/src/Ractive/prototype/shared/makeQuery/cancel.js index f11d7f8fd0..e621ec6f32 100644 --- a/src/Ractive/prototype/shared/makeQuery/cancel.js +++ b/src/Ractive/prototype/shared/makeQuery/cancel.js @@ -16,4 +16,4 @@ define( function () { } }; -}); \ No newline at end of file +}); diff --git a/src/Ractive/prototype/shared/makeQuery/dirty.js b/src/Ractive/prototype/shared/makeQuery/dirty.js index 2be69a62cd..0f8e8fddf9 100644 --- a/src/Ractive/prototype/shared/makeQuery/dirty.js +++ b/src/Ractive/prototype/shared/makeQuery/dirty.js @@ -1,12 +1,16 @@ -define( function () { +define([ + 'global/runloop' +], function ( + runloop +) { 'use strict'; return function () { if ( !this._dirty ) { - this._root._deferred.liveQueries.push( this ); + runloop.addLiveQuery( this ); this._dirty = true; } }; -}); \ No newline at end of file +}); diff --git a/src/Ractive/prototype/shared/makeQuery/remove.js b/src/Ractive/prototype/shared/makeQuery/remove.js index 15c283f521..37cf384256 100644 --- a/src/Ractive/prototype/shared/makeQuery/remove.js +++ b/src/Ractive/prototype/shared/makeQuery/remove.js @@ -2,12 +2,12 @@ define( function () { 'use strict'; - return function ( item ) { - var index = this.indexOf( this._isComponentQuery ? item.instance : item.node ); + return function ( nodeOrComponent ) { + var index = this.indexOf( this._isComponentQuery ? nodeOrComponent.instance : nodeOrComponent ); if ( index !== -1 ) { this.splice( index, 1 ); } }; -}); \ No newline at end of file +}); diff --git a/src/Ractive/prototype/shared/makeQuery/sort.js b/src/Ractive/prototype/shared/makeQuery/sort.js index 8be9d99192..da6c00ddfa 100644 --- a/src/Ractive/prototype/shared/makeQuery/sort.js +++ b/src/Ractive/prototype/shared/makeQuery/sort.js @@ -13,4 +13,4 @@ define([ this._dirty = false; }; -}); \ No newline at end of file +}); diff --git a/src/Ractive/prototype/shared/makeQuery/sortByDocumentPosition.js b/src/Ractive/prototype/shared/makeQuery/sortByDocumentPosition.js index 107d525637..558a524e45 100644 --- a/src/Ractive/prototype/shared/makeQuery/sortByDocumentPosition.js +++ b/src/Ractive/prototype/shared/makeQuery/sortByDocumentPosition.js @@ -19,4 +19,4 @@ define([ return sortByItemPosition( node, otherNode ); }; -}); \ No newline at end of file +}); diff --git a/src/Ractive/prototype/shared/makeQuery/sortByItemPosition.js b/src/Ractive/prototype/shared/makeQuery/sortByItemPosition.js index 6f3f477e4b..5cebfdb1a6 100644 --- a/src/Ractive/prototype/shared/makeQuery/sortByItemPosition.js +++ b/src/Ractive/prototype/shared/makeQuery/sortByItemPosition.js @@ -80,4 +80,4 @@ define( function () { return ancestry; } -}); \ No newline at end of file +}); diff --git a/src/Ractive/prototype/shared/makeQuery/test.js b/src/Ractive/prototype/shared/makeQuery/test.js index f7e5032320..192a3ae003 100644 --- a/src/Ractive/prototype/shared/makeQuery/test.js +++ b/src/Ractive/prototype/shared/makeQuery/test.js @@ -20,4 +20,4 @@ define([ } }; -}); \ No newline at end of file +}); diff --git a/src/Ractive/prototype/shared/replaceData.js b/src/Ractive/prototype/shared/replaceData.js deleted file mode 100644 index bde1b4d622..0000000000 --- a/src/Ractive/prototype/shared/replaceData.js +++ /dev/null @@ -1,62 +0,0 @@ -define( function () { - - 'use strict'; - - return function ( ractive, keypath, value ) { - var keys, accumulated, wrapped, obj, key, currentKeypath, keypathToClear; - - keys = keypath.split( '.' ); - accumulated = []; - - // Get the root object - if ( wrapped = ractive._wrapped[ '' ] ) { - if ( wrapped.set ) { - // Root object is wrapped, so we need to use the wrapper's - // set() method - wrapped.set( keys.join( '.' ), value ); - } - - obj = wrapped.get(); - } else { - obj = ractive.data; - } - - - while ( keys.length > 1 ) { - key = accumulated[ accumulated.length ] = keys.shift(); - currentKeypath = accumulated.join( '.' ); - - if ( wrapped = ractive._wrapped[ currentKeypath ] ) { - if ( wrapped.set ) { - wrapped.set( keys.join( '.' ), value ); - } - - obj = wrapped.get(); - } - - else { - // If this branch doesn't exist yet, create a new one - if the next - // key matches /^\s*[0-9]+\s*$/, assume we want an array branch rather - // than an object - if ( !obj.hasOwnProperty( key ) ) { - - // if we're creating a new branch, we may need to clear the upstream - // keypath - if ( !keypathToClear ) { - keypathToClear = currentKeypath; - } - - obj[ key ] = ( /^\s*[0-9]+\s*$/.test( keys[0] ) ? [] : {} ); - } - - obj = obj[ key ]; - } - } - - key = keys[0]; - obj[ key ] = value; - - return keypathToClear; - }; - -}); \ No newline at end of file diff --git a/src/Ractive/prototype/subtract.js b/src/Ractive/prototype/subtract.js index 3f8996fd72..1fe5202fca 100644 --- a/src/Ractive/prototype/subtract.js +++ b/src/Ractive/prototype/subtract.js @@ -3,7 +3,7 @@ define([ 'Ractive/prototype/shared/add' ], function ( add ) { 'use strict'; return function ( keypath, d ) { - add( this, keypath, ( d === undefined ? -1 : -d ) ); + return add( this, keypath, ( d === undefined ? -1 : -d ) ); }; -}); \ No newline at end of file +}); diff --git a/src/Ractive/prototype/teardown.js b/src/Ractive/prototype/teardown.js index 4e7429a981..98896c58d3 100755 --- a/src/Ractive/prototype/teardown.js +++ b/src/Ractive/prototype/teardown.js @@ -1,24 +1,67 @@ // Teardown. This goes through the root fragment and all its children, removing observers // and generally cleaning up after itself define([ - 'shared/makeTransitionManager', + 'config/types', + 'global/css', + 'global/runloop', + 'utils/Promise', 'shared/clearCache' ], function ( - makeTransitionManager, + types, + css, + runloop, + Promise, clearCache ) { 'use strict'; - return function ( complete ) { - var keypath, transitionManager, previousTransitionManager; + return function ( callback ) { + var keypath, promise, fulfilPromise, shouldDestroy, originalCallback, fragment, nearestDetachingElement, unresolvedImplicitDependency; this.fire( 'teardown' ); - previousTransitionManager = this._transitionManager; - this._transitionManager = transitionManager = makeTransitionManager( this, complete ); + // If this is a component, and the component isn't marked for destruction, + // don't detach nodes from the DOM unnecessarily + shouldDestroy = !this.component || this.component.shouldDestroy; - this.fragment.teardown( true ); + if ( this.constructor.css ) { + // We need to find the nearest detaching element. When it gets removed + // from the DOM, it's safe to remove our CSS + if ( shouldDestroy ) { + originalCallback = callback; + callback = function () { + if ( originalCallback ) { + originalCallback.call( this ); + } + + css.remove( this.constructor ); + }; + } else { + fragment = this.component.parentFragment; + + do { + if ( fragment.owner.type !== types.ELEMENT ) { + continue; + } + + if ( fragment.owner.willDetach ) { + nearestDetachingElement = fragment.owner; + } + } while ( !nearestDetachingElement && ( fragment = fragment.parent ) ); + + if ( !nearestDetachingElement ) { + throw new Error( 'A component is being torn down but doesn\'t have a nearest detaching element... this shouldn\'t happen!' ); + } + + nearestDetachingElement.cssDetachQueue.push( this.constructor ); + } + } + + promise = new Promise( function ( fulfil ) { fulfilPromise = fulfil; }); + runloop.start( this, fulfilPromise ); + + this.fragment.teardown( shouldDestroy ); // Cancel any animations in progress while ( this._animations[0] ) { @@ -30,9 +73,18 @@ define([ clearCache( this, keypath ); } - // transition manager has finished its work - this._transitionManager = previousTransitionManager; - transitionManager.ready(); + // Teardown any failed lookups - we don't need them to resolve any more + while ( unresolvedImplicitDependency = this._unresolvedImplicitDependencies.pop() ) { + unresolvedImplicitDependency.teardown(); + } + + runloop.end(); + + if ( callback ) { + promise.then( callback.bind( this ) ); + } + + return promise; }; -}); \ No newline at end of file +}); diff --git a/src/Ractive/prototype/toHTML.js b/src/Ractive/prototype/toHTML.js index 079874bb06..d52bdca51c 100644 --- a/src/Ractive/prototype/toHTML.js +++ b/src/Ractive/prototype/toHTML.js @@ -6,4 +6,4 @@ define( function () { return this.fragment.toString(); }; -}); \ No newline at end of file +}); diff --git a/src/Ractive/prototype/toggle.js b/src/Ractive/prototype/toggle.js index ebeee5038e..b261a8d072 100644 --- a/src/Ractive/prototype/toggle.js +++ b/src/Ractive/prototype/toggle.js @@ -2,7 +2,7 @@ define( function () { 'use strict'; - return function ( keypath ) { + return function ( keypath, callback ) { var value; if ( typeof keypath !== 'string' ) { @@ -13,7 +13,7 @@ define( function () { } value = this.get( keypath ); - this.set( keypath, !value ); + return this.set( keypath, !value, callback ); }; -}); \ No newline at end of file +}); diff --git a/src/Ractive/prototype/update.js b/src/Ractive/prototype/update.js index 35b87c3e79..01249cc37c 100755 --- a/src/Ractive/prototype/update.js +++ b/src/Ractive/prototype/update.js @@ -1,51 +1,42 @@ define([ - 'shared/makeTransitionManager', - 'shared/attemptKeypathResolution', + 'global/runloop', + 'utils/Promise', 'shared/clearCache', - 'shared/notifyDependants', - 'shared/processDeferredUpdates' + 'shared/notifyDependants' ], function ( - makeTransitionManager, - attemptKeypathResolution, + runloop, + Promise, clearCache, - notifyDependants, - processDeferredUpdates + notifyDependants ) { 'use strict'; - return function ( keypath, complete ) { - var transitionManager, previousTransitionManager; + return function ( keypath, callback ) { + var promise, fulfilPromise; if ( typeof keypath === 'function' ) { - complete = keypath; + callback = keypath; keypath = ''; + } else { + keypath = keypath || ''; } - // manage transitions - previousTransitionManager = this._transitionManager; - this._transitionManager = transitionManager = makeTransitionManager( this, complete ); - - // if we're using update, it's possible that we've introduced new values, and - // some unresolved references can be dealt with - attemptKeypathResolution( this ); + promise = new Promise( function ( fulfil ) { fulfilPromise = fulfil; }); + runloop.start( this, fulfilPromise ); - clearCache( this, keypath || '' ); - notifyDependants( this, keypath || '' ); + clearCache( this, keypath ); + notifyDependants( this, keypath ); - processDeferredUpdates( this ); + runloop.end(); - // transition manager has finished its work - this._transitionManager = previousTransitionManager; - transitionManager.ready(); + this.fire( 'update', keypath ); - if ( typeof keypath === 'string' ) { - this.fire( 'update', keypath ); - } else { - this.fire( 'update' ); + if ( callback ) { + promise.then( callback.bind( this ) ); } - return this; + return promise; }; -}); \ No newline at end of file +}); diff --git a/src/Ractive/prototype/updateModel.js b/src/Ractive/prototype/updateModel.js index b9fc2b9631..58d0df4060 100755 --- a/src/Ractive/prototype/updateModel.js +++ b/src/Ractive/prototype/updateModel.js @@ -10,7 +10,7 @@ define([ 'use strict'; - return function ( keypath, cascade ) { + return function Ractive_prototype_updateModel ( keypath, cascade ) { var values, deferredCheckboxes, i; if ( typeof keypath !== 'string' ) { @@ -47,11 +47,11 @@ define([ // special case - checkbox name bindings if ( binding.checkboxName ) { - if ( binding.changed() && !deferredCheckboxes[ keypath ] ) { + if ( binding.changed() && ( deferredCheckboxes[ keypath ] !== true ) ) { // we will need to see which checkboxes with the same name are checked, // but we only want to do so once deferredCheckboxes[ keypath ] = true; // for quick lookup without indexOf - deferredCheckboxes[ deferredCheckboxes.length ] = keypath; + deferredCheckboxes.push( keypath ); } continue; @@ -85,4 +85,4 @@ define([ } } -}); \ No newline at end of file +}); diff --git a/src/circular.js b/src/circular.js index c335360286..1531b457d3 100644 --- a/src/circular.js +++ b/src/circular.js @@ -6,4 +6,4 @@ define( function () { return []; -}); \ No newline at end of file +}); diff --git a/src/config/errors.js b/src/config/errors.js index 664d371d5b..cf2d414ba7 100644 --- a/src/config/errors.js +++ b/src/config/errors.js @@ -1,3 +1,3 @@ define({ missingParser: 'Missing Ractive.parse - cannot parse template. Either preparse or use the version that includes the parser' -}); \ No newline at end of file +}); diff --git a/src/config/initOptions.js b/src/config/initOptions.js new file mode 100644 index 0000000000..b6f8d5dfde --- /dev/null +++ b/src/config/initOptions.js @@ -0,0 +1,39 @@ +define([ + 'legacy' // for Object.keys polyfill +], function () { + + 'use strict'; + + var defaults, initOptions; + + defaults = { + el: null, + template: '', + complete: null, + preserveWhitespace: false, + append: false, + twoway: true, + modifyArrays: true, + lazy: false, + debug: false, + noIntro: false, + transitionsEnabled: true, + magic: false, + noCssTransform: false, + adapt: [], + sanitize: false, + stripComments: true, + isolated: false, + delimiters: [ '{{', '}}' ], + tripleDelimiters: [ '{{{', '}}}' ], + computed: null + }; + + initOptions = { + keys: Object.keys( defaults ), + defaults: defaults + }; + + return initOptions; + +}); diff --git a/src/config/isClient.js b/src/config/isClient.js index 1d3f710b01..0e853ebbfc 100644 --- a/src/config/isClient.js +++ b/src/config/isClient.js @@ -2,10 +2,6 @@ define( function () { 'use strict'; - if ( typeof document === 'object' ) { - return true; - } + return ( typeof document === 'object' ); - return false; - -}); \ No newline at end of file +}); diff --git a/src/config/namespaces.js b/src/config/namespaces.js index 5dcb45b399..bb7ddf81f7 100644 --- a/src/config/namespaces.js +++ b/src/config/namespaces.js @@ -5,4 +5,4 @@ define({ xlink: 'http://www.w3.org/1999/xlink', xml: 'http://www.w3.org/XML/1998/namespace', xmlns: 'http://www.w3.org/2000/xmlns/' -}); \ No newline at end of file +}); diff --git a/src/config/registries.js b/src/config/registries.js new file mode 100644 index 0000000000..283acd1022 --- /dev/null +++ b/src/config/registries.js @@ -0,0 +1,17 @@ +define( function () { + + 'use strict'; + + return [ + 'adaptors', + 'components', + 'decorators', + 'easing', + 'events', + 'interpolators', + 'partials', + 'transitions', + 'data' + ]; + +}); diff --git a/src/config/svg.js b/src/config/svg.js index 90018495b1..8d23e2f876 100644 --- a/src/config/svg.js +++ b/src/config/svg.js @@ -8,4 +8,4 @@ define( function () { return document && document.implementation.hasFeature( 'http://www.w3.org/TR/SVG11/feature#BasicStructure', '1.1' ); -}); \ No newline at end of file +}); diff --git a/src/config/types.js b/src/config/types.js index 9449455083..26db01a9f1 100644 --- a/src/config/types.js +++ b/src/config/types.js @@ -34,4 +34,4 @@ define({ INFIX_OPERATOR : 36, INVOCATION : 40 -}); \ No newline at end of file +}); diff --git a/src/config/vendors.js b/src/config/vendors.js new file mode 100644 index 0000000000..0ee7c8f96e --- /dev/null +++ b/src/config/vendors.js @@ -0,0 +1,7 @@ +define( function () { + + 'use strict'; + + return [ 'o', 'ms', 'moz', 'webkit' ]; + +}); diff --git a/src/config/voidElementNames.js b/src/config/voidElementNames.js index 5ab7aacb4c..05e004f092 100644 --- a/src/config/voidElementNames.js +++ b/src/config/voidElementNames.js @@ -4,4 +4,4 @@ define( function () { return 'area base br col command doctype embed hr img input keygen link meta param source track wbr'.split( ' ' ); -}); \ No newline at end of file +}); diff --git a/src/empty/README.md b/src/empty/README.md new file mode 100644 index 0000000000..ef78f005e9 --- /dev/null +++ b/src/empty/README.md @@ -0,0 +1 @@ +Empty modules allow us to exclude certain code from the build, e.g. excluding the parse module when building the runtime version. Unfortunately it looks as though we need to have an empty module for each module we're stubbing out, otherwise the build fails... something to put on the TODO list diff --git a/src/empty/legacy.js b/src/empty/legacy.js new file mode 100644 index 0000000000..2f28b5d186 --- /dev/null +++ b/src/empty/legacy.js @@ -0,0 +1 @@ +define( function () {}); diff --git a/src/empty/parse.js b/src/empty/parse.js new file mode 100644 index 0000000000..2f28b5d186 --- /dev/null +++ b/src/empty/parse.js @@ -0,0 +1 @@ +define( function () {}); diff --git a/src/extend/_extend.js b/src/extend/_extend.js index e134ea2b6e..2174b4e9cb 100644 --- a/src/extend/_extend.js +++ b/src/extend/_extend.js @@ -1,5 +1,8 @@ define([ 'utils/create', + 'utils/defineProperties', + 'utils/getGuid', + 'utils/extend', 'extend/inheritFromParent', 'extend/inheritFromChildProps', 'extend/extractInlinePartials', @@ -9,6 +12,9 @@ define([ 'circular' ], function ( create, + defineProperties, + getGuid, + extendObject, inheritFromParent, inheritFromChildProps, extractInlinePartials, @@ -26,9 +32,15 @@ define([ Ractive = circular.Ractive; }); - return function ( childProps ) { + return function extend ( childProps ) { - var Parent = this, Child; + var Parent = this, Child, adaptor, i; + + // if we're extending with another Ractive instance, inherit its + // prototype methods and default options as well + if ( childProps.prototype instanceof Ractive ) { + childProps = ( extendObject( {}, childProps, childProps.prototype, childProps.defaults ) ); + } // create Child constructor Child = function ( options ) { @@ -38,20 +50,37 @@ define([ Child.prototype = create( Parent.prototype ); Child.prototype.constructor = Child; + defineProperties( Child, { + extend: { value: Parent.extend }, + + // each component needs a guid, for managing CSS etc + _guid: { value: getGuid() } + }); + // Inherit options from parent inheritFromParent( Child, Parent ); // Add new prototype methods and init options inheritFromChildProps( Child, childProps ); - // Parse template and any partials that need it - conditionallyParseTemplate( Child ); - extractInlinePartials( Child, childProps ); - conditionallyParsePartials( Child ); + // Special case - adaptors. Convert to function if possible + if ( Child.adaptors && ( i = Child.defaults.adapt.length ) ) { + while ( i-- ) { + adaptor = Child.defaults.adapt[i]; + if ( typeof adaptor === 'string' ) { + Child.defaults.adapt[i] = Child.adaptors[ adaptor ] || adaptor; + } + } + } - Child.extend = Parent.extend; + // Parse template and any partials that need it + if ( childProps.template ) { // ignore inherited templates! + conditionallyParseTemplate( Child ); + extractInlinePartials( Child, childProps ); + conditionallyParsePartials( Child ); + } return Child; }; -}); \ No newline at end of file +}); diff --git a/src/extend/conditionallyParsePartials.js b/src/extend/conditionallyParsePartials.js index 6e085f7acf..9fa60a030e 100644 --- a/src/extend/conditionallyParsePartials.js +++ b/src/extend/conditionallyParsePartials.js @@ -25,4 +25,4 @@ define([ } }; -}); \ No newline at end of file +}); diff --git a/src/extend/conditionallyParseTemplate.js b/src/extend/conditionallyParseTemplate.js index b356bb704e..40f00aa270 100644 --- a/src/extend/conditionallyParseTemplate.js +++ b/src/extend/conditionallyParseTemplate.js @@ -13,22 +13,22 @@ define([ return function ( Child ) { var templateEl; - if ( typeof Child.template === 'string' ) { + if ( typeof Child.defaults.template === 'string' ) { if ( !parse ) { throw new Error( errors.missingParser ); } - if ( Child.template.charAt( 0 ) === '#' && isClient ) { - templateEl = document.getElementById( Child.template.substring( 1 ) ); + if ( Child.defaults.template.charAt( 0 ) === '#' && isClient ) { + templateEl = document.getElementById( Child.defaults.template.substring( 1 ) ); if ( templateEl && templateEl.tagName === 'SCRIPT' ) { - Child.template = parse( templateEl.innerHTML, Child ); + Child.defaults.template = parse( templateEl.innerHTML, Child ); } else { - throw new Error( 'Could not find template element (' + Child.template + ')' ); + throw new Error( 'Could not find template element (' + Child.defaults.template + ')' ); } } else { - Child.template = parse( Child.template, Child ); // all the relevant options are on Child + Child.defaults.template = parse( Child.defaults.template, Child.defaults ); // all the relevant options are on Child.defaults } } }; -}); \ No newline at end of file +}); diff --git a/src/extend/extractInlinePartials.js b/src/extend/extractInlinePartials.js index e573c9256f..b622ab8573 100644 --- a/src/extend/extractInlinePartials.js +++ b/src/extend/extractInlinePartials.js @@ -10,13 +10,13 @@ define([ return function ( Child, childProps ) { // does our template contain inline partials? - if ( isObject( Child.template ) ) { + if ( isObject( Child.defaults.template ) ) { if ( !Child.partials ) { Child.partials = {}; } // get those inline partials - augment( Child.partials, Child.template.partials ); + augment( Child.partials, Child.defaults.template.partials ); // but we also need to ensure that any explicit partials override inline ones if ( childProps.partials ) { @@ -24,8 +24,8 @@ define([ } // move template to where it belongs - Child.template = Child.template.main; + Child.defaults.template = Child.defaults.template.main; } }; -}); \ No newline at end of file +}); diff --git a/src/extend/inheritFromChildProps.js b/src/extend/inheritFromChildProps.js index d0f9b0a150..30c5af3bf5 100644 --- a/src/extend/inheritFromChildProps.js +++ b/src/extend/inheritFromChildProps.js @@ -1,22 +1,23 @@ define([ - 'extend/registries', - 'extend/initOptions', + 'config/initOptions', + 'config/registries', + 'utils/defineProperty', 'extend/wrapMethod', - 'extend/utils/augment' + 'extend/utils/augment', + 'extend/utils/transformCss' ], function ( - registries, initOptions, + registries, + defineProperty, wrapMethod, - augment + augment, + transformCss ) { 'use strict'; - var blacklist, blacklisted; - - blacklist = registries.concat( initOptions ); - blacklisted = {}; - blacklist.forEach( function ( property ) { + var blacklisted = {}; + registries.concat( initOptions.keys ).forEach( function ( property ) { blacklisted[ property ] = true; }); @@ -38,21 +39,21 @@ define([ } }); - initOptions.forEach( function ( property ) { - var value = childProps[ property ]; + initOptions.keys.forEach( function ( key ) { + var value = childProps[ key ]; if ( value !== undefined ) { // we may need to wrap a function (e.g. the `complete` option) - if ( typeof value === 'function' && typeof Child[ property ] === 'function' ) { - Child[ property ] = wrapMethod( value, Child[ property ] ); + if ( typeof value === 'function' && typeof Child[ key ] === 'function' ) { + Child.defaults[ key ] = wrapMethod( value, Child[ key ] ); } else { - Child[ property ] = childProps[ property ]; + Child.defaults[ key ] = childProps[ key ]; } } }); for ( key in childProps ) { - if ( childProps.hasOwnProperty( key ) && !blacklisted[ key ] ) { + if ( !blacklisted[ key ] && childProps.hasOwnProperty( key ) ) { member = childProps[ key ]; // if this is a method that overwrites a prototype method, we may need @@ -64,6 +65,15 @@ define([ } } } + + // Special case - CSS + if ( childProps.css ) { + defineProperty( Child, 'css', { + value: Child.defaults.noCssTransform + ? childProps.css + : transformCss( childProps.css, Child._guid ) + }); + } }; -}); \ No newline at end of file +}); diff --git a/src/extend/inheritFromParent.js b/src/extend/inheritFromParent.js index 48b8be3c1f..9d2524859e 100644 --- a/src/extend/inheritFromParent.js +++ b/src/extend/inheritFromParent.js @@ -1,11 +1,13 @@ define([ - 'extend/registries', - 'extend/initOptions', - 'utils/create' + 'config/registries', + 'utils/create', + 'utils/defineProperty', + 'extend/utils/transformCss' ], function ( registries, - initOptions, - create + create, + defineProperty, + transformCss ) { 'use strict'; @@ -20,9 +22,18 @@ define([ } }); - initOptions.forEach( function ( property ) { - Child[ property ] = Parent[ property ]; + defineProperty( Child, 'defaults', { + value: create( Parent.defaults ) }); + + // Special case - CSS + if ( Parent.css ) { + defineProperty( Child, 'css', { + value: Parent.defaults.noCssTransform + ? Parent.css + : transformCss( Parent.css, Child._guid ) + }); + } }; -}); \ No newline at end of file +}); diff --git a/src/extend/initChildInstance.js b/src/extend/initChildInstance.js index 477a932506..a48e07f701 100644 --- a/src/extend/initChildInstance.js +++ b/src/extend/initChildInstance.js @@ -1,13 +1,9 @@ define([ - 'utils/fillGaps', - 'extend/initOptions', - 'extend/utils/clone', + 'config/initOptions', 'extend/wrapMethod', 'Ractive/initialise' ], function ( - fillGaps, initOptions, - clone, wrapMethod, initialise ) { @@ -16,17 +12,13 @@ define([ // The Child constructor contains the default init options for this class - return function ( child, Child, options ) { + return function initChildInstance ( child, Child, options ) { - initOptions.forEach( function ( property ) { - var value = options[ property ], defaultValue = Child[ property ]; + initOptions.keys.forEach( function ( key ) { + var value = options[ key ], defaultValue = Child.defaults[ key ]; if ( typeof value === 'function' && typeof defaultValue === 'function' ) { - options[ property ] = wrapMethod( value, defaultValue ); - } - - else if ( value === undefined && defaultValue !== undefined ) { - options[ property ] = defaultValue; + options[ key ] = wrapMethod( value, defaultValue ); } }); @@ -36,9 +28,16 @@ define([ initialise( child, options ); - if ( child.init ) { + // If this is an inline component (i.e. NOT created with `var widget = new Widget()`, + // but rather `` or similar), we don't want to call the `init` method until + // the component is in the DOM. That makes it easier for component authors to do stuff + // like `this.width = this.find('*').clientWidth` or whatever without using + // ugly setTimeout hacks. + if ( options._parent && options._parent._rendering ) { + options._parent._childInitQueue.push({ instance: child, options: options }); + } else if ( child.init ) { child.init( options ); } }; -}); \ No newline at end of file +}); diff --git a/src/extend/initOptions.js b/src/extend/initOptions.js deleted file mode 100644 index d778e1ed64..0000000000 --- a/src/extend/initOptions.js +++ /dev/null @@ -1,22 +0,0 @@ -define( function () { - - 'use strict'; - - return [ - 'el', - 'template', - 'complete', - 'modifyArrays', - 'magic', - 'twoway', - 'lazy', - 'append', - 'preserveWhitespace', - 'sanitize', - 'stripComments', - 'noIntro', - 'transitionsEnabled', - 'adaptors' - ]; - -}); \ No newline at end of file diff --git a/src/extend/registries.js b/src/extend/registries.js deleted file mode 100644 index 710937b33d..0000000000 --- a/src/extend/registries.js +++ /dev/null @@ -1,7 +0,0 @@ -define( function () { - - 'use strict'; - - return [ 'partials', 'transitions', 'events', 'components', 'decorators', 'data' ]; - -}); \ No newline at end of file diff --git a/src/extend/utils/augment.js b/src/extend/utils/augment.js index d45eb74cd8..bedda5ee35 100644 --- a/src/extend/utils/augment.js +++ b/src/extend/utils/augment.js @@ -14,4 +14,4 @@ define( function () { return target; }; -}); \ No newline at end of file +}); diff --git a/src/extend/utils/clone.js b/src/extend/utils/clone.js deleted file mode 100644 index d95e0ebdab..0000000000 --- a/src/extend/utils/clone.js +++ /dev/null @@ -1,17 +0,0 @@ -define( function () { - - 'use strict'; - - return function ( source ) { - var target = {}, key; - - for ( key in source ) { - if ( source.hasOwnProperty( key ) ) { - target[ key ] = source[ key ]; - } - } - - return target; - }; - -}); \ No newline at end of file diff --git a/src/extend/utils/transformCss.js b/src/extend/utils/transformCss.js new file mode 100644 index 0000000000..fe94b80af9 --- /dev/null +++ b/src/extend/utils/transformCss.js @@ -0,0 +1,73 @@ +define( function () { + + 'use strict'; + + var selectorsPattern = /(?:^|\})?\s*([^\{\}]+)\s*\{/g, + commentsPattern = /\/\*.*?\*\//g, + selectorUnitPattern = /((?:(?:\[[^\]+]\])|(?:[^\s\+\>\~:]))+)((?::[^\s\+\>\~]+)?\s*[\s\+\>\~]?)\s*/g; + + return function transformCss( css, guid ) { + var transformed, addGuid; + + addGuid = function ( selector ) { + var selectorUnits, match, unit, dataAttr, base, prepended, appended, i, transformed = []; + + selectorUnits = []; + + while ( match = selectorUnitPattern.exec( selector ) ) { + selectorUnits.push({ + str: match[0], + base: match[1], + modifiers: match[2] + }); + } + + // For each simple selector within the selector, we need to create a version + // that a) combines with the guid, and b) is inside the guid + dataAttr = '[data-rvcguid="' + guid + '"]'; + base = selectorUnits.map( extractString ); + + i = selectorUnits.length; + while ( i-- ) { + appended = base.slice(); + + // Pseudo-selectors should go after the attribute selector + unit = selectorUnits[i]; + appended[i] = unit.base + dataAttr + unit.modifiers || ''; + + prepended = base.slice(); + prepended[i] = dataAttr + ' ' + prepended[i]; + + transformed.push( appended.join( ' ' ), prepended.join( ' ' ) ); + } + + return transformed.join( ', ' ); + }; + + transformed = css + .replace( commentsPattern, '' ) + .replace( selectorsPattern, function ( match, $1 ) { + var selectors, transformed; + + selectors = $1.split( ',' ).map( trim ); + transformed = selectors.map( addGuid ).join( ', ' ) + ' '; + + return match.replace( $1, transformed ); + }); + + return transformed; + }; + + function trim ( str ) { + if ( str.trim ) { + return str.trim(); + } + + return str.replace( /^\s+/, '' ).replace( /\s+$/, '' ); + } + + function extractString ( unit ) { + return unit.str; + } + +}); diff --git a/src/extend/wrapMethod.js b/src/extend/wrapMethod.js index 405b2b5866..fd614ad57f 100644 --- a/src/extend/wrapMethod.js +++ b/src/extend/wrapMethod.js @@ -20,4 +20,4 @@ define( function () { } }; -}); \ No newline at end of file +}); diff --git a/src/global/css.js b/src/global/css.js new file mode 100644 index 0000000000..467ed56172 --- /dev/null +++ b/src/global/css.js @@ -0,0 +1,97 @@ +define([ + 'circular', + 'config/isClient', + 'utils/removeFromArray' +], function ( + circular, + isClient, + removeFromArray +) { + + 'use strict'; + + var runloop, + styleElement, + head, + styleSheet, + inDom, + prefix = '/* Ractive.js component styles */\n', + componentsInPage = {}, + styles = []; + + if ( !isClient ) { + return; + } + + circular.push( function () { + runloop = circular.runloop; + }); + + styleElement = document.createElement( 'style' ); + styleElement.type = 'text/css'; + + head = document.getElementsByTagName( 'head' )[0]; + + inDom = false; + + // Internet Exploder won't let you use styleSheet.innerHTML - we have to + // use styleSheet.cssText instead + styleSheet = styleElement.styleSheet; + + return { + add: function ( Component ) { + if ( !Component.css ) { + return; + } + + if ( !componentsInPage[ Component._guid ] ) { + // we create this counter so that we can in/decrement it as + // instances are added and removed. When all components are + // removed, the style is too + componentsInPage[ Component._guid ] = 0; + styles.push( Component.css ); + + runloop.scheduleCssUpdate(); + } + + componentsInPage[ Component._guid ] += 1; + }, + + remove: function ( Component ) { + if ( !Component.css ) { + return; + } + + componentsInPage[ Component._guid ] -= 1; + + if ( !componentsInPage[ Component._guid ] ) { + removeFromArray( styles, Component.css ); + + runloop.scheduleCssUpdate(); + } + }, + + update: function () { + var css; + + if ( styles.length ) { + css = prefix + styles.join( ' ' ); + + if ( styleSheet ) { + styleSheet.cssText = css; + } else { + styleElement.innerHTML = css; + } + + if ( !inDom ) { + head.appendChild( styleElement ); + } + } + + else if ( inDom ) { + head.removeChild( styleElement ); + } + } + }; + +}); diff --git a/src/global/runloop.js b/src/global/runloop.js new file mode 100644 index 0000000000..b87f3c4bc1 --- /dev/null +++ b/src/global/runloop.js @@ -0,0 +1,313 @@ +define([ + 'circular', + 'global/css', + 'utils/removeFromArray', + 'shared/getValueFromCheckboxes', + 'shared/resolveRef', + 'shared/getUpstreamChanges', + 'shared/notifyDependants', + 'shared/makeTransitionManager' +], function ( + circular, + css, + removeFromArray, + getValueFromCheckboxes, + resolveRef, + getUpstreamChanges, + notifyDependants, + makeTransitionManager +) { + + 'use strict'; + + circular.push( function () { + get = circular.get; + set = circular.set; + }); + + var runloop, + get, + set, + + dirty = false, + flushing = false, + pendingCssChanges, + inFlight = 0, + toFocus = null, + + liveQueries = [], + decorators = [], + transitions = [], + observers = [], + attributes = [], + activeBindings = [], + + evaluators = [], + computations = [], + selectValues = [], + checkboxKeypaths = {}, + checkboxes = [], + radios = [], + unresolved = [], + + instances = [], + transitionManager; + + runloop = { + start: function ( instance, callback ) { + this.addInstance( instance ); + + if ( !flushing ) { + inFlight += 1; + + // create a new transition manager + transitionManager = makeTransitionManager( callback, transitionManager ); + } + }, + + end: function () { + if ( flushing ) { + attemptKeypathResolution(); + return; + } + + if ( !--inFlight ) { + flushing = true; + flushChanges(); + flushing = false; + + land(); + } + + transitionManager.init(); + transitionManager = transitionManager._previous; + }, + + trigger: function () { + if ( inFlight || flushing ) { + attemptKeypathResolution(); + return; + } + + flushing = true; + flushChanges(); + flushing = false; + + land(); + }, + + focus: function ( node ) { + toFocus = node; + }, + + addInstance: function ( instance ) { + if ( instance && !instances[ instance._guid ] ) { + instances.push( instance ); + instances[ instances._guid ] = true; + } + }, + + addLiveQuery: function ( query ) { + liveQueries.push( query ); + }, + + addDecorator: function ( decorator ) { + decorators.push( decorator ); + }, + + addTransition: function ( transition ) { + transition._manager = transitionManager; + transitionManager.push( transition ); + transitions.push( transition ); + }, + + addObserver: function ( observer ) { + observers.push( observer ); + }, + + addAttribute: function ( attribute ) { + attributes.push( attribute ); + }, + + addBinding: function ( binding ) { + binding.active = true; + activeBindings.push( binding ); + }, + + scheduleCssUpdate: function () { + // if runloop isn't currently active, we need to trigger change immediately + if ( !inFlight && !flushing ) { + // TODO does this ever happen? + css.update(); + } else { + pendingCssChanges = true; + } + }, + + // changes that may cause additional changes... + addEvaluator: function ( evaluator ) { + dirty = true; + evaluators.push( evaluator ); + }, + + addComputation: function ( thing ) { + dirty = true; + computations.push( thing ); + }, + + addSelectValue: function ( selectValue ) { + dirty = true; + selectValues.push( selectValue ); + }, + + addCheckbox: function ( checkbox ) { + if ( !checkboxKeypaths[ checkbox.keypath ] ) { + dirty = true; + checkboxes.push( checkbox ); + } + }, + + addRadio: function ( radio ) { + dirty = true; + radios.push( radio ); + }, + + addUnresolved: function ( thing ) { + dirty = true; + unresolved.push( thing ); + }, + + removeUnresolved: function ( thing ) { + removeFromArray( unresolved, thing ); + }, + + // synchronise node detachments with transition ends + detachWhenReady: function ( thing ) { + transitionManager.detachQueue.push( thing ); + } + }; + + circular.runloop = runloop; + return runloop; + + + function land () { + var thing, changedKeypath, changeHash; + + if ( toFocus ) { + toFocus.focus(); + toFocus = null; + } + + while ( thing = attributes.pop() ) { + thing.update().deferred = false; + } + + while ( thing = liveQueries.pop() ) { + thing._sort(); + } + + while ( thing = decorators.pop() ) { + thing.init(); + } + + while ( thing = transitions.pop() ) { + thing.init(); + } + + while ( thing = observers.pop() ) { + thing.update(); + } + + while ( thing = activeBindings.pop() ) { + thing.active = false; + } + + // Change events are fired last + while ( thing = instances.pop() ) { + instances[ thing._guid ] = false; + + if ( thing._changes.length ) { + changeHash = {}; + + while ( changedKeypath = thing._changes.pop() ) { + changeHash[ changedKeypath ] = get( thing, changedKeypath ); + } + + thing.fire( 'change', changeHash ); + } + } + + if ( pendingCssChanges ) { + css.update(); + pendingCssChanges = false; + } + } + + function flushChanges () { + var thing, upstreamChanges, i; + + i = instances.length; + while ( i-- ) { + thing = instances[i]; + + if ( thing._changes.length ) { + upstreamChanges = getUpstreamChanges( thing._changes ); + notifyDependants.multiple( thing, upstreamChanges, true ); + } + } + + attemptKeypathResolution(); + + while ( dirty ) { + dirty = false; + + while ( thing = computations.pop() ) { + thing.update(); + } + + while ( thing = evaluators.pop() ) { + thing.update().deferred = false; + } + + while ( thing = selectValues.pop() ) { + thing.deferredUpdate(); + } + + while ( thing = checkboxes.pop() ) { + set( thing.root, thing.keypath, getValueFromCheckboxes( thing.root, thing.keypath ) ); + } + + while ( thing = radios.pop() ) { + thing.update(); + } + } + } + + function attemptKeypathResolution () { + var array, thing, keypath; + + if ( !unresolved.length ) { + return; + } + + // see if we can resolve any unresolved references + array = unresolved.splice( 0, unresolved.length ); + while ( thing = array.pop() ) { + if ( thing.keypath ) { + continue; // it did resolve after all. TODO does this ever happen? + } + + keypath = resolveRef( thing.root, thing.ref, thing.parentFragment ); + + if ( keypath !== undefined ) { + // If we've resolved the keypath, we can initialise this item + thing.resolve( keypath ); + } else { + // If we can't resolve the reference, try again next time + unresolved.push( thing ); + } + } + } + +}); diff --git a/src/legacy.js b/src/legacy.js index ac309a7eb7..7b52212088 100755 --- a/src/legacy.js +++ b/src/legacy.js @@ -1,8 +1,16 @@ -(function ( win ) { +define( function () { 'use strict'; - var doc = win.document; + var win, doc, exportedShims; + + if ( typeof window === 'undefined' ) { + return; + } + + win = window; + doc = win.document; + exportedShims = {}; if ( !doc ) { return; @@ -105,11 +113,20 @@ if ( !Array.prototype.map ) { Array.prototype.map = function ( mapper, context ) { - var i, len, mapped = []; + var array = this, i, len, mapped = [], isActuallyString; + + // incredibly, if you do something like + // Array.prototype.map.call( someString, iterator ) + // then `this` will become an instance of String in IE8. + // And in IE8, you then can't do string[i]. Facepalm. + if ( array instanceof String ) { + array = array.toString(); + isActuallyString = true; + } - for ( i=0, len=this.length; i 1 ) { + value = opt_initialValue; + valueIsSet = true; + } + + for ( i = 0; i < len; i += 1) { + if ( this.hasOwnProperty( i ) ) { + if ( valueIsSet ) { + value = callback(value, this[i], i, this); + } + } else { + value = this[i]; + valueIsSet = true; + } + } + + if ( !valueIsSet ) { + throw new TypeError( 'Reduce of empty array with no initial value' ); + } + + return value; + }; + } + if ( !Array.prototype.filter ) { Array.prototype.filter = function ( filter, context ) { var i, len, filtered = []; @@ -132,6 +184,31 @@ } + if ( typeof Function.prototype.bind !== 'function' ) { + Function.prototype.bind = function ( context ) { + var args, fn, Empty, bound, slice = [].slice; + + if ( typeof this !== 'function' ) { + throw new TypeError( 'Function.prototype.bind called on non-function' ); + } + + args = slice.call( arguments, 1 ); + fn = this; + Empty = function () {}; + + bound = function () { + var ctx = this instanceof Empty && context ? this : context; + return fn.apply( ctx, args.concat( slice.call( arguments ) ) ); + }; + + Empty.prototype = this.prototype; + bound.prototype = new Empty(); + + return bound; + }; + } + + // https://gist.github.com/Rich-Harris/6010282 via https://gist.github.com/jonathantneal/2869388 // addEventListener polyfill IE6+ @@ -221,9 +298,12 @@ } + // The getComputedStyle polyfill interacts badly with jQuery, so we don't attach + // it to window. Instead, we export it for other modules to use as needed + // https://github.com/jonathantneal/Polyfills-for-IE8/blob/master/getComputedStyle.js if ( !win.getComputedStyle ) { - win.getComputedStyle = (function () { + exportedShims.getComputedStyle = (function () { function getPixelSize(element, style, property, fontSize) { var sizeWithSuffix = style[property], @@ -297,4 +377,6 @@ }()); } -}( typeof window !== 'undefined' ? window : this )); + return exportedShims; + +}); diff --git a/src/parse/Parser/StringStub/StringParser.js b/src/parse/Parser/StringStub/StringParser.js index 4a4703e4a1..ec28d3e97b 100644 --- a/src/parse/Parser/StringStub/StringParser.js +++ b/src/parse/Parser/StringStub/StringParser.js @@ -45,4 +45,4 @@ define([ return StringParser; -}); \ No newline at end of file +}); diff --git a/src/parse/Parser/StringStub/_StringStub.js b/src/parse/Parser/StringStub/_StringStub.js index 5a7166e108..a78a73a4fc 100644 --- a/src/parse/Parser/StringStub/_StringStub.js +++ b/src/parse/Parser/StringStub/_StringStub.js @@ -41,4 +41,4 @@ define([ return StringStub; -}); \ No newline at end of file +}); diff --git a/src/parse/Parser/_Parser.js b/src/parse/Parser/_Parser.js index 6c6a697dfc..f555147b8e 100644 --- a/src/parse/Parser/_Parser.js +++ b/src/parse/Parser/_Parser.js @@ -32,18 +32,18 @@ define([ stubs.push( stub ); } - this.result = jsonifyStubs( stubs ); + this.result = jsonifyStubs( stubs, options.noStringify, true ); }; Parser.prototype = { - getStub: function () { + getStub: function ( preserveWhitespace ) { var token = this.next(); if ( !token ) { return null; } - return this.getText( token ) || + return this.getText( token, this.preserveWhitespace || preserveWhitespace ) || this.getComment( token ) || this.getMustache( token ) || this.getElement( token ); @@ -61,4 +61,4 @@ define([ return Parser; -}); \ No newline at end of file +}); diff --git a/src/parse/Parser/getComment/_getComment.js b/src/parse/Parser/getComment/_getComment.js index db6773b42d..b2f9bf7bc7 100644 --- a/src/parse/Parser/getComment/_getComment.js +++ b/src/parse/Parser/getComment/_getComment.js @@ -17,4 +17,4 @@ define([ return null; }; -}); \ No newline at end of file +}); diff --git a/src/parse/Parser/getElement/ElementStub/_ElementStub.js b/src/parse/Parser/getElement/ElementStub/_ElementStub.js index 183cb03c42..92988ae026 100644 --- a/src/parse/Parser/getElement/ElementStub/_ElementStub.js +++ b/src/parse/Parser/getElement/ElementStub/_ElementStub.js @@ -2,8 +2,6 @@ define([ 'config/types', 'config/voidElementNames', 'utils/warn', - 'utils/camelCase', - 'parse/Parser/utils/stringifyStubs', 'parse/Parser/getElement/ElementStub/utils/siblingsByTagName', 'parse/Parser/getElement/ElementStub/utils/filterAttributes', @@ -17,8 +15,6 @@ define([ types, voidElementNames, warn, - camelCase, - stringifyStubs, siblingsByTagName, filterAttributes, @@ -66,7 +62,7 @@ define([ } // if this is a
 element, preserve whitespace within
-		preserveWhitespace = ( preserveWhitespace || lowerCaseTag === 'pre' );
+		preserveWhitespace = ( preserveWhitespace || lowerCaseTag === 'pre' || lowerCaseTag === 'style' || lowerCaseTag === 'script' );
 
 		if ( firstToken.attrs ) {
 			filtered = filterAttributes( firstToken.attrs );
@@ -150,7 +146,7 @@ define([
 
 			}
 
-			this.items[ this.items.length ] = parser.getStub();
+			this.items.push( parser.getStub( preserveWhitespace ) );
 
 			next = parser.next();
 		}
@@ -194,4 +190,4 @@ define([
 
 	return ElementStub;
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Parser/getElement/ElementStub/toJSON.js b/src/parse/Parser/getElement/ElementStub/toJSON.js
index 7b8af2854d..b69d6d1a8d 100644
--- a/src/parse/Parser/getElement/ElementStub/toJSON.js
+++ b/src/parse/Parser/getElement/ElementStub/toJSON.js
@@ -17,17 +17,10 @@ define([
 			return this[ 'json_' + noStringify ];
 		}
 
-		if ( this.component ) {
-			json = {
-				t: types.COMPONENT,
-				e: this.component
-			};
-		} else {
-			json = {
-				t: types.ELEMENT,
-				e: this.tag
-			};
-		}
+		json = {
+			t: types.ELEMENT,
+			e: this.tag
+		};
 
 		if ( this.doctype ) {
 			json.y = 1;
@@ -87,4 +80,4 @@ define([
 		return json;
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Parser/getElement/ElementStub/toString.js b/src/parse/Parser/getElement/ElementStub/toString.js
index 8c6f217672..23d49564e1 100644
--- a/src/parse/Parser/getElement/ElementStub/toString.js
+++ b/src/parse/Parser/getElement/ElementStub/toString.js
@@ -19,11 +19,6 @@ define([
 			return this.str;
 		}
 
-		// components can't be stringified
-		if ( this.component ) {
-			return ( this.str = false );
-		}
-
 		// if this isn't an HTML element, it can't be stringified (since the only reason to stringify an
 		// element is to use with innerHTML, and SVG doesn't support that method.
 		// Note: table elements and select children are excluded from this, because IE (of course)
@@ -110,4 +105,4 @@ define([
 		return ( this.str = str );
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Parser/getElement/ElementStub/utils/filterAttributes.js b/src/parse/Parser/getElement/ElementStub/utils/filterAttributes.js
index 0d902b5bc1..37ee36567e 100644
--- a/src/parse/Parser/getElement/ElementStub/utils/filterAttributes.js
+++ b/src/parse/Parser/getElement/ElementStub/utils/filterAttributes.js
@@ -38,12 +38,12 @@ define([ 'utils/isArray' ], function ( isArray ) {
 			// Proxy?
 			else if ( item.name.substr( 0, 6 ) === 'proxy-' ) {
 				item.name = item.name.substring( 6 );
-				proxies[ proxies.length ] = item;
+				proxies.push( item );
 			}
 
 			else if ( item.name.substr( 0, 3 ) === 'on-' ) {
 				item.name = item.name.substring( 3 );
-				proxies[ proxies.length ] = item;
+				proxies.push( item );
 			}
 
 			// Decorator?
@@ -53,7 +53,7 @@ define([ 'utils/isArray' ], function ( isArray ) {
 
 			// Attribute?
 			else {
-				attrs[ attrs.length ] = item;
+				attrs.push( item );
 			}
 		}
 
@@ -84,4 +84,4 @@ define([ 'utils/isArray' ], function ( isArray ) {
 		return result;
 	}
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Parser/getElement/ElementStub/utils/jsonifyDirective.js b/src/parse/Parser/getElement/ElementStub/utils/jsonifyDirective.js
index 0f35f34124..aba92c1a69 100644
--- a/src/parse/Parser/getElement/ElementStub/utils/jsonifyDirective.js
+++ b/src/parse/Parser/getElement/ElementStub/utils/jsonifyDirective.js
@@ -29,4 +29,4 @@ define([ 'parse/Parser/StringStub/_StringStub' ], function ( StringStub ) {
 		return result;
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Parser/getElement/ElementStub/utils/processDirective.js b/src/parse/Parser/getElement/ElementStub/utils/processDirective.js
index ec6f29557e..3c1c1bd7be 100644
--- a/src/parse/Parser/getElement/ElementStub/utils/processDirective.js
+++ b/src/parse/Parser/getElement/ElementStub/utils/processDirective.js
@@ -27,16 +27,16 @@ define([ 'config/types', 'utils/parseJSON' ], function ( types, parseJSON ) {
 				colonIndex = token.value.indexOf( ':' );
 
 				if ( colonIndex === -1 ) {
-					directiveName[ directiveName.length ] = token;
+					directiveName.push( token );
 				} else {
 
 					// is the colon the first character?
 					if ( colonIndex ) {
 						// no
-						directiveName[ directiveName.length ] = {
+						directiveName.push({
 							type: types.TEXT,
 							value: token.value.substr( 0, colonIndex )
-						};
+						});
 					}
 
 					// if there is anything after the colon in this token, treat
@@ -53,7 +53,7 @@ define([ 'config/types', 'utils/parseJSON' ], function ( types, parseJSON ) {
 			}
 
 			else {
-				directiveName[ directiveName.length ] = token;
+				directiveName.push( token );
 			}
 		}
 
@@ -79,4 +79,4 @@ define([ 'config/types', 'utils/parseJSON' ], function ( types, parseJSON ) {
 		return processed;
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Parser/getElement/ElementStub/utils/siblingsByTagName.js b/src/parse/Parser/getElement/ElementStub/utils/siblingsByTagName.js
index 8ccc5f02f9..abb8e3c667 100644
--- a/src/parse/Parser/getElement/ElementStub/utils/siblingsByTagName.js
+++ b/src/parse/Parser/getElement/ElementStub/utils/siblingsByTagName.js
@@ -18,4 +18,4 @@ define( function () {
 		th: [ 'td', 'th' ]
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Parser/getElement/_getElement.js b/src/parse/Parser/getElement/_getElement.js
index 63f5daf0b6..82246b07d7 100644
--- a/src/parse/Parser/getElement/_getElement.js
+++ b/src/parse/Parser/getElement/_getElement.js
@@ -1,8 +1,6 @@
 define([
-	'config/types',
 	'parse/Parser/getElement/ElementStub/_ElementStub'
 ], function (
-	types,
 	ElementStub
 ) {
 
@@ -16,7 +14,7 @@ define([
 			}
 		}
 
-		return new ElementStub( token, this );
+		return new ElementStub( token, this, this.preserveWhitespace );
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Parser/getMustache/ExpressionStub/_ExpressionStub.js b/src/parse/Parser/getMustache/ExpressionStub.js
similarity index 84%
rename from src/parse/Parser/getMustache/ExpressionStub/_ExpressionStub.js
rename to src/parse/Parser/getMustache/ExpressionStub.js
index de63fb5611..256fff16f1 100644
--- a/src/parse/Parser/getMustache/ExpressionStub/_ExpressionStub.js
+++ b/src/parse/Parser/getMustache/ExpressionStub.js
@@ -1,14 +1,14 @@
-define([ 'config/types', 'utils/isObject' ], function ( types, isObject ) {
+define([
+	'config/types',
+	'utils/isObject'
+], function (
+	types,
+	isObject
+) {
 
 	'use strict';
 
-	var ExpressionStub,
-
-		// helpers
-		getRefs,
-		stringify;
-
-	ExpressionStub = function ( token ) {
+	var ExpressionStub = function ( token ) {
 		this.refs = [];
 
 		getRefs( token, this.refs );
@@ -17,22 +17,26 @@ define([ 'config/types', 'utils/isObject' ], function ( types, isObject ) {
 
 	ExpressionStub.prototype = {
 		toJSON: function () {
-			if ( this.json ) {
-				return this.json;
+			if ( !this.json ) {
+				this.json = {
+					r: this.refs,
+					s: this.str
+				};
 			}
 
-			this.json = {
-				r: this.refs,
-				s: this.str
-			};
-
 			return this.json;
 		}
 	};
 
+	return ExpressionStub;
+
+
+	function quoteStringLiteral ( str ) {
+		return JSON.stringify( String( str ) );
+	}
 
 	// TODO maybe refactor this?
-	getRefs = function ( token, refs ) {
+	function getRefs ( token, refs ) {
 		var i, list;
 
 		if ( token.t === types.REFERENCE ) {
@@ -64,10 +68,9 @@ define([ 'config/types', 'utils/isObject' ], function ( types, isObject ) {
 		if ( token.v ) {
 			getRefs( token.v, refs );
 		}
-	};
-
+	}
 
-	stringify = function ( token, refs ) {
+	function stringify ( token, refs ) {
 		var map = function ( item ) {
 			return stringify( item, refs );
 		};
@@ -79,7 +82,7 @@ define([ 'config/types', 'utils/isObject' ], function ( types, isObject ) {
 			return token.v;
 
 			case types.STRING_LITERAL:
-			return "'" + token.v.replace( /'/g, "\\'" ) + "'";
+			return quoteStringLiteral(token.v);
 
 			case types.ARRAY_LITERAL:
 			return '[' + ( token.m ? token.m.map( map ).join( ',' ) : '' ) + ']';
@@ -117,8 +120,6 @@ define([ 'config/types', 'utils/isObject' ], function ( types, isObject ) {
 			default:
 			throw new Error( 'Could not stringify expression token. This error is unexpected' );
 		}
-	};
-
-	return ExpressionStub;
+	}
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Parser/getMustache/KeypathExpressionStub.js b/src/parse/Parser/getMustache/KeypathExpressionStub.js
new file mode 100644
index 0000000000..e2a9c03565
--- /dev/null
+++ b/src/parse/Parser/getMustache/KeypathExpressionStub.js
@@ -0,0 +1,48 @@
+define([
+	'config/types',
+	'parse/Parser/getMustache/ExpressionStub'
+], function (
+	types,
+	ExpressionStub
+) {
+
+	'use strict';
+
+	var KeypathExpressionStub;
+
+	KeypathExpressionStub = function ( token ) {
+		this.json = {
+			r: token.r,
+			m: token.m.map( jsonify )
+		};
+	};
+
+	KeypathExpressionStub.prototype = {
+		toJSON: function () {
+			return this.json;
+		}
+	};
+
+	return KeypathExpressionStub;
+
+	function jsonify ( member ) {
+		// Straightforward property, e.g. `foo.bar`?
+		if ( member.n ) {
+			return member.n;
+		}
+
+		// String or number literal, e.g. `foo["bar"]` or `foo[1]`?
+		if ( member.x.t === types.STRING_LITERAL || member.x.t === types.NUMBER_LITERAL ) {
+			return member.x.v;
+		}
+
+		// Straightforward reference, e.g. `foo[bar]`?
+		if ( member.x.t === types.REFERENCE ) {
+			return member.x;
+		}
+
+		// If none of the above, we need to process the AST
+		return new ExpressionStub( member.x ).toJSON();
+	}
+
+});
diff --git a/src/parse/Parser/getMustache/MustacheStub/_MustacheStub.js b/src/parse/Parser/getMustache/MustacheStub.js
similarity index 71%
rename from src/parse/Parser/getMustache/MustacheStub/_MustacheStub.js
rename to src/parse/Parser/getMustache/MustacheStub.js
index 1cf8bb2583..9036c096e3 100644
--- a/src/parse/Parser/getMustache/MustacheStub/_MustacheStub.js
+++ b/src/parse/Parser/getMustache/MustacheStub.js
@@ -1,8 +1,10 @@
 define([
 	'config/types',
-	'parse/Parser/getMustache/ExpressionStub/_ExpressionStub'
+	'parse/Parser/getMustache/KeypathExpressionStub',
+	'parse/Parser/getMustache/ExpressionStub'
 ], function (
 	types,
+	KeypathExpressionStub,
 	ExpressionStub
 ) {
 
@@ -15,6 +17,10 @@ define([
 			this.ref = token.ref;
 		}
 
+		if ( token.keypathExpression ) {
+			this.keypathExpr = new KeypathExpressionStub( token.keypathExpression );
+		}
+
 		if ( token.expression ) {
 			this.expr = new ExpressionStub( token.expression );
 		}
@@ -38,6 +44,10 @@ define([
 				json.r = this.ref;
 			}
 
+			if ( this.keypathExpr ) {
+				json.kx = this.keypathExpr.toJSON();
+			}
+
 			if ( this.expr ) {
 				json.x = this.expr.toJSON();
 			}
@@ -54,4 +64,4 @@ define([
 
 	return MustacheStub;
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Parser/getMustache/SectionStub/_SectionStub.js b/src/parse/Parser/getMustache/SectionStub.js
similarity index 57%
rename from src/parse/Parser/getMustache/SectionStub/_SectionStub.js
rename to src/parse/Parser/getMustache/SectionStub.js
index d80bb936a1..993f350a81 100644
--- a/src/parse/Parser/getMustache/SectionStub/_SectionStub.js
+++ b/src/parse/Parser/getMustache/SectionStub.js
@@ -1,10 +1,14 @@
 define([
 	'config/types',
+	'utils/normaliseKeypath',
 	'parse/Parser/utils/jsonifyStubs',
-	'parse/Parser/getMustache/ExpressionStub/_ExpressionStub'
+	'parse/Parser/getMustache/KeypathExpressionStub',
+	'parse/Parser/getMustache/ExpressionStub'
 ], function (
 	types,
+	normaliseKeypath,
 	jsonifyStubs,
+	KeypathExpressionStub,
 	ExpressionStub
 ) {
 
@@ -18,6 +22,10 @@ define([
 
 		this.inverted = ( firstToken.mustacheType === types.INVERTED );
 
+		if ( firstToken.keypathExpression ) {
+			this.keypathExpr = new KeypathExpressionStub( firstToken.keypathExpression );
+		}
+
 		if ( firstToken.expression ) {
 			this.expr = new ExpressionStub( firstToken.expression );
 		}
@@ -29,21 +37,33 @@ define([
 
 		while ( next ) {
 			if ( next.mustacheType === types.CLOSING ) {
-				if ( ( next.ref.trim() === this.ref ) || this.expr ) {
-					parser.pos += 1;
-					break;
-				}
-
-				else {
-					throw new Error( 'Could not parse template: Illegal closing section' );
-				}
+				validateClosing(this, next);
+				parser.pos += 1;
+				break;
 			}
 
-			this.items[ this.items.length ] = parser.getStub();
+			this.items.push( parser.getStub() );
 			next = parser.next();
 		}
+
 	};
 
+	function validateClosing(stub, token){
+		var opening = stub.ref, 
+			closing = normaliseKeypath( token.ref.trim() );
+
+		if ( !opening || !closing ) { return; }
+
+		if( stub.indexRef ) { opening += ':' + stub.indexRef; }
+
+		if ( opening.substr( 0, closing.length) !== closing ) {
+
+			throw new Error( 'Could not parse template: Illegal closing section {{/' 
+				+ closing + '}}. Expected {{/' + stub.ref + '}}.' );
+
+		}
+	}
+						
 	SectionStub.prototype = {
 		toJSON: function ( noStringify ) {
 			var json;
@@ -70,6 +90,10 @@ define([
 				json.x = this.expr.toJSON();
 			}
 
+			if ( this.keypathExpr ) {
+				json.kx = this.keypathExpr.toJSON();
+			}
+
 			if ( this.items.length ) {
 				json.f = jsonifyStubs( this.items, noStringify );
 			}
@@ -86,4 +110,4 @@ define([
 
 	return SectionStub;
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Parser/getMustache/_getMustache.js b/src/parse/Parser/getMustache/_getMustache.js
index f7379dbcef..7d968ecf69 100644
--- a/src/parse/Parser/getMustache/_getMustache.js
+++ b/src/parse/Parser/getMustache/_getMustache.js
@@ -1,7 +1,7 @@
 define([
 	'config/types',
-	'parse/Parser/getMustache/MustacheStub/_MustacheStub',
-	'parse/Parser/getMustache/SectionStub/_SectionStub'
+	'parse/Parser/getMustache/MustacheStub',
+	'parse/Parser/getMustache/SectionStub'
 ], function (
 	types,
 	MustacheStub,
@@ -20,4 +20,4 @@ define([
 		}
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Parser/getText/TextStub/_TextStub.js b/src/parse/Parser/getText/TextStub/_TextStub.js
index 731fce8b97..12970adeeb 100644
--- a/src/parse/Parser/getText/TextStub/_TextStub.js
+++ b/src/parse/Parser/getText/TextStub/_TextStub.js
@@ -114,4 +114,4 @@ define([ 'config/types' ], function ( types ) {
 
 	return TextStub;
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Parser/getText/_getText.js b/src/parse/Parser/getText/_getText.js
index e6106b5b81..f77cac2dae 100644
--- a/src/parse/Parser/getText/_getText.js
+++ b/src/parse/Parser/getText/_getText.js
@@ -8,13 +8,13 @@ define([
 
 	'use strict';
 
-	return function ( token ) {
+	return function ( token, preserveWhitespace ) {
 		if ( token.type === types.TEXT ) {
 			this.pos += 1;
-			return new TextStub( token, this.preserveWhitespace );
+			return new TextStub( token, preserveWhitespace );
 		}
 
 		return null;
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Parser/utils/jsonifyStubs.js b/src/parse/Parser/utils/jsonifyStubs.js
index 322ecbbd19..4e660b9d00 100644
--- a/src/parse/Parser/utils/jsonifyStubs.js
+++ b/src/parse/Parser/utils/jsonifyStubs.js
@@ -2,10 +2,10 @@ define([ 'parse/Parser/utils/stringifyStubs' ], function ( stringifyStubs ) {
 
 	'use strict';
 
-	return function ( items, noStringify ) {
+	return function ( items, noStringify, topLevel ) {
 		var str, json;
 
-		if ( !noStringify ) {
+		if ( !topLevel && !noStringify ) {
 			str = stringifyStubs( items );
 			if ( str !== false ) {
 				return str;
@@ -19,4 +19,4 @@ define([ 'parse/Parser/utils/stringifyStubs' ], function ( stringifyStubs ) {
 		return json;
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Parser/utils/stringifyStubs.js b/src/parse/Parser/utils/stringifyStubs.js
index 65fad99c4e..3b481548e8 100644
--- a/src/parse/Parser/utils/stringifyStubs.js
+++ b/src/parse/Parser/utils/stringifyStubs.js
@@ -22,4 +22,4 @@ define( function () {
 		return str;
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Tokenizer/_Tokenizer.js b/src/parse/Tokenizer/_Tokenizer.js
index ad5789140b..82628ebbc6 100644
--- a/src/parse/Tokenizer/_Tokenizer.js
+++ b/src/parse/Tokenizer/_Tokenizer.js
@@ -29,8 +29,10 @@ define([
 
 		this.str = str;
 		this.pos = 0;
+
 		this.delimiters = options.delimiters;
 		this.tripleDelimiters = options.tripleDelimiters;
+		this.interpolate = options.interpolate;
 
 		this.tokens = [];
 
@@ -97,4 +99,4 @@ define([
 
 	return Tokenizer;
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Tokenizer/getComment/getComment.js b/src/parse/Tokenizer/getComment/getComment.js
index d50e71d050..55df72e5ab 100644
--- a/src/parse/Tokenizer/getComment/getComment.js
+++ b/src/parse/Tokenizer/getComment/getComment.js
@@ -29,4 +29,4 @@ define([
 		};
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Tokenizer/getExpression/_getExpression.js b/src/parse/Tokenizer/getExpression/_getExpression.js
index 89e209703e..e53dd964cd 100755
--- a/src/parse/Tokenizer/getExpression/_getExpression.js
+++ b/src/parse/Tokenizer/getExpression/_getExpression.js
@@ -16,4 +16,4 @@ define([
 		return getConditional( this );
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Tokenizer/getExpression/getConditional.js b/src/parse/Tokenizer/getExpression/getConditional.js
index 5d50f289ef..9e417b4f51 100644
--- a/src/parse/Tokenizer/getExpression/getConditional.js
+++ b/src/parse/Tokenizer/getExpression/getConditional.js
@@ -55,4 +55,4 @@ define([
 		};
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Tokenizer/getExpression/getLogicalOr.js b/src/parse/Tokenizer/getExpression/getLogicalOr.js
index aee3a667f3..02b67c6614 100644
--- a/src/parse/Tokenizer/getExpression/getLogicalOr.js
+++ b/src/parse/Tokenizer/getExpression/getLogicalOr.js
@@ -19,34 +19,43 @@ define([
 				return null;
 			}
 
-			start = tokenizer.pos;
-
-			tokenizer.allowWhitespace();
-
-			if ( !tokenizer.getStringMatch( symbol ) ) {
-				tokenizer.pos = start;
-				return left;
-			}
-
-			// special case - in operator must not be followed by [a-zA-Z_$0-9]
-			if ( symbol === 'in' && /[a-zA-Z_$0-9]/.test( tokenizer.remaining().charAt( 0 ) ) ) {
-				tokenizer.pos = start;
-				return left;
+			// Loop to handle left-recursion in a case like `a * b * c` and produce
+			// left association, i.e. `(a * b) * c`.  The matcher can't call itself
+			// to parse `left` because that would be infinite regress.
+			while (true) {
+				start = tokenizer.pos;
+
+			   tokenizer.allowWhitespace();
+
+				if ( !tokenizer.getStringMatch( symbol ) ) {
+					tokenizer.pos = start;
+					return left;
+				}
+
+				// special case - in operator must not be followed by [a-zA-Z_$0-9]
+				if ( symbol === 'in' && /[a-zA-Z_$0-9]/.test( tokenizer.remaining().charAt( 0 ) ) ) {
+					tokenizer.pos = start;
+					return left;
+				}
+
+			   tokenizer.allowWhitespace();
+
+				// right operand must also consist of only higher-precedence operators
+				right = fallthrough( tokenizer );
+				if ( !right ) {
+					tokenizer.pos = start;
+					return left;
+				}
+
+				left = {
+					t: types.INFIX_OPERATOR,
+					s: symbol,
+					o: [ left, right ]
+				};
+
+				// Loop back around.  If we don't see another occurrence of the symbol,
+				// we'll return left.
 			}
-
-			tokenizer.allowWhitespace();
-
-			right = tokenizer.getExpression();
-			if ( !right ) {
-				tokenizer.pos = start;
-				return left;
-			}
-
-			return {
-				t: types.INFIX_OPERATOR,
-				s: symbol,
-				o: [ left, right ]
-			};
 		};
 	};
 
@@ -73,4 +82,4 @@ define([
 
 	return getLogicalOr;
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Tokenizer/getExpression/getMemberOrInvocation.js b/src/parse/Tokenizer/getExpression/getMemberOrInvocation.js
index 6f68ece3a4..070ea57cda 100644
--- a/src/parse/Tokenizer/getExpression/getMemberOrInvocation.js
+++ b/src/parse/Tokenizer/getExpression/getMemberOrInvocation.js
@@ -61,4 +61,4 @@ define([
 		return expression;
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Tokenizer/getExpression/getPrimary/_getPrimary.js b/src/parse/Tokenizer/getExpression/getPrimary/_getPrimary.js
index 29940e4f2b..94756e1c7d 100644
--- a/src/parse/Tokenizer/getExpression/getPrimary/_getPrimary.js
+++ b/src/parse/Tokenizer/getExpression/getPrimary/_getPrimary.js
@@ -16,4 +16,4 @@ define([
 		    || getBracketedExpression( tokenizer );
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Tokenizer/getExpression/getPrimary/getBracketedExpression.js b/src/parse/Tokenizer/getExpression/getPrimary/getBracketedExpression.js
index 628cdd6df7..3e05eb5b2e 100644
--- a/src/parse/Tokenizer/getExpression/getPrimary/getBracketedExpression.js
+++ b/src/parse/Tokenizer/getExpression/getPrimary/getBracketedExpression.js
@@ -32,4 +32,4 @@ define([ 'config/types' ], function ( types ) {
 		};
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/_getLiteral.js b/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/_getLiteral.js
index e6416ce5c6..e079d08e6e 100644
--- a/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/_getLiteral.js
+++ b/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/_getLiteral.js
@@ -24,4 +24,4 @@ define([
 		return literal;
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getArrayLiteral.js b/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getArrayLiteral.js
index 153038eed4..8a054d1b16 100644
--- a/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getArrayLiteral.js
+++ b/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getArrayLiteral.js
@@ -34,4 +34,4 @@ define([
 		};
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getBooleanLiteral.js b/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getBooleanLiteral.js
index 2e1cb1a81d..7150105ab0 100644
--- a/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getBooleanLiteral.js
+++ b/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getBooleanLiteral.js
@@ -24,4 +24,4 @@ define([ 'config/types' ], function ( types ) {
 		return null;
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getNumberLiteral.js b/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getNumberLiteral.js
index ae4b4da433..590743a03d 100644
--- a/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getNumberLiteral.js
+++ b/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getNumberLiteral.js
@@ -24,4 +24,4 @@ define([
 		return null;
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getObjectLiteral/_getObjectLiteral.js b/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getObjectLiteral/_getObjectLiteral.js
index 1ceaa17501..6227bf14d6 100644
--- a/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getObjectLiteral/_getObjectLiteral.js
+++ b/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getObjectLiteral/_getObjectLiteral.js
@@ -37,4 +37,4 @@ define([
 		};
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getObjectLiteral/getKeyValuePair.js b/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getObjectLiteral/getKeyValuePair.js
index 9d5d35be81..c9c75a1536 100644
--- a/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getObjectLiteral/getKeyValuePair.js
+++ b/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getObjectLiteral/getKeyValuePair.js
@@ -48,4 +48,4 @@ define([
 		};
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getObjectLiteral/getKeyValuePairs.js b/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getObjectLiteral/getKeyValuePairs.js
index 1a22e7f7d4..c003ea8217 100644
--- a/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getObjectLiteral/getKeyValuePairs.js
+++ b/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getObjectLiteral/getKeyValuePairs.js
@@ -32,4 +32,4 @@ define([
 		return pairs;
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getStringLiteral/_getStringLiteral.js b/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getStringLiteral/_getStringLiteral.js
index 8ebc903c56..e057c1f9fd 100644
--- a/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getStringLiteral/_getStringLiteral.js
+++ b/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getStringLiteral/_getStringLiteral.js
@@ -1,9 +1,11 @@
 define([
 	'config/types',
-	'parse/Tokenizer/getExpression/getPrimary/getLiteral/getStringLiteral/getQuotedString'
+	'parse/Tokenizer/getExpression/getPrimary/getLiteral/getStringLiteral/getSingleQuotedString',
+	'parse/Tokenizer/getExpression/getPrimary/getLiteral/getStringLiteral/getDoubleQuotedString',
 ], function (
 	types,
-	getQuotedString
+	getSingleQuotedString,
+	getDoubleQuotedString
 ) {
 
 	'use strict';
@@ -14,7 +16,7 @@ define([
 		start = tokenizer.pos;
 
 		if ( tokenizer.getStringMatch( '"' ) ) {
-			string = getQuotedString( tokenizer, false );
+			string = getDoubleQuotedString( tokenizer );
 
 			if ( !tokenizer.getStringMatch( '"' ) ) {
 				tokenizer.pos = start;
@@ -28,7 +30,7 @@ define([
 		}
 
 		if ( tokenizer.getStringMatch( "'" ) ) {
-			string = getQuotedString( tokenizer, true );
+			string = getSingleQuotedString( tokenizer );
 
 			if ( !tokenizer.getStringMatch( "'" ) ) {
 				tokenizer.pos = start;
@@ -44,4 +46,4 @@ define([
 		return null;
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getStringLiteral/getDoubleQuotedString.js b/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getStringLiteral/getDoubleQuotedString.js
new file mode 100644
index 0000000000..e8c74d28f4
--- /dev/null
+++ b/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getStringLiteral/getDoubleQuotedString.js
@@ -0,0 +1,11 @@
+define([
+	'parse/Tokenizer/getExpression/getPrimary/getLiteral/getStringLiteral/makeQuotedStringMatcher'
+], function (
+	makeQuotedStringMatcher
+) {
+
+	'use strict';
+
+	return makeQuotedStringMatcher( "'" );
+
+});
diff --git a/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getStringLiteral/getEscapedChars.js b/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getStringLiteral/getEscapedChars.js
deleted file mode 100644
index 54b9c52174..0000000000
--- a/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getStringLiteral/getEscapedChars.js
+++ /dev/null
@@ -1,31 +0,0 @@
-define( function () {
-
-	'use strict';
-
-	return function ( tokenizer ) {
-		var chars = '', character;
-
-		character = getEscapedChar( tokenizer );
-		while ( character ) {
-			chars += character;
-			character = getEscapedChar( tokenizer );
-		}
-
-		return chars || null;
-	};
-
-
-	function getEscapedChar ( tokenizer ) {
-		var character;
-
-		if ( !tokenizer.getStringMatch( '\\' ) ) {
-			return null;
-		}
-
-		character = tokenizer.str.charAt( tokenizer.pos );
-		tokenizer.pos += 1;
-
-		return character;
-	}
-
-});
\ No newline at end of file
diff --git a/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getStringLiteral/getQuotedString.js b/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getStringLiteral/getQuotedString.js
deleted file mode 100644
index df58517685..0000000000
--- a/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getStringLiteral/getQuotedString.js
+++ /dev/null
@@ -1,44 +0,0 @@
-define([
-	'parse/Tokenizer/utils/makeRegexMatcher',
-	'parse/Tokenizer/getExpression/getPrimary/getLiteral/getStringLiteral/getEscapedChars'
-], function (
-	makeRegexMatcher,
-	getEscapedChars
-) {
-
-	'use strict';
-
-	var getUnescapedDoubleQuotedChars = makeRegexMatcher( /^[^\\"]+/ ),
-		getUnescapedSingleQuotedChars = makeRegexMatcher( /^[^\\']+/ );
-
-	return function getQuotedString ( tokenizer, singleQuotes ) {
-		var start, string, escaped, unescaped, next, matcher;
-
-		start = tokenizer.pos;
-
-		string = '';
-		matcher = ( singleQuotes ? getUnescapedSingleQuotedChars : getUnescapedDoubleQuotedChars );
-
-		escaped = getEscapedChars( tokenizer );
-		if ( escaped ) {
-			string += escaped;
-		}
-
-		unescaped = matcher( tokenizer );
-		if ( unescaped ) {
-			string += unescaped;
-		}
-
-		if ( !string ) {
-			return '';
-		}
-
-		next = getQuotedString( tokenizer, singleQuotes );
-		while ( next !== '' ) {
-			string += next;
-		}
-
-		return string;
-	};
-
-});
\ No newline at end of file
diff --git a/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getStringLiteral/getSingleQuotedString.js b/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getStringLiteral/getSingleQuotedString.js
new file mode 100644
index 0000000000..2a65ca04e1
--- /dev/null
+++ b/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getStringLiteral/getSingleQuotedString.js
@@ -0,0 +1,11 @@
+define([
+	'parse/Tokenizer/getExpression/getPrimary/getLiteral/getStringLiteral/makeQuotedStringMatcher'
+], function (
+	makeQuotedStringMatcher
+) {
+
+	'use strict';
+
+	return makeQuotedStringMatcher( '"' );
+
+});
diff --git a/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getStringLiteral/makeQuotedStringMatcher.js b/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getStringLiteral/makeQuotedStringMatcher.js
new file mode 100644
index 0000000000..b98e9b2885
--- /dev/null
+++ b/src/parse/Tokenizer/getExpression/getPrimary/getLiteral/getStringLiteral/makeQuotedStringMatcher.js
@@ -0,0 +1,59 @@
+define([
+	'parse/Tokenizer/utils/makeRegexMatcher'
+], function (
+	makeRegexMatcher
+) {
+
+	'use strict';
+
+	var getStringMiddle, getEscapeSequence, getLineContinuation;
+
+	// Match one or more characters until: ", ', \, or EOL/EOF.
+	// EOL/EOF is written as (?!.) (meaning there's no non-newline char next).
+	getStringMiddle = makeRegexMatcher( /^(?=.)[^"'\\]+?(?:(?!.)|(?=["'\\]))/ );
+
+	// Match one escape sequence, including the backslash.
+	getEscapeSequence = makeRegexMatcher( /^\\(?:['"\\bfnrt]|0(?![0-9])|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|(?=.)[^ux0-9])/ );
+
+	// Match one ES5 line continuation (backslash + line terminator).
+	getLineContinuation = makeRegexMatcher( /^\\(?:\r\n|[\u000A\u000D\u2028\u2029])/ );
+
+	// Helper for defining getDoubleQuotedString and getSingleQuotedString.
+	return function ( okQuote ) {
+		return function ( tokenizer ) {
+			var start, literal, done, next;
+
+			start = tokenizer.pos;
+			literal = '"';
+			done = false;
+
+			while ( !done ) {
+				next = ( getStringMiddle( tokenizer ) || getEscapeSequence( tokenizer ) ||
+					tokenizer.getStringMatch( okQuote ) );
+				if ( next ) {
+					if ( next === '"' ) {
+						literal += '\\"';
+					} else if ( next === "\\'" ) {
+						literal += "'";
+					} else {
+						literal += next;
+					}
+				} else {
+					next = getLineContinuation( tokenizer );
+					if ( next ) {
+						// convert \(newline-like) into a \u escape, which is allowed in JSON
+						literal += '\\u' + ( '000' + next.charCodeAt(1).toString(16) ).slice( -4 );
+					} else {
+						done = true;
+					}
+				}
+			}
+
+			literal += '"';
+
+			// use JSON.parse to interpret escapes
+			return JSON.parse( literal );
+		};
+	};
+
+});
diff --git a/src/parse/Tokenizer/getExpression/getPrimary/getReference.js b/src/parse/Tokenizer/getExpression/getPrimary/getReference.js
index bbecf168d1..1c2f3da7f3 100644
--- a/src/parse/Tokenizer/getExpression/getPrimary/getReference.js
+++ b/src/parse/Tokenizer/getExpression/getPrimary/getReference.js
@@ -94,4 +94,4 @@ define([
 
 
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Tokenizer/getExpression/getTypeOf.js b/src/parse/Tokenizer/getExpression/getTypeOf.js
index 4dc181da0f..b8000a7828 100644
--- a/src/parse/Tokenizer/getExpression/getTypeOf.js
+++ b/src/parse/Tokenizer/getExpression/getTypeOf.js
@@ -55,4 +55,4 @@ define([
 
 	return getTypeOf;
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Tokenizer/getExpression/shared/getExpressionList.js b/src/parse/Tokenizer/getExpression/shared/getExpressionList.js
index e87903accc..5372bea77f 100644
--- a/src/parse/Tokenizer/getExpression/shared/getExpressionList.js
+++ b/src/parse/Tokenizer/getExpression/shared/getExpressionList.js
@@ -33,4 +33,4 @@ define( function () {
 		return expressions;
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Tokenizer/getExpression/shared/getKey.js b/src/parse/Tokenizer/getExpression/shared/getKey.js
index fd09a69285..516bcabccc 100644
--- a/src/parse/Tokenizer/getExpression/shared/getKey.js
+++ b/src/parse/Tokenizer/getExpression/shared/getKey.js
@@ -30,4 +30,4 @@ define([
 		}
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Tokenizer/getExpression/shared/getName.js b/src/parse/Tokenizer/getExpression/shared/getName.js
index c951995f0e..f7ac0acbb1 100644
--- a/src/parse/Tokenizer/getExpression/shared/getName.js
+++ b/src/parse/Tokenizer/getExpression/shared/getName.js
@@ -4,4 +4,4 @@ define([ 'parse/Tokenizer/utils/makeRegexMatcher' ], function ( makeRegexMatcher
 
 	return makeRegexMatcher( /^[a-zA-Z_$][a-zA-Z_$0-9]*/ );
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Tokenizer/getExpression/shared/getRefinement.js b/src/parse/Tokenizer/getExpression/shared/getRefinement.js
index be8717fec9..cdfb1e1faa 100644
--- a/src/parse/Tokenizer/getExpression/shared/getRefinement.js
+++ b/src/parse/Tokenizer/getExpression/shared/getRefinement.js
@@ -53,4 +53,4 @@ define([
 		return null;
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Tokenizer/getMustache/_getMustache.js b/src/parse/Tokenizer/getMustache/_getMustache.js
index 94d5035e53..b1913b563e 100755
--- a/src/parse/Tokenizer/getMustache/_getMustache.js
+++ b/src/parse/Tokenizer/getMustache/_getMustache.js
@@ -62,4 +62,4 @@ define([
 		return content;
 	}
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Tokenizer/getMustache/getDelimiterChange.js b/src/parse/Tokenizer/getMustache/getDelimiterChange.js
index 8e5995bb40..b42dd5c6ae 100644
--- a/src/parse/Tokenizer/getMustache/getDelimiterChange.js
+++ b/src/parse/Tokenizer/getMustache/getDelimiterChange.js
@@ -46,4 +46,4 @@ define([
 		return [ opening, closing ];
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Tokenizer/getMustache/getMustacheContent.js b/src/parse/Tokenizer/getMustache/getMustacheContent.js
index 26160fb83c..22ed142f85 100644
--- a/src/parse/Tokenizer/getMustache/getMustacheContent.js
+++ b/src/parse/Tokenizer/getMustache/getMustacheContent.js
@@ -14,7 +14,7 @@ define([
 		arrayMember = /^[0-9][1-9]*$/;
 
 	return function ( tokenizer, isTriple ) {
-		var start, mustache, type, expr, i, remaining, index;
+		var start, mustache, type, expr, i, remaining, index, delimiter, keypathExpression;
 
 		start = tokenizer.pos;
 
@@ -70,6 +70,27 @@ define([
 
 			// get expression
 			expr = tokenizer.getExpression();
+
+			// With certain valid references that aren't valid expressions,
+			// e.g. {{1.foo}}, we have a problem: it looks like we've got an
+			// expression, but the expression didn't consume the entire
+			// reference. So we need to check that the mustache delimiters
+			// appear next, unless there's an index reference (i.e. a colon)
+			remaining = tokenizer.remaining();
+			delimiter = isTriple ? tokenizer.tripleDelimiters[1] : tokenizer.delimiters[1];
+
+			if ( ( remaining.substr( 0, delimiter.length ) !== delimiter ) && ( remaining.charAt( 0 ) !== ':' ) ) {
+				tokenizer.pos = start;
+
+				remaining = tokenizer.remaining();
+				index = remaining.indexOf( tokenizer.delimiters[1] );
+
+				if ( index !== -1 ) {
+					mustache.ref = remaining.substr( 0, index ).trim();
+					tokenizer.pos += index;
+					return mustache;
+				}
+			}
 		}
 
 		while ( expr.t === types.BRACKETED && expr.x ) {
@@ -82,6 +103,8 @@ define([
 			mustache.ref = expr.n;
 		} else if ( expr.t === types.NUMBER_LITERAL && arrayMember.test( expr.v ) ) {
 			mustache.ref = expr.v;
+		} else if ( keypathExpression = getKeypathExpression( expr ) ) {
+			mustache.keypathExpression = keypathExpression;
 		} else {
 			mustache.expression = expr;
 		}
@@ -95,4 +118,22 @@ define([
 		return mustache;
 	};
 
-});
\ No newline at end of file
+	function getKeypathExpression ( expr ) {
+		var members = [];
+
+		while ( expr.t === types.MEMBER && expr.r.t === types.REFINEMENT ) {
+			members.unshift( expr.r );
+			expr = expr.x;
+		}
+
+		if ( expr.t !== types.REFERENCE ) {
+			return null;
+		}
+
+		return {
+			r: expr.n,
+			m: members
+		};
+	}
+
+});
diff --git a/src/parse/Tokenizer/getMustache/getMustacheType.js b/src/parse/Tokenizer/getMustache/getMustacheType.js
index f571885189..8903f483de 100644
--- a/src/parse/Tokenizer/getMustache/getMustacheType.js
+++ b/src/parse/Tokenizer/getMustache/getMustacheType.js
@@ -22,4 +22,4 @@ define([ 'config/types' ], function ( types ) {
 		return type;
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Tokenizer/getTag/_getTag.js b/src/parse/Tokenizer/getTag/_getTag.js
index a3ffe97b25..5327effd3c 100755
--- a/src/parse/Tokenizer/getTag/_getTag.js
+++ b/src/parse/Tokenizer/getTag/_getTag.js
@@ -137,6 +137,12 @@ define([
 
 		start = tokenizer.pos;
 
+		// if the next character isn't whitespace, there are no attributes...
+		if ( !tokenizer.getStringMatch( ' ' ) && !tokenizer.getStringMatch( '\n' ) ) {
+			return null;
+		}
+
+		// ...but allow arbitrary amounts of whitespace
 		tokenizer.allowWhitespace();
 
 		attr = getAttribute( tokenizer );
@@ -149,7 +155,7 @@ define([
 		attrs = [];
 
 		while ( attr !== null ) {
-			attrs[ attrs.length ] = attr;
+			attrs.push( attr );
 
 			tokenizer.allowWhitespace();
 			attr = getAttribute( tokenizer );
@@ -239,7 +245,7 @@ define([
 
 		token = tokenizer.getMustache() || getUnquotedAttributeValueToken( tokenizer );
 		while ( token !== null ) {
-			tokens[ tokens.length ] = token;
+			tokens.push( token );
 			token = tokenizer.getMustache() || getUnquotedAttributeValueToken( tokenizer );
 		}
 
@@ -263,7 +269,7 @@ define([
 
 		token = tokenizer.getMustache() || getQuotedStringToken( tokenizer, quoteMark );
 		while ( token !== null ) {
-			tokens[ tokens.length ] = token;
+			tokens.push( token );
 			token = tokenizer.getMustache() || getQuotedStringToken( tokenizer, quoteMark );
 		}
 
@@ -301,4 +307,4 @@ define([
 
 	return getTag;
 
-});
\ No newline at end of file
+});
diff --git a/src/parse/Tokenizer/getText/_getText.js b/src/parse/Tokenizer/getText/_getText.js
index 6b5ba2f410..1f938a66f3 100755
--- a/src/parse/Tokenizer/getText/_getText.js
+++ b/src/parse/Tokenizer/getText/_getText.js
@@ -14,7 +14,12 @@ define([
 		remaining = this.remaining();
 
 		barrier = this.inside ? ' child bindings for this
+				}
+
+				if ( binding.keypath === indexRef ) {
+					childInstance.set( binding.otherKeypath, newIndex );
+				}
+
+				if ( updated = getNewKeypath( binding.keypath, oldKeypath, newKeypath ) ) {
+					binding.reassign( updated );
+				}
+			});
+
+			if ( indexRefAlias = this.indexRefBindings[ indexRef ] ) {
+				childInstance.set( indexRefAlias, newIndex );
+			}
+
+			if ( query = this.root._liveComponentQueries[ this.name ] ) {
+				query._makeDirty();
+			}
+		},
+
 		toString: function () {
 			return this.instance.fragment.toString();
 		},
@@ -59,6 +88,10 @@ define([
 				return this.instance;
 			}
 
+			if ( this.instance.fragment ) {
+				return this.instance.fragment.findComponent( selector );
+			}
+
 			return null;
 		},
 
@@ -73,4 +106,17 @@ define([
 
 	return DomComponent;
 
-});
\ No newline at end of file
+
+	function removeFromLiveComponentQueries ( component ) {
+		var instance, query;
+
+		instance = component.root;
+
+		do {
+			if ( query = instance._liveComponentQueries[ component.name ] ) {
+				query._remove( component );
+			}
+		} while ( instance = instance._parent );
+	}
+
+});
diff --git a/src/render/DomFragment/Component/initialise/_initialise.js b/src/render/DomFragment/Component/initialise/_initialise.js
index cc36d62c43..1ca10d9ecf 100644
--- a/src/render/DomFragment/Component/initialise/_initialise.js
+++ b/src/render/DomFragment/Component/initialise/_initialise.js
@@ -3,7 +3,7 @@ define([
 	'utils/warn',
 	'render/DomFragment/Component/initialise/createModel/_createModel',
 	'render/DomFragment/Component/initialise/createInstance',
-	'render/DomFragment/Component/initialise/createObservers',
+	'render/DomFragment/Component/initialise/createBindings',
 	'render/DomFragment/Component/initialise/propagateEvents',
 	'render/DomFragment/Component/initialise/updateLiveQueries'
 ], function (
@@ -11,14 +11,14 @@ define([
 	warn,
 	createModel,
 	createInstance,
-	createObservers,
+	createBindings,
 	propagateEvents,
 	updateLiveQueries
 ) {
 
 	'use strict';
 
-	return function ( component, options, docFrag ) {
+	return function initialiseComponent ( component, options, docFrag ) {
 		var parentFragment,
 			root,
 			Component,
@@ -32,10 +32,8 @@ define([
 		component.type = types.COMPONENT;
 		component.name = options.descriptor.e;
 		component.index = options.index;
-
-		// we may need to create some observers to handle data-binding
-		// between parent and child
-		component.observers = [];
+		component.indexRefBindings = {};
+		component.bindings = [];
 
 		// get the component constructor
 		Component = root.components[ options.descriptor.e ];
@@ -51,10 +49,10 @@ define([
 		// This may involve setting up some bindings, but we can't do it
 		// yet so we take some notes instead
 		toBind = [];
-		data = createModel( component, options.descriptor.a, toBind );
+		data = createModel( component, Component.data || {}, options.descriptor.a, toBind );
 
 		createInstance( component, Component, data, docFrag, options.descriptor.f );
-		createObservers( component, toBind );
+		createBindings( component, toBind );
 		propagateEvents( component, options.descriptor.v );
 
 		// intro, outro and decorator directives have no effect
@@ -65,4 +63,4 @@ define([
 		updateLiveQueries( component );
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/render/DomFragment/Component/initialise/createBindings.js b/src/render/DomFragment/Component/initialise/createBindings.js
new file mode 100644
index 0000000000..4bf3ca023f
--- /dev/null
+++ b/src/render/DomFragment/Component/initialise/createBindings.js
@@ -0,0 +1,28 @@
+define([
+	'shared/createComponentBinding',
+	'shared/get/_get',
+	'shared/set'
+], function (
+	createComponentBinding,
+	get,
+	set
+) {
+
+	'use strict';
+
+	return function createInitialComponentBindings ( component, toBind ) {
+		toBind.forEach( function createInitialComponentBinding ( pair ) {
+			var childValue, parentValue;
+
+			createComponentBinding( component, component.root, pair.parentKeypath, pair.childKeypath );
+
+			childValue = get( component.instance, pair.childKeypath );
+			parentValue = get( component.root, pair.parentKeypath );
+
+			if ( childValue !== undefined && parentValue === undefined ) {
+				set( component.root, pair.parentKeypath, childValue );
+			}
+		});
+	};
+
+});
diff --git a/src/render/DomFragment/Component/initialise/createInstance.js b/src/render/DomFragment/Component/initialise/createInstance.js
index d4f36d0612..2a461c73a3 100644
--- a/src/render/DomFragment/Component/initialise/createInstance.js
+++ b/src/render/DomFragment/Component/initialise/createInstance.js
@@ -1,13 +1,9 @@
-define([
-
-], function (
-
-) {
+define( function () {
 
 	'use strict';
 
 	return function ( component, Component, data, docFrag, contentDescriptor ) {
-		var instance, parentFragment, partials, root;
+		var instance, parentFragment, partials, root, adapt;
 
 		parentFragment = component.parentFragment;
 		root = component.root;
@@ -15,27 +11,65 @@ define([
 		// Make contents available as a {{>content}} partial
 		partials = { content: contentDescriptor || [] };
 
-		// TODO don't clone parent node - instead use a document fragment (and pass in the namespaceURI
-		// of the parent node, for SVG purposes) and insert contents that way?
+		// Use component default adaptors AND inherit parent adaptors.
+		adapt = combineAdaptors( root, Component.defaults.adapt, Component.adaptors );
+
 		instance = new Component({
-			el: parentFragment.pNode.cloneNode( false ), // to ensure correct namespaceURI
+			el: parentFragment.pNode,
+			append: true,
 			data: data,
 			partials: partials,
+			magic: root.magic || Component.defaults.magic,
+			modifyArrays: root.modifyArrays,
 			_parent: root,
-			adaptors: root.adaptors
+			_component: component,
+			adapt: adapt
 		});
 
-		// Need to store references in both directions
-		instance.component = component;
-		component.instance = instance;
+		if ( docFrag ) {
+			// The component may be in the wrong place! This is because we
+			// are still populating the document fragment that will be appended
+			// to its parent node. So even though the component is *already*
+			// a child of the parent node, we need to detach it, then insert
+			// it into said document fragment, so that order is maintained
+			// (both figuratively and literally).
+			instance.insert( docFrag );
 
-		// Insert the component into the current document fragment...
-		instance.insert( docFrag );
-
-		// ...and reset node reference
-		instance.fragment.pNode = parentFragment.pNode;
+			// (After inserting, we need to reset the node reference)
+			instance.fragment.pNode = instance.el = parentFragment.pNode;
+		}
 
 		return instance;
 	};
 
-});
\ No newline at end of file
+
+	function combineAdaptors ( root, defaultAdapt ) {
+		var adapt, len, i;
+
+		// Parent adaptors should take precedence, so they go first
+		if ( root.adapt.length ) {
+			adapt = root.adapt.map( function ( stringOrObject ) {
+				if ( typeof stringOrObject === 'object' ) {
+					return stringOrObject;
+				}
+
+				return root.adaptors[ stringOrObject ] || stringOrObject;
+			});
+		} else {
+			adapt = [];
+		}
+
+		// If the component has any adaptors that aren't already included,
+		// include them now
+		if ( len = defaultAdapt.length ) {
+			for ( i = 0; i < len; i += 1 ) {
+				if ( adapt.indexOf( defaultAdapt[i] ) === -1 ) {
+					adapt.push( defaultAdapt[i] );
+				}
+			}
+		}
+
+		return adapt;
+	}
+
+});
diff --git a/src/render/DomFragment/Component/initialise/createModel/ComponentParameter.js b/src/render/DomFragment/Component/initialise/createModel/ComponentParameter.js
index 7a887add95..83ec23ebda 100644
--- a/src/render/DomFragment/Component/initialise/createModel/ComponentParameter.js
+++ b/src/render/DomFragment/Component/initialise/createModel/ComponentParameter.js
@@ -1,6 +1,8 @@
 define([
+	'global/runloop',
 	'render/StringFragment/_StringFragment'
 ], function (
+	runloop,
 	StringFragment
 ) {
 
@@ -15,8 +17,7 @@ define([
 		this.fragment = new StringFragment({
 			descriptor:   value,
 			root:         component.root,
-			owner:        this,
-			contextStack: component.parentFragment.contextStack
+			owner:        this
 		});
 
 		this.selfUpdating = this.fragment.isSimple();
@@ -34,7 +35,7 @@ define([
 			// updated once all the information is in, to prevent unnecessary
 			// DOM manipulation
 			else if ( !this.deferred && this.ready ) {
-				this.root._deferred.attrs.push( this );
+				runloop.addAttribute( this );
 				this.deferred = true;
 			}
 		},
diff --git a/src/render/DomFragment/Component/initialise/createModel/_createModel.js b/src/render/DomFragment/Component/initialise/createModel/_createModel.js
index 4f610415ba..0091472353 100644
--- a/src/render/DomFragment/Component/initialise/createModel/_createModel.js
+++ b/src/render/DomFragment/Component/initialise/createModel/_createModel.js
@@ -2,17 +2,19 @@ define([
 	'config/types',
 	'utils/parseJSON',
 	'shared/resolveRef',
+	'shared/get/_get',
 	'render/DomFragment/Component/initialise/createModel/ComponentParameter'
 ], function (
 	types,
 	parseJSON,
 	resolveRef,
+	get,
 	ComponentParameter
 ) {
 
 	'use strict';
 
-	return function ( component, attributes, toBind ) {
+	return function ( component, defaultData, attributes, toBind ) {
 		var data, key, value;
 
 		data = {};
@@ -25,7 +27,8 @@ define([
 		for ( key in attributes ) {
 			if ( attributes.hasOwnProperty( key ) ) {
 				value = getValue( component, key, attributes[ key ], toBind );
-				if ( value !== undefined ) {
+
+				if ( value !== undefined || ( defaultData[ key ] === undefined ) ) {
 					data[ key ] = value;
 				}
 			}
@@ -35,9 +38,9 @@ define([
 	};
 
 	function getValue ( component, key, descriptor, toBind ) {
-		var parameter, parsed, root, parentFragment, keypath;
+		var parameter, parsed, parentInstance, parentFragment, keypath, indexRef;
 
-		root = component.root;
+		parentInstance = component.root;
 		parentFragment = component.parentFragment;
 
 		// If this is a static value, great
@@ -55,18 +58,19 @@ define([
 		if ( descriptor.length === 1 && descriptor[0].t === types.INTERPOLATOR && descriptor[0].r ) {
 
 			// Is it an index reference?
-			if ( parentFragment.indexRefs && parentFragment.indexRefs[ descriptor[0].r ] !== undefined ) {
-				return parentFragment.indexRefs[ descriptor[0].r ];
+			if ( parentFragment.indexRefs && parentFragment.indexRefs[ ( indexRef = descriptor[0].r ) ] !== undefined ) {
+				component.indexRefBindings[ indexRef ] = key;
+				return parentFragment.indexRefs[ indexRef ];
 			}
 
 			// TODO what about references that resolve late? Should these be considered?
-			keypath = resolveRef( root, descriptor[0].r, parentFragment.contextStack ) || descriptor[0].r;
+			keypath = resolveRef( parentInstance, descriptor[0].r, parentFragment ) || descriptor[0].r;
 
 			// We need to set up bindings between parent and child, but
 			// we can't do it yet because the child instance doesn't exist
 			// yet - so we make a note instead
 			toBind.push({ childKeypath: key, parentKeypath: keypath });
-			return root.get( keypath );
+			return get( parentInstance, keypath );
 		}
 
 		// We have a 'complex parameter' - we need to create a full-blown string
@@ -77,4 +81,4 @@ define([
 		return parameter.value;
 	}
 
-});
\ No newline at end of file
+});
diff --git a/src/render/DomFragment/Component/initialise/createObservers.js b/src/render/DomFragment/Component/initialise/createObservers.js
deleted file mode 100644
index c822bc4d25..0000000000
--- a/src/render/DomFragment/Component/initialise/createObservers.js
+++ /dev/null
@@ -1,61 +0,0 @@
-define([
-
-], function (
-
-) {
-
-	'use strict';
-
-	var observeOptions = { init: false, debug: true };
-
-	return function ( component, toBind ) {
-		var pair, i;
-
-		component.observers = [];
-
-		i = toBind.length;
-		while ( i-- ) {
-			pair = toBind[i];
-			bind( component, pair.parentKeypath, pair.childKeypath );
-		}
-	};
-
-
-	function bind ( component, parentKeypath, childKeypath ) {
-		var parentInstance, childInstance, settingParent, settingChild, observers, observer, value;
-
-		parentInstance = component.root;
-		childInstance = component.instance;
-
-		observers = component.observers;
-
-		observer = parentInstance.observe( parentKeypath, function ( value ) {
-			if ( !settingParent && !parentInstance._wrapped[ parentKeypath ] ) {
-				settingChild = true;
-				childInstance.set( childKeypath, value );
-				settingChild = false;
-			}
-		}, observeOptions );
-
-		observers.push( observer );
-
-		if ( childInstance.twoway ) {
-			observer = childInstance.observe( childKeypath, function ( value ) {
-				if ( !settingChild ) {
-					settingParent = true;
-					parentInstance.set( parentKeypath, value );
-					settingParent = false;
-				}
-			}, observeOptions );
-
-			observers.push( observer );
-
-			// initialise - in case the component has default data etc
-			value = childInstance.get( childKeypath );
-			if ( value !== undefined ) {
-				parentInstance.set( parentKeypath, value );
-			}
-		}
-	}
-
-});
\ No newline at end of file
diff --git a/src/render/DomFragment/Component/initialise/propagateEvents.js b/src/render/DomFragment/Component/initialise/propagateEvents.js
index 235f6acf87..2ce6252abf 100644
--- a/src/render/DomFragment/Component/initialise/propagateEvents.js
+++ b/src/render/DomFragment/Component/initialise/propagateEvents.js
@@ -41,4 +41,4 @@ define([
 		});
 	}
 
-});
\ No newline at end of file
+});
diff --git a/src/render/DomFragment/Component/initialise/updateLiveQueries.js b/src/render/DomFragment/Component/initialise/updateLiveQueries.js
index eac45e2325..188f91859e 100644
--- a/src/render/DomFragment/Component/initialise/updateLiveQueries.js
+++ b/src/render/DomFragment/Component/initialise/updateLiveQueries.js
@@ -16,4 +16,4 @@ define( function () {
 		}
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/render/DomFragment/Element/_Element.js b/src/render/DomFragment/Element/_Element.js
index fe013634c9..ee52d04af9 100755
--- a/src/render/DomFragment/Element/_Element.js
+++ b/src/render/DomFragment/Element/_Element.js
@@ -1,7 +1,9 @@
 define([
+	'global/runloop',
+	'global/css',
 	'render/DomFragment/Element/initialise/_initialise',
-
 	'render/DomFragment/Element/prototype/teardown',
+	'render/DomFragment/Element/prototype/reassign',
 	'render/DomFragment/Element/prototype/toString',
 	'render/DomFragment/Element/prototype/find',
 	'render/DomFragment/Element/prototype/findAll',
@@ -9,9 +11,11 @@ define([
 	'render/DomFragment/Element/prototype/findAllComponents',
 	'render/DomFragment/Element/prototype/bind'
 ], function (
+	runloop,
+	css,
 	initialise,
-
 	teardown,
+	reassign,
 	toString,
 	find,
 	findAll,
@@ -28,6 +32,8 @@ define([
 
 	DomElement.prototype = {
 		detach: function () {
+			var Component;
+
 			if ( this.node ) {
 				// need to check for parent node - DOM may have been altered
 				// by something other than Ractive! e.g. jQuery UI...
@@ -36,10 +42,23 @@ define([
 				}
 				return this.node;
 			}
+
+			// If this element has child components with their own CSS, that CSS needs to
+			// be removed now
+			// TODO optimise this
+			if ( this.cssDetachQueue.length ) {
+				runloop.start();
+				while ( Component === this.cssDetachQueue.pop() ) {
+					css.remove( Component );
+				}
+				runloop.end();
+			}
 		},
 
 		teardown: teardown,
 
+		reassign: reassign,
+
 		firstNode: function () {
 			return this.node;
 		},
@@ -61,4 +80,4 @@ define([
 
 	return DomElement;
 
-});
\ No newline at end of file
+});
diff --git a/src/render/DomFragment/Element/initialise/_initialise.js b/src/render/DomFragment/Element/initialise/_initialise.js
index 96d0a3c72e..60ca288ab1 100644
--- a/src/render/DomFragment/Element/initialise/_initialise.js
+++ b/src/render/DomFragment/Element/initialise/_initialise.js
@@ -1,12 +1,14 @@
 define([
+	'global/runloop',
 	'config/types',
 	'config/namespaces',
 	'utils/create',
 	'utils/defineProperty',
-	'utils/matches',
 	'utils/warn',
 	'utils/createElement',
+	'shared/getInnerContext',
 	'render/DomFragment/Element/initialise/getElementNamespace',
+	'render/DomFragment/Element/initialise/createElementAttribute',
 	'render/DomFragment/Element/initialise/createElementAttributes',
 	'render/DomFragment/Element/initialise/appendElementChildren',
 	'render/DomFragment/Element/initialise/decorate/_decorate',
@@ -15,14 +17,16 @@ define([
 	'render/DomFragment/Element/shared/executeTransition/_executeTransition',
 	'render/DomFragment/shared/enforceCase'
 ], function (
+	runloop,
 	types,
 	namespaces,
 	create,
 	defineProperty,
-	matches,
 	warn,
 	createElement,
+	getInnerContext,
 	getElementNamespace,
+	createElementAttribute,
 	createElementAttributes,
 	appendElementChildren,
 	decorate,
@@ -34,10 +38,9 @@ define([
 
 	'use strict';
 
-	return function ( element, options, docFrag ) {
+	return function initialiseElement ( element, options, docFrag ) {
 		var parentFragment,
 			pNode,
-			contextStack,
 			descriptor,
 			namespace,
 			name,
@@ -54,9 +57,10 @@ define([
 		// stuff we'll need later
 		parentFragment = element.parentFragment = options.parentFragment;
 		pNode = parentFragment.pNode;
-		contextStack = parentFragment.contextStack;
 		descriptor = element.descriptor = options.descriptor;
 
+		element.parent = options.pElement;
+
 		element.root = root = parentFragment.root;
 		element.index = options.index;
 		element.lcName = descriptor.e.toLowerCase();
@@ -64,6 +68,8 @@ define([
 		element.eventListeners = [];
 		element.customEventListeners = [];
 
+		element.cssDetachQueue = [];
+
 		// get namespace, if we're actually rendering (not server-side stringifying)
 		if ( pNode ) {
 			namespace = element.namespace = getElementNamespace( descriptor, pNode );
@@ -74,12 +80,19 @@ define([
 			// create the DOM node
 			element.node = createElement( name, namespace );
 
+			// Is this a top-level node of a component? If so, we may need to add
+			// a data-rvcguid attribute, for CSS encapsulation
+			if ( root.css && pNode === root.el ) {
+				element.node.setAttribute( 'data-rvcguid', root.constructor._guid || root._guid );
+			}
+
+
 			// Add _ractive property to the node - we use this object to store stuff
 			// related to proxy events, two-way bindings etc
 			defineProperty( element.node, '_ractive', {
 				value: {
 					proxy: element,
-					keypath: ( contextStack.length ? contextStack[ contextStack.length - 1 ] : '' ),
+					keypath: getInnerContext( parentFragment ),
 					index: parentFragment.indexRefs,
 					events: create( null ),
 					root: root
@@ -157,12 +170,12 @@ define([
 
 			// apply decorator(s)
 			if ( descriptor.o ) {
-				decorate( descriptor.o, root, element, contextStack );
+				decorate( descriptor.o, root, element );
 			}
 
 			// trigger intro transition
 			if ( descriptor.t1 ) {
-				executeTransition( descriptor.t1, root, element, contextStack, true );
+				executeTransition( descriptor.t1, root, element, true );
 			}
 
 			if ( element.node.tagName === 'OPTION' ) {
@@ -173,6 +186,13 @@ define([
 					selectBinding.deferUpdate();
 				}
 
+				// If a value attribute was not given, we need to create one based on
+				// the content of the node, so that `` behaves the
+				// same as `` with two-way binding
+				if ( !attributes.value ) {
+					createElementAttribute( element, 'value', descriptor.f );
+				}
+
 				// Special case... a select may have had its value set before a matching
 				// option was rendered. This might be that option element
 				if ( element.node._ractive.value == pNode._ractive.value ) {
@@ -184,11 +204,25 @@ define([
 				// Special case. Some browsers (*cough* Firefix *cough*) have a problem
 				// with dynamically-generated elements having autofocus, and they won't
 				// allow you to programmatically focus the element until it's in the DOM
-				root._deferred.focusable = element.node;
+				runloop.focus( element.node );
 			}
 		}
 
+		// If this is an option element, we need to store a reference to its select
+		if ( element.lcName === 'option' ) {
+			element.select = findParentSelect( element.parent );
+		}
+
 		updateLiveQueries( element );
 	};
 
-});
\ No newline at end of file
+
+	function findParentSelect ( element ) {
+		do {
+			if ( element.lcName === 'select' ) {
+				return element;
+			}
+		} while ( element = element.parent );
+	}
+
+});
diff --git a/src/render/DomFragment/Element/initialise/addEventProxies/_addEventProxies.js b/src/render/DomFragment/Element/initialise/addEventProxies/_addEventProxies.js
index 1ec6716349..9e4c485ea8 100644
--- a/src/render/DomFragment/Element/initialise/addEventProxies/_addEventProxies.js
+++ b/src/render/DomFragment/Element/initialise/addEventProxies/_addEventProxies.js
@@ -11,10 +11,10 @@ define([ 'render/DomFragment/Element/initialise/addEventProxies/addEventProxy' ]
 				i = eventNames.length;
 
 				while ( i-- ) {
-					addEventProxy( element, eventNames[i], proxies[ eventName ], element.parentFragment.contextStack );
+					addEventProxy( element, eventNames[i], proxies[ eventName ] );
 				}
 			}
 		}
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/render/DomFragment/Element/initialise/addEventProxies/addEventProxy.js b/src/render/DomFragment/Element/initialise/addEventProxies/addEventProxy.js
index 06bd941072..c3c26b8582 100644
--- a/src/render/DomFragment/Element/initialise/addEventProxies/addEventProxy.js
+++ b/src/render/DomFragment/Element/initialise/addEventProxies/addEventProxy.js
@@ -14,23 +14,22 @@ define([ 'utils/warn', 'render/StringFragment/_StringFragment' ], function ( war
 		genericHandler,
 		getCustomHandler;
 
-	addEventProxy = function ( element, triggerEventName, proxyDescriptor, contextStack, indexRefs ) {
+	addEventProxy = function ( element, triggerEventName, proxyDescriptor, indexRefs ) {
 		var events, master;
 
 		events = element.node._ractive.events;
-		master = events[ triggerEventName ] || ( events[ triggerEventName ] = new MasterEventHandler( element, triggerEventName, contextStack, indexRefs ) );
+		master = events[ triggerEventName ] || ( events[ triggerEventName ] = new MasterEventHandler( element, triggerEventName, indexRefs ) );
 
 		master.add( proxyDescriptor );
 	};
 
-	MasterEventHandler = function ( element, eventName, contextStack ) {
+	MasterEventHandler = function ( element, eventName ) {
 		var definition;
 
 		this.element = element;
 		this.root = element.root;
 		this.node = element.node;
 		this.name = eventName;
-		this.contextStack = contextStack; // TODO do we need to pass contextStack down everywhere? Doesn't it belong to the parentFragment?
 		this.proxies = [];
 
 		if ( definition = this.root.events[ eventName ] ) {
@@ -38,7 +37,7 @@ define([ 'utils/warn', 'render/StringFragment/_StringFragment' ], function ( war
 		} else {
 			// Looks like we're dealing with a standard DOM event... but let's check
 			if ( !( 'on' + eventName in this.node ) ) {
-				warn( 'Missing "' + this.name + '" event. You may need to download a plugin via https://github.com/RactiveJS/Ractive/wiki/Plugins#events' );
+				warn( 'Missing "' + this.name + '" event. You may need to download a plugin via http://docs.ractivejs.org/latest/plugins#events' );
 			}
 
 			this.node.addEventListener( eventName, genericHandler, false );
@@ -47,7 +46,7 @@ define([ 'utils/warn', 'render/StringFragment/_StringFragment' ], function ( war
 
 	MasterEventHandler.prototype = {
 		add: function ( proxy ) {
-			this.proxies[ this.proxies.length ] = new ProxyEvent( this.element, this.root, proxy, this.contextStack );
+			this.proxies.push( new ProxyEvent( this.element, this.root, proxy ) );
 		},
 
 		// TODO teardown when element torn down
@@ -75,7 +74,7 @@ define([ 'utils/warn', 'render/StringFragment/_StringFragment' ], function ( war
 		}
 	};
 
-	ProxyEvent = function ( element, ractive, descriptor, contextStack ) {
+	ProxyEvent = function ( element, ractive, descriptor ) {
 		var name;
 
 		this.root = ractive;
@@ -88,8 +87,7 @@ define([ 'utils/warn', 'render/StringFragment/_StringFragment' ], function ( war
 			this.n = new StringFragment({
 				descriptor:   descriptor.n,
 				root:         this.root,
-				owner:        element,
-				contextStack: contextStack
+				owner:        element
 			});
 		}
 
@@ -103,8 +101,7 @@ define([ 'utils/warn', 'render/StringFragment/_StringFragment' ], function ( war
 			this.d = new StringFragment({
 				descriptor:   descriptor.d,
 				root:         this.root,
-				owner:        element,
-				contextStack: contextStack
+				owner:        element
 			});
 			this.fire = fireEventWithDynamicArgs;
 			return;
@@ -180,4 +177,4 @@ define([ 'utils/warn', 'render/StringFragment/_StringFragment' ], function ( war
 
 	return addEventProxy;
 
-});
\ No newline at end of file
+});
diff --git a/src/render/DomFragment/Element/initialise/appendElementChildren.js b/src/render/DomFragment/Element/initialise/appendElementChildren.js
index fc4068a6f7..977d6b65f5 100644
--- a/src/render/DomFragment/Element/initialise/appendElementChildren.js
+++ b/src/render/DomFragment/Element/initialise/appendElementChildren.js
@@ -2,11 +2,13 @@ define([
 	'utils/warn',
 	'config/namespaces',
 	'render/StringFragment/_StringFragment',
+	'render/DomFragment/Element/shared/getMatchingStaticNodes',
 	'circular'
 ], function (
 	warn,
 	namespaces,
 	StringFragment,
+	getMatchingStaticNodes,
 	circular
 ) {
 
@@ -24,9 +26,10 @@ define([
 
 		if ( node.styleSheet ) {
 			node.styleSheet.cssText = content;
+		} else {
+			node.innerHTML = content;
 		}
 
-		node.innerHTML = content;
 	};
 
 	updateScript = function () {
@@ -37,26 +40,23 @@ define([
 			// But this would be a terrible idea with unpredictable results, so let's not.
 		}
 
-		this.node.innerHTML = this.fragment.toString();
+		this.node.text = this.fragment.toString();
 	};
 
 
-	return function ( element, node, descriptor, docFrag ) {
-		var liveQueries, i, selector, queryAllResult, j;
-
+	return function appendElementChildren ( element, node, descriptor, docFrag ) {
 		// Special case - script and style tags
 		if ( element.lcName === 'script' || element.lcName === 'style' ) {
 			element.fragment = new StringFragment({
 				descriptor:   descriptor.f,
 				root:         element.root,
-				contextStack: element.parentFragment.contextStack,
 				owner:        element
 			});
 
 			if ( docFrag ) {
 				if ( element.lcName === 'script' ) {
 					element.bubble = updateScript;
-					element.node.innerHTML = element.fragment.toString(); // bypass warning initially
+					element.node.text = element.fragment.toString(); // bypass warning initially
 				} else {
 					element.bubble = updateCss;
 					element.bubble();
@@ -74,30 +74,18 @@ define([
 				node.innerHTML = element.html;
 
 				// Update live queries, if applicable
-				liveQueries = element.root._liveQueries;
-				i = liveQueries.length;
-				while ( i-- ) {
-					selector = liveQueries[i];
-
-					if ( ( queryAllResult = node.querySelectorAll( selector ) ) && ( j = queryAllResult.length ) ) {
-						( element.liveQueries || ( element.liveQueries = [] ) ).push( selector );
-						element.liveQueries[ selector ] = [];
-
-						while ( j-- ) {
-							element.liveQueries[ selector ][j] = queryAllResult[j];
-						}
-					}
-				}
+				element.matchingStaticNodes = {}; // so we can remove matches made with querySelectorAll at teardown time
+				updateLiveQueries( element );
 			}
 		}
 
 		else {
 			element.fragment = new DomFragment({
-				descriptor:   descriptor.f,
-				root:         element.root,
-				pNode:        node,
-				contextStack: element.parentFragment.contextStack,
-				owner:        element
+				descriptor:    descriptor.f,
+				root:          element.root,
+				pNode:         node,
+				owner:         element,
+				pElement:      element,
 			});
 
 			if ( docFrag ) {
@@ -106,4 +94,24 @@ define([
 		}
 	};
 
-});
\ No newline at end of file
+	function updateLiveQueries ( element ) {
+		var instance, liveQueries, node, selector, query, matchingStaticNodes, i;
+
+		node = element.node;
+		instance = element.root;
+
+		do {
+			liveQueries = instance._liveQueries;
+
+			i = liveQueries.length;
+			while ( i-- ) {
+				selector = liveQueries[i];
+				query = liveQueries[ selector ];
+
+				matchingStaticNodes = getMatchingStaticNodes( element, selector );
+				query.push.apply( query, matchingStaticNodes );
+			}
+		} while ( instance = instance._parent );
+	}
+
+});
diff --git a/src/render/DomFragment/Element/initialise/createElementAttribute.js b/src/render/DomFragment/Element/initialise/createElementAttribute.js
new file mode 100644
index 0000000000..19cab6032f
--- /dev/null
+++ b/src/render/DomFragment/Element/initialise/createElementAttribute.js
@@ -0,0 +1,31 @@
+define([
+	'render/DomFragment/Attribute/_Attribute'
+], function (
+	Attribute
+) {
+
+	'use strict';
+
+	return function createElementAttribute ( element, name, fragment ) {
+		var attr = new Attribute({
+			element:      element,
+			name:         name,
+			value:        fragment,
+			root:         element.root,
+			pNode:        element.node
+		});
+
+		// store against both index and name, for fast iteration and lookup
+		element.attributes.push( element.attributes[ name ] = attr );
+
+		// The name attribute is a special case - it is the only two-way attribute that updates
+		// the viewmodel based on the value of another attribute. For that reason it must wait
+		// until the node has been initialised, and the viewmodel has had its first two-way
+		// update, before updating itself (otherwise it may disable a checkbox or radio that
+		// was enabled in the template)
+		if ( name !== 'name' ) {
+			attr.update();
+		}
+	};
+
+});
diff --git a/src/render/DomFragment/Element/initialise/createElementAttributes.js b/src/render/DomFragment/Element/initialise/createElementAttributes.js
index 6165ce1bc0..ea409b8fb6 100644
--- a/src/render/DomFragment/Element/initialise/createElementAttributes.js
+++ b/src/render/DomFragment/Element/initialise/createElementAttributes.js
@@ -1,40 +1,21 @@
-define([ 'render/DomFragment/Attribute/_Attribute' ], function ( DomAttribute ) {
+define([
+	'render/DomFragment/Element/initialise/createElementAttribute'
+], function ( createElementAttribute ) {
 
 	'use strict';
 
 	return function ( element, attributes ) {
-		var attrName, attrValue, attr;
+		var attrName;
 
 		element.attributes = [];
 
 		for ( attrName in attributes ) {
 			if ( attributes.hasOwnProperty( attrName ) ) {
-				attrValue = attributes[ attrName ];
-
-				attr = new DomAttribute({
-					element:      element,
-					name:         attrName,
-					value:        attrValue,
-					root:         element.root,
-					pNode:        element.node,
-					contextStack: element.parentFragment.contextStack
-				});
-
-				// store against both index and name, for fast iteration and lookup
-				element.attributes[ element.attributes.length ] = element.attributes[ attrName ] = attr;
-
-				// The name attribute is a special case - it is the only two-way attribute that updates
-				// the viewmodel based on the value of another attribute. For that reason it must wait
-				// until the node has been initialised, and the viewmodel has had its first two-way
-				// update, before updating itself (otherwise it may disable a checkbox or radio that
-				// was enabled in the template)
-				if ( attrName !== 'name' ) {
-					attr.update();
-				}
+				createElementAttribute( element, attrName, attributes[ attrName ] );
 			}
 		}
 
 		return element.attributes;
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/render/DomFragment/Element/initialise/decorate/Decorator.js b/src/render/DomFragment/Element/initialise/decorate/Decorator.js
index dfb2f9e76e..208bd97572 100644
--- a/src/render/DomFragment/Element/initialise/decorate/Decorator.js
+++ b/src/render/DomFragment/Element/initialise/decorate/Decorator.js
@@ -8,20 +8,19 @@ define([
 
 	'use strict';
 
-	var Decorator = function ( descriptor, root, owner, contextStack ) {
-		var name, fragment, errorMessage;
+	var Decorator = function ( descriptor, ractive, owner ) {
+		var decorator = this, name, fragment, errorMessage;
 
-		this.root = root;
-		this.node = owner.node;
+		decorator.root = ractive;
+		decorator.node = owner.node;
 
 		name = descriptor.n || descriptor;
 
 		if ( typeof name !== 'string' ) {
 			fragment = new StringFragment({
 				descriptor:   name,
-				root:         this.root,
-				owner:        owner,
-				contextStack: contextStack
+				root:         ractive,
+				owner:        owner
 			});
 
 			name = fragment.toString();
@@ -29,27 +28,34 @@ define([
 		}
 
 		if ( descriptor.a ) {
-			this.params = descriptor.a;
+			decorator.params = descriptor.a;
 		}
 
 		else if ( descriptor.d ) {
-			fragment = new StringFragment({
+			decorator.fragment = new StringFragment({
 				descriptor:   descriptor.d,
-				root:         this.root,
-				owner:        owner,
-				contextStack: contextStack
+				root:         ractive,
+				owner:        owner
 			});
 
-			this.params = fragment.toArgsList();
-			fragment.teardown();
+			decorator.params = decorator.fragment.toArgsList();
+
+			decorator.fragment.bubble = function () {
+				this.dirty = true;
+				decorator.params = this.toArgsList();
+
+				if ( decorator.ready ) {
+					decorator.update();
+				}
+			};
 		}
 
-		this.fn = root.decorators[ name ];
+		decorator.fn = ractive.decorators[ name ];
 
-		if ( !this.fn ) {
-			errorMessage = 'Missing "' + name + '" decorator. You may need to download a plugin via https://github.com/RactiveJS/Ractive/wiki/Plugins#decorators';
+		if ( !decorator.fn ) {
+			errorMessage = 'Missing "' + name + '" decorator. You may need to download a plugin via http://docs.ractivejs.org/latest/plugins#decorators';
 
-			if ( root.debug ) {
+			if ( ractive.debug ) {
 				throw new Error( errorMessage );
 			} else {
 				warn( errorMessage );
@@ -73,10 +79,30 @@ define([
 			}
 
 			// TODO does this make sense?
-			this.teardown = result.teardown;
+			this.actual = result;
+			this.ready = true;
+		},
+
+		update: function () {
+			if ( this.actual.update ) {
+				this.actual.update.apply( this.root, this.params );
+			}
+
+			else {
+				this.actual.teardown( true );
+				this.init();
+			}
+		},
+
+		teardown: function ( updating ) {
+			this.actual.teardown();
+
+			if ( !updating && this.fragment ) {
+				this.fragment.teardown();
+			}
 		}
 	};
 
 	return Decorator;
 
-});
\ No newline at end of file
+});
diff --git a/src/render/DomFragment/Element/initialise/decorate/_decorate.js b/src/render/DomFragment/Element/initialise/decorate/_decorate.js
index b63101e170..6dd3a9f0ae 100644
--- a/src/render/DomFragment/Element/initialise/decorate/_decorate.js
+++ b/src/render/DomFragment/Element/initialise/decorate/_decorate.js
@@ -1,17 +1,20 @@
 define([
+	'global/runloop',
 	'render/DomFragment/Element/initialise/decorate/Decorator'
 ], function (
+	runloop,
 	Decorator
 ) {
 
 	'use strict';
 
-	return function ( descriptor, root, owner, contextStack ) {
-		owner.decorator = new Decorator( descriptor, root, owner, contextStack );
+	return function ( descriptor, root, owner ) {
+		var decorator = new Decorator( descriptor, root, owner );
 
-		if ( owner.decorator.fn ) {
-			root._deferred.decorators.push( owner.decorator );
+		if ( decorator.fn ) {
+			owner.decorator = decorator;
+			runloop.addDecorator( owner.decorator );
 		}
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/render/DomFragment/Element/initialise/getElementNamespace.js b/src/render/DomFragment/Element/initialise/getElementNamespace.js
index f70a3ae3bb..c735eca433 100644
--- a/src/render/DomFragment/Element/initialise/getElementNamespace.js
+++ b/src/render/DomFragment/Element/initialise/getElementNamespace.js
@@ -12,4 +12,4 @@ define([ 'config/namespaces' ], function ( namespaces ) {
 		return ( descriptor.e === 'svg' ? namespaces.svg : parentNode.namespaceURI || namespaces.html );
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/render/DomFragment/Element/initialise/updateLiveQueries.js b/src/render/DomFragment/Element/initialise/updateLiveQueries.js
index 24ac5efd92..52f6f841e2 100644
--- a/src/render/DomFragment/Element/initialise/updateLiveQueries.js
+++ b/src/render/DomFragment/Element/initialise/updateLiveQueries.js
@@ -3,23 +3,25 @@ define( function () {
 	'use strict';
 
 	return function ( element ) {
-		var ractive, liveQueries, i, selector, query;
+		var instance, liveQueries, i, selector, query;
 
 		// Does this need to be added to any live queries?
-		ractive = element.root;
-		liveQueries = ractive._liveQueries;
+		instance = element.root;
 
-		i = liveQueries.length;
-		while ( i-- ) {
-			selector = liveQueries[i];
-			query = liveQueries[ selector ];
+		do {
+			liveQueries = instance._liveQueries;
 
-			if ( query._test( element ) ) {
-				// keep register of applicable selectors, for when we teardown
-				( element.liveQueries || ( element.liveQueries = [] ) ).push( selector );
-				element.liveQueries[ selector ] = [ element.node ];
+			i = liveQueries.length;
+			while ( i-- ) {
+				selector = liveQueries[i];
+				query = liveQueries[ selector ];
+
+				if ( query._test( element ) ) {
+					// keep register of applicable selectors, for when we teardown
+					( element.liveQueries || ( element.liveQueries = [] ) ).push( query );
+				}
 			}
-		}
+		} while ( instance = instance._parent );
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/render/DomFragment/Element/prototype/bind.js b/src/render/DomFragment/Element/prototype/bind.js
index a131a4b930..795c5f7444 100644
--- a/src/render/DomFragment/Element/prototype/bind.js
+++ b/src/render/DomFragment/Element/prototype/bind.js
@@ -51,4 +51,4 @@ define( function () {
 		}
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/render/DomFragment/Element/prototype/find.js b/src/render/DomFragment/Element/prototype/find.js
index d09500c28c..4b700d55d1 100644
--- a/src/render/DomFragment/Element/prototype/find.js
+++ b/src/render/DomFragment/Element/prototype/find.js
@@ -18,4 +18,4 @@ define([ 'utils/matches' ], function ( matches ) {
 		}
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/render/DomFragment/Element/prototype/findAll.js b/src/render/DomFragment/Element/prototype/findAll.js
index 9a69424426..506f6f7e9a 100644
--- a/src/render/DomFragment/Element/prototype/findAll.js
+++ b/src/render/DomFragment/Element/prototype/findAll.js
@@ -1,34 +1,26 @@
-define( function () {
+define([
+	'render/DomFragment/Element/shared/getMatchingStaticNodes'
+], function (
+	getMatchingStaticNodes
+) {
 
 	'use strict';
 
 	return function ( selector, query ) {
-		var queryAllResult, i, numNodes, node, registeredNodes;
+		var matchingStaticNodes, matchedSelf;
 
 		// Add this node to the query, if applicable, and register the
 		// query on this element
 		if ( query._test( this, true ) && query.live ) {
-			( this.liveQueries || ( this.liveQueries = [] ) ).push( selector );
-			this.liveQueries[ selector ] = [ this.node ];
+			( this.liveQueries || ( this.liveQueries = [] ) ).push( query );
 		}
 
-		if ( this.html && ( queryAllResult = this.node.querySelectorAll( selector ) ) && ( numNodes = queryAllResult.length ) ) {
-			if ( query.live ) {
-				if ( !this.liveQueries[ selector ] ) {
-					( this.liveQueries || ( this.liveQueries = [] ) ).push( selector );
-					this.liveQueries[ selector ] = [];
-				}
+		if ( this.html ) {
+			matchingStaticNodes = getMatchingStaticNodes( this, selector );
+			query.push.apply( query, matchingStaticNodes );
 
-				registeredNodes = this.liveQueries[ selector ];
-			}
-
-			for ( i = 0; i < numNodes; i += 1 ) {
-				node = queryAllResult[i];
-				query.push( node );
-
-				if ( query.live ) {
-					registeredNodes.push( node );
-				}
+			if ( query.live && !matchedSelf ) {
+				( this.liveQueries || ( this.liveQueries = [] ) ).push( query );
 			}
 		}
 
@@ -37,4 +29,4 @@ define( function () {
 		}
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/render/DomFragment/Element/prototype/findAllComponents.js b/src/render/DomFragment/Element/prototype/findAllComponents.js
index 80822271c0..baa479a3b3 100644
--- a/src/render/DomFragment/Element/prototype/findAllComponents.js
+++ b/src/render/DomFragment/Element/prototype/findAllComponents.js
@@ -8,4 +8,4 @@ define( function () {
 		}
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/render/DomFragment/Element/prototype/findComponent.js b/src/render/DomFragment/Element/prototype/findComponent.js
index 46fd36680e..57ea996769 100644
--- a/src/render/DomFragment/Element/prototype/findComponent.js
+++ b/src/render/DomFragment/Element/prototype/findComponent.js
@@ -8,4 +8,4 @@ define( function () {
 		}
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/render/DomFragment/Element/prototype/reassign.js b/src/render/DomFragment/Element/prototype/reassign.js
new file mode 100644
index 0000000000..25f795fa9d
--- /dev/null
+++ b/src/render/DomFragment/Element/prototype/reassign.js
@@ -0,0 +1,76 @@
+define([
+	'render/shared/utils/assignNewKeypath'
+], function (
+	assignNewKeypath
+) {
+
+	'use strict';
+
+	return function reassignElement ( indexRef, newIndex, oldKeypath, newKeypath ) {
+		var i, storage, masterEventName, proxies, proxy, binding, bindings, liveQueries, ractive;
+
+		i = this.attributes.length;
+		while ( i-- ) {
+			this.attributes[i].reassign( indexRef, newIndex, oldKeypath, newKeypath );
+		}
+
+		if ( storage = this.node._ractive ) {
+
+			//adjust keypath if needed
+			assignNewKeypath(storage, 'keypath', oldKeypath, newKeypath);
+
+			if ( indexRef != undefined ) {
+				storage.index[ indexRef ] = newIndex;
+			}
+
+			for ( masterEventName in storage.events ) {
+				proxies = storage.events[ masterEventName ].proxies;
+				i = proxies.length;
+
+				while ( i-- ) {
+					proxy = proxies[i];
+
+					if ( typeof proxy.n === 'object' ) {
+						proxy.a.reassign( indexRef, newIndex, oldKeypath, newKeypath );
+					}
+
+					if ( proxy.d ) {
+						proxy.d.reassign( indexRef, newIndex, oldKeypath, newKeypath );
+					}
+				}
+			}
+
+			if ( binding = storage.binding ) {
+				if ( binding.keypath.substr( 0, oldKeypath.length ) === oldKeypath ) {
+					bindings = storage.root._twowayBindings[ binding.keypath ];
+
+					// remove binding reference for old keypath
+					bindings.splice( bindings.indexOf( binding ), 1 );
+
+					// update keypath
+					binding.keypath = binding.keypath.replace( oldKeypath, newKeypath );
+
+					// add binding reference for new keypath
+					bindings = storage.root._twowayBindings[ binding.keypath ] || ( storage.root._twowayBindings[ binding.keypath ] = [] );
+					bindings.push( binding );
+				}
+			}
+		}
+
+		// reassign children
+		if ( this.fragment ) {
+			this.fragment.reassign( indexRef, newIndex, oldKeypath, newKeypath );
+		}
+
+		// Update live queries, if necessary
+		if ( liveQueries = this.liveQueries ) {
+			ractive = this.root;
+
+			i = liveQueries.length;
+			while ( i-- ) {
+				liveQueries[i]._makeDirty();
+			}
+		}
+	};
+
+});
diff --git a/src/render/DomFragment/Element/prototype/teardown.js b/src/render/DomFragment/Element/prototype/teardown.js
index 001235827f..8b8724eeb4 100644
--- a/src/render/DomFragment/Element/prototype/teardown.js
+++ b/src/render/DomFragment/Element/prototype/teardown.js
@@ -1,13 +1,21 @@
 define([
+	'global/runloop',
 	'render/DomFragment/Element/shared/executeTransition/_executeTransition'
 ], function (
+	runloop,
 	executeTransition
 ) {
 
 	'use strict';
 
-	return function ( destroy ) {
-		var eventName, binding, bindings, i, liveQueries, selector, query, nodesToRemove, j;
+	return function Element_prototype_teardown ( destroy ) {
+		var eventName, binding, bindings;
+
+		// Detach as soon as we can
+		if ( destroy ) {
+			this.willDetach = true;
+			runloop.detachWhenReady( this );
+		}
 
 		// Children first. that way, any transitions on child elements will be
 		// handled by the current transitionManager
@@ -39,30 +47,32 @@ define([
 
 		// Outro, if necessary
 		if ( this.descriptor.t2 ) {
-			executeTransition( this.descriptor.t2, this.root, this, this.parentFragment.contextStack, false );
+			executeTransition( this.descriptor.t2, this.root, this, false );
 		}
 
-		// Detach as soon as we can
-		if ( destroy ) {
-			this.root._transitionManager.detachWhenReady( this );
+		// Remove this node from any live queries
+		if ( this.liveQueries ) {
+			removeFromLiveQueries( this );
 		}
+	};
 
-		// Remove this node from any live queries
-		if ( liveQueries = this.liveQueries ) {
-			i = liveQueries.length;
-			while ( i-- ) {
-				selector = liveQueries[i];
-
-				if ( nodesToRemove = this.liveQueries[ selector ] ) {
-					j = nodesToRemove.length;
-					query = this.root._liveQueries[ selector ];
-
-					while ( j-- ) {
-						query._remove( nodesToRemove[j] );
-					}
+	function removeFromLiveQueries ( element ) {
+		var query, selector, matchingStaticNodes, i, j;
+
+		i = element.liveQueries.length;
+		while ( i-- ) {
+			query = element.liveQueries[i];
+			selector = query.selector;
+
+			query._remove( element.node );
+
+			if ( element.matchingStaticNodes && ( matchingStaticNodes = element.matchingStaticNodes[ selector ] ) ) {
+				j = matchingStaticNodes.length;
+				while ( j-- ) {
+					query.remove( matchingStaticNodes[j] );
 				}
 			}
 		}
-	};
+	}
 
-});
\ No newline at end of file
+});
diff --git a/src/render/DomFragment/Element/prototype/toString.js b/src/render/DomFragment/Element/prototype/toString.js
index ddbe1e1a85..889b372525 100644
--- a/src/render/DomFragment/Element/prototype/toString.js
+++ b/src/render/DomFragment/Element/prototype/toString.js
@@ -1,15 +1,33 @@
-define([ 'config/voidElementNames' ], function ( voidElementNames ) {
+define([
+	'config/voidElementNames',
+	'utils/isArray'
+], function (
+	voidElementNames,
+	isArray
+) {
 
 	'use strict';
 
 	return function () {
-		var str, i, len;
+		var str, i, len, attrStr;
 
 		str = '<' + ( this.descriptor.y ? '!doctype' : this.descriptor.e );
 
 		len = this.attributes.length;
 		for ( i=0; i';
 		}
 
+		this.stringifying = false;
 		return str;
 	};
 
-});
\ No newline at end of file
+
+	function optionIsSelected ( element ) {
+		var optionValue, selectValueAttribute, selectValueInterpolator, selectValue, i;
+
+		optionValue = element.attributes.value.value;
+
+		selectValueAttribute = element.select.attributes.value;
+		selectValueInterpolator = selectValueAttribute.interpolator;
+
+		if ( !selectValueInterpolator ) {
+			return;
+		}
+
+		selectValue = element.root.get( selectValueInterpolator.keypath || selectValueInterpolator.ref );
+
+		if ( selectValue == optionValue ) {
+			return true;
+		}
+
+		if ( element.select.attributes.multiple && isArray( selectValue ) ) {
+			i = selectValue.length;
+			while ( i-- ) {
+				if ( selectValue[i] == optionValue ) {
+					return true;
+				}
+			}
+		}
+	}
+
+	function inputIsCheckedRadio ( element ) {
+		var attributes, typeAttribute, valueAttribute, nameAttribute;
+
+		attributes = element.attributes;
+
+		typeAttribute  = attributes.type;
+		valueAttribute = attributes.value;
+		nameAttribute  = attributes.name;
+
+		if ( !typeAttribute || ( typeAttribute.value !== 'radio' ) || !valueAttribute || !nameAttribute.interpolator ) {
+			return;
+		}
+
+		if ( valueAttribute.value === nameAttribute.interpolator.value ) {
+			return true;
+		}
+	}
+
+});
diff --git a/src/render/DomFragment/Element/shared/executeTransition/Transition.js b/src/render/DomFragment/Element/shared/executeTransition/Transition.js
deleted file mode 100644
index d8ecfcc7ad..0000000000
--- a/src/render/DomFragment/Element/shared/executeTransition/Transition.js
+++ /dev/null
@@ -1,398 +0,0 @@
-define([
-	'config/isClient',
-	'utils/createElement',
-	'utils/warn',
-	'utils/isNumeric',
-	'utils/isArray',
-	'utils/camelCase',
-	'utils/fillGaps',
-	'render/StringFragment/_StringFragment'
-], function (
-	isClient,
-	createElement,
-	warn,
-	isNumeric,
-	isArray,
-	camelCase,
-	fillGaps,
-	StringFragment
-) {
-
-	'use strict';
-
-	var Transition,
-
-		testStyle,
-		vendors,
-		vendorPattern,
-		unprefixPattern,
-		prefixCache,
-
-		CSS_TRANSITIONS_ENABLED,
-		TRANSITION,
-		TRANSITION_DURATION,
-		TRANSITION_PROPERTY,
-		TRANSITION_TIMING_FUNCTION,
-		TRANSITIONEND;
-
-	if ( !isClient ) {
-		// not relevant server-side
-		return;
-	}
-
-	testStyle = createElement( 'div' ).style;
-
-	// determine some facts about our environment
-	(function () {
-
-		if ( testStyle.transition !== undefined ) {
-			TRANSITION = 'transition';
-			TRANSITIONEND = 'transitionend';
-			CSS_TRANSITIONS_ENABLED = true;
-		} else if ( testStyle.webkitTransition !== undefined ) {
-			TRANSITION = 'webkitTransition';
-			TRANSITIONEND = 'webkitTransitionEnd';
-			CSS_TRANSITIONS_ENABLED = true;
-		} else {
-			CSS_TRANSITIONS_ENABLED = false;
-		}
-
-	}());
-
-	if ( TRANSITION ) {
-		TRANSITION_DURATION = TRANSITION + 'Duration';
-		TRANSITION_PROPERTY = TRANSITION + 'Property';
-		TRANSITION_TIMING_FUNCTION = TRANSITION + 'TimingFunction';
-	}
-
-	Transition = function ( descriptor, root, owner, contextStack, isIntro ) {
-		var t = this, name, fragment, errorMessage;
-
-		this.root = root;
-		this.node = owner.node;
-		this.isIntro = isIntro;
-
-		// store original style attribute
-		this.originalStyle = this.node.getAttribute( 'style' );
-
-		// create t.complete() - we don't want this on the prototype,
-		// because we don't want `this` silliness when passing it as
-		// an argument
-		this.complete = function ( noReset ) {
-			if ( !noReset && t.isIntro ) {
-				t.resetStyle();
-			}
-
-			t._manager.pop( t.node );
-			t.node._ractive.transition = null;
-		};
-
-
-		name = descriptor.n || descriptor;
-
-		if ( typeof name !== 'string' ) {
-			fragment = new StringFragment({
-				descriptor:   name,
-				root:         this.root,
-				owner:        owner,
-				contextStack: contextStack
-			});
-
-			name = fragment.toString();
-			fragment.teardown();
-		}
-
-		this.name = name;
-
-		if ( descriptor.a ) {
-			this.params = descriptor.a;
-		}
-
-		else if ( descriptor.d ) {
-			// TODO is there a way to interpret dynamic arguments without all the
-			// 'dependency thrashing'?
-			fragment = new StringFragment({
-				descriptor:   descriptor.d,
-				root:         this.root,
-				owner:        owner,
-				contextStack: contextStack
-			});
-
-			this.params = fragment.toArgsList();
-			fragment.teardown();
-		}
-
-		this._fn = root.transitions[ name ];
-		if ( !this._fn ) {
-			errorMessage = 'Missing "' + name + '" transition. You may need to download a plugin via https://github.com/RactiveJS/Ractive/wiki/Plugins#transitions';
-
-			if ( root.debug ) {
-				throw new Error( errorMessage );
-			} else {
-				warn( errorMessage );
-			}
-
-			return;
-		}
-	};
-
-	Transition.prototype = {
-		init: function () {
-			if ( this._inited ) {
-				throw new Error( 'Cannot initialize a transition more than once' );
-			}
-
-			this._inited = true;
-			this._fn.apply( this.root, [ this ].concat( this.params ) );
-		},
-
-		getStyle: function ( props ) {
-			var computedStyle, styles, i, prop, value;
-
-			computedStyle = window.getComputedStyle( this.node );
-
-			if ( typeof props === 'string' ) {
-				value = computedStyle[ prefix( props ) ];
-				if ( value === '0px' ) {
-					value = 0;
-				}
-				return value;
-			}
-
-			if ( !isArray( props ) ) {
-				throw new Error( 'Transition#getStyle must be passed a string, or an array of strings representing CSS properties' );
-			}
-
-			styles = {};
-
-			i = props.length;
-			while ( i-- ) {
-				prop = props[i];
-				value = computedStyle[ prefix( prop ) ];
-				if ( value === '0px' ) {
-					value = 0;
-				}
-				styles[ prop ] = value;
-			}
-
-			return styles;
-		},
-
-		setStyle: function ( style, value ) {
-			var prop;
-
-			if ( typeof style === 'string' ) {
-				this.node.style[ prefix( style ) ] = value;
-			}
-
-			else {
-				for ( prop in style ) {
-					if ( style.hasOwnProperty( prop ) ) {
-						this.node.style[ prefix( prop ) ] = style[ prop ];
-					}
-				}
-			}
-
-			return this;
-		},
-
-		animateStyle: function ( style, value, options, complete ) {
-			var t = this, propertyNames, changedProperties, computedStyle, current, to, from, transitionEndHandler, i, prop;
-
-			if ( typeof style === 'string' ) {
-				to = {};
-				to[ style ] = value;
-			} else {
-				to = style;
-
-				// shuffle arguments
-				complete = options;
-				options = value;
-			}
-
-			// As of 0.3.9, transition authors should supply an `option` object with
-			// `duration` and `easing` properties (and optional `delay`), plus a
-			// callback function that gets called after the animation completes
-
-			// TODO remove this check in a future version
-			if ( !options ) {
-				warn( 'The "' + t.name + '" transition does not supply an options object to `t.animateStyle()`. This will break in a future version of Ractive. For more info see https://github.com/RactiveJS/Ractive/issues/340' );
-
-				options = t;
-				complete = t.complete;
-			}
-
-			// Edge case - if duration is zero, set style synchronously and complete
-			if ( !options.duration ) {
-				t.setStyle( to );
-
-				if ( complete ) {
-					complete();
-				}
-			}
-
-			// Get a list of the properties we're animating
-			propertyNames = Object.keys( to );
-			changedProperties = [];
-
-			// Store the current styles
-			computedStyle = window.getComputedStyle( t.node );
-
-			from = {};
-			i = propertyNames.length;
-			while ( i-- ) {
-				prop = propertyNames[i];
-				current = computedStyle[ prefix( prop ) ];
-
-				if ( current === '0px' ) {
-					current = 0;
-				}
-
-				// we need to know if we're actually changing anything
-				if ( current != to[ prop ] ) { // use != instead of !==, so we can compare strings with numbers
-					changedProperties[ changedProperties.length ] = prop;
-
-					// make the computed style explicit, so we can animate where
-					// e.g. height='auto'
-					t.node.style[ prefix( prop ) ] = current;
-				}
-			}
-
-			// If we're not actually changing anything, the transitionend event
-			// will never fire! So we complete early
-			if ( !changedProperties.length ) {
-				if ( complete ) {
-					complete();
-				}
-				return;
-			}
-
-			// Wait a beat (otherwise the target styles will be applied immediately)
-			// TODO use a fastdom-style mechanism?
-			setTimeout( function () {
-
-				t.node.style[ TRANSITION_PROPERTY ] = propertyNames.map( prefix ).map( hyphenate ).join( ',' );
-				t.node.style[ TRANSITION_TIMING_FUNCTION ] = hyphenate( options.easing || 'linear' );
-				t.node.style[ TRANSITION_DURATION ] = ( options.duration / 1000 ) + 's';
-
-				transitionEndHandler = function ( event ) {
-					var index;
-
-					index = changedProperties.indexOf( camelCase( unprefix( event.propertyName ) ) );
-					if ( index !== -1 ) {
-						changedProperties.splice( index, 1 );
-					}
-
-					if ( changedProperties.length ) {
-						// still transitioning...
-						return;
-					}
-
-					t.root.fire(t.name + ':end');
-
-					t.node.removeEventListener( TRANSITIONEND, transitionEndHandler, false );
-
-					if ( complete ) {
-						complete();
-					}
-				};
-
-				t.node.addEventListener( TRANSITIONEND, transitionEndHandler, false );
-
-				setTimeout( function () {
-					var i = changedProperties.length;
-
-					while ( i-- ) {
-						prop = changedProperties[i];
-						t.node.style[ prefix( prop ) ] = to[ prop ];
-					}
-				}, 0 );
-			}, options.delay || 0 );
-		},
-
-		resetStyle: function () {
-			if ( this.originalStyle ) {
-				this.node.setAttribute( 'style', this.originalStyle );
-			} else {
-
-				// Next line is necessary, to remove empty style attribute!
-				// See http://stackoverflow.com/a/7167553
-				this.node.getAttribute( 'style' );
-				this.node.removeAttribute( 'style' );
-			}
-		},
-
-		processParams: function ( params, defaults ) {
-			if ( typeof params === 'number' ) {
-				params = { duration: params };
-			}
-
-			else if ( typeof params === 'string' ) {
-				if ( params === 'slow' ) {
-					params = { duration: 600 };
-				} else if ( params === 'fast' ) {
-					params = { duration: 200 };
-				} else {
-					params = { duration: 400 };
-				}
-			} else if ( !params ) {
-				params = {};
-			}
-
-			return fillGaps( params, defaults );
-		}
-	};
-
-	// get prefixed style attributes
-	vendors = [ 'o', 'ms', 'moz', 'webkit' ];
-	vendorPattern = new RegExp( '^(?:' + vendors.join( '|' ) + ')([A-Z])' );
-	unprefixPattern = new RegExp( '^-(?:' + vendors.join( '|' ) + ')-' );
-	prefixCache = {};
-
-	function prefix ( prop ) {
-		var i, vendor, capped;
-
-		if ( !prefixCache[ prop ] ) {
-			if ( testStyle[ prop ] !== undefined ) {
-				prefixCache[ prop ] = prop;
-			}
-
-			else {
-				// test vendors...
-				capped = prop.charAt( 0 ).toUpperCase() + prop.substring( 1 );
-
-				i = vendors.length;
-				while ( i-- ) {
-					vendor = vendors[i];
-					if ( testStyle[ vendor + capped ] !== undefined ) {
-						prefixCache[ prop ] = vendor + capped;
-						break;
-					}
-				}
-			}
-		}
-
-		return prefixCache[ prop ];
-	}
-
-	function unprefix ( prop ) {
-		return prop.replace( unprefixPattern, '' );
-	}
-
-	function hyphenate ( str ) {
-		var hyphenated;
-
-		if ( vendorPattern.test( str ) ) {
-			str = '-' + str;
-		}
-
-		hyphenated = str.replace( /[A-Z]/g, function ( match ) {
-			return '-' + match.toLowerCase();
-		});
-
-		return hyphenated;
-	}
-
-	return Transition;
-
-});
diff --git a/src/render/DomFragment/Element/shared/executeTransition/Transition/_Transition.js b/src/render/DomFragment/Element/shared/executeTransition/Transition/_Transition.js
new file mode 100644
index 0000000000..835ad4870d
--- /dev/null
+++ b/src/render/DomFragment/Element/shared/executeTransition/Transition/_Transition.js
@@ -0,0 +1,105 @@
+define([
+	'utils/warn',
+	'render/StringFragment/_StringFragment',
+	'render/DomFragment/Element/shared/executeTransition/Transition/prototype/init',
+	'render/DomFragment/Element/shared/executeTransition/Transition/prototype/getStyle',
+	'render/DomFragment/Element/shared/executeTransition/Transition/prototype/setStyle',
+	'render/DomFragment/Element/shared/executeTransition/Transition/prototype/animateStyle/_animateStyle',
+	'render/DomFragment/Element/shared/executeTransition/Transition/prototype/processParams',
+	'render/DomFragment/Element/shared/executeTransition/Transition/prototype/resetStyle'
+], function (
+	warn,
+	StringFragment,
+	init,
+	getStyle,
+	setStyle,
+	animateStyle,
+	processParams,
+	resetStyle
+) {
+
+	'use strict';
+
+	var Transition;
+
+	Transition = function ( descriptor, root, owner, isIntro ) {
+		var t = this, name, fragment, errorMessage;
+
+		this.root = root;
+		this.node = owner.node;
+		this.isIntro = isIntro;
+
+		// store original style attribute
+		this.originalStyle = this.node.getAttribute( 'style' );
+
+		// create t.complete() - we don't want this on the prototype,
+		// because we don't want `this` silliness when passing it as
+		// an argument
+		t.complete = function ( noReset ) {
+			if ( !noReset && t.isIntro ) {
+				t.resetStyle();
+			}
+
+			t.node._ractive.transition = null;
+			t._manager.remove( t );
+		};
+
+
+		name = descriptor.n || descriptor;
+
+		if ( typeof name !== 'string' ) {
+			fragment = new StringFragment({
+				descriptor:   name,
+				root:         this.root,
+				owner:        owner
+			});
+
+			name = fragment.toString();
+			fragment.teardown();
+		}
+
+		this.name = name;
+
+		if ( descriptor.a ) {
+			this.params = descriptor.a;
+		}
+
+		else if ( descriptor.d ) {
+			// TODO is there a way to interpret dynamic arguments without all the
+			// 'dependency thrashing'?
+			fragment = new StringFragment({
+				descriptor:   descriptor.d,
+				root:         this.root,
+				owner:        owner
+			});
+
+			this.params = fragment.toArgsList();
+			fragment.teardown();
+		}
+
+		this._fn = root.transitions[ name ];
+		if ( !this._fn ) {
+			errorMessage = 'Missing "' + name + '" transition. You may need to download a plugin via http://docs.ractivejs.org/latest/plugins#transitions';
+
+			if ( root.debug ) {
+				throw new Error( errorMessage );
+			} else {
+				warn( errorMessage );
+			}
+
+			return;
+		}
+	};
+
+	Transition.prototype = {
+		init: init,
+		getStyle: getStyle,
+		setStyle: setStyle,
+		animateStyle: animateStyle,
+		processParams: processParams,
+		resetStyle: resetStyle
+	};
+
+	return Transition;
+
+});
diff --git a/src/render/DomFragment/Element/shared/executeTransition/Transition/helpers/hyphenate.js b/src/render/DomFragment/Element/shared/executeTransition/Transition/helpers/hyphenate.js
new file mode 100644
index 0000000000..287596b938
--- /dev/null
+++ b/src/render/DomFragment/Element/shared/executeTransition/Transition/helpers/hyphenate.js
@@ -0,0 +1,29 @@
+define([
+	'config/vendors'
+], function (
+	vendors
+) {
+
+	'use strict';
+
+	var vendorPattern = new RegExp( '^(?:' + vendors.join( '|' ) + ')([A-Z])' );
+
+	return function ( str ) {
+		var hyphenated;
+
+		if ( !str ) {
+			return ''; // edge case
+		}
+
+		if ( vendorPattern.test( str ) ) {
+			str = '-' + str;
+		}
+
+		hyphenated = str.replace( /[A-Z]/g, function ( match ) {
+			return '-' + match.toLowerCase();
+		});
+
+		return hyphenated;
+	};
+
+});
diff --git a/src/render/DomFragment/Element/shared/executeTransition/Transition/helpers/prefix.js b/src/render/DomFragment/Element/shared/executeTransition/Transition/helpers/prefix.js
new file mode 100644
index 0000000000..ff39f4e862
--- /dev/null
+++ b/src/render/DomFragment/Element/shared/executeTransition/Transition/helpers/prefix.js
@@ -0,0 +1,48 @@
+define([
+	'config/isClient',
+	'config/vendors',
+	'utils/createElement'
+], function (
+	isClient,
+	vendors,
+	createElement
+) {
+
+	'use strict';
+
+	var prefixCache, testStyle;
+
+	if ( !isClient ) {
+		return;
+	}
+
+	prefixCache = {};
+	testStyle = createElement( 'div' ).style;
+
+	return function ( prop ) {
+		var i, vendor, capped;
+
+		if ( !prefixCache[ prop ] ) {
+			if ( testStyle[ prop ] !== undefined ) {
+				prefixCache[ prop ] = prop;
+			}
+
+			else {
+				// test vendors...
+				capped = prop.charAt( 0 ).toUpperCase() + prop.substring( 1 );
+
+				i = vendors.length;
+				while ( i-- ) {
+					vendor = vendors[i];
+					if ( testStyle[ vendor + capped ] !== undefined ) {
+						prefixCache[ prop ] = vendor + capped;
+						break;
+					}
+				}
+			}
+		}
+
+		return prefixCache[ prop ];
+	};
+
+});
diff --git a/src/render/DomFragment/Element/shared/executeTransition/Transition/helpers/unprefix.js b/src/render/DomFragment/Element/shared/executeTransition/Transition/helpers/unprefix.js
new file mode 100644
index 0000000000..933bb74082
--- /dev/null
+++ b/src/render/DomFragment/Element/shared/executeTransition/Transition/helpers/unprefix.js
@@ -0,0 +1,15 @@
+define([
+	'config/vendors'
+], function (
+	vendors
+) {
+
+	'use strict';
+
+	var unprefixPattern = new RegExp( '^-(?:' + vendors.join( '|' ) + ')-' );
+
+	return function ( prop ) {
+		return prop.replace( unprefixPattern, '' );
+	};
+
+});
diff --git a/src/render/DomFragment/Element/shared/executeTransition/Transition/prototype/animateStyle/_animateStyle.js b/src/render/DomFragment/Element/shared/executeTransition/Transition/prototype/animateStyle/_animateStyle.js
new file mode 100644
index 0000000000..96f8f2c7a7
--- /dev/null
+++ b/src/render/DomFragment/Element/shared/executeTransition/Transition/prototype/animateStyle/_animateStyle.js
@@ -0,0 +1,111 @@
+define([
+	'legacy',
+	'config/isClient',
+	'utils/warn',
+	'utils/Promise',
+	'render/DomFragment/Element/shared/executeTransition/Transition/helpers/prefix',
+	'render/DomFragment/Element/shared/executeTransition/Transition/prototype/animateStyle/createTransitions'
+], function (
+	legacy,
+	isClient,
+	warn,
+	Promise,
+	prefix,
+	createTransitions
+) {
+
+	'use strict';
+
+	var getComputedStyle;
+
+	if ( !isClient ) {
+		return;
+	}
+
+	getComputedStyle = window.getComputedStyle || legacy.getComputedStyle;
+
+	return function ( style, value, options, complete ) {
+
+		var t = this, to;
+
+		if ( typeof style === 'string' ) {
+			to = {};
+			to[ style ] = value;
+		} else {
+			to = style;
+
+			// shuffle arguments
+			complete = options;
+			options = value;
+		}
+
+		// As of 0.3.9, transition authors should supply an `option` object with
+		// `duration` and `easing` properties (and optional `delay`), plus a
+		// callback function that gets called after the animation completes
+
+		// TODO remove this check in a future version
+		if ( !options ) {
+			warn( 'The "' + t.name + '" transition does not supply an options object to `t.animateStyle()`. This will break in a future version of Ractive. For more info see https://github.com/RactiveJS/Ractive/issues/340' );
+
+			options = t;
+			complete = t.complete;
+		}
+
+		var promise = new Promise( function ( resolve ) {
+			var propertyNames, changedProperties, computedStyle, current, from, transitionEndHandler, i, prop;
+
+			// Edge case - if duration is zero, set style synchronously and complete
+			if ( !options.duration ) {
+				t.setStyle( to );
+				resolve();
+				return;
+			}
+
+			// Get a list of the properties we're animating
+			propertyNames = Object.keys( to );
+			changedProperties = [];
+
+			// Store the current styles
+			computedStyle = window.getComputedStyle( t.node );
+
+			from = {};
+			i = propertyNames.length;
+			while ( i-- ) {
+				prop = propertyNames[i];
+				current = computedStyle[ prefix( prop ) ];
+
+				if ( current === '0px' ) {
+					current = 0;
+				}
+
+				// we need to know if we're actually changing anything
+				if ( current != to[ prop ] ) { // use != instead of !==, so we can compare strings with numbers
+					changedProperties.push( prop );
+
+					// make the computed style explicit, so we can animate where
+					// e.g. height='auto'
+					t.node.style[ prefix( prop ) ] = current;
+				}
+			}
+
+			// If we're not actually changing anything, the transitionend event
+			// will never fire! So we complete early
+			if ( !changedProperties.length ) {
+				resolve();
+				return;
+			}
+
+			createTransitions( t, to, options, changedProperties, transitionEndHandler, resolve );
+		});
+
+		// If a callback was supplied, do the honours
+		// TODO remove this check in future
+		if ( complete ) {
+			warn( 't.animateStyle returns a Promise as of 0.4.0. Transition authors should do t.animateStyle(...).then(callback)' );
+			promise.then( complete );
+		}
+
+		return promise;
+	};
+
+});
diff --git a/src/render/DomFragment/Element/shared/executeTransition/Transition/prototype/animateStyle/createTransitions.js b/src/render/DomFragment/Element/shared/executeTransition/Transition/prototype/animateStyle/createTransitions.js
new file mode 100644
index 0000000000..38171ef60c
--- /dev/null
+++ b/src/render/DomFragment/Element/shared/executeTransition/Transition/prototype/animateStyle/createTransitions.js
@@ -0,0 +1,202 @@
+define([
+	'config/isClient',
+	'utils/warn',
+	'utils/createElement',
+	'utils/camelCase',
+	'shared/interpolate',
+	'shared/Ticker',
+	'render/DomFragment/Element/shared/executeTransition/Transition/helpers/prefix',
+	'render/DomFragment/Element/shared/executeTransition/Transition/helpers/unprefix',
+	'render/DomFragment/Element/shared/executeTransition/Transition/helpers/hyphenate'
+], function (
+	isClient,
+	warn,
+	createElement,
+	camelCase,
+	interpolate,
+	Ticker,
+	prefix,
+	unprefix,
+	hyphenate
+) {
+
+	'use strict';
+
+	var testStyle,
+		TRANSITION,
+		TRANSITIONEND,
+		CSS_TRANSITIONS_ENABLED,
+		TRANSITION_DURATION,
+		TRANSITION_PROPERTY,
+		TRANSITION_TIMING_FUNCTION,
+		canUseCssTransitions = {},
+		cannotUseCssTransitions = {};
+
+	if ( !isClient ) {
+		return;
+	}
+
+	testStyle = createElement( 'div' ).style;
+
+	// determine some facts about our environment
+	(function () {
+
+		if ( testStyle.transition !== undefined ) {
+			TRANSITION = 'transition';
+			TRANSITIONEND = 'transitionend';
+			CSS_TRANSITIONS_ENABLED = true;
+		} else if ( testStyle.webkitTransition !== undefined ) {
+			TRANSITION = 'webkitTransition';
+			TRANSITIONEND = 'webkitTransitionEnd';
+			CSS_TRANSITIONS_ENABLED = true;
+		} else {
+			CSS_TRANSITIONS_ENABLED = false;
+		}
+
+	}());
+
+	if ( TRANSITION ) {
+		TRANSITION_DURATION = TRANSITION + 'Duration';
+		TRANSITION_PROPERTY = TRANSITION + 'Property';
+		TRANSITION_TIMING_FUNCTION = TRANSITION + 'TimingFunction';
+	}
+
+
+	return function ( t, to, options, changedProperties, transitionEndHandler, resolve ) {
+
+		// Wait a beat (otherwise the target styles will be applied immediately)
+		// TODO use a fastdom-style mechanism?
+		setTimeout( function () {
+
+			var hashPrefix, jsTransitionsComplete, cssTransitionsComplete, checkComplete;
+
+			checkComplete = function () {
+				if ( jsTransitionsComplete && cssTransitionsComplete ) {
+					resolve();
+				}
+			};
+
+			// this is used to keep track of which elements can use CSS to animate
+			// which properties
+			hashPrefix = t.node.namespaceURI + t.node.tagName;
+
+			t.node.style[ TRANSITION_PROPERTY ] = changedProperties.map( prefix ).map( hyphenate ).join( ',' );
+			t.node.style[ TRANSITION_TIMING_FUNCTION ] = hyphenate( options.easing || 'linear' );
+			t.node.style[ TRANSITION_DURATION ] = ( options.duration / 1000 ) + 's';
+
+			transitionEndHandler = function ( event ) {
+				var index;
+
+				index = changedProperties.indexOf( camelCase( unprefix( event.propertyName ) ) );
+				if ( index !== -1 ) {
+					changedProperties.splice( index, 1 );
+				}
+
+				if ( changedProperties.length ) {
+					// still transitioning...
+					return;
+				}
+
+				t.root.fire(t.name + ':end');
+
+				t.node.removeEventListener( TRANSITIONEND, transitionEndHandler, false );
+
+				cssTransitionsComplete = true;
+				checkComplete();
+			};
+
+			t.node.addEventListener( TRANSITIONEND, transitionEndHandler, false );
+
+			setTimeout( function () {
+				var i = changedProperties.length, hash, originalValue, index, propertiesToTransitionInJs = [], prop;
+
+				while ( i-- ) {
+					prop = changedProperties[i];
+					hash = hashPrefix + prop;
+
+					if ( canUseCssTransitions[ hash ] ) {
+						// We can definitely use CSS transitions, because
+						// we've already tried it and it worked
+						t.node.style[ prefix( prop ) ] = to[ prop ];
+					} else {
+						// one way or another, we'll need this
+						originalValue = t.getStyle( prop ); // TODO don't we already have this value?
+					}
+
+
+					if ( canUseCssTransitions[ hash ] === undefined ) {
+						// We're not yet sure if we can use CSS transitions -
+						// let's find out
+						t.node.style[ prefix( prop ) ] = to[ prop ];
+
+						// if this property is transitionable in this browser,
+						// the current style will be different from the target style
+						canUseCssTransitions[ hash ] = ( t.getStyle( prop ) != to[ prop ] );
+						cannotUseCssTransitions[ hash ] = !canUseCssTransitions[ hash ];
+					}
+
+
+					if ( cannotUseCssTransitions[ hash ] ) {
+						// we need to fall back to timer-based stuff
+
+						// need to remove this from changedProperties, otherwise transitionEndHandler
+						// will get confused
+						index = changedProperties.indexOf( prop );
+						if ( index === -1 ) {
+							warn( 'Something very strange happened with transitions. If you see this message, please let @RactiveJS know. Thanks!' );
+						} else {
+							changedProperties.splice( index, 1 );
+						}
+
+
+						// TODO Determine whether this property is animatable at all
+
+						// for now assume it is. First, we need to set the value to what it was...
+						t.node.style[ prefix( prop ) ] = originalValue;
+
+						// ...then kick off a timer-based transition
+						propertiesToTransitionInJs.push({
+							name: prefix( prop ),
+							interpolator: interpolate( originalValue, to[ prop ] )
+						});
+					}
+				}
+
+
+				// javascript transitions
+				if ( propertiesToTransitionInJs.length ) {
+					new Ticker({
+						root: t.root,
+						duration: options.duration,
+						easing: camelCase( options.easing ),
+						step: function ( pos ) {
+							var prop, i;
+
+							i = propertiesToTransitionInJs.length;
+							while ( i-- ) {
+								prop = propertiesToTransitionInJs[i];
+								t.node.style[ prop.name ] = prop.interpolator( pos );
+							}
+						},
+						complete: function () {
+							jsTransitionsComplete = true;
+							checkComplete();
+						}
+					});
+				} else {
+					jsTransitionsComplete = true;
+				}
+
+
+				if ( !changedProperties.length ) {
+					// We need to cancel the transitionEndHandler, and deal with
+					// the fact that it will never fire
+					t.node.removeEventListener( TRANSITIONEND, transitionEndHandler, false );
+					cssTransitionsComplete = true;
+					checkComplete();
+				}
+			}, 0 );
+		}, options.delay || 0 );
+	};
+
+});
diff --git a/src/render/DomFragment/Element/shared/executeTransition/Transition/prototype/getStyle.js b/src/render/DomFragment/Element/shared/executeTransition/Transition/prototype/getStyle.js
new file mode 100644
index 0000000000..c87af6be4b
--- /dev/null
+++ b/src/render/DomFragment/Element/shared/executeTransition/Transition/prototype/getStyle.js
@@ -0,0 +1,55 @@
+define([
+	'legacy',
+	'config/isClient',
+	'utils/isArray',
+	'render/DomFragment/Element/shared/executeTransition/Transition/helpers/prefix',
+], function (
+	legacy,
+	isClient,
+	isArray,
+	prefix
+) {
+
+	'use strict';
+
+	var getComputedStyle;
+
+	if ( !isClient ) {
+		return;
+	}
+
+	getComputedStyle = window.getComputedStyle || legacy.getComputedStyle;
+
+	return function ( props ) {
+		var computedStyle, styles, i, prop, value;
+
+		computedStyle = window.getComputedStyle( this.node );
+
+		if ( typeof props === 'string' ) {
+			value = computedStyle[ prefix( props ) ];
+			if ( value === '0px' ) {
+				value = 0;
+			}
+			return value;
+		}
+
+		if ( !isArray( props ) ) {
+			throw new Error( 'Transition#getStyle must be passed a string, or an array of strings representing CSS properties' );
+		}
+
+		styles = {};
+
+		i = props.length;
+		while ( i-- ) {
+			prop = props[i];
+			value = computedStyle[ prefix( prop ) ];
+			if ( value === '0px' ) {
+				value = 0;
+			}
+			styles[ prop ] = value;
+		}
+
+		return styles;
+	};
+
+});
diff --git a/src/render/DomFragment/Element/shared/executeTransition/Transition/prototype/init.js b/src/render/DomFragment/Element/shared/executeTransition/Transition/prototype/init.js
new file mode 100644
index 0000000000..9079758f64
--- /dev/null
+++ b/src/render/DomFragment/Element/shared/executeTransition/Transition/prototype/init.js
@@ -0,0 +1,14 @@
+define( function () {
+
+	'use strict';
+
+	return function () {
+		if ( this._inited ) {
+			throw new Error( 'Cannot initialize a transition more than once' );
+		}
+
+		this._inited = true;
+		this._fn.apply( this.root, [ this ].concat( this.params ) );
+	};
+
+});
diff --git a/src/render/DomFragment/Element/shared/executeTransition/Transition/prototype/processParams.js b/src/render/DomFragment/Element/shared/executeTransition/Transition/prototype/processParams.js
new file mode 100644
index 0000000000..c724a775dd
--- /dev/null
+++ b/src/render/DomFragment/Element/shared/executeTransition/Transition/prototype/processParams.js
@@ -0,0 +1,29 @@
+define([
+	'utils/fillGaps'
+], function (
+	fillGaps
+) {
+
+	'use strict';
+
+	return function ( params, defaults ) {
+		if ( typeof params === 'number' ) {
+			params = { duration: params };
+		}
+
+		else if ( typeof params === 'string' ) {
+			if ( params === 'slow' ) {
+				params = { duration: 600 };
+			} else if ( params === 'fast' ) {
+				params = { duration: 200 };
+			} else {
+				params = { duration: 400 };
+			}
+		} else if ( !params ) {
+			params = {};
+		}
+
+		return fillGaps( params, defaults );
+	};
+
+});
diff --git a/src/render/DomFragment/Element/shared/executeTransition/Transition/prototype/resetStyle.js b/src/render/DomFragment/Element/shared/executeTransition/Transition/prototype/resetStyle.js
new file mode 100644
index 0000000000..910d241ce6
--- /dev/null
+++ b/src/render/DomFragment/Element/shared/executeTransition/Transition/prototype/resetStyle.js
@@ -0,0 +1,17 @@
+define( function () {
+
+	'use strict';
+
+	return function () {
+		if ( this.originalStyle ) {
+			this.node.setAttribute( 'style', this.originalStyle );
+		} else {
+
+			// Next line is necessary, to remove empty style attribute!
+			// See http://stackoverflow.com/a/7167553
+			this.node.getAttribute( 'style' );
+			this.node.removeAttribute( 'style' );
+		}
+	};
+
+});
diff --git a/src/render/DomFragment/Element/shared/executeTransition/Transition/prototype/setStyle.js b/src/render/DomFragment/Element/shared/executeTransition/Transition/prototype/setStyle.js
new file mode 100644
index 0000000000..012acbe779
--- /dev/null
+++ b/src/render/DomFragment/Element/shared/executeTransition/Transition/prototype/setStyle.js
@@ -0,0 +1,27 @@
+define([
+	'render/DomFragment/Element/shared/executeTransition/Transition/helpers/prefix'
+], function (
+	prefix
+) {
+
+	'use strict';
+
+	return function ( style, value ) {
+		var prop;
+
+		if ( typeof style === 'string' ) {
+			this.node.style[ prefix( style ) ] = value;
+		}
+
+		else {
+			for ( prop in style ) {
+				if ( style.hasOwnProperty( prop ) ) {
+					this.node.style[ prefix( prop ) ] = style[ prop ];
+				}
+			}
+		}
+
+		return this;
+	};
+
+});
diff --git a/src/render/DomFragment/Element/shared/executeTransition/_executeTransition.js b/src/render/DomFragment/Element/shared/executeTransition/_executeTransition.js
index 581a9df934..3161ca5535 100644
--- a/src/render/DomFragment/Element/shared/executeTransition/_executeTransition.js
+++ b/src/render/DomFragment/Element/shared/executeTransition/_executeTransition.js
@@ -1,28 +1,26 @@
 define([
-	'utils/warn',
-	'render/DomFragment/Element/shared/executeTransition/Transition'
+	'global/runloop',
+	'render/DomFragment/Element/shared/executeTransition/Transition/_Transition'
 ], function (
-	warn,
+	runloop,
 	Transition
 ) {
 
 	'use strict';
 
-	return function ( descriptor, root, owner, contextStack, isIntro ) {
-		var transition,
-			node,
-			oldTransition;
+	return function ( descriptor, ractive, owner, isIntro ) {
+		var transition, node, oldTransition;
 
-		if ( !root.transitionsEnabled || ( root._parent && !root._parent.transitionsEnabled ) ) {
+		// TODO this can't be right!
+		if ( !ractive.transitionsEnabled || ( ractive._parent && !ractive._parent.transitionsEnabled ) ) {
 			return;
 		}
 
 		// get transition name, args and function
-		transition = new Transition( descriptor, root, owner, contextStack, isIntro );
+		transition = new Transition( descriptor, ractive, owner, isIntro );
 
 		if ( transition._fn ) {
 			node = transition.node;
-			transition._manager = root._transitionManager;
 
 			// Existing transition (i.e. we're outroing before intro is complete)?
 			// End it prematurely
@@ -31,17 +29,8 @@ define([
 			}
 
 			node._ractive.transition = transition;
-
-			transition._manager.push( node );
-
-			if ( isIntro ) {
-				// we don't want to call the transition function until this node
-				// exists on the DOM
-				root._deferred.transitions.push( transition );
-			} else {
-				transition.init();
-			}
+			runloop.addTransition( transition );
 		}
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/render/DomFragment/Element/shared/getMatchingStaticNodes.js b/src/render/DomFragment/Element/shared/getMatchingStaticNodes.js
new file mode 100644
index 0000000000..baf7dd6736
--- /dev/null
+++ b/src/render/DomFragment/Element/shared/getMatchingStaticNodes.js
@@ -0,0 +1,17 @@
+define([
+	'utils/toArray'
+], function (
+	toArray
+) {
+
+	'use strict';
+
+	return function getMatchingStaticNodes ( element, selector ) {
+		if ( !element.matchingStaticNodes[ selector ] ) {
+			element.matchingStaticNodes[ selector ] = toArray( element.node.querySelectorAll( selector ) );
+		}
+
+		return element.matchingStaticNodes[ selector ];
+	};
+
+});
diff --git a/src/render/DomFragment/Interpolator.js b/src/render/DomFragment/Interpolator.js
index d09d57e1dd..ae013bea26 100755
--- a/src/render/DomFragment/Interpolator.js
+++ b/src/render/DomFragment/Interpolator.js
@@ -1,15 +1,13 @@
 define([
 	'config/types',
 	'shared/teardown',
-	'render/shared/initMustache',
-	'render/shared/resolveMustache',
-	'render/shared/updateMustache'
+	'render/shared/Mustache/_Mustache',
+	'render/DomFragment/shared/detach'
 ], function (
 	types,
 	teardown,
-	initMustache,
-	resolveMustache,
-	updateMustache
+	Mustache,
+	detach
 ) {
 
 	'use strict';
@@ -28,17 +26,14 @@ define([
 		}
 
 		// extend Mustache
-		initMustache( this, options );
+		Mustache.init( this, options );
 	};
 
 	DomInterpolator.prototype = {
-		update: updateMustache,
-		resolve: resolveMustache,
-
-		detach: function () {
-			this.node.parentNode.removeChild( this.node );
-			return this.node;
-		},
+		update: Mustache.update,
+		resolve: Mustache.resolve,
+		reassign: Mustache.reassign,
+		detach: detach,
 
 		teardown: function ( destroy ) {
 			if ( destroy ) {
@@ -47,7 +42,7 @@ define([
 
 			teardown( this );
 		},
-
+		
 		render: function ( value ) {
 			if ( this.node ) {
 				this.node.data = ( value == undefined ? '' : value );
@@ -66,4 +61,4 @@ define([
 
 	return DomInterpolator;
 
-});
\ No newline at end of file
+});
diff --git a/src/render/DomFragment/Partial/_Partial.js b/src/render/DomFragment/Partial/_Partial.js
index e8623a5244..36af19b397 100644
--- a/src/render/DomFragment/Partial/_Partial.js
+++ b/src/render/DomFragment/Partial/_Partial.js
@@ -1,10 +1,12 @@
 define([
 	'config/types',
 	'render/DomFragment/Partial/getPartialDescriptor',
+	'render/DomFragment/Partial/applyIndent',
 	'circular'
 ], function (
 	types,
 	getPartialDescriptor,
+	applyIndent,
 	circular
 ) {
 
@@ -34,7 +36,6 @@ define([
 			descriptor:   descriptor,
 			root:         parentFragment.root,
 			pNode:        parentFragment.pNode,
-			contextStack: parentFragment.contextStack,
 			owner:        this
 		});
 
@@ -56,12 +57,32 @@ define([
 			return this.fragment.detach();
 		},
 
+		reassign: function ( indexRef, newIndex, oldKeypath, newKeypath ) {
+			return this.fragment.reassign( indexRef, newIndex, oldKeypath, newKeypath );
+		},
+
 		teardown: function ( destroy ) {
 			this.fragment.teardown( destroy );
 		},
 
 		toString: function () {
-			return this.fragment.toString();
+			var string, previousItem, lastLine, match;
+
+			string = this.fragment.toString();
+
+			previousItem = this.parentFragment.items[ this.index - 1 ];
+
+			if ( !previousItem || ( previousItem.type !== types.TEXT ) ) {
+				return string;
+			}
+
+			lastLine = previousItem.descriptor.split( '\n' ).pop();
+
+			if ( match = /^\s+$/.exec( lastLine ) ) {
+				return applyIndent( string, match[0] );
+			}
+
+			return string;
 		},
 
 		find: function ( selector ) {
@@ -83,4 +104,4 @@ define([
 
 	return DomPartial;
 
-});
\ No newline at end of file
+});
diff --git a/src/render/DomFragment/Partial/applyIndent.js b/src/render/DomFragment/Partial/applyIndent.js
new file mode 100644
index 0000000000..2628000187
--- /dev/null
+++ b/src/render/DomFragment/Partial/applyIndent.js
@@ -0,0 +1,19 @@
+define( function () {
+
+	'use strict';
+
+	return function ( string, indent ) {
+		var indented;
+
+		if ( !indent ) {
+			return string;
+		}
+
+		indented = string.split( '\n' ).map( function ( line, notFirstLine ) {
+			return notFirstLine ? indent + line : line;
+		}).join( '\n' );
+
+		return indented;
+	};
+
+});
diff --git a/src/render/DomFragment/Partial/deIndent.js b/src/render/DomFragment/Partial/deIndent.js
new file mode 100644
index 0000000000..8b9216df75
--- /dev/null
+++ b/src/render/DomFragment/Partial/deIndent.js
@@ -0,0 +1,44 @@
+define( function () {
+
+	'use strict';
+
+	var empty = /^\s*$/, leadingWhitespace = /^\s*/;
+
+	return function ( str ) {
+		var lines, firstLine, lastLine, minIndent;
+
+		lines = str.split( '\n' );
+
+		// remove first and last line, if they only contain whitespace
+		firstLine = lines[0];
+		if ( firstLine !== undefined && empty.test( firstLine ) ) {
+			lines.shift();
+		}
+
+		lastLine = lines[ lines.length - 1 ];
+		if ( lastLine !== undefined && empty.test( lastLine ) ) {
+			lines.pop();
+		}
+
+		minIndent = lines.reduce( reducer, null );
+
+		if ( minIndent ) {
+			str = lines.map( function ( line ) {
+				return line.replace( minIndent, '' );
+			}).join( '\n' );
+		}
+
+		return str;
+	};
+
+	function reducer ( previous, line ) {
+		var lineIndent = leadingWhitespace.exec( line )[0];
+
+		if ( previous === null || ( lineIndent.length < previous.length ) ) {
+			return lineIndent;
+		}
+
+		return previous;
+	}
+
+});
diff --git a/src/render/DomFragment/Partial/getPartialDescriptor.js b/src/render/DomFragment/Partial/getPartialDescriptor.js
index b3b5c827ab..f60906ab45 100644
--- a/src/render/DomFragment/Partial/getPartialDescriptor.js
+++ b/src/render/DomFragment/Partial/getPartialDescriptor.js
@@ -4,14 +4,16 @@ define([
 	'utils/warn',
 	'utils/isObject',
 	'registries/partials',
-	'parse/_parse'
+	'parse/_parse',
+	'render/DomFragment/Partial/deIndent'
 ], function (
 	errors,
 	isClient,
 	warn,
 	isObject,
 	partials,
-	parse
+	parse,
+	deIndent
 ) {
 
 	'use strict';
@@ -39,7 +41,7 @@ define([
 					throw new Error( errors.missingParser );
 				}
 
-				registerPartial( parse( el.innerHTML ), name, partials );
+				registerPartial( parse( deIndent( el.text ), root.parseOptions ), name, partials );
 			}
 		}
 
@@ -61,23 +63,23 @@ define([
 		return unpack( partial );
 	};
 
-	getPartialFromRegistry = function ( registryOwner, name ) {
+	getPartialFromRegistry = function ( ractive, name ) {
 		var partial;
 
-		if ( registryOwner.partials[ name ] ) {
+		if ( ractive.partials[ name ] ) {
 
 			// If this was added manually to the registry, but hasn't been parsed,
 			// parse it now
-			if ( typeof registryOwner.partials[ name ] === 'string' ) {
+			if ( typeof ractive.partials[ name ] === 'string' ) {
 				if ( !parse ) {
 					throw new Error( errors.missingParser );
 				}
 
-				partial = parse( registryOwner.partials[ name ], registryOwner.parseOptions );
-				registerPartial( partial, name, registryOwner.partials );
+				partial = parse( ractive.partials[ name ], ractive.parseOptions );
+				registerPartial( partial, name, ractive.partials );
 			}
 
-			return unpack( registryOwner.partials[ name ] );
+			return unpack( ractive.partials[ name ] );
 		}
 	};
 
@@ -108,4 +110,4 @@ define([
 
 	return getPartialDescriptor;
 
-});
\ No newline at end of file
+});
diff --git a/src/render/DomFragment/Section/_Section.js b/src/render/DomFragment/Section/_Section.js
index 5372f2b3dd..5e0369fca2 100644
--- a/src/render/DomFragment/Section/_Section.js
+++ b/src/render/DomFragment/Section/_Section.js
@@ -1,25 +1,17 @@
 define([
 	'config/types',
-	'config/isClient',
-	'render/shared/initMustache',
-	'render/shared/updateMustache',
-	'render/shared/resolveMustache',
-	'render/shared/updateSection',
-	'render/DomFragment/Section/reassignFragment',
-	'render/DomFragment/Section/reassignFragments',
+	'render/shared/Mustache/_Mustache',
 	'render/DomFragment/Section/prototype/merge',
+	'render/DomFragment/Section/prototype/render',
+	'render/DomFragment/Section/prototype/splice',
 	'shared/teardown',
 	'circular'
 ], function (
 	types,
-	isClient,
-	initMustache,
-	updateMustache,
-	resolveMustache,
-	updateSection,
-	reassignFragment,
-	reassignFragments,
+	Mustache,
 	merge,
+	render,
+	splice,
 	teardown,
 	circular
 ) {
@@ -45,7 +37,7 @@ define([
 		}
 
 		this.initialising = true;
-		initMustache( this, options );
+		Mustache.init( this, options );
 
 		if ( docFrag ) {
 			docFrag.appendChild( this.docFrag );
@@ -55,149 +47,23 @@ define([
 	};
 
 	DomSection.prototype = {
-		update: updateMustache,
-		resolve: resolveMustache,
-
-		smartUpdate: function ( methodName, args ) {
-			var fragmentOptions;
-
-			if ( methodName === 'push' || methodName === 'unshift' || methodName === 'splice' ) {
-				fragmentOptions = {
-					descriptor: this.descriptor.f,
-					root:       this.root,
-					pNode:      this.parentFragment.pNode,
-					owner:      this
-				};
-
-				if ( this.descriptor.i ) {
-					fragmentOptions.indexRef = this.descriptor.i;
-				}
-			}
-
-			if ( this[ methodName ] ) { // if not, it's sort or reverse, which doesn't affect us (i.e. our length)
-				this.rendering = true;
-				this[ methodName ]( fragmentOptions, args );
-				this.rendering = false;
-			}
-		},
-
-		pop: function () {
-			// teardown last fragment
-			if ( this.length ) {
-				this.fragments.pop().teardown( true );
-				this.length -= 1;
-			}
-		},
-
-		push: function ( fragmentOptions, args ) {
-			var start, end, i;
-
-			// append list item to context stack
-			start = this.length;
-			end = start + args.length;
-
-			for ( i=start; i items.3 - the keypaths,
-			// context stacks and index refs will have changed)
-			reassignStart = ( start + addedItems );
-
-			reassignFragments( this.root, this, reassignStart, this.length, balance );
-		},
-
+		update: Mustache.update,
+		resolve: Mustache.resolve,
+		reassign: Mustache.reassign,
+		splice: splice,
 		merge: merge,
 
 		detach: function () {
 			var i, len;
 
-			len = this.fragments.length;
-			for ( i = 0; i < len; i += 1 ) {
-				this.docFrag.appendChild( this.fragments[i].detach() );
-			}
+			if ( this.docFrag ) {
+				len = this.fragments.length;
+				for ( i = 0; i < len; i += 1 ) {
+					this.docFrag.appendChild( this.fragments[i].detach() );
+				}
 
-			return this.docFrag;
+				return this.docFrag;
+			}
 		},
 
 		teardown: function ( destroy ) {
@@ -223,68 +89,14 @@ define([
 		},
 
 		teardownFragments: function ( destroy ) {
-			var id, fragment;
+			var fragment;
 
 			while ( fragment = this.fragments.shift() ) {
 				fragment.teardown( destroy );
 			}
-
-			if ( this.fragmentsById ) {
-				for ( id in this.fragmentsById ) {
-					if ( this.fragments[ id ] ) {
-						this.fragmentsById[ id ].teardown( destroy );
-						this.fragmentsById[ id ] = null;
-					}
-				}
-			}
 		},
 
-		render: function ( value ) {
-			var nextNode, wrapped;
-
-			// with sections, we need to get the fake value if we have a wrapped object
-			if ( wrapped = this.root._wrapped[ this.keypath ] ) {
-				value = wrapped.get();
-			}
-
-			// prevent sections from rendering multiple times (happens if
-			// evaluators evaluate while update is happening)
-			if ( this.rendering ) {
-				return;
-			}
-
-			this.rendering = true;
-			updateSection( this, value );
-			this.rendering = false;
-
-			// if we have no new nodes to insert (i.e. the section length stayed the
-			// same, or shrank), we don't need to go any further
-			if ( this.docFrag && !this.docFrag.childNodes.length ) {
-				return;
-			}
-
-			// if this isn't the initial render, we need to insert any new nodes in
-			// the right place
-			if ( !this.initialising && isClient ) {
-
-				// Normally this is just a case of finding the next node, and inserting
-				// items before it...
-				nextNode = this.parentFragment.findNextNode( this );
-
-				if ( nextNode && ( nextNode.parentNode === this.parentFragment.pNode ) ) {
-					this.parentFragment.pNode.insertBefore( this.docFrag, nextNode );
-				}
-
-				// ...but in some edge cases the next node will not have been attached to
-				// the DOM yet, in which case we append to the end of the parent node
-				else {
-					// TODO could there be a situation in which later nodes could have
-					// been attached to the parent node, i.e. we need to find a sibling
-					// to insert before?
-					this.parentFragment.pNode.appendChild( this.docFrag );
-				}
-			}
-		},
+		render: render,
 
 		createFragment: function ( options ) {
 			var fragment = new DomFragment( options );
@@ -297,7 +109,7 @@ define([
 		},
 
 		toString: function () {
-			var str, i, id, len;
+			var str, i, len;
 
 			str = '';
 
@@ -308,14 +120,6 @@ define([
 				str += this.fragments[i].toString();
 			}
 
-			if ( this.fragmentsById ) {
-				for ( id in this.fragmentsById ) {
-					if ( this.fragmentsById[ id ] ) {
-						str += this.fragmentsById[ id ].toString();
-					}
-				}
-			}
-
 			return str;
 		},
 
@@ -366,4 +170,4 @@ define([
 
 	return DomSection;
 
-});
\ No newline at end of file
+});
diff --git a/src/render/DomFragment/Section/prototype/merge.js b/src/render/DomFragment/Section/prototype/merge.js
index d472ea0dee..873913c560 100644
--- a/src/render/DomFragment/Section/prototype/merge.js
+++ b/src/render/DomFragment/Section/prototype/merge.js
@@ -1,34 +1,30 @@
-define([
-	'render/DomFragment/Section/reassignFragment'
-], function (
-	reassignFragment
-) {
+define([], function () {
 
 	'use strict';
 
-	return function ( newIndices ) {
+	var toTeardown = [];
+
+	return function sectionMerge ( newIndices ) {
 		var section = this,
 			parentFragment,
 			firstChange,
-			changed,
 			i,
 			newLength,
-			newFragments,
-			toTeardown,
+			reassignedFragments,
 			fragmentOptions,
 			fragment,
 			nextNode;
 
 		parentFragment = this.parentFragment;
 
-		newFragments = [];
+		reassignedFragments = [];
 
 		// first, reassign existing fragments
-		newIndices.forEach( function ( newIndex, oldIndex ) {
-			var by, oldKeypath, newKeypath;
+		newIndices.forEach( function reassignIfNecessary ( newIndex, oldIndex ) {
+			var fragment, by, oldKeypath, newKeypath;
 
 			if ( newIndex === oldIndex ) {
-				newFragments[ newIndex ] = section.fragments[ oldIndex ];
+				reassignedFragments[ newIndex ] = section.fragments[ oldIndex ];
 				return;
 			}
 
@@ -38,27 +34,23 @@ define([
 
 			// does this fragment need to be torn down?
 			if ( newIndex === -1 ) {
-				( toTeardown || ( toTeardown = [] ) ).push( section.fragments[ oldIndex ] );
+				toTeardown.push( section.fragments[ oldIndex ] );
 				return;
 			}
 
 			// Otherwise, it needs to be reassigned to a new index
+			fragment = section.fragments[ oldIndex ];
+
 			by = newIndex - oldIndex;
 			oldKeypath = section.keypath + '.' + oldIndex;
 			newKeypath = section.keypath + '.' + newIndex;
 
-			reassignFragment( section.fragments[ oldIndex ], section.descriptor.i, oldIndex, newIndex, by, oldKeypath, newKeypath );
-
-			newFragments[ newIndex ] = section.fragments[ oldIndex ];
-
-			changed = true;
-
+			fragment.reassign( section.descriptor.i, oldIndex, newIndex, by, oldKeypath, newKeypath );
+			reassignedFragments[ newIndex ] = fragment;
 		});
 
-		if ( toTeardown ) {
-			while ( fragment = toTeardown.pop() ) {
-				fragment.teardown( true );
-			}
+		while ( fragment = toTeardown.pop() ) {
+			fragment.teardown( true );
 		}
 
 		// If nothing changed with the existing fragments, then we start adding
@@ -67,7 +59,8 @@ define([
 			firstChange = this.length;
 		}
 
-		newLength = this.root.get( this.keypath ).length;
+		this.length = newLength = this.root.get( this.keypath ).length;
+
 		if ( newLength === firstChange ) {
 			// ...unless there are no new fragments to add
 			return;
@@ -90,12 +83,12 @@ define([
 		for ( i = firstChange; i < newLength; i += 1 ) {
 
 			// is this an existing fragment?
-			if ( fragment = newFragments[i] ) {
+			if ( fragment = reassignedFragments[i] ) {
 				this.docFrag.appendChild( fragment.detach( false ) );
 			}
 
 			else {
-				fragmentOptions.contextStack = this.contextStack.concat( this.keypath + '.' + i );
+				fragmentOptions.context = this.keypath + '.' + i;
 				fragmentOptions.index = i;
 
 				fragment = this.createFragment( fragmentOptions );
@@ -107,8 +100,6 @@ define([
 		// reinsert fragment
 		nextNode = parentFragment.findNextNode( this );
 		parentFragment.pNode.insertBefore( this.docFrag, nextNode );
-
-		this.length = newLength;
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/render/DomFragment/Section/prototype/render.js b/src/render/DomFragment/Section/prototype/render.js
new file mode 100644
index 0000000000..a2f994f43d
--- /dev/null
+++ b/src/render/DomFragment/Section/prototype/render.js
@@ -0,0 +1,58 @@
+define([
+	'config/isClient',
+	'render/shared/updateSection'
+], function (
+	isClient,
+	updateSection
+) {
+
+	'use strict';
+
+	return function DomSection_prototype_render ( value ) {
+		var nextNode, wrapped;
+
+		// with sections, we need to get the fake value if we have a wrapped object
+		if ( wrapped = this.root._wrapped[ this.keypath ] ) {
+			value = wrapped.get();
+		}
+
+		// prevent sections from rendering multiple times (happens if
+		// evaluators evaluate while update is happening)
+		if ( this.rendering ) {
+			return;
+		}
+
+		this.rendering = true;
+		updateSection( this, value );
+		this.rendering = false;
+
+		// if we have no new nodes to insert (i.e. the section length stayed the
+		// same, or shrank), we don't need to go any further
+		if ( this.docFrag && !this.docFrag.childNodes.length ) {
+			return;
+		}
+
+		// if this isn't the initial render, we need to insert any new nodes in
+		// the right place
+		if ( !this.initialising && isClient ) {
+
+			// Normally this is just a case of finding the next node, and inserting
+			// items before it...
+			nextNode = this.parentFragment.findNextNode( this );
+
+			if ( nextNode && ( nextNode.parentNode === this.parentFragment.pNode ) ) {
+				this.parentFragment.pNode.insertBefore( this.docFrag, nextNode );
+			}
+
+			// ...but in some edge cases the next node will not have been attached to
+			// the DOM yet, in which case we append to the end of the parent node
+			else {
+				// TODO could there be a situation in which later nodes could have
+				// been attached to the parent node, i.e. we need to find a sibling
+				// to insert before?
+				this.parentFragment.pNode.appendChild( this.docFrag );
+			}
+		}
+	};
+
+});
diff --git a/src/render/DomFragment/Section/prototype/splice.js b/src/render/DomFragment/Section/prototype/splice.js
new file mode 100644
index 0000000000..f9eaedf88b
--- /dev/null
+++ b/src/render/DomFragment/Section/prototype/splice.js
@@ -0,0 +1,84 @@
+define([
+	'render/DomFragment/Section/reassignFragments'
+], function (
+	reassignFragments
+) {
+
+	'use strict';
+
+	return function ( spliceSummary ) {
+		var section = this, balance, start, insertStart, insertEnd, spliceArgs;
+
+		balance = spliceSummary.balance;
+
+		if ( !balance ) {
+			// The array length hasn't changed - we don't need to add or remove anything
+			return;
+		}
+
+		start = spliceSummary.start;
+		section.length += balance;
+
+		// If more items were removed from the array than added, we tear down
+		// the excess fragments and remove them...
+		if ( balance < 0 ) {
+			section.fragments.splice( start, -balance ).forEach( teardown );
+
+			// Reassign fragments after the ones we've just removed
+			reassignFragments( section, start, section.length, balance );
+
+			// Nothing more to do
+			return;
+		}
+
+		// ...otherwise we need to add some things to the DOM.
+		insertStart = start + spliceSummary.removed;
+		insertEnd = start + spliceSummary.added;
+
+		// Make room for the new fragments by doing a splice that simulates
+		// what happened to the data array
+		spliceArgs = [ insertStart, 0 ];
+		spliceArgs.length += balance;
+		section.fragments.splice.apply( section.fragments, spliceArgs );
+
+		// Reassign existing fragments at the end of the array
+		reassignFragments( section, insertEnd, section.length, balance );
+
+		// Create the new ones
+		renderNewFragments( section, insertStart, insertEnd );
+	};
+
+	function teardown ( fragment ) {
+		fragment.teardown( true );
+	}
+
+	function renderNewFragments ( section, start, end ) {
+		var fragmentOptions, i, insertionPoint;
+
+		section.rendering = true;
+
+		fragmentOptions = {
+			descriptor: section.descriptor.f,
+			root:       section.root,
+			pNode:      section.parentFragment.pNode,
+			owner:      section,
+			indexRef:   section.descriptor.i
+		};
+
+		for ( i = start; i < end; i += 1 ) {
+			fragmentOptions.context = section.keypath + '.' + i;
+			fragmentOptions.index = i;
+
+			section.fragments[i] = section.createFragment( fragmentOptions );
+		}
+
+		// Figure out where these new nodes need to be inserted
+		insertionPoint = ( section.fragments[ end ] ? section.fragments[ end ].firstNode() : section.parentFragment.findNextNode( section ) );
+
+		// Append docfrag in front of insertion point
+		section.parentFragment.pNode.insertBefore( section.docFrag, insertionPoint );
+
+		section.rendering = false;
+	}
+
+});
diff --git a/src/render/DomFragment/Section/reassignFragment.js b/src/render/DomFragment/Section/reassignFragment.js
deleted file mode 100644
index dfd79c4c90..0000000000
--- a/src/render/DomFragment/Section/reassignFragment.js
+++ /dev/null
@@ -1,184 +0,0 @@
-define([
-	'config/types',
-	'shared/unregisterDependant',
-	'render/shared/ExpressionResolver/_ExpressionResolver'
-], function (
-	types,
-	unregisterDependant,
-	ExpressionResolver
-) {
-
-	'use strict';
-
-	return reassignFragment;
-
-	function reassignFragment ( fragment, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath ) {
-		var i, item, context, query;
-
-		// If this fragment was rendered with innerHTML, we have nothing to do
-		// TODO a less hacky way of determining this
-		if ( fragment.html ) {
-			return;
-		}
-
-		if ( fragment.indexRefs && fragment.indexRefs[ indexRef ] !== undefined ) {
-			fragment.indexRefs[ indexRef ] = newIndex;
-		}
-
-		// fix context stack
-		i = fragment.contextStack.length;
-		while ( i-- ) {
-			context = fragment.contextStack[i];
-			if ( context.substr( 0, oldKeypath.length ) === oldKeypath ) {
-				fragment.contextStack[i] = context.replace( oldKeypath, newKeypath );
-			}
-		}
-
-		i = fragment.items.length;
-		while ( i-- ) {
-			item = fragment.items[i];
-
-			switch ( item.type ) {
-				case types.ELEMENT:
-				reassignElement( item, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath );
-				break;
-
-				case types.PARTIAL:
-				reassignFragment( item.fragment, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath );
-				break;
-
-				case types.COMPONENT:
-				reassignFragment( item.instance.fragment, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath );
-				if ( query = fragment.root._liveComponentQueries[ item.name ] ) {
-					query._makeDirty();
-				}
-				break;
-
-				case types.SECTION:
-				case types.INTERPOLATOR:
-				case types.TRIPLE:
-				reassignMustache( item, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath );
-				break;
-			}
-		}
-	}
-
-	function reassignElement ( element, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath ) {
-		var i, attribute, storage, masterEventName, proxies, proxy, binding, bindings, liveQueries, ractive;
-
-		i = element.attributes.length;
-		while ( i-- ) {
-			attribute = element.attributes[i];
-
-			if ( attribute.fragment ) {
-				reassignFragment( attribute.fragment, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath );
-
-				if ( attribute.twoway ) {
-					attribute.updateBindings();
-				}
-			}
-		}
-
-		if ( storage = element.node._ractive ) {
-			if ( storage.keypath.substr( 0, oldKeypath.length ) === oldKeypath ) {
-				storage.keypath = storage.keypath.replace( oldKeypath, newKeypath );
-			}
-
-			if ( indexRef !== undefined ) {
-				storage.index[ indexRef ] = newIndex;
-			}
-
-			for ( masterEventName in storage.events ) {
-				proxies = storage.events[ masterEventName ].proxies;
-				i = proxies.length;
-
-				while ( i-- ) {
-					proxy = proxies[i];
-
-					if ( typeof proxy.n === 'object' ) {
-						reassignFragment( proxy.a, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath );
-					}
-
-					if ( proxy.d ) {
-						reassignFragment( proxy.d, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath );
-					}
-				}
-			}
-
-			if ( binding = storage.binding ) {
-				if ( binding.keypath.substr( 0, oldKeypath.length ) === oldKeypath ) {
-					bindings = storage.root._twowayBindings[ binding.keypath ];
-
-					// remove binding reference for old keypath
-					bindings.splice( bindings.indexOf( binding ), 1 );
-
-					// update keypath
-					binding.keypath = binding.keypath.replace( oldKeypath, newKeypath );
-
-					// add binding reference for new keypath
-					bindings = storage.root._twowayBindings[ binding.keypath ] || ( storage.root._twowayBindings[ binding.keypath ] = [] );
-					bindings.push( binding );
-				}
-			}
-		}
-
-		// reassign children
-		if ( element.fragment ) {
-			reassignFragment( element.fragment, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath );
-		}
-
-		// Update live queries, if necessary
-		if ( liveQueries = element.liveQueries ) {
-			ractive = element.root;
-
-			i = liveQueries.length;
-			while ( i-- ) {
-				ractive._liveQueries[ liveQueries[i] ]._makeDirty();
-			}
-		}
-	}
-
-	function reassignMustache ( mustache, indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath ) {
-		var i;
-
-		// expression mustache?
-		if ( mustache.descriptor.x ) {
-			// TODO should we unregister here, or leave the mustache be in the
-			// expectation that it will be unregistered when the expression
-			// resolver checks in? For now, the latter (nb if this changes, we
-			// need to manually set mustache.resolved = false, otherwise we
-			// come up against a nasty bug - #271)
-
-			if ( mustache.expressionResolver ) {
-				mustache.expressionResolver.teardown();
-			}
-
-			mustache.expressionResolver = new ExpressionResolver( mustache );
-		}
-
-		// normal keypath mustache?
-		if ( mustache.keypath ) {
-			if ( mustache.keypath.substr( 0, oldKeypath.length ) === oldKeypath ) {
-				mustache.resolve( mustache.keypath.replace( oldKeypath, newKeypath ) );
-			}
-		}
-
-		// index ref mustache?
-		else if ( mustache.indexRef === indexRef ) {
-			mustache.value = newIndex;
-			mustache.render( newIndex );
-		}
-
-		// otherwise, it's an unresolved reference. the context stack has been updated
-		// so it will take care of itself
-
-		// if it's a section mustache, we need to go through any children
-		if ( mustache.fragments ) {
-			i = mustache.fragments.length;
-			while ( i-- ) {
-				reassignFragment( mustache.fragments[i], indexRef, oldIndex, newIndex, by, oldKeypath, newKeypath );
-			}
-		}
-	}
-
-});
\ No newline at end of file
diff --git a/src/render/DomFragment/Section/reassignFragments.js b/src/render/DomFragment/Section/reassignFragments.js
index 9a345b54e9..f54cf6aac8 100644
--- a/src/render/DomFragment/Section/reassignFragments.js
+++ b/src/render/DomFragment/Section/reassignFragments.js
@@ -1,37 +1,24 @@
-define([
-	'config/types',
-	'render/DomFragment/Section/reassignFragment',
-	'shared/preDomUpdate'
-], function (
-	types,
-	reassignFragment,
-	preDomUpdate
-) {
+define([], function () {
 
 	'use strict';
 
-	return function ( root, section, start, end, by ) {
-		var i, fragment, indexRef, oldIndex, newIndex, oldKeypath, newKeypath;
+	return function ( section, start, end, by ) {
+
+		var i, fragment, indexRef, oldKeypath, newKeypath;
 
 		indexRef = section.descriptor.i;
 
 		for ( i=start; i
+			if ( pNode.tagName === 'SELECT' && pNode._ractive && pNode._ractive.binding ) {
+				pNode._ractive.binding.update();
+			}
 		},
 
 		toString: function () {
@@ -149,4 +154,4 @@ define([
 
 	return DomTriple;
 
-});
\ No newline at end of file
+});
diff --git a/src/render/DomFragment/_DomFragment.js b/src/render/DomFragment/_DomFragment.js
index 7a7b23d048..13eb81091d 100755
--- a/src/render/DomFragment/_DomFragment.js
+++ b/src/render/DomFragment/_DomFragment.js
@@ -1,7 +1,7 @@
 define([
 	'config/types',
 	'utils/matches',
-	'render/shared/initFragment',
+	'render/shared/Fragment/_Fragment',
 	'render/DomFragment/shared/insertHtml',
 	'render/DomFragment/Text',
 	'render/DomFragment/Interpolator',
@@ -15,7 +15,7 @@ define([
 ], function (
 	types,
 	matches,
-	initFragment,
+	Fragment,
 	insertHtml,
 	Text,
 	Interpolator,
@@ -40,37 +40,41 @@ define([
 			this.html = options.descriptor;
 
 			if ( this.docFrag ) {
-				this.nodes = insertHtml( this.html, options.pNode.tagName, this.docFrag );
+				this.nodes = insertHtml( this.html, options.pNode.tagName, options.pNode.namespaceURI, this.docFrag );
 			}
 		}
 
 		else {
 			// otherwise we need to make a proper fragment
-			initFragment( this, options );
+			Fragment.init( this, options );
 		}
 	};
 
 	DomFragment.prototype = {
+		reassign: Fragment.reassign,
+
 		detach: function () {
 			var len, i;
 
-			// if this was built from HTML, we just need to remove the nodes
-			if ( this.nodes ) {
-				i = this.nodes.length;
-				while ( i-- ) {
-					this.docFrag.appendChild( this.nodes[i] );
+			if ( this.docFrag ) {
+				// if this was built from HTML, we just need to remove the nodes
+				if ( this.nodes ) {
+					len = this.nodes.length;
+					for ( i = 0; i < len; i += 1 ) {
+						this.docFrag.appendChild( this.nodes[i] );
+					}
 				}
-			}
 
-			// otherwise we need to detach each item
-			else if ( this.items ) {
-				len = this.items.length;
-				for ( i = 0; i < len; i += 1 ) {
-					this.docFrag.appendChild( this.items[i].detach() );
+				// otherwise we need to detach each item
+				else if ( this.items ) {
+					len = this.items.length;
+					for ( i = 0; i < len; i += 1 ) {
+						this.docFrag.appendChild( this.items[i].detach() );
+					}
 				}
-			}
 
-			return this.docFrag;
+				return this.docFrag;
+			}
 		},
 
 		createItem: function ( options ) {
@@ -285,4 +289,4 @@ define([
 	circular.DomFragment = DomFragment;
 	return DomFragment;
 
-});
\ No newline at end of file
+});
diff --git a/src/render/DomFragment/shared/detach.js b/src/render/DomFragment/shared/detach.js
new file mode 100644
index 0000000000..85787442f2
--- /dev/null
+++ b/src/render/DomFragment/shared/detach.js
@@ -0,0 +1,14 @@
+define( function () {
+
+	'use strict';
+
+	return function () {
+		var node = this.node, parentNode;
+
+		if ( node && ( parentNode = node.parentNode ) ) {
+			parentNode.removeChild( node );
+			return node;
+		}
+	};
+
+});
diff --git a/src/render/DomFragment/shared/enforceCase.js b/src/render/DomFragment/shared/enforceCase.js
index 3febe8e8d0..e94e72843f 100644
--- a/src/render/DomFragment/shared/enforceCase.js
+++ b/src/render/DomFragment/shared/enforceCase.js
@@ -22,4 +22,4 @@ define( function () {
 		return map[ lowerCaseElementName ] || lowerCaseElementName;
 	};
 
-});
\ No newline at end of file
+});
diff --git a/src/render/DomFragment/shared/insertHtml.js b/src/render/DomFragment/shared/insertHtml.js
index 9347bd3e83..a9b6a07cb8 100755
--- a/src/render/DomFragment/shared/insertHtml.js
+++ b/src/render/DomFragment/shared/insertHtml.js
@@ -1,22 +1,52 @@
 define([
+	'config/namespaces',
 	'utils/createElement'
 ], function (
+	namespaces,
 	createElement
 ) {
 
 	'use strict';
 
-	var elementCache = {};
+	var elementCache = {}, ieBug, ieBlacklist;
 
-	return function ( html, tagName, docFrag ) {
-		var container, nodes = [];
+	try {
+		createElement( 'table' ).innerHTML = 'foo';
+	} catch ( err ) {
+		ieBug = true;
+
+		ieBlacklist = {
+			TABLE:  [ '', '
' ], + THEAD: [ '', '
' ], + TBODY: [ '', '
' ], + TR: [ '', '
' ], + SELECT: [ '' ] + }; + } + + return function ( html, tagName, namespace, docFrag ) { + var container, nodes = [], wrapper; if ( html ) { - container = elementCache[ tagName ] || ( elementCache[ tagName ] = createElement( tagName ) ); - container.innerHTML = html; + if ( ieBug && ( wrapper = ieBlacklist[ tagName ] ) ) { + container = element( 'DIV' ); + container.innerHTML = wrapper[0] + html + wrapper[1]; + container = container.querySelector( '.x' ); + } + + else if ( namespace === namespaces.svg ) { + container = element( 'DIV' ); + container.innerHTML = '' + html + ''; + container = container.querySelector( '.x' ); + } + + else { + container = element( tagName ); + container.innerHTML = html; + } while ( container.firstChild ) { - nodes[ nodes.length ] = container.firstChild; + nodes.push( container.firstChild ); docFrag.appendChild( container.firstChild ); } } @@ -24,4 +54,8 @@ define([ return nodes; }; -}); \ No newline at end of file + function element ( tagName ) { + return elementCache[ tagName ] || ( elementCache[ tagName ] = createElement( tagName ) ); + } + +}); diff --git a/src/render/StringFragment/Interpolator.js b/src/render/StringFragment/Interpolator.js index a1f8577d99..294632630e 100755 --- a/src/render/StringFragment/Interpolator.js +++ b/src/render/StringFragment/Interpolator.js @@ -1,27 +1,24 @@ define([ 'config/types', 'shared/teardown', - 'render/shared/initMustache', - 'render/shared/updateMustache', - 'render/shared/resolveMustache' + 'render/shared/Mustache/_Mustache', ], function ( types, teardown, - initMustache, - updateMustache, - resolveMustache + Mustache ) { 'use strict'; var StringInterpolator = function ( options ) { this.type = types.INTERPOLATOR; - initMustache( this, options ); + Mustache.init( this, options ); }; StringInterpolator.prototype = { - update: updateMustache, - resolve: resolveMustache, + update: Mustache.update, + resolve: Mustache.resolve, + reassign: Mustache.reassign, render: function ( value ) { this.value = value; @@ -51,4 +48,4 @@ define([ return JSON.stringify( value ); } -}); \ No newline at end of file +}); diff --git a/src/render/StringFragment/Section.js b/src/render/StringFragment/Section.js index 1867c092c5..0e39d687f8 100755 --- a/src/render/StringFragment/Section.js +++ b/src/render/StringFragment/Section.js @@ -1,16 +1,12 @@ define([ 'config/types', - 'render/shared/initMustache', - 'render/shared/updateMustache', - 'render/shared/resolveMustache', + 'render/shared/Mustache/_Mustache', 'render/shared/updateSection', 'shared/teardown', 'circular' ], function ( types, - initMustache, - updateMustache, - resolveMustache, + Mustache, updateSection, teardown, circular @@ -29,12 +25,13 @@ define([ this.fragments = []; this.length = 0; - initMustache( this, options ); + Mustache.init( this, options ); }; StringSection.prototype = { - update: updateMustache, - resolve: resolveMustache, + update: Mustache.update, + resolve: Mustache.resolve, + reassign: Mustache.reassign, teardown: function () { this.teardownFragments(); diff --git a/src/render/StringFragment/Text.js b/src/render/StringFragment/Text.js index 4f1dcafd4a..5038eb2ccf 100755 --- a/src/render/StringFragment/Text.js +++ b/src/render/StringFragment/Text.js @@ -12,6 +12,8 @@ define([ 'config/types' ], function ( types ) { return this.text; }, + reassign: function () {}, //no-op + teardown: function () {} // no-op }; diff --git a/src/render/StringFragment/_StringFragment.js b/src/render/StringFragment/_StringFragment.js index 8231045461..c8bf298bb0 100755 --- a/src/render/StringFragment/_StringFragment.js +++ b/src/render/StringFragment/_StringFragment.js @@ -1,7 +1,7 @@ define([ 'config/types', 'utils/parseJSON', - 'render/shared/initFragment', + 'render/shared/Fragment/_Fragment', 'render/StringFragment/Interpolator', 'render/StringFragment/Section', 'render/StringFragment/Text', @@ -10,7 +10,7 @@ define([ ], function ( types, parseJSON, - initFragment, + Fragment, Interpolator, Section, Text, @@ -21,10 +21,12 @@ define([ 'use strict'; var StringFragment = function ( options ) { - initFragment( this, options ); + Fragment.init( this, options ); }; StringFragment.prototype = { + reassign: Fragment.reassign, + createItem: function ( options ) { if ( typeof options.descriptor === 'string' ) { return new Text( options.descriptor ); @@ -39,7 +41,6 @@ define([ } }, - bubble: function () { this.dirty = true; this.owner.bubble(); diff --git a/src/render/shared/Evaluator/Reference.js b/src/render/shared/Evaluator/Reference.js index 0fb592ac11..e2e63d0b59 100644 --- a/src/render/shared/Evaluator/Reference.js +++ b/src/render/shared/Evaluator/Reference.js @@ -129,4 +129,4 @@ define([ return fn[ '_' + ractive._guid ]; } -}); \ No newline at end of file +}); diff --git a/src/render/shared/Evaluator/SoftReference.js b/src/render/shared/Evaluator/SoftReference.js index e3307c6d34..95f1b3955e 100644 --- a/src/render/shared/Evaluator/SoftReference.js +++ b/src/render/shared/Evaluator/SoftReference.js @@ -37,4 +37,4 @@ define([ return SoftReference; -}); \ No newline at end of file +}); diff --git a/src/render/shared/Evaluator/_Evaluator.js b/src/render/shared/Evaluator/_Evaluator.js index 2262c7c73d..937666b627 100644 --- a/src/render/shared/Evaluator/_Evaluator.js +++ b/src/render/shared/Evaluator/_Evaluator.js @@ -1,20 +1,18 @@ define([ + 'global/runloop', + 'utils/warn', 'utils/isEqual', - 'utils/defineProperty', 'shared/clearCache', 'shared/notifyDependants', - 'shared/registerDependant', - 'shared/unregisterDependant', 'shared/adaptIfNecessary', 'render/shared/Evaluator/Reference', 'render/shared/Evaluator/SoftReference' ], function ( + runloop, + warn, isEqual, - defineProperty, clearCache, notifyDependants, - registerDependant, - unregisterDependant, adaptIfNecessary, Reference, SoftReference @@ -24,37 +22,34 @@ define([ var Evaluator, cache = {}; - Evaluator = function ( root, keypath, functionStr, args, priority ) { - var i, arg; + Evaluator = function ( root, keypath, uniqueString, functionStr, args, priority ) { + var evaluator = this; - this.root = root; - this.keypath = keypath; - this.priority = priority; + evaluator.root = root; + evaluator.uniqueString = uniqueString; + evaluator.keypath = keypath; + evaluator.priority = priority; - this.fn = getFunctionFromString( functionStr, args.length ); - this.values = []; - this.refs = []; + evaluator.fn = getFunctionFromString( functionStr, args.length ); + evaluator.values = []; + evaluator.refs = []; - i = args.length; - while ( i-- ) { - if ( arg = args[i] ) { - if ( arg[0] ) { - // this is an index ref... we don't need to register a dependant - this.values[i] = arg[1]; - } + args.forEach( function ( arg, i ) { + if ( !arg ) { + return; + } - else { - this.refs[ this.refs.length ] = new Reference( root, arg[1], this, i, priority ); - } + if ( arg.indexRef ) { + // this is an index ref... we don't need to register a dependant + evaluator.values[i] = arg.value; } else { - this.values[i] = undefined; + evaluator.refs.push( new Reference( root, arg.keypath, evaluator, i, priority ) ); } - } + }); - this.selfUpdating = ( this.refs.length <= 1 ); - this.update(); + evaluator.selfUpdating = ( evaluator.refs.length <= 1 ); }; Evaluator.prototype = { @@ -68,7 +63,7 @@ define([ // updated once all the information is in, to prevent unnecessary // cascading. Only if we're already resolved, obviously else if ( !this.deferred ) { - this.root._deferred.evals.push( this ); + runloop.addEvaluator( this ); this.deferred = true; } }, @@ -87,20 +82,18 @@ define([ value = this.fn.apply( null, this.values ); } catch ( err ) { if ( this.root.debug ) { - throw err; - } else { - value = undefined; + warn( 'Error evaluating "' + this.uniqueString + '": ' + err.message || err ); } + + value = undefined; } if ( !isEqual( value, this.value ) ) { + this.value = value; + clearCache( this.root, this.keypath ); - this.root._cache[ this.keypath ] = value; - // TODO teardown previous wrapper? adaptIfNecessary( this.root, this.keypath, value, true ); - - this.value = value; notifyDependants( this.root, this.keypath ); } @@ -161,7 +154,7 @@ define([ keypath = softDeps[i]; if ( !this.softRefs[ keypath ] ) { ref = new SoftReference( this.root, keypath, this ); - this.softRefs[ this.softRefs.length ] = ref; + this.softRefs.push( ref ); this.softRefs[ keypath ] = true; } } @@ -193,4 +186,4 @@ define([ return fn; } -}); \ No newline at end of file +}); diff --git a/src/render/shared/ExpressionResolver/ReferenceScout.js b/src/render/shared/ExpressionResolver/ReferenceScout.js deleted file mode 100644 index 596bc85ee1..0000000000 --- a/src/render/shared/ExpressionResolver/ReferenceScout.js +++ /dev/null @@ -1,46 +0,0 @@ -define([ - 'shared/resolveRef', - 'shared/teardown' -], function ( - resolveRef, - teardown -) { - - 'use strict'; - - var ReferenceScout = function ( resolver, ref, contextStack, argNum ) { - var keypath, root; - - root = this.root = resolver.root; - - keypath = resolveRef( root, ref, contextStack ); - if ( keypath !== undefined ) { - resolver.resolveRef( argNum, false, keypath ); - } else { - this.ref = ref; - this.argNum = argNum; - this.resolver = resolver; - this.contextStack = contextStack; - - root._pendingResolution[ root._pendingResolution.length ] = this; - } - }; - - ReferenceScout.prototype = { - resolve: function ( keypath ) { - this.keypath = keypath; - this.resolver.resolveRef( this.argNum, false, keypath ); - }, - - teardown: function () { - // if we haven't found a keypath yet, we can - // stop the search now - if ( !this.keypath ) { - teardown( this ); - } - } - }; - - return ReferenceScout; - -}); \ No newline at end of file diff --git a/src/render/shared/ExpressionResolver/_ExpressionResolver.js b/src/render/shared/ExpressionResolver/_ExpressionResolver.js deleted file mode 100644 index dda942bf6f..0000000000 --- a/src/render/shared/ExpressionResolver/_ExpressionResolver.js +++ /dev/null @@ -1,113 +0,0 @@ -define([ - 'render/shared/Evaluator/_Evaluator', - 'render/shared/ExpressionResolver/ReferenceScout', - 'render/shared/ExpressionResolver/getKeypath', - 'render/shared/ExpressionResolver/reassignDependants' -], function ( - Evaluator, - ReferenceScout, - getKeypath, - reassignDependants -) { - - 'use strict'; - - var ExpressionResolver = function ( mustache ) { - - var expression, i, len, ref, indexRefs; - - this.root = mustache.root; - this.mustache = mustache; - this.args = []; - this.scouts = []; - - expression = mustache.descriptor.x; - indexRefs = mustache.parentFragment.indexRefs; - - this.str = expression.s; - - // send out scouts for each reference - len = this.unresolved = this.args.length = ( expression.r ? expression.r.length : 0 ); - - if ( !len ) { - this.resolved = this.ready = true; - this.bubble(); // some expressions don't have references. edge case, but, yeah. - return; - } - - for ( i=0; i this.end ) { + if ( this.step ) { + this.step( 1 ); + } + + if ( this.complete ) { + this.complete( 1 ); + } + + return false; + } + + elapsed = now - this.start; + eased = this.easing( elapsed / this.duration ); + + if ( this.step ) { + this.step( eased ); + } + + return true; + }, + + stop: function () { + if ( this.abort ) { + this.abort(); + } + + this.running = false; + } + }; + + return Ticker; + + function linear ( t ) { return t; } + +}); diff --git a/src/shared/Unresolved.js b/src/shared/Unresolved.js new file mode 100644 index 0000000000..c6d20dafd9 --- /dev/null +++ b/src/shared/Unresolved.js @@ -0,0 +1,27 @@ +define([ + 'global/runloop' +], function ( + runloop +) { + + 'use strict'; + + var Unresolved = function ( ractive, ref, parentFragment, callback ) { + this.root = ractive; + this.ref = ref; + this.parentFragment = parentFragment; + + this.resolve = callback; + + runloop.addUnresolved( this ); + }; + + Unresolved.prototype = { + teardown: function () { + runloop.removeUnresolved( this ); + } + }; + + return Unresolved; + +}); diff --git a/src/shared/adaptIfNecessary.js b/src/shared/adaptIfNecessary.js index dab7c32253..3306848da3 100644 --- a/src/shared/adaptIfNecessary.js +++ b/src/shared/adaptIfNecessary.js @@ -1,24 +1,26 @@ define([ 'registries/adaptors', - 'Ractive/prototype/get/arrayAdaptor', - 'Ractive/prototype/get/magicAdaptor' + 'shared/get/arrayAdaptor/_arrayAdaptor', + 'shared/get/magicAdaptor', + 'shared/get/magicArrayAdaptor' ], function ( adaptorRegistry, arrayAdaptor, - magicAdaptor + magicAdaptor, + magicArrayAdaptor ) { 'use strict'; var prefixers = {}; - return function ( ractive, keypath, value, isExpressionResult ) { + return function adaptIfNecessary ( ractive, keypath, value, isExpressionResult ) { var len, i, adaptor, wrapped; // Do we have an adaptor for this value? - len = ractive.adaptors.length; + len = ractive.adapt.length; for ( i = 0; i < len; i += 1 ) { - adaptor = ractive.adaptors[i]; + adaptor = ractive.adapt[i]; // Adaptors can be specified as e.g. [ 'Backbone.Model', 'Backbone.Collection' ] - // we need to get the actual adaptor if that's the case @@ -26,25 +28,34 @@ define([ if ( !adaptorRegistry[ adaptor ] ) { throw new Error( 'Missing adaptor "' + adaptor + '"' ); } - adaptor = ractive.adaptors[i] = adaptorRegistry[ adaptor ]; + adaptor = ractive.adapt[i] = adaptorRegistry[ adaptor ]; } if ( adaptor.filter( value, keypath, ractive ) ) { wrapped = ractive._wrapped[ keypath ] = adaptor.wrap( ractive, value, keypath, getPrefixer( keypath ) ); wrapped.value = value; - return; + return value; } } if ( !isExpressionResult ) { - if ( ractive.magic && magicAdaptor.filter( value, keypath, ractive ) ) { - ractive._wrapped[ keypath ] = magicAdaptor.wrap( ractive, value, keypath ); + + if ( ractive.magic ) { + if ( magicArrayAdaptor.filter( value, keypath, ractive ) ) { + ractive._wrapped[ keypath ] = magicArrayAdaptor.wrap( ractive, value, keypath ); + } + + else if ( magicAdaptor.filter( value, keypath, ractive ) ) { + ractive._wrapped[ keypath ] = magicAdaptor.wrap( ractive, value, keypath ); + } } else if ( ractive.modifyArrays && arrayAdaptor.filter( value, keypath, ractive ) ) { ractive._wrapped[ keypath ] = arrayAdaptor.wrap( ractive, value, keypath ); } } + + return value; }; function prefixKeypath ( obj, prefix ) { @@ -90,4 +101,4 @@ define([ return prefixers[ rootKeypath ]; } -}); \ No newline at end of file +}); diff --git a/src/Ractive/prototype/animate/animations.js b/src/shared/animations.js old mode 100755 new mode 100644 similarity index 71% rename from src/Ractive/prototype/animate/animations.js rename to src/shared/animations.js index be20b835ad..24ef108ebf --- a/src/Ractive/prototype/animate/animations.js +++ b/src/shared/animations.js @@ -1,4 +1,12 @@ -define([ 'Ractive/prototype/animate/requestAnimationFrame' ], function ( rAF ) { +define([ + 'utils/requestAnimationFrame', + 'utils/getTime', + 'global/runloop' +], function ( + rAF, + getTime, + runloop +) { 'use strict'; @@ -6,17 +14,23 @@ define([ 'Ractive/prototype/animate/requestAnimationFrame' ], function ( rAF ) { var animations = { tick: function () { - var i, animation; + var i, animation, now; + + now = getTime(); + + runloop.start(); for ( i=0; i 1 ) { + keys.pop(); + upstreamKeypath = keys.join( '.' ); + + if ( upstreamChanges[ upstreamKeypath ] !== true ) { + upstreamChanges.push( upstreamKeypath ); + upstreamChanges[ upstreamKeypath ] = true; + } + } + } + + return upstreamChanges; + }; + +}); diff --git a/src/shared/getValueFromCheckboxes.js b/src/shared/getValueFromCheckboxes.js index 6522aacd24..ea20ac1928 100644 --- a/src/shared/getValueFromCheckboxes.js +++ b/src/shared/getValueFromCheckboxes.js @@ -12,7 +12,7 @@ define( function () { // if we're still in the initial render, we need to find the inputs from the as-yet off-DOM // document fragment. otherwise, the root element - rootEl = ractive.rendered ? ractive.el : ractive.fragment.docFrag; + rootEl = ractive._rendering ? ractive.fragment.docFrag : ractive.el; checkboxes = rootEl.querySelectorAll( 'input[type="checkbox"][name="{{' + keypath + '}}"]' ); len = checkboxes.length; @@ -21,11 +21,11 @@ define( function () { checkbox = checkboxes[i]; if ( checkbox.hasAttribute( 'checked' ) || checkbox.checked ) { - value[ value.length ] = checkbox._ractive.value; + value.push( checkbox._ractive.value ); } } return value; }; -}); \ No newline at end of file +}); diff --git a/src/shared/interpolate.js b/src/shared/interpolate.js index a61b0921e5..4bcc57a75a 100644 --- a/src/shared/interpolate.js +++ b/src/shared/interpolate.js @@ -1,118 +1,40 @@ define([ - 'utils/isArray', - 'utils/isObject', - 'utils/isNumeric' + 'circular', + 'utils/warn', + 'registries/interpolators' ], function ( - isArray, - isObject, - isNumeric + circular, + warn, + interpolators ) { 'use strict'; - // TODO short circuit values that stay the same - // TODO make this plugin-able - - var interpolate = function ( from, to ) { - if ( isNumeric( from ) && isNumeric( to ) ) { - return makeNumberInterpolator( +from, +to ); + var interpolate = function ( from, to, ractive, type ) { + if ( from === to ) { + return snap( to ); } - if ( isArray( from ) && isArray( to ) ) { - return makeArrayInterpolator( from, to ); - } + if ( type ) { + if ( ractive.interpolators[ type ] ) { + return ractive.interpolators[ type ]( from, to ) || snap( to ); + } - if ( isObject( from ) && isObject( to ) ) { - return makeObjectInterpolator( from, to ); + warn( 'Missing "' + type + '" interpolator. You may need to download a plugin from [TODO]' ); } - return function () { return to; }; + return interpolators.number( from, to ) || + interpolators.array( from, to ) || + interpolators.object( from, to ) || + interpolators.cssLength( from, to ) || + snap( to ); }; + circular.interpolate = interpolate; return interpolate; - - function makeNumberInterpolator ( from, to ) { - var delta = to - from; - - if ( !delta ) { - return function () { return from; }; - } - - return function ( t ) { - return from + ( t * delta ); - }; - } - - function makeArrayInterpolator ( from, to ) { - var intermediate, interpolators, len, i; - - intermediate = []; - interpolators = []; - - i = len = Math.min( from.length, to.length ); - while ( i-- ) { - interpolators[i] = interpolate( from[i], to[i] ); - } - - // surplus values - don't interpolate, but don't exclude them either - for ( i=len; i - - - Events | Ractive Test Suite - - - -
-
- - - - - - - - - diff --git a/test/build/find.html b/test/build/find.html deleted file mode 100644 index 11ddd5cd7c..0000000000 --- a/test/build/find.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - Find | Ractive Test Suite - - - -
-
- - - - - - - - - diff --git a/test/build/index.html b/test/build/index.html deleted file mode 100755 index 6fb322ba81..0000000000 --- a/test/build/index.html +++ /dev/null @@ -1,56 +0,0 @@ - - - - Ractive Test Suite - - - -
-
- - - - - - - - - diff --git a/test/build/misc.html b/test/build/misc.html deleted file mode 100755 index c1b958d1a9..0000000000 --- a/test/build/misc.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - Miscellaneous | Ractive Test Suite - - - -
-
- - - - - - - - - diff --git a/test/build/mustache.html b/test/build/mustache.html deleted file mode 100755 index 626b65bf7d..0000000000 --- a/test/build/mustache.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - Mustache | Ractive Test Suite - - - -
-
- - - - - - - - - diff --git a/test/build/observe.html b/test/build/observe.html deleted file mode 100644 index 5779516e5b..0000000000 --- a/test/build/observe.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - Observe | Ractive Test Suite - - - -
-
- - - - - - - - - diff --git a/test/build/parse.html b/test/build/parse.html deleted file mode 100755 index 7fa931b51f..0000000000 --- a/test/build/parse.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - Parsing | Ractive Test Suite - - - -
-
- - - - - - - - - diff --git a/test/build/render.html b/test/build/render.html deleted file mode 100755 index bb84abd1ba..0000000000 --- a/test/build/render.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - Rendering | Ractive Test Suite - - - -
-
- - - - - - - - - diff --git a/test/modules/adaptors.js b/test/modules/adaptors.js new file mode 100644 index 0000000000..950b0e6dd7 --- /dev/null +++ b/test/modules/adaptors.js @@ -0,0 +1,252 @@ +define([ 'ractive' ], function ( Ractive ) { + + 'use strict'; + + return function () { + + var fixture, Model, adaptor; + + module( 'Adaptors' ); + + // setup + fixture = document.getElementById( 'qunit-fixture' ); + + Model = function ( attributes ) { + this.attributes = attributes; + this.callbacks = {}; + this.transformers = {}; + }; + + Model.prototype = { + set: function ( attr, newValue ) { + var transformer, oldValue = this.attributes[ attr ]; + + if ( transformer = this.transformers[ attr ] ) { + newValue = transformer.call( this, newValue, oldValue ); + } + + if ( oldValue !== newValue ) { + this.attributes[ attr ] = newValue; + this.fire( 'change', attr, newValue ); + } + }, + + get: function ( attr ) { + return this.attributes[ attr ]; + }, + + reset: function ( newData ) { + var attr; + + this.attributes = {}; + + for ( attr in newData ) { + if ( newData.hasOwnProperty( attr ) ) { + this.set( attr, newData[ attr ] ); + } + } + }, + + transform: function ( attr, transformer ) { + this.transformers[ attr ] = transformer; + if ( this.attributes.hasOwnProperty( attr ) ) { + this.set( attr, this.get( attr ) ); + } + }, + + on: function ( eventName, callback ) { + var self = this; + + if ( !this.callbacks[ eventName ] ) { + this.callbacks[ eventName ] = []; + } + + this.callbacks[ eventName ].push( callback ); + + return { + cancel: function () { + self.off( eventName, callback ); + } + } + }, + + off: function ( eventName, callback ) { + var callbacks, index; + + callbacks = this.callbacks[ eventName ]; + + if ( !callbacks ) { + return; + } + + index = callbacks.indexOf( callback ); + if ( index !== -1 ) { + callbacks.splice( index, 1 ); + } + }, + + fire: function ( eventName ) { + var args, callbacks, i; + + callbacks = this.callbacks[ eventName ]; + + if ( !callbacks ) { + return; + } + + args = Array.prototype.slice.call( arguments, 1 ); + i = callbacks.length; + while ( i-- ) { + callbacks[i].apply( null, args ); + } + } + }; + + adaptor = { + filter: function ( object ) { + return object instanceof Model; + }, + wrap: function ( ractive, object, keypath, prefix ) { + var listener, setting; + + listener = object.on( 'change', function ( attr, value ) { + if ( setting ) { + return; + } + + setting = true; + ractive.set( prefix( attr, value ) ); + setting = false; + }); + + return { + get: function () { + return object.attributes; + }, + teardown: function () { + listener.cancel(); + }, + set: function ( attr, value ) { + if ( setting ) { + return; + } + + setting = true; + object.set( attr, value ); + setting = false; + }, + reset: function ( newData ) { + var attr; + + if ( newData instanceof Model ) { + return false; // teardown + } + + if ( !newData || typeof newData !== 'object' ) { + return false; + } + + object.reset( newData ); + ractive.update( keypath ); + } + }; + } + }; + + test( 'Adaptors can change data as it is .set() (#442)', function ( t ) { + var model, ractive; + + model = new Model({ + foo: 'BAR', + percent: 150 + }); + + model.transform( 'foo', function ( newValue, oldValue ) { + return newValue.toLowerCase(); + }); + + model.transform( 'percent', function ( newValue, oldValue ) { + return Math.min( 100, Math.max( 0, newValue ) ); + }); + + ractive = new Ractive({ + el: fixture, + template: '

{{model.foo}}

{{model.percent}}

', + data: { + model: model + }, + adapt: [ adaptor ] + }); + + t.htmlEqual( fixture.innerHTML, '

bar

100

' ); + + ractive.set( 'model.foo', 'BAZ' ); + ractive.set( 'model.percent', -20 ); + t.htmlEqual( fixture.innerHTML, '

baz

0

' ); + + ractive.set( 'model', { + foo: 'QUX', + percent: 50 + }); + t.htmlEqual( fixture.innerHTML, '

qux

50

' ); + }); + + test( 'ractive.reset() calls are forwarded to wrappers if the root data object is wrapped', function ( t ) { + var model, ractive; + + model = new Model({ + foo: 'BAR', + unwanted: 'here' + }); + + model.transform( 'foo', function ( newValue, oldValue ) { + return newValue.toLowerCase(); + }); + + ractive = new Ractive({ + el: fixture, + template: '

{{foo}}

{{unwanted}}', + data: model, + adapt: [ adaptor ] + }); + + ractive.reset({ foo: 'BAZ' }); + t.htmlEqual( fixture.innerHTML, '

baz

' ); + + model = new Model({ foo: 'QUX' }); + + model.transform( 'foo', function ( newValue, oldValue ) { + return newValue.toLowerCase(); + }); + + ractive.reset( model ); + t.htmlEqual( fixture.innerHTML, '

qux

' ); + }); + + test( 'If a wrapper\'s reset() method returns false, it should be torn down (#467)', function ( t ) { + var model1, model2, ractive; + + model1 = new Model({ + foo: 'bar' + }); + + model2 = new Model({ + foo: 'baz' + }); + + ractive = new Ractive({ + el: fixture, + template: '

{{model.foo}}

', + data: { model: model1 }, + adapt: [ adaptor ] + }); + + t.htmlEqual( fixture.innerHTML, '

bar

' ); + + ractive.set( 'model', model2 ); + t.htmlEqual( fixture.innerHTML, '

baz

' ); + }); + + }; + +}); diff --git a/test/modules/arrays.js b/test/modules/arrays.js new file mode 100644 index 0000000000..50e8f1cd26 --- /dev/null +++ b/test/modules/arrays.js @@ -0,0 +1,201 @@ +define([ 'ractive' ], function ( Ractive ) { + + 'use strict'; + + return function () { + + var fixture, List, baseItems; + + module( 'Arrays' ); + + // some set-up + fixture = document.getElementById( 'qunit-fixture' ); + + List = Ractive.extend({ + template: '
    {{#items}}
  • {{.}}
  • {{/items}}
' + }); + + baseItems = [ 'alice', 'bob', 'charles' ]; + + test( 'array.push()', function ( t ) { + var items, ractive; + + items = baseItems.slice(); + + ractive = new List({ + el: fixture, + data: { items: items } + }); + + items.push( 'dave' ); + t.htmlEqual( fixture.innerHTML, '
  • alice
  • bob
  • charles
  • dave
' ); + }); + + test( 'array.pop()', function ( t ) { + var items, ractive; + + items = baseItems.slice(); + + ractive = new List({ + el: fixture, + data: { items: items } + }); + + items.pop(); + t.htmlEqual( fixture.innerHTML, '
  • alice
  • bob
' ); + }); + + test( 'array.shift()', function ( t ) { + var items, ractive; + + items = baseItems.slice(); + + ractive = new List({ + el: fixture, + data: { items: items } + }); + + items.shift(); + t.htmlEqual( fixture.innerHTML, '
  • bob
  • charles
' ); + }); + + test( 'array.unshift()', function ( t ) { + var items, ractive; + + items = baseItems.slice(); + + ractive = new List({ + el: fixture, + data: { items: items } + }); + + items.unshift( 'dave'); + t.htmlEqual( fixture.innerHTML, '
  • dave
  • alice
  • bob
  • charles
' ); + }); + + test( 'array.splice()', function ( t ) { + var items, ractive; + + items = baseItems.slice(); + + ractive = new List({ + el: fixture, + data: { items: items } + }); + + items.splice( 1, 1, 'dave', 'eric' ); + t.htmlEqual( fixture.innerHTML, '
  • alice
  • dave
  • eric
  • charles
' ); + }); + + test( 'Regression test for #425', function ( t ) { + var items, ractive; + + items = []; + + ractive = new Ractive({ + el: fixture, + template: '{{#items.length < limit}}

{{items.length}} / {{limit}}

{{/items.length < limit}}', + data: { + items: items, + limit: 3 + } + }); + + t.htmlEqual( fixture.innerHTML, '

0 / 3

' ); + + items.push( 'x', 'y' ); + t.htmlEqual( fixture.innerHTML, '

2 / 3

' ); + + items.push( 'z' ); + t.htmlEqual( fixture.innerHTML, '' ); + }); + + test( 'Component bindings will survive a splice', function ( t ) { + var Widget, people, ractive; + + Widget = Ractive.extend({ + template: '

{{person.name}}

' + }); + + people = [ + { name: 'alice' }, + { name: 'bob' }, + { name: 'charles' } + ]; + + ractive = new Ractive({ + el: fixture, + template: '{{#people}}{{/people}}', + data: { people: people }, + components: { widget: Widget } + }); + + t.htmlEqual( fixture.innerHTML, '

alice

bob

charles

'); + + people.splice( 0, 0, { name: 'daisy' }); + t.htmlEqual( fixture.innerHTML, '

daisy

alice

bob

charles

'); + + people.splice( 2, 1, { name: 'erica' }, { name: 'fenton' }); + t.htmlEqual( fixture.innerHTML, '

daisy

alice

erica

fenton

charles

'); + }); + + test( 'Component \'backwash\' is prevented during a splice (#406)', function ( t ) { + var Widget, people, ractive; + + Widget = Ractive.extend({ + template: '

{{person.name}}

' + }); + + people = [ + { name: 'alice' }, + { name: 'bob' }, + { name: 'charles' } + ]; + + ractive = new Ractive({ + el: fixture, + template: '{{#people}}{{/people}}{{#people}}{{/people}}', + data: { people: people }, + components: { widget: Widget } + }); + + t.htmlEqual( fixture.innerHTML, '

alice

bob

charles

alice

bob

charles

'); + + people.splice( 0, 0, { name: 'daisy' }); + t.htmlEqual( fixture.innerHTML, '

daisy

alice

bob

charles

daisy

alice

bob

charles

'); + + people.splice( 2, 1, { name: 'erica' }, { name: 'fenton' }); + t.htmlEqual( fixture.innerHTML, '

daisy

alice

erica

fenton

charles

daisy

alice

erica

fenton

charles

'); + }); + + test( 'Keypath expression resolvers survive a splice operation', function ( t ) { + var ractive = new Ractive({ + el: fixture, + template: '{{#rows:r}}{{#columns:c}}

{{columns[c]}}{{r}}{{rows[r][this]}}

{{/columns}}{{rows[r][selectedColumn]}}{{/rows}}', + data: { + rows: [ + { foo: 'a', bar: 'b', baz: 'c' }, + { foo: 'd', bar: 'e', baz: 'f' }, + { foo: 'g', bar: 'h', baz: 'i' } + ], + columns: [ 'foo', 'bar', 'baz' ], + selectedColumn: 'foo' + } + }); + + t.htmlEqual( fixture.innerHTML, '

foo0a

bar0b

baz0c

a

foo1d

bar1e

baz1f

d

foo2g

bar2h

baz2i

g' ); + + ractive.get( 'rows' ).splice( 1, 1 ); + t.htmlEqual( fixture.innerHTML, '

foo0a

bar0b

baz0c

a

foo1g

bar1h

baz1i

g'); + + ractive.set( 'rows[1].foo', 'G' ); + t.htmlEqual( fixture.innerHTML, '

foo0a

bar0b

baz0c

a

foo1G

bar1h

baz1i

G'); + + ractive.get( 'columns' ).splice( 0, 1 ); + ractive.set( 'selectedColumn', 'baz' ); + t.htmlEqual( fixture.innerHTML, '

bar0b

baz0c

c

bar1h

baz1i

i'); + }); + + }; + +}); diff --git a/test/modules/components.js b/test/modules/components.js new file mode 100644 index 0000000000..888c653d22 --- /dev/null +++ b/test/modules/components.js @@ -0,0 +1,878 @@ +define([ 'ractive' ], function ( Ractive ) { + + 'use strict'; + + return function () { + + var fixture, Foo; + + module( 'Components' ); + + // some set-up + fixture = document.getElementById( 'qunit-fixture' ); + + test( 'Static data is propagated from parent to child', function ( t ) { + var Widget, ractive, widget; + + Widget = Ractive.extend({ + template: '

{{foo}}

' + }); + + ractive = new Ractive({ + el: fixture, + template: '', + components: { + widget: Widget + } + }); + + widget = ractive.findComponent( 'widget' ); + + t.equal( widget.get( 'foo' ), 'blah' ); + t.htmlEqual( fixture.innerHTML, '

blah

' ); + }); + + test( 'Static object data is propagated from parent to child', function ( t ) { + var Widget, ractive, widget; + + Widget = Ractive.extend({ + template: '

{{foo.bar}}

' + }); + + ractive = new Ractive({ + el: fixture, + template: '', + components: { + widget: Widget + } + }); + + widget = ractive.findComponent( 'widget' ); + t.deepEqual( widget.get( 'foo' ), { bar: 'biz' } ); + t.htmlEqual( fixture.innerHTML, '

biz

' ); + + widget.set('foo.bar', 'bah') + t.deepEqual( widget.get( 'foo' ), { bar: 'bah' } ); + t.htmlEqual( fixture.innerHTML, '

bah

' ); + }); + + test( 'Dynamic data is propagated from parent to child, and (two-way) bindings are created', function ( t ) { + var Widget, ractive, widget; + + Widget = Ractive.extend({ + template: '

{{foo}}

' + }); + + ractive = new Ractive({ + el: fixture, + template: '', + components: { + widget: Widget + }, + data: { + bar: 'blah' + } + }); + + widget = ractive.findComponent( 'widget' ); + + t.equal( widget.get( 'foo' ), 'blah' ); + t.htmlEqual( fixture.innerHTML, '

blah

' ); + + ractive.set( 'bar', 'flup' ); + t.equal( widget.get( 'foo' ), 'flup' ); + t.htmlEqual( fixture.innerHTML, '

flup

' ); + + widget.set( 'foo', 'shmup' ); + t.equal( ractive.get( 'bar' ), 'shmup' ); + t.htmlEqual( fixture.innerHTML, '

shmup

' ); + }); + + // Commenting out this test for the moment - is this a desirable feature? + // It prevents JavaScript closure-like behaviour with data contexts + /*test( 'Missing data on the parent is not propagated', function ( t ) { + var Widget, ractive, widget; + + Widget = Ractive.extend({ + template: '

{{foo}}

' + }); + + ractive = new Ractive({ + el: fixture, + template: '', + components: { + widget: Widget + } + }); + + widget = ractive.findComponent( 'widget' ); + + t.ok( !( widget.data.hasOwnProperty( 'foo' ) ) ); + t.htmlEqual( fixture.innerHTML, '

' ); + });*/ + + test( 'Missing data on the parent is added when set', function ( t ) { + var Widget, ractive, widget; + + Widget = Ractive.extend({ + template: '

{{foo}}

' + }); + + ractive = new Ractive({ + el: fixture, + template: '', + components: { + widget: Widget + } + }); + + widget = ractive.findComponent( 'widget' ); + + t.htmlEqual( fixture.innerHTML, '

' ); + + ractive.set('missing', 'found') + t.ok( widget.data.hasOwnProperty( 'foo' ) ); + t.htmlEqual( fixture.innerHTML, '

found

' ); + + }); + + test( 'Data on the child is propagated to the parent, if it is not missing', function ( t ) { + var Widget, ractive, widget; + + Widget = Ractive.extend({ + template: '

{{foo}}{{bar}}

', + data: { + foo: 'yes' + } + }); + + ractive = new Ractive({ + el: fixture, + template: '', + components: { + widget: Widget + } + }); + + widget = ractive.findComponent( 'widget' ); + + t.equal( ractive.get( 'one' ), 'yes' ); + t.ok( !( ractive.data.hasOwnProperty( 'two' ) ) ); + t.htmlEqual( fixture.innerHTML, '

yes

' ); + }); + + test( 'Parent data overrides child data during child model creation', function ( t ) { + var Widget, ractive, widget; + + Widget = Ractive.extend({ + template: '

{{foo}}{{bar}}

', + data: { + foo: 'yes', + bar: 'no' + } + }); + + ractive = new Ractive({ + el: fixture, + template: '', + components: { + widget: Widget + }, + data: { + one: 'uno', + two: 'dos' + } + }); + + widget = ractive.findComponent( 'widget' ); + + t.equal( ractive.get( 'one' ), 'uno' ); + t.equal( ractive.get( 'two' ), 'dos' ); + t.equal( widget.get( 'foo' ), 'uno' ); + t.equal( widget.get( 'bar' ), 'dos' ); + + t.htmlEqual( fixture.innerHTML, '

unodos

' ); + }); + + test( 'Components are rendered in the correct place', function ( t ) { + var Component, ractive; + + Component = Ractive.extend({ + template: '

this is a component!

' + }); + + ractive = new Ractive({ + el: fixture, + template: '

Here is a component:

(that was a component)

', + components: { + component: Component + } + }); + + t.htmlEqual( fixture.innerHTML, '

Here is a component:

this is a component!

(that was a component)

' ); + }); + + test( 'Top-level sections in components are updated correctly', function ( t ) { + var ractive, Component, component; + + Component = Ractive.extend({ + template: '{{#foo}}foo is truthy{{/foo}}{{^foo}}foo is falsy{{/foo}}' + }); + + ractive = new Ractive({ + el: fixture, + template: '', + components: { + component: Component + } + }); + + t.htmlEqual( fixture.innerHTML, 'foo is falsy' ); + + ractive.set( 'foo', true ); + t.htmlEqual( fixture.innerHTML, 'foo is truthy' ); + }); + + test( 'Element order is maintained correctly with components with multiple top-level elements', function ( t ) { + var ractive, TestComponent; + + TestComponent = Ractive.extend({ + template: '{{#bool}}TRUE{{/bool}}{{^bool}}FALSE{{/bool}}' + }); + + ractive = new Ractive({ + el: fixture, + template: '

before

after

', + components: { test: TestComponent } + }); + + t.htmlEqual( fixture.innerHTML, '

before

FALSE

after

' ); + + ractive.set( 'bool', true ); + t.htmlEqual( fixture.innerHTML, '

before

TRUE

after

' ); + + ractive.set( 'bool', false ); + t.htmlEqual( fixture.innerHTML, '

before

FALSE

after

' ); + }); + + test( 'Regression test for #317', function ( t ) { + var Widget, widget, ractive, items; + + Widget = Ractive.extend({ + template: '
    {{#items:i}}
  • {{i}}: {{.}}
  • {{/items}}
', + init: function () { + widget = this; + } + }); + + ractive = new Ractive({ + el: fixture, + template: '

{{ items.join( " " ) }}

', + data: { items: [ 'a', 'b', 'c', 'd' ] }, + components: { + widget: Widget + } + }); + + items = ractive.get( 'items' ); + + t.htmlEqual( fixture.innerHTML, '
  • 0: a
  • 1: b
  • 2: c
  • 3: d

a b c d

' ); + + items.push( 'e' ); + t.htmlEqual( fixture.innerHTML, '
  • 0: a
  • 1: b
  • 2: c
  • 3: d
  • 4: e

a b c d e

' ); + + items.splice( 2, 1 ); + t.htmlEqual( fixture.innerHTML, '
  • 0: a
  • 1: b
  • 2: d
  • 3: e

a b d e

' ); + + items.pop(); + t.htmlEqual( fixture.innerHTML, '
  • 0: a
  • 1: b
  • 2: d

a b d

' ); + + ractive.set( 'items[0]', 'f' ); + t.htmlEqual( fixture.innerHTML, '
  • 0: f
  • 1: b
  • 2: d

f b d

' ); + + + // reset items from within widget + widget.set( 'items', widget.get( 'items' ).slice() ); + items = ractive.get( 'items' ); + + items.push( 'g' ); + t.htmlEqual( fixture.innerHTML, '
  • 0: f
  • 1: b
  • 2: d
  • 3: g

f b d g

' ); + + items.splice( 1, 1 ); + t.htmlEqual( fixture.innerHTML, '
  • 0: f
  • 1: d
  • 2: g

f d g

' ); + + items.pop(); + t.htmlEqual( fixture.innerHTML, '
  • 0: f
  • 1: d

f d

' ); + + widget.set( 'items[0]', 'h' ); + t.htmlEqual( fixture.innerHTML, '
  • 0: h
  • 1: d

h d

' ); + }); + + asyncTest( 'Component complete() methods are called', function ( t ) { + var ractive, Widget, counter, done; + + expect( 2 ); + + counter = 2; + done = function () { --counter || start(); }; + + Widget = Ractive.extend({ + complete: function () { + t.ok( true ); + done(); + } + }); + + ractive = new Ractive({ + el: fixture, + template: '', + complete: function () { + t.ok( true ); + done(); + }, + components: { + widget: Widget + } + }); + }); + + test( 'Components can access outer data context, in the same way JavaScript functions can access outer lexical scope', function ( t ) { + var ractive, Widget; + + Widget = Ractive.extend({ + template: '

{{foo || "missing"}}

' + }); + + ractive = new Ractive({ + el: fixture, + template: '', + data: { + foo: 'one', + bar: 'two' + }, + components: { + widget: Widget + } + }); + + t.htmlEqual( fixture.innerHTML, '

one

two

missing

' ); + + ractive.set({ + foo: 'three', + bar: 'four', + baz: 'five' + }); + + t.htmlEqual( fixture.innerHTML, '

three

four

five

' ); + }); + + + test( 'Nested components can access outer-most data context', function ( t ) { + var ractive, Widget; + + ractive = new Ractive({ + el: fixture, + template: '', + components: { + widget: Ractive.extend({ + template: '', + components: { + grandwidget: Ractive.extend({ + template: 'hello {{world}}' + }) + }, + }) + }, + data: { world: 'mars' } + }); + + t.htmlEqual( fixture.innerHTML, 'hello mars' ); + ractive.set('world', 'venus'); + t.htmlEqual( fixture.innerHTML, 'hello venus' ); + }); + + test( 'Nested components registered at global Ractive can access outer-most data context', function ( t ) { + var ractive, Widget; + + Ractive.components.widget = Ractive.extend({ template: '' }); + Ractive.components.grandwidget = Ractive.extend({ template: 'hello {{world}}' }); + + ractive = new Ractive({ + el: fixture, + template: '', + data: { world: 'mars' } + }); + + t.htmlEqual( fixture.innerHTML, 'hello mars' ); + ractive.set('world', 'venus'); + t.htmlEqual( fixture.innerHTML, 'hello venus' ); + + /* This works, but is it risky to polute global for other tests? */ + delete Ractive.components.widget + delete Ractive.components.grandwidget + }); + + asyncTest( 'Data passed into component updates inside component in magic mode', function ( t ) { + var ractive, Widget; + + expect( 1 ); + + Widget = Ractive.extend({ + template: '{{world}}', + magic: true, + complete: function(){ + this.data.world = 'venus' + t.htmlEqual( fixture.innerHTML, 'venusvenus' ); + start(); + } + }); + + var data = { world: 'mars' } + + ractive = new Ractive({ + el: fixture, + template: '{{world}}', + magic: true, + components: { widget: Widget }, + data: data + }); + }); + + test( 'Data passed into component updates from outside component in magic mode', function ( t ) { + var ractive, Widget; + + Widget = Ractive.extend({ + template: '{{world}}', + magic: true + }); + + var data = { world: 'mars' } + ractive = new Ractive({ + el: fixture, + template: '{{world}}', + magic: true, + components: { widget: Widget }, + data: data + }); + + data.world = 'venus' + + t.htmlEqual( fixture.innerHTML, 'venusvenus' ); + }); + + test( 'Component data passed but non-existent on parent data', function ( t ) { + var ractive, Widget; + + Widget = Ractive.extend({ + template: '{{exists}}{{missing}}' + }); + + ractive = new Ractive({ + el: fixture, + template: '', + components: { widget: Widget }, + data: { exists: 'exists' } + }); + + t.htmlEqual( fixture.innerHTML, 'exists' ); + }); + + test( 'Some component data not included in invocation parameters', function ( t ) { + var ractive, Widget; + + Widget = Ractive.extend({ + template: '{{exists}}{{missing}}', + }); + + ractive = new Ractive({ + el: fixture, + template: '', + components: { widget: Widget }, + data: { exists: 'exists' } + }); + + t.htmlEqual( fixture.innerHTML, 'exists' ); + }); + + test( 'Some component data not included, with implicit sibling', function ( t ) { + var ractive, Widget; + + Widget = Ractive.extend({ + template: '{{exists}}{{also}}{{missing}}', + }); + + ractive = new Ractive({ + el: fixture, + template: '{{#stuff:exists}}{{/stuff}}', + components: { widget: Widget }, + data: { + stuff: { + exists: 'also' + } + } + }); + + t.htmlEqual( fixture.innerHTML, 'existsalso' ); + }); + + test( 'Isolated components do not interact with ancestor viewmodels', function ( t ) { + var ractive, Widget; + + Widget = Ractive.extend({ + template: '{{foo}}.{{bar}}', + isolated: true + }); + + ractive = new Ractive({ + el: fixture, + template: '', + components: { widget: Widget }, + data: { + foo: 'you should see me', + bar: 'but not me' + } + }); + + t.htmlEqual( fixture.innerHTML, 'you should see me.' ); + }); + + test( 'Top-level list sections in components do not cause elements to be out of order (#412 regression)', function ( t ) { + var Widget, ractive; + + Widget = Ractive.extend({ + template: '{{#numbers:o}}

{{.}}

{{/numbers}}' + }); + + ractive = new Ractive({ + el: fixture, + template: '

Names

', + components: { + widget: Widget + }, + data: { + first: { one: 'one', two: 'two' }, + second: { three: 'three', four: 'four' } + } + }); + + t.htmlEqual( fixture.innerHTML, '

Names

one

two

three

four

' ); + }); + + test( 'Children do not nuke parent data when inheriting from ancestors', function ( t ) { + var Widget, Block, ractive; + + Widget = Ractive.extend({ + template: '

value: {{thing.value}}

' + }); + + Block = Ractive.extend({ + template: '', + components: { widget: Widget } + }); + + // YOUR CODE GOES HERE + ractive = new Ractive({ + el: fixture, + template: '', + data: { + things: { + one: { value: 1 }, + two: { value: 2 }, + three: { value: 3 } + } + }, + components: { + block: Block + } + }); + + t.deepEqual( ractive.get( 'things' ), { one: { value: 1 }, two: { value: 2 }, three: { value: 3 } } ) + }); + + test( 'Uninitialised implicit dependencies of evaluators that use inherited functions are handled', function ( t ) { + var Widget, ractive; + + Widget = Ractive.extend({ + template: '{{status()}}' + }); + + ractive = new Ractive({ + el: fixture, + template: '{{status()}}-', + data: { + status: function () { + return this.get( '_status' ); + } + }, + components: { + widget: Widget + } + }); + + t.htmlEqual( fixture.innerHTML, '-' ); + + ractive.set( '_status', 'foo' ); + t.htmlEqual( fixture.innerHTML, 'foo-foo' ); + + ractive.set( '_status', 'bar' ); + t.htmlEqual( fixture.innerHTML, 'bar-bar' ); + }); + + asyncTest( 'Instances with multiple components still fire complete() handlers (#486 regression)', function ( t ) { + var Widget, ractive, counter, done; + + Widget = Ractive.extend({ + template: 'foo', + complete: function () { + t.ok( true ); + done(); + } + }); + + expect( 3 ); + + counter = 3; + done = function () { --counter || start(); }; + + ractive = new Ractive({ + el: fixture, + template: '', + components: { widget: Widget }, + complete: function () { + t.ok( true ); + done(); + } + }); + }); + + test( 'findComponent and findAllComponents work through {{>content}}', function ( t ) { + + var Wrapper, Component, ractive; + + Component = Ractive.extend({}); + Wrapper = Ractive.extend({ + template: '

{{>content}}

', + components: { + component: Component + } + }); + + ractive = new Ractive({ + template: '', + components: { + wrapper: Wrapper, + component: Component + } + }); + + var find = ractive.findComponent('component'), + findAll = ractive.findAllComponents('component'); + + t.ok( find, 'component not found' ); + t.equal( findAll.length, 1); + }); + + test( 'Indirect changes propagate across components in magic mode (#480)', function ( t ) { + var Blocker, ractive, blocker; + + Blocker = Ractive.extend({ + template: '{{foo.bar.baz}}' + }); + + ractive = new Ractive({ + el: fixture, + template: '', + data: { foo: { bar: { baz: 50 } } }, + magic: true, + components: { blocker: Blocker } + }); + + ractive.set( 'foo.bar.baz', 42 ); + t.equal( ractive.get( 'foo.bar.baz' ), 42 ); + + ractive.data.foo.bar.baz = 1337; + t.equal( ractive.data.foo.bar.baz, 1337 ); + t.equal( ractive.get( 'foo.bar.baz' ), 1337 ); + + blocker = ractive.findComponent( 'blocker' ); + + blocker.set( 'foo.bar.baz', 42 ); + t.equal( blocker.get( 'foo.bar.baz' ), 42 ); + + blocker.data.foo.bar.baz = 1337; + t.equal( blocker.data.foo.bar.baz, 1337 ); + t.equal( blocker.get( 'foo.bar.baz' ), 1337 ); + }); + + test( 'Correct value is given to node._ractive.keypath when a component is torn down and re-rendered (#470)', function ( t ) { + var ractive; + + ractive = new Ractive({ + el: fixture, + template: '{{#foo}}{{/foo}}', + data: { foo: {}, visible: true }, + components: { + widget: Ractive.extend({ + template: '{{#visible}}

{{test}}

{{/visible}}' + }) + } + }); + + t.equal( ractive.find( 'p' )._ractive.keypath, '' ); + + ractive.set( 'visible', false ); + ractive.set( 'visible', true ); + + t.equal( ractive.find( 'p' )._ractive.keypath, '' ); + }); + + test( 'Nested components fire the init() event correctly (#511)', function ( t ) { + var ractive, Outer, Inner, outerInitCount = 0, innerInitCount = 0; + + Inner = Ractive.extend({ + init: function () { + innerInitCount += 1; + } + }); + + Outer = Ractive.extend({ + template: '', + init: function () { + outerInitCount += 1; + }, + components: { inner: Inner } + }); + + ractive = new Ractive({ + el: fixture, + template: '{{#foo}}{{/foo}}', + data: { foo: false }, + components: { outer: Outer } + }); + + ractive.set( 'foo', true ); + + // initCounts should have incremented synchronously + t.equal( outerInitCount, 1, ' component should call init()' ); + t.equal( innerInitCount, 1, ' component should call init()' ); + }); + + test( 'foo.bar should stay in sync between and ', function ( t ) { + var ractive = new Ractive({ + el: fixture, + template: '', + components: { + one: Ractive.extend({ template: '

{{foo.bar}}

' }), + two: Ractive.extend({ template: '

{{foo.bar}}

' }) + } + }); + + ractive.set( 'foo', {} ); + t.htmlEqual( fixture.innerHTML, '

' ); + + ractive.findComponent( 'one' ).set( 'foo.bar', 'baz' ); + t.htmlEqual( fixture.innerHTML, '

baz

baz

' ); + + ractive.findComponent( 'two' ).set( 'foo.bar', 'qux' ); + t.htmlEqual( fixture.innerHTML, '

qux

qux

' ); + }); + + test( 'Index references propagate down to non-isolated components', function ( t ) { + var ractive = new Ractive({ + el: fixture, + template: '{{#items:i}}{{/items}}', + data: { items: [ 'a', 'b', 'c' ] }, + components: { + widget: Ractive.extend({ + template: '

{{i}}: {{letter}}

' + }) + } + }); + + t.htmlEqual( fixture.innerHTML, '

0: a

1: b

2: c

' ); + + ractive.get( 'items' ).splice( 1, 1 ); + t.htmlEqual( fixture.innerHTML, '

0: a

1: c

' ); + }); + + test( 'Component removed from DOM on tear-down with teardown override that calls _super', function ( t ) { + + var Widget = Ractive.extend({ + template: 'foo', + teardown: function(){ + this._super(); + } + }); + var ractive = new Ractive({ + el: fixture, + template: '{{#item}}{{/item}}', + data: { item: {} }, + components: { + widget: Widget + } + }); + + t.htmlEqual( fixture.innerHTML, 'foo' ); + + ractive.set( 'item' ); + t.htmlEqual( fixture.innerHTML, '' ); + }); + + test( 'Component names cannot include underscores (#483)', function ( t ) { + var Component, ractive; + + expect( 1 ); + + Component = Ractive.extend({ template: '{{foo}}' }); + + try { + ractive = new Ractive({ + el: fixture, + template: '', + components: { + no_lo_dash: Component + } + }); + t.ok( false ); + } catch ( err ) { + t.ok( true ); + } + }); + + test( 'Data will propagate up through multiple component boundaries (#520)', function ( t ) { + var ractive, Outer, Inner, inner; + + Inner = Ractive.extend({ + template: '{{input.value}}', + update: function ( val ) { + this.set( 'input', { value: val }); + } + }); + + Outer = Ractive.extend({ + template: '{{#inputs}}{{/inputs}}', + components: { inner: Inner } + }); + + ractive = new Ractive({ + el: fixture, + template: '{{#simulation}}{{/simulation}}', + components: { outer: Outer }, + data: { + simulation: { inputs: [{ value: 1 }] } + } + }); + + t.equal( ractive.get( 'simulation.inputs[0].value' ), 1 ); + + inner = ractive.findComponent( 'inner' ); + + inner.update( 2 ); + t.equal( ractive.get( 'simulation.inputs[0].value' ), 2 ); + t.htmlEqual( fixture.innerHTML, '2' ); + + }); + + }; + +}); diff --git a/test/modules/computations.js b/test/modules/computations.js new file mode 100644 index 0000000000..7fabe28bc4 --- /dev/null +++ b/test/modules/computations.js @@ -0,0 +1,180 @@ +define([ 'ractive' ], function ( Ractive ) { + + 'use strict'; + + return function () { + + var fixture, Foo; + + module( 'Computations' ); + + // some set-up + fixture = document.getElementById( 'qunit-fixture' ); + + test( 'Computed value declared as a function', function ( t ) { + var ractive = new Ractive({ + el: fixture, + template: '

area: {{area}}

', + data: { + width: 10, + height: 10 + }, + computed: { + area: function () { + return this.get( 'width' ) * this.get( 'height' ) + } + } + }); + + t.htmlEqual( fixture.innerHTML, '

area: 100

' ); + + ractive.set( 'width', 15 ); + t.htmlEqual( fixture.innerHTML, '

area: 150

' ); + + ractive.set( 'height', 15 ); + t.htmlEqual( fixture.innerHTML, '

area: 225

' ); + }); + + test( 'Computed value declared as a string', function ( t ) { + var ractive = new Ractive({ + el: fixture, + template: '

area: {{area}}

', + data: { + width: 10, + height: 10 + }, + computed: { + area: '${width} * ${height}' + } + }); + + t.htmlEqual( fixture.innerHTML, '

area: 100

' ); + + ractive.set( 'width', 15 ); + t.htmlEqual( fixture.innerHTML, '

area: 150

' ); + + ractive.set( 'height', 15 ); + t.htmlEqual( fixture.innerHTML, '

area: 225

' ); + }); + + test( 'Computed value with a set() method', function ( t ) { + var ractive = new Ractive({ + el: fixture, + template: '

First name: {{first}}

Last name: {{last}}

Full name: {{full}}

', + data: { + first: 'Jim', + last: 'Beam' + }, + computed: { + full: { + get: '${first} + " " + ${last}', + set: function ( fullname ) { + var parts = fullname.split( ' ' ); + + this.set({ + first: parts[0] || '', + last: parts[1] || '' + }); + } + } + } + }); + + t.equal( ractive.get( 'full' ), 'Jim Beam' ); + t.htmlEqual( fixture.innerHTML, '

First name: Jim

Last name: Beam

Full name: Jim Beam

' ); + + ractive.set( 'last', 'Belushi' ); + t.equal( ractive.get( 'full' ), 'Jim Belushi' ); + t.htmlEqual( fixture.innerHTML, '

First name: Jim

Last name: Belushi

Full name: Jim Belushi

' ); + + ractive.set( 'full', 'John Belushi' ); + t.equal( ractive.get( 'first' ), 'John' ); + t.htmlEqual( fixture.innerHTML, '

First name: John

Last name: Belushi

Full name: John Belushi

' ); + }); + + test( 'Components can have default computed properties', function ( t ) { + var Box, ractive; + + Box = Ractive.extend({ + template: '
{{area}}px squared
', + computed: { + area: '${width} * ${height}' + } + }); + + ractive = new Ractive({ + el: fixture, + template: '', + data: { + width: 100, + height: 100 + }, + components: { box: Box } + }); + + t.htmlEqual( fixture.innerHTML, '
10000px squared
' ); + + ractive.set( 'width', 200 ); + t.htmlEqual( fixture.innerHTML, '
20000px squared
' ); + }); + + test( 'Instances can augment default computed properties of components', function ( t ) { + var Box, ractive; + + Box = Ractive.extend({ + template: '
{{area}}px squared
', + computed: { + area: '${width} * ${height}' + } + }); + + ractive = new Box({ + el: fixture, + data: { + width: 100, + height: 100 + }, + computed: { irrelevant: '"foo"' } + }); + + t.htmlEqual( fixture.innerHTML, '
10000px squared
' ); + + ractive.set( 'width', 200 ); + t.htmlEqual( fixture.innerHTML, '
20000px squared
' ); + }); + + test( 'Computed values can depend on other computed values', function ( t ) { + var ractive = new Ractive({ + el: fixture, + template: '{{number}} - {{squared}} - {{cubed}}', + data: { number: 5 }, + computed: { + squared: '${number} * ${number}', + cubed: '${squared} * ${number}' + } + }); + + t.htmlEqual( fixture.innerHTML, '5 - 25 - 125' ); + + ractive.add( 'number', 1 ); + t.htmlEqual( fixture.innerHTML, '6 - 36 - 216' ); + }); + + test( 'Computations that cause errors are considered undefined', function ( t ) { + var ractive = new Ractive({ + el: fixture, + template: '{{uppercaseBar}}', + computed: { + uppercaseBar: '${foo}.bar.toUpperCase()' + } + }); + + t.htmlEqual( fixture.innerHTML, '' ); + + ractive.set( 'foo.bar', 'works' ); + t.htmlEqual( fixture.innerHTML, 'WORKS' ); + }) + + }; + +}); diff --git a/test/modules/css.js b/test/modules/css.js new file mode 100644 index 0000000000..9b2afb79df --- /dev/null +++ b/test/modules/css.js @@ -0,0 +1,152 @@ +define([ 'ractive' ], function ( Ractive ) { + + 'use strict'; + + return function () { + + var fixture, colorTester, colors; + + module( 'CSS encapsulation' ); + + // some set-up + fixture = document.getElementById( 'qunit-fixture' ); + + // normalise colours + colorTester = document.createElement( 'div' ); + document.getElementsByTagName( 'body' )[0].appendChild( colorTester ); + + colors = {}; + [ 'red', 'green', 'blue', 'black' ].forEach( function ( color ) { + colors[ color ] = normaliseColor( color ); + }); + + test( 'CSS is applied to components', function ( t ) { + var Widget, ractive; + + Widget = Ractive.extend({ + template: '

foo

', + css: 'p { color: red; }' + }); + + ractive = new Widget({ + el: fixture + }); + + t.equal( getComputedStyle( ractive.find( 'p' ) ).color, colors.red ); + }); + + test( 'CSS is encapsulated', function ( t ) { + var Widget, ractive, paragraphs; + + Widget = Ractive.extend({ + template: '

red

', + css: 'p { color: red; }' + }); + + ractive = new Ractive({ + el: fixture, + template: '

black

', + components: { + widget: Widget + } + }); + + paragraphs = ractive.findAll( 'p' ); + + t.equal( getComputedStyle( paragraphs[0] ).color, colors.black ); + t.equal( getComputedStyle( paragraphs[1] ).color, colors.red ); + }); + + asyncTest( 'CSS encapsulation transformation is optional', function ( t ) { + var Widget, ractive, paragraphs; + + Widget = Ractive.extend({ + template: '

red

', + css: 'p { color: red; }', + noCssTransform: true + }); + + ractive = new Ractive({ + el: fixture, + template: '

red

', + components: { + widget: Widget + } + }); + + paragraphs = ractive.findAll( 'p' ); + + t.equal( getComputedStyle( paragraphs[0] ).color, colors.red ); + t.equal( getComputedStyle( paragraphs[1] ).color, colors.red ); + + // we need to clean up after ourselves otherwise the global styles remain in the DOM! + ractive.teardown().then( start ); + }); + + test( 'Comments do not break transformed CSS', function ( t ) { + var Widget, ractive; + + Widget = Ractive.extend({ + template: '

foo

', + css: '/*p { color: red; }*/ p { color: blue; }' + }); + + ractive = new Widget({ + el: fixture + }); + + t.equal( getComputedStyle( ractive.find( 'p' ) ).color, colors.blue ); + }); + + test( 'Multiple pseudo-selectors work', function ( t ) { + var Widget, ractive, paragraphs; + + Widget = Ractive.extend({ + template: '

blue

black

', + css: 'p:first-child:nth-child(1) { color: blue; }' + }); + + ractive = new Ractive({ + el: fixture, + template: '

black

black

', + components: { widget: Widget } + }); + + paragraphs = ractive.findAll( 'p' ); + + t.equal( getComputedStyle( paragraphs[0] ).color, colors.black ); + t.equal( getComputedStyle( paragraphs[1] ).color, colors.black ); + t.equal( getComputedStyle( paragraphs[2] ).color, colors.blue ); + t.equal( getComputedStyle( paragraphs[3] ).color, colors.black ); + }); + + test( 'Combinators work', function ( t ) { + var Widget, ractive, paragraphs; + + Widget = Ractive.extend({ + template: '

black

green

', + css: 'p + p { color: green; }' + }); + + ractive = new Ractive({ + el: fixture, + template: '

black

black

', + components: { widget: Widget } + }); + + paragraphs = ractive.findAll( 'p' ); + + t.equal( getComputedStyle( paragraphs[0] ).color, colors.black ); + t.equal( getComputedStyle( paragraphs[1] ).color, colors.black ); + t.equal( getComputedStyle( paragraphs[2] ).color, colors.black ); + t.equal( getComputedStyle( paragraphs[3] ).color, colors.green ); + }); + + + function normaliseColor ( color ) { + colorTester.style.color = color; + return getComputedStyle( colorTester ).color; + } + }; + +}); diff --git a/test/modules/decorators.js b/test/modules/decorators.js new file mode 100644 index 0000000000..3249f4bf87 --- /dev/null +++ b/test/modules/decorators.js @@ -0,0 +1,181 @@ +define([ 'ractive' ], function ( Ractive ) { + + 'use strict'; + + return function () { + + var fixture; + + module( 'Decorators' ); + + // some set-up + fixture = document.getElementById( 'qunit-fixture' ); + + test( 'Basic decorator', function ( t ) { + var ractive = new Ractive({ + el: fixture, + template: '
this text will be overwritten
', + decorators: { + foo: function ( node ) { + var contents = node.innerHTML; + node.innerHTML = 'foo'; + + return { + teardown: function () { + node.innerHTML = contents; + } + } + } + } + }); + + t.htmlEqual( fixture.innerHTML, '
foo
' ); + }); + + test( 'Decorator with a static argument', function ( t ) { + var ractive = new Ractive({ + el: fixture, + template: '
this text will be overwritten
', + decorators: { + foo: function ( node, newContents ) { + var contents = node.innerHTML; + node.innerHTML = newContents; + + return { + teardown: function () { + node.innerHTML = contents; + } + } + } + } + }); + + t.htmlEqual( fixture.innerHTML, '
bar
' ); + }); + + test( 'Decorator with a dynamic argument', function ( t ) { + var ractive = new Ractive({ + el: fixture, + template: '
this text will be overwritten
', + data: { + foo: 'baz' + }, + decorators: { + foo: function ( node, newContents ) { + var contents = node.innerHTML; + node.innerHTML = newContents; + + return { + teardown: function () { + node.innerHTML = contents; + } + } + } + } + }); + + t.htmlEqual( fixture.innerHTML, '
baz
' ); + }); + + test( 'Decorator with a dynamic argument that changes, without update() method', function ( t ) { + var ractive = new Ractive({ + el: fixture, + template: '
this text will be overwritten
', + data: { + foo: 'baz' + }, + decorators: { + foo: function ( node, newContents ) { + var contents = node.innerHTML; + node.innerHTML = newContents; + + return { + teardown: function () { + node.innerHTML = contents; + } + } + } + } + }); + + t.htmlEqual( fixture.innerHTML, '
baz
' ); + ractive.set( 'foo', 'qux' ); + t.htmlEqual( fixture.innerHTML, '
qux
' ); + }); + + test( 'Decorator with a dynamic argument that changes, with update() method', function ( t ) { + var ractive = new Ractive({ + el: fixture, + template: '
this text will be overwritten
', + data: { + foo: 'baz' + }, + decorators: { + foo: function ( node, newContents ) { + var contents = node.innerHTML; + node.innerHTML = newContents; + + return { + update: function ( newContents ) { + node.innerHTML = newContents; + }, + teardown: function () { + node.innerHTML = contents; + } + } + } + } + }); + + t.htmlEqual( fixture.innerHTML, '
baz
' ); + ractive.set( 'foo', 'qux' ); + t.htmlEqual( fixture.innerHTML, '
qux
' ); + }); + + test( 'Referencing parent data context in magic mode does not break decorators', function ( t ) { + var ractive, data; + + data = { + item: { name: 'one' }, + foo: { + bar: 'biz' + } + }; + + ractive = new Ractive({ + el: fixture, + template: '{{#item}}{{foo.bar}}{{name}}{{/item}}', + magic: true, + data: data, + decorators: { + decorateme: function(node, foo){ + node.innerHTML = foo ? foo.bar || 'fail' : 'fail'; + return { teardown: function () {} }; + } + } + }); + + t.htmlEqual( fixture.innerHTML, 'bizonebiz' ); + }); + + test( 'Decorator without arguments can be torn down (#453)', function ( t ) { + var ractive = new Ractive({ + el: fixture, + template: '{{#foo}}

foo

{{/foo}}', + data: { foo: true }, + decorators: { + bar: function( node ) { + return { teardown: function () {} } + } + } + }); + + expect( 1 ); + + ractive.set("foo", false); + t.ok( true ); + }); + + }; + +}); diff --git a/test/tests/events.js b/test/modules/events.js old mode 100755 new mode 100644 similarity index 86% rename from test/tests/events.js rename to test/modules/events.js index 4b1a8af5ac..66f0f97c1f --- a/test/tests/events.js +++ b/test/modules/events.js @@ -3,9 +3,7 @@ // // TODO: add moar tests -define([ 'Ractive', '../vendor/Ractive-events-tap' ], function ( Ractive ) { - - window.Ractive = Ractive; +define([ 'ractive', '../vendor/ractive-events-tap' ], function ( Ractive ) { return function () { @@ -43,7 +41,7 @@ define([ 'Ractive', '../vendor/Ractive-events-tap' ], function ( Ractive ) { ractive.on( 'someEvent', function ( event ) { t.equal( event.node, ractive.nodes.test ); - t.equal( event.original, fakeEvent ); + t.ok( event.original ); t.equal( event.keypath, '' ); t.equal( event.context, ractive.data ); t.equal( event.index, undefined ); @@ -354,7 +352,8 @@ define([ 'Ractive', '../vendor/Ractive-events-tap' ], function ( Ractive ) { t.equal( tapped, true ); }); - test( 'Pressing spacebar on a focused button results in a tap event', function ( t ) { + // TODO move this into Ractive-events-tap repo + asyncTest( 'Pressing spacebar on a focused button results in a tap event', function ( t ) { var ractive, node, tapped; ractive = new Ractive({ @@ -376,7 +375,11 @@ define([ 'Ractive', '../vendor/Ractive-events-tap' ], function ( Ractive ) { node.focus(); t.equal( document.activeElement, node ); simulant.fire( node, 'keydown', { which: 32 }); - t.equal( tapped, true ); + + setTimeout( function () { + t.ok( tapped ); + start(); + }, 0 ); }); test( 'Calling ractive.off() without a keypath removes all handlers', function ( t ) { @@ -406,6 +409,38 @@ define([ 'Ractive', '../vendor/Ractive-events-tap' ], function ( Ractive ) { ractive.fire( 'baz' ); }); + test( 'Changes triggered by two-way bindings propagate properly (#460)', function ( t ) { + var changes, ractive = new Ractive({ + el: fixture, + template: '{{#items}}{{/items}}

{{ items.filter( completed ).length }}

{{# items.filter( completed ).length }}

foo

{{/ items.filter( completed ).length }}', + data: { + items: [ + { completed: true, description: 'fix this bug' }, + { completed: false, description: 'fix other bugs' }, + { completed: false, description: 'housework' } + ], + completed: function ( item ) { + return !!item.completed; + } + } + }); + + ractive.on( 'change', function ( c ) { + changes = c; + }); + + t.htmlEqual( ractive.find( '.result' ).innerHTML, '1' ); + + simulant.fire( ractive.findAll( 'input' )[1], 'click' ); + t.htmlEqual( ractive.find( '.result' ).innerHTML, '2' ); + + t.deepEqual( changes, { 'items.1.completed': true }); + + simulant.fire( ractive.findAll( 'input' )[0], 'click' ); + simulant.fire( ractive.findAll( 'input' )[1], 'click' ); + t.htmlEqual( ractive.find( '.result' ).innerHTML, '0' ); + }); + }; -}); \ No newline at end of file +}); diff --git a/test/tests/find.js b/test/modules/find.js similarity index 82% rename from test/tests/find.js rename to test/modules/find.js index 0ad435aca8..5adc8fdcd1 100644 --- a/test/tests/find.js +++ b/test/modules/find.js @@ -1,9 +1,7 @@ -define([ 'Ractive' ], function ( Ractive ) { +define([ 'ractive' ], function ( Ractive ) { 'use strict'; - window.Ractive = Ractive; - return function () { var fixture, Widget, Decoy; @@ -21,8 +19,12 @@ define([ 'Ractive' ], function ( Ractive ) { template: '

I am a decoy

' }); - Ractive.components.widget = Widget; - Ractive.components.decoy = Decoy; + Ractive = Ractive.extend({ + components: { + widget: Widget, + decoy: Decoy + } + }); test( 'find() works with a string-only template', function ( t ) { var ractive; @@ -71,6 +73,21 @@ define([ 'Ractive' ], function ( Ractive ) { t.equal( divs.length, 3 ); }); + test( 'findAll() works with a string-only template', function ( t ) { + var ractive, paragraphs; + + ractive = new Ractive({ + el: fixture, + template: '

foo

bar

' + }); + + paragraphs = ractive.findAll( 'p' ); + + t.ok( paragraphs.length === 2 ); + t.ok( paragraphs[0].innerHTML === 'foo' ); + t.ok( paragraphs[1].innerHTML === 'bar' ); + }); + test( 'findAll() with { live: true } gets an updating array of all nodes matching a selector', function ( t ) { var ractive, lis; @@ -178,8 +195,6 @@ define([ 'Ractive' ], function ( Ractive ) { widgets = ractive.findAllComponents( 'widget', { live: true }); - window.widgets = widgets; - t.equal( widgets.length, 3 ); t.ok( widgets[0] instanceof Widget && widgets[1] instanceof Widget && widgets[2] instanceof Widget ); t.equal( widgets[0].get( 'content' ), 'a' ); @@ -225,8 +240,35 @@ define([ 'Ractive' ], function ( Ractive ) { ractive.set( 'shown', true ); t.equal( widgets.length, 3 ); + + ractive.set( 'shown', false ); + t.equal( widgets.length, 0 ); }); + test( 'Nodes belonging to components are removed from live queries when those components are torn down', function ( t ) { + var Widget, ractive, divs; + + Widget = Ractive.extend({ + template: '
this should be removed
' + }); + + ractive = new Ractive({ + el: fixture, + template: '{{#widgets}}{{/widgets}}', + components: { + widget: Widget + } + }); + + divs = ractive.findAll( 'div', { live: true }); + t.equal( divs.length, 0 ); + + [ 3, 2, 5, 10, 0 ].forEach( function ( length ) { + ractive.set( 'widgets', new Array( length ) ); + t.equal( divs.length, length ); + }); + }) + // TODO add tests (and add the functionality)... // * cancelling a live query (also, followed by teardown) @@ -235,4 +277,4 @@ define([ 'Ractive' ], function ( Ractive ) { }; -}); \ No newline at end of file +}); diff --git a/test/modules/magic.js b/test/modules/magic.js new file mode 100644 index 0000000000..9d409a3bac --- /dev/null +++ b/test/modules/magic.js @@ -0,0 +1,251 @@ +define([ 'ractive' ], function ( Ractive ) { + + 'use strict'; + + return function () { + + var fixture, fixture2, makeObj; + + // only run these tests if magic mode is supported + try { + var obj = {}, _foo; + Object.defineProperty( obj, 'foo', { + get: function () { + return _foo; + }, + set: function ( value ) { + _foo = value; + } + }); + } catch ( err ) { + return; + } + + module( 'Magic mode' ); + + // some set-up + fixture = document.getElementById( 'qunit-fixture' ); + fixture2 = document.createElement( 'div' ); + + Ractive = Ractive.extend({ + template: '{{name}}: {{type}}', + magic: true + }); + + makeObj = function () { + return { + name: 'Kermit', + type: 'frog' + }; + }; + + test( 'Mustaches update when property values change', function ( t ) { + var muppet, ractive; + + muppet = makeObj(); + + ractive = new Ractive({ + el: fixture, + data: muppet + }); + + muppet.name = 'Rizzo'; + muppet.type = 'rat'; + + t.htmlEqual( fixture.innerHTML, 'Rizzo: rat' ); + + muppet.name = 'Fozzie'; + muppet.type = 'bear'; + + t.htmlEqual( fixture.innerHTML, 'Fozzie: bear' ); + }); + + test( 'Multiple instances can share an object', function ( t ) { + var muppet, ractive1, ractive2; + + muppet = makeObj(); + + ractive1 = new Ractive({ + el: fixture, + data: muppet + }); + + ractive2 = new Ractive({ + el: fixture2, + data: muppet + }); + + muppet.name = 'Rizzo'; + muppet.type = 'rat'; + + t.htmlEqual( fixture.innerHTML, 'Rizzo: rat' ); + t.htmlEqual( fixture2.innerHTML, 'Rizzo: rat' ); + + muppet.name = 'Fozzie'; + muppet.type = 'bear'; + + t.htmlEqual( fixture.innerHTML, 'Fozzie: bear' ); + t.htmlEqual( fixture2.innerHTML, 'Fozzie: bear' ); + }); + + test( 'Direct property access can be used interchangeably with ractive.set()', function ( t ) { + var muppet, ractive1, ractive2; + + muppet = makeObj(); + + ractive1 = new Ractive({ + el: fixture, + data: muppet + }); + + ractive2 = new Ractive({ + el: fixture2, + data: muppet + }); + + muppet.name = 'Rizzo'; + muppet.type = 'rat'; + + t.htmlEqual( fixture.innerHTML, 'Rizzo: rat' ); + t.htmlEqual( fixture2.innerHTML, 'Rizzo: rat' ); + + ractive1.set({ + name: 'Fozzie', + type: 'bear' + }); + + t.htmlEqual( fixture.innerHTML, 'Fozzie: bear' ); + t.htmlEqual( fixture2.innerHTML, 'Fozzie: bear' ); + + ractive2.set({ + name: 'Miss Piggy', + type: 'pig' + }); + + t.htmlEqual( fixture.innerHTML, 'Miss Piggy: pig' ); + t.htmlEqual( fixture2.innerHTML, 'Miss Piggy: pig' ); + + muppet.name = 'Pepe'; + muppet.type = 'king prawn'; + + t.htmlEqual( fixture.innerHTML, 'Pepe: king prawn' ); + t.htmlEqual( fixture2.innerHTML, 'Pepe: king prawn' ); + }); + + test( 'Magic mode works with existing accessors', function ( t ) { + var _foo, data, ractive; + + _foo = 'Bar'; + + data = {}; + + Object.defineProperty( data, 'foo', { + get: function () { + return _foo.toLowerCase(); + }, + set: function ( value ) { + _foo = value; + }, + configurable: true, + enumerable: true + }); + + ractive = new Ractive({ + el: fixture, + template: '{{foo}}', + data: data + }); + + t.htmlEqual( fixture.innerHTML, 'bar' ); + + data.foo = 'BAZ'; + t.htmlEqual( fixture.innerHTML, 'baz' ); + }); + + test( 'Setting properties in magic mode triggers change events', function ( t ) { + var ractive, foo; + + foo = { bar: 'baz' }; + + ractive = new Ractive({ + el: fixture, + template: '{{foo.bar}}', + data: { foo: foo } + }); + + expect( 1 ); + + ractive.on( 'change', function ( changeHash ) { + t.deepEqual( changeHash, { 'foo.bar': 'qux' }); + }); + + foo.bar = 'qux'; + }); + + test( 'Regression test for #393', function ( t ) { + var View, ractive; + + View = Ractive.extend({ + data: { + foo: { + a: 1, + b: 2 + }, + + bar: [ + 'a', 'b', 'c' + ] + } + }); + + ractive = new View({ + el: fixture, + template: '{{ JSON.stringify(foo) }} | {{ JSON.stringify(bar) }}', + magic: true + }); + + t.htmlEqual( fixture.innerHTML, '{"a":1,"b":2} | ["a","b","c"]' ); + + ractive.set( 'foo.b', 3 ); + t.deepEqual( View.data, {foo:{a:1,b:2},bar:['a', 'b', 'c']}); + t.htmlEqual( fixture.innerHTML, '{"a":1,"b":3} | ["a","b","c"]' ); + + ractive.set( 'bar[1]', 'd' ); + t.deepEqual( View.data, {foo:{a:1,b:2},bar:['a', 'b', 'c']}); + t.htmlEqual( fixture.innerHTML, '{"a":1,"b":3} | ["a","d","c"]' ); + }); + + test( 'A magic component is magic regardless of whether its parent is magic', function ( t ) { + var Magician, ractive; + + expect( 3 ); + + Magician = Ractive.extend({ + template: '

{{magician}}

', + magic: true, + data: { magician: 'Harry Houdini' }, + changeMagician: function () { + this.data.magician = 'David Copperfield' + }, + init: function () { + t.ok( this.magic ); + } + }); + + window.Magician = Magician; + + ractive = new Ractive({ + el: fixture, + magic: false, + template: '', + components: { magician: Magician } + }); + + t.htmlEqual( fixture.innerHTML, '

Harry Houdini

' ); + ractive.findComponent( 'magician' ).changeMagician(); + t.htmlEqual( fixture.innerHTML, '

David Copperfield

' ); + }); + + }; + +}); diff --git a/test/tests/merge.js b/test/modules/merge.js similarity index 94% rename from test/tests/merge.js rename to test/modules/merge.js index bc4f59ca0a..1f12883b0a 100644 --- a/test/tests/merge.js +++ b/test/modules/merge.js @@ -1,9 +1,7 @@ -define([ 'Ractive' ], function ( Ractive ) { +define([ 'ractive' ], function ( Ractive ) { 'use strict'; - window.Ractive = Ractive; - return function () { var fixture = document.getElementById( 'qunit-fixture' ); @@ -89,7 +87,7 @@ define([ 'Ractive' ], function ( Ractive ) { t.equal( exited, 1 ); t.ok( foo === ractive.nodes.foo ); - t.ok( !bar.parentNode ); + t.ok( isOrphan( bar ) ); t.ok( baz === ractive.nodes.baz ); }); @@ -132,7 +130,7 @@ define([ 'Ractive' ], function ( Ractive ) { t.equal( exited, 1 ); t.ok( foo === ractive.nodes.foo ); - t.ok( !bar.parentNode ); + t.ok( isOrphan( bar ) ); t.ok( baz === ractive.nodes.baz ); }); @@ -175,7 +173,7 @@ define([ 'Ractive' ], function ( Ractive ) { t.equal( exited, 1 ); t.ok( foo === ractive.nodes.foo ); - t.ok( !bar.parentNode ); + t.ok( isOrphan( bar ) ); t.ok( baz === ractive.nodes.baz ); }); @@ -218,7 +216,7 @@ define([ 'Ractive' ], function ( Ractive ) { t.equal( exited, 1 ); t.ok( foo === ractive.nodes.foo ); - t.ok( !bar.parentNode ); + t.ok( isOrphan( bar ) ); t.ok( baz === ractive.nodes.baz ); }); @@ -261,10 +259,16 @@ define([ 'Ractive' ], function ( Ractive ) { t.equal( exited, 3 ); t.ok( foo !== ractive.nodes.foo ); - t.ok( !bar.parentNode ); + t.ok( isOrphan( bar ) ); t.ok( baz !== ractive.nodes.baz ); }); }; -}); \ No newline at end of file + function isOrphan ( node ) { + // IE8... when you detach a node from its parent it thinks the document + // is its parent + return !node.parentNode || node.parentNode instanceof HTMLDocument; + } + +}); diff --git a/test/tests/misc.js b/test/modules/misc.js old mode 100755 new mode 100644 similarity index 81% rename from test/tests/misc.js rename to test/modules/misc.js index f3b775dbfd..d709fb29ea --- a/test/tests/misc.js +++ b/test/modules/misc.js @@ -1,9 +1,7 @@ -define([ 'Ractive', '../vendor/Ractive-events-tap' ], function ( Ractive ) { +define([ 'ractive', 'vendor/ractive-events-tap' ], function ( Ractive ) { 'use strict'; - window.Ractive = Ractive; - return function () { var fixture, Foo; @@ -194,7 +192,7 @@ define([ 'Ractive', '../vendor/Ractive-events-tap' ], function ( Ractive ) { el: fixture, template: '{{#items}}{{/items}}', data: { - items: [{ title: 'Title1', }], + items: [{ title: 'Title1' }] } }); @@ -203,36 +201,16 @@ define([ 'Ractive', '../vendor/Ractive-events-tap' ], function ( Ractive ) { t.htmlEqual( fixture.innerHTML, '' ); }); - test( 'Array splice works when simultaneously adding and removing items', function ( t ) { - var items, ractive; - - items = [ 'zero', 'one', 'two', 'four' ]; - - ractive = new Ractive({ - el: fixture, - template: '{{#items:i}}{{i}}:{{.}}{{/items}}', - data: { items: items } - }); - - t.htmlEqual( fixture.innerHTML, '0:zero1:one2:two3:four' ); - - items.splice( 3, 0, 'three' ); - t.htmlEqual( fixture.innerHTML, '0:zero1:one2:two3:three4:four' ); - - items.splice( 3, 1, 'THREE' ); - t.htmlEqual( fixture.innerHTML, '0:zero1:one2:two3:THREE4:four' ); - }); - test( 'If a select value with two-way binding has a selected option at render time, the model updates accordingly', function ( t ) { var ractive; ractive = new Ractive({ el: fixture, - template: '

selected {{color}}

' + template: '

selected {{color}}

' }); t.equal( ractive.get( 'color' ), 'green' ); - t.htmlEqual( fixture.innerHTML, '

selected green

' ); + t.htmlEqual( fixture.innerHTML, '

selected green

' ); }); test( 'If a select value with two-way binding has no selected option at render time, the model defaults to the top value', function ( t ) { @@ -240,11 +218,11 @@ define([ 'Ractive', '../vendor/Ractive-events-tap' ], function ( Ractive ) { ractive = new Ractive({ el: fixture, - template: '

selected {{color}}

' + template: '

selected {{color}}

' }); t.equal( ractive.get( 'color' ), 'red' ); - t.htmlEqual( fixture.innerHTML, '

selected red

' ); + t.htmlEqual( fixture.innerHTML, '

selected red

' ); }); @@ -284,6 +262,47 @@ define([ 'Ractive', '../vendor/Ractive-events-tap' ], function ( Ractive ) { t.ok( ractive.nodes._3.selected ); }); + test( 'Setting the value of a select works with options added via a triple', function ( t ) { + var ractive = new Ractive({ + el: fixture, + template: '', + data: { + value: 2, + triple: '' + } + }); + + t.equal( ractive.find( 'select' ).value, 2); + t.ok( ractive.findAll( 'option' )[1].selected ); + + ractive.set( 'triple', '' ); + t.equal( ractive.find( 'select' ).value, 1 ); + t.equal( ractive.get( 'value' ), 1 ); + }); + + test( 'A two-way select updates to the actual value of its selected option, not the stringified value', function ( t ) { + var ractive = new Ractive({ + el: fixture, + template: '

Selected {{selected.description}}

', + data: { + options: [ + { description: 'foo' }, + { description: 'bar' }, + { description: 'baz' } + ] + } + }); + + t.deepEqual( ractive.get( 'selected' ), { description: 'foo' }); + + ractive.findAll( 'option' )[1].selected = true; + ractive.updateModel(); + t.deepEqual( ractive.get( 'selected' ), { description: 'bar' }); + + ractive.set( 'selected', ractive.get( 'options[2]' ) ); + t.ok( ractive.findAll( 'option' )[2].selected ); + }) + /* test( 'If a multiple select value with two-way binding has a selected option at render time, the model updates accordingly', function ( t ) { var ractive; @@ -585,52 +604,14 @@ define([ 'Ractive', '../vendor/Ractive-events-tap' ], function ( Ractive ) { t.htmlEqual( fixture.innerHTML, '
  • a
  • b
  • c
' ); }); - test( 'findAll returns a static node list', function ( t ) { - var items, ractive, list; - - items = [ 'a', 'b', 'c' ]; - - ractive = new Ractive({ - el: fixture, - template: '
    {{#items}}
  • {{.}}
  • {{/items}}
', - data: { items: items } - }); - - list = ractive.findAll( 'li' ); - t.equal( list.length, 3 ); - - items.push( 'd' ); - t.equal( items.length, 4 ); - t.equal( list.length, 3 ); - }); - - test( 'findAll with live: true returns a live node list', function ( t ) { - var items, ractive, list; - - items = [ 'a', 'b', 'c' ]; - - ractive = new Ractive({ - el: fixture, - template: '
    {{#items}}
  • {{.}}
  • {{/items}}
', - data: { items: items } - }); - - list = ractive.findAll( 'li', { live: true }); - t.equal( list.length, 3 ); - - items.push( 'd' ); - t.equal( items.length, 4 ); - t.equal( list.length, 4 ); - }); - test( 'Delimiters can be reset globally', function ( t ) { var oldDelimiters, oldTripledDelimiters, ractive; - oldDelimiters = Ractive.delimiters; - oldTripledDelimiters = Ractive.tripleDelimiters; + oldDelimiters = Ractive.defaults.delimiters; + oldTripledDelimiters = Ractive.defaults.tripleDelimiters; - Ractive.delimiters = [ '[[', ']]' ]; - Ractive.tripleDelimiters = [ '[[[', ']]]' ]; + Ractive.defaults.delimiters = [ '[[', ']]' ]; + Ractive.defaults.tripleDelimiters = [ '[[[', ']]]' ]; ractive = new Ractive({ el: fixture, @@ -640,8 +621,8 @@ define([ 'Ractive', '../vendor/Ractive-events-tap' ], function ( Ractive ) { t.htmlEqual( fixture.innerHTML, 'text html' ); - Ractive.delimiters = oldDelimiters; - Ractive.tripleDelimiters = oldTripledDelimiters; + Ractive.defaults.delimiters = oldDelimiters; + Ractive.defaults.tripleDelimiters = oldTripledDelimiters; }); test( 'Teardown works without throwing an error (#205)', function ( t ) { @@ -671,7 +652,7 @@ define([ 'Ractive', '../vendor/Ractive-events-tap' ], function ( Ractive ) { value_id: 42, values: [ { id: 1, name: "Boo" }, - { id: 42, name: "Here 'tis" }, + { id: 42, name: "Here 'tis" } ] } }); @@ -708,22 +689,6 @@ define([ 'Ractive', '../vendor/Ractive-events-tap' ], function ( Ractive ) { } }); - test( 'Attempting to set up two-way binding against an expression throws an error', function ( t ) { - var ractive; - - expect( 1 ); - - try { - ractive = new Ractive({ - el: fixture, - template: '', - debug: true - }); - } catch ( err ) { - t.ok( err ); - } - }); - test( 'Keypath resolutions that trigger teardowns don\'t cause the universe to implode', function ( t ) { var ractive = new Ractive({ el: fixture, @@ -785,9 +750,9 @@ define([ 'Ractive', '../vendor/Ractive-events-tap' ], function ( Ractive ) { partialScr = document.createElement( 'script' ); partialScr.id = 'thePartial'; partialScr.type = 'text/ractive'; - partialScr.innerHTML = '{{one}}{{two}}{{three}}'; + partialScr.text = '{{one}}{{two}}{{three}}'; - document.body.appendChild( partialScr ); + document.getElementsByTagName('body')[0].appendChild( partialScr ); ractive = new Ractive({ el: fixture, @@ -994,7 +959,7 @@ define([ 'Ractive', '../vendor/Ractive-events-tap' ], function ( Ractive ) { ractive = new Ractive({ el: fixture, template: '', - adaptors: [ 'foo' ], + adapt: [ 'foo' ], data: { thing: new Foo( 'whee!' ) } @@ -1007,7 +972,7 @@ define([ 'Ractive', '../vendor/Ractive-events-tap' ], function ( Ractive ) { var Widget, ractive; Widget = Ractive.extend({ - adaptors: [ 'foo' ] + adapt: [ 'foo' ] }); ractive = new Widget({ @@ -1018,7 +983,7 @@ define([ 'Ractive', '../vendor/Ractive-events-tap' ], function ( Ractive ) { } }); - t.deepEqual( ractive.adaptors, [ Ractive.adaptors.foo ] ); + t.deepEqual( ractive.adapt, [ Ractive.adaptors.foo ] ); t.htmlEqual( fixture.innerHTML, '

whee!

' ); }); @@ -1122,6 +1087,248 @@ define([ 'Ractive', '../vendor/Ractive-events-tap' ], function ( Ractive ) { t.htmlEqual( fixture.innerHTML, '' ); }); + asyncTest( 'Subclass instance complete() handlers can call _super', function ( t ) { + var Subclass, instance; + + expect( 1 ); + + Subclass = Ractive.extend({ + complete: function () { + return 42; + } + }); + + instance = new Subclass({ + complete: function () { + t.equal( this._super(), 42 ); + start(); + } + }); + }); + + test( 'A string can be supplied instead of an array for the `adapt` option (if there\'s only one adaptor listed', function ( t ) { + var Subclass, instance; + + Subclass = Ractive.extend({ adapt: 'Foo' }); + instance = new Subclass(); + + t.deepEqual( instance.adapt, ['Foo'] ); + }); + + test( 'Regression test for #393', function ( t ) { + var View, ractive; + + View = Ractive.extend({ + data: { + foo: { + a: 1, + b: 2 + }, + + bar: [ + 'a', 'b', 'c' + ] + } + }); + + ractive = new View({ + el: fixture, + template: '{{ JSON.stringify(foo) }} | {{ JSON.stringify(bar) }}' + }); + + t.htmlEqual( fixture.innerHTML, '{"a":1,"b":2} | ["a","b","c"]' ); + ractive.set( 'foo.b', 3 ); + t.deepEqual( View.data, {foo:{a:1,b:2},bar:['a', 'b', 'c']}); + t.htmlEqual( fixture.innerHTML, '{"a":1,"b":3} | ["a","b","c"]' ); + ractive.set( 'bar[1]', 'd' ); + t.deepEqual( View.data, {foo:{a:1,b:2},bar:['a', 'b', 'c']}); + t.htmlEqual( fixture.innerHTML, '{"a":1,"b":3} | ["a","d","c"]' ); + }); + + + test( 'ractive.insert() with triples doesn\'t invoke Yoda (#391)', function ( t ) { + var ractive = new Ractive({ + el: document.createElement( 'div' ), + template: '{{{value}}}', + data: { + 'value': ' you are very puzzled now' + } + }); + + ractive.insert( fixture ); + t.htmlEqual( fixture.innerHTML, ' you are very puzzled now' ); + }); + + + test( ' where foo === null should not render a value (#390)', function ( t ) { + var ractive = new Ractive({ + el: fixture, + template: '', + data: { + foo: null + } + }); + + t.equal( ractive.find( 'input' ).value, '' ); + }); + + // only run these tests if magic mode is supported + try { + var obj = {}, _foo; + Object.defineProperty( obj, 'foo', { + get: function () { + return _foo; + }, + set: function ( value ) { + _foo = value; + } + }); + + test( 'Array mutators work when `magic` is `true` (#376)', function ( t ) { + var ractive, items; + + items = [ + { name: 'one' }, + { name: 'two' }, + { name: 'three' } + ]; + + ractive = new Ractive({ + el: fixture, + template: '{{#items}}{{name}}{{/items}}', + magic: true, + data: { + items: items + } + }); + + ractive.data.items.push({ name: 'four' }); + + t.htmlEqual( fixture.innerHTML, 'onetwothreefour' ); + }); + + test( 'Implicit iterators work in magic mode', function ( t ) { + var ractive, items; + + items = [ + { name: 'one' }, + { name: 'two' }, + { name: 'three' } + ]; + + ractive = new Ractive({ + el: fixture, + template: '{{#.}}{{name}}{{/.}}', + magic: true, + data: items + }); + + t.htmlEqual( fixture.innerHTML, 'onetwothree' ); + + ractive.data[2].name = 'threefourfive'; + t.htmlEqual( fixture.innerHTML, 'onetwothreefourfive' ); + }); + + obj.foo = 'bar'; + } catch ( err ) { + // do nothing + } + + test( 'Foo.extend(Bar), where both Foo and Bar are Ractive instances, returns on object that inherits from Foo and Bar', function ( t ) { + var Human, Spider, Spiderman, spiderman; + + Human = Ractive.extend({ + template: '

type: {{type}}

', + + talk: function () { + return 'hello'; + } + }); + + Spider = Ractive.extend({ + // registries + data: { + type: 'arachnid' + }, + + // defaults + lazy: true, + + // methods + climb: function () { + return 'climbing'; + }, + + talk: function () { + return this._super() + ' my name is Peter Parker'; + } + }); + + Spiderman = Human.extend( Spider ); + + spiderman = new Spiderman({ + el: fixture + }); + + t.htmlEqual( fixture.innerHTML, '

type: arachnid

' ); + t.ok( spiderman.lazy ); + t.equal( spiderman.climb(), 'climbing' ); + t.equal( spiderman.talk(), 'hello my name is Peter Parker' ); + }); + + + test( 'Regression test for #460', function ( t ) { + var items, ractive, baz; + + items = [ + { desc: 'foo' }, + { desc: 'bar' }, + { desc: 'baz' } + ] + + ractive = new Ractive({ + el: fixture, + template: '{{#items}}

{{desc}}:{{missing[data]}}

{{/items}}', + data: { items: items } + }); + + baz = items.pop(); + t.htmlEqual( fixture.innerHTML, '

foo:

bar:

' ); + + items.push( baz ); + t.htmlEqual( fixture.innerHTML, '

foo:

bar:

baz:

' ); + }); + + test( 'Regression test for #457', function ( t ) { + var ractive = new Ractive({ + el: fixture, + template: '{{#step.current == step.current}}

{{foo}}

{{/step.current == step.current}}' + }); + + ractive.set({ + "foo": "bar", + "step": { + "current": 2 + } + }); + t.ok( true ); + }); + + test( 'Triples work inside SVG elements', function ( t ) { + var text, ractive = new Ractive({ + el: document.createElementNS( 'http://www.w3.org/2000/svg', 'svg' ), + template: '{{{code}}}', + data: { + code: 'works' + } + }); + + text = ractive.find( 'text' ); + t.ok( !!text ); + t.equal( text.namespaceURI, 'http://www.w3.org/2000/svg' ); + }); + + // These tests run fine in the browser but not in PhantomJS. WTF I don't even. // Anyway I can't be bothered to figure it out right now so I'm just commenting // these out so it will build @@ -1243,4 +1450,4 @@ define([ 'Ractive', '../vendor/Ractive-events-tap' ], function ( Ractive ) { }; -}); \ No newline at end of file +}); diff --git a/test/tests/mustache.js b/test/modules/mustache.js old mode 100755 new mode 100644 similarity index 99% rename from test/tests/mustache.js rename to test/modules/mustache.js index b6ef4c8d14..537e112dd9 --- a/test/tests/mustache.js +++ b/test/modules/mustache.js @@ -11,9 +11,7 @@ // works fine, but IE8 gets all confused about whitespace when doing innerHTML. // For the sake of sanity, these tests are also marked. -define([ 'Ractive' ], function ( Ractive ) { - - window.Ractive = Ractive; +define([ 'ractive' ], function ( Ractive ) { return function () { @@ -847,7 +845,8 @@ define([ 'Ractive' ], function ( Ractive ) { partials: { partial: ">" }, - oldIe: true + oldIe: true, + unpassable: true }, { name: "Standalone Without Previous Line", @@ -1227,4 +1226,4 @@ define([ 'Ractive' ], function ( Ractive ) { }; -}); \ No newline at end of file +}); diff --git a/test/tests/observe.js b/test/modules/observe.js similarity index 78% rename from test/tests/observe.js rename to test/modules/observe.js index da64625009..6fa3857c13 100644 --- a/test/tests/observe.js +++ b/test/modules/observe.js @@ -1,9 +1,7 @@ -define([ 'Ractive' ], function ( Ractive ) { +define([ 'ractive' ], function ( Ractive ) { 'use strict'; - window.Ractive = Ractive; - return function () { var fixture = document.getElementById( 'qunit-fixture' ); @@ -182,6 +180,56 @@ define([ 'Ractive' ], function ( Ractive ) { ractive.set( 'gup.foo.bar', { baz: 2 }); }); + test( 'Observers can observe multiple keypaths, separated by a space', function ( t ) { + var ractive, results; + + ractive = new Ractive({ + el: fixture, + template: 'irrelevant' + }); + + results = {}; + + ractive.observe( 'foo bar baz', function ( n, o, k ) { + results[ k ] = n; + }); + + ractive.observe({ + 'a b': function ( n, o, k ) { + results[ k ] = n; + } + }) + + ractive.set( 'foo', 'one' ); + ractive.set({ + bar: 'two', + baz: 'three' + }); + + ractive.set( 'a', 1 ); + ractive.set( 'b', 2 ); + + t.deepEqual( results, { foo: 'one', bar: 'two', baz: 'three', a: 1, b: 2 }); + }); + + test( 'Pattern observers fire when ractive.update() is called without parameters', function ( t ) { + var ractive = new Ractive({ + el: fixture, + template: 'whatever', + data: { items: [ 'a', 'b', 'c' ] } + }); + + expect( 2 ); + + ractive.observe( 'items.*', function ( n, o, k ) { + t.equal( k, 'items.1' ); + t.equal( n, 'd' ); + }, { init: false }); + + ractive.get( 'items' )[1] = 'd'; + ractive.update(); + }); + }; -}); \ No newline at end of file +}); diff --git a/test/modules/parse.js b/test/modules/parse.js new file mode 100644 index 0000000000..188128402b --- /dev/null +++ b/test/modules/parse.js @@ -0,0 +1,41 @@ +// PARSING TESTS +// ============= +// +// TODO: add moar samples + +define([ 'ractive', 'samples/parse' ], function ( Ractive, tests ) { + + return function () { + + module( 'Parse' ); + + runTest = function ( theTest ) { + test( theTest.name, function ( t ) { + var parsed = Ractive.parse( theTest.template, theTest.options ); + + t.deepEqual( parsed, theTest.parsed ); + }); + }; + + for ( i=0; i 1}}' + + '

{{{format(inner)}}}

' + + '{{/ inner}}' + + '{{/thing}}{{/model}}' + var called = 0 + + var ractive = new Ractive({ + el: fixture, + template: template, + data: { + model: [ { thing: { inner: [3,4] } } ], + format: function(a){ + called++; + return a; + } + } + }); + + t.htmlEqual( fixture.innerHTML, '

3,4

'); + ractive.get('model').splice(0, 0, {thing: {inner: [1,2]}}); + t.htmlEqual( fixture.innerHTML, '

1,2

3,4

'); + }) + + test( 'Components in a list can be reassigned', function ( t ) { + var ractive = new Ractive({ + el: fixture, + template: '{{#items}}{{/items}}', + data: { items: [ 'a', 'b', 'c' ] }, + components: { + widget: Ractive.extend({ + template: '

{{letter}}

' + }) + } + }); + + t.htmlEqual( fixture.innerHTML, '

a

b

c

' ); + + ractive.get( 'items' ).splice( 1, 1 ); + t.htmlEqual( fixture.innerHTML, '

a

c

' ); + + ractive.set( 'items[0]', 'd' ); + ractive.set( 'items[1]', 'e' ); + t.htmlEqual( fixture.innerHTML, '

d

e

' ); + }); + + test( 'Index references can be used as key attributes on components, and reassignment works', function ( t ) { + var ractive = new Ractive({ + el: fixture, + template: '{{#items:i}}{{/items}}', + data: { items: [ 'a', 'b', 'c' ] }, + components: { + widget: Ractive.extend({ + template: '

{{index}}: {{letter}}

' + }) + } + }); + + t.htmlEqual( fixture.innerHTML, '

0: a

1: b

2: c

' ); + + ractive.get( 'items' ).splice( 1, 1 ); + t.htmlEqual( fixture.innerHTML, '

0: a

1: c

' ); + }); + + test('Section with partials that use indexRef update correctly', function(t){ + var ractive = new Ractive({ + el: fixture, + template: '{{#items:i}}{{>partial}},{{/items}}', + partials: { + partial: '{{i}}' + }, + data: { items: [1,2,3,4,5] } + }); + + t.htmlEqual( fixture.innerHTML, '0,1,2,3,4,'); + + var items = ractive.get('items'); + items.splice(1,2,10); + t.deepEqual(items, [1,10,4,5]); + t.htmlEqual( fixture.innerHTML, '0,1,2,3,'); + }) + + }; + +}); diff --git a/test/modules/render.js b/test/modules/render.js new file mode 100644 index 0000000000..e168260258 --- /dev/null +++ b/test/modules/render.js @@ -0,0 +1,123 @@ +// RENDERING TESTS +// =============== +// +// TODO: add moar tests + +define([ 'ractive', 'samples/render' ], function ( Ractive, tests ) { + + return function () { + + var fixture = document.getElementById( 'qunit-fixture' ), runTest, theTest, magicModes, hasSvg, i; + + module ( 'Render' ); + + try { + var obj = {}, _foo; + Object.defineProperty( obj, 'foo', { + get: function () { + return _foo; + }, + set: function ( value ) { + _foo = value; + } + }); + magicModes = [ false, true ]; + } catch ( err ) { + magicModes = [ false ]; + } + + hasSvg = document.implementation.hasFeature( 'http://www.w3.org/TR/SVG11/feature#BasicStructure', '1.1' ); + + // argh IE + if ( ![].reduce ) { + Array.prototype.reduce = function ( reducer, start ) { + var i, len, reduced; + + reduced = start || 0; + + len = this.length; + for ( i=0; ifoo', + beforeComplete: function ( transition, params ) { + shouldHaveCompleted = true; + t.ok( fixture.contains( p ), '

element has already been removed from the DOM' ); + } + }); + + ractive = new Ractive({ + el: fixture, + template: '{{#foo}}

{{/foo}}', + components: { + widget: Widget + }, + data: { foo: true } + }); + + p = ractive.find( 'p' ); + + ractive.set( 'foo', false ).then( function () { + t.ok( shouldHaveCompleted, 'promise was fulfilled before transition had completed' ); + t.ok( !fixture.contains( p ), '

element should have been removed from the DOM' ); + start(); + }); + }); + + }; + +}); diff --git a/test/modules/twoway.js b/test/modules/twoway.js new file mode 100644 index 0000000000..0f3592e96e --- /dev/null +++ b/test/modules/twoway.js @@ -0,0 +1,115 @@ +define([ 'ractive' ], function ( Ractive ) { + + 'use strict'; + + return function () { + + var fixture = document.getElementById( 'qunit-fixture' ); + + module( 'Two-way bindings' ); + + test( 'Two-way bindings work with index references', function ( t ) { + var input, ractive; + + ractive = new Ractive({ + el: fixture, + template: '{{#items:i}}{{/items}}', + data: { items: [{ name: 'foo' }, { name: 'bar' }] } + }); + + input = ractive.find( 'input' ); + + input.value = 'baz'; + simulant.fire( input, 'change' ); + t.equal( ractive.get( 'items[0].name' ), 'baz' ); + t.htmlEqual( fixture.innerHTML, '' ); + }); + + test( 'Two-way bindings work with foo["bar"] type notation', function ( t ) { + var input, ractive; + + ractive = new Ractive({ + el: fixture, + template: '', + data: { foo: { bar: { baz: 1 } } } + }); + + input = ractive.find( 'input' ); + + input.value = 2; + simulant.fire( input, 'change' ); + + t.equal( ractive.get( 'foo.bar.baz' ), 2 ); + t.htmlEqual( fixture.innerHTML, '' ); + }); + + test( 'Two-way bindings work with arbitrary expressions that resolve to keypaths', function ( t ) { + var input, ractive; + + ractive = new Ractive({ + el: fixture, + template: '', + data: { + foo: { + bar: [ + null, + { baz: { qux: [ null, 'yes' ] } } + ] + }, + a: 0, + b: 'qux' + } + }); + + input = ractive.find( 'input' ); + + input.value = 'it works'; + simulant.fire( input, 'change' ); + + t.equal( ractive.get( 'foo.bar[1].baz.qux[1]' ), 'it works' ); + t.htmlEqual( fixture.innerHTML, '' ); + }); + + test( ' behaves the same as ', function ( t ) { + var ractive, options; + + ractive = new Ractive({ + el: fixture, + template: '', + data: { options: [ 'a', 'b', 'c' ]} + }); + + t.equal( ractive.get( 'test1' ), 'a' ); + t.equal( ractive.get( 'test2' ), 'a' ); + + options = ractive.findAll( 'option' ); + + options[1].selected = true; + options[5].selected = true; + + ractive.updateModel(); + + t.equal( ractive.get( 'test1' ), 'b' ); + t.equal( ractive.get( 'test2' ), 'c' ); + }); + + test( 'A select whose options are re-rendered will update its binding', function ( t ) { + var ractive = new Ractive({ + el: fixture, + template: '

selected: {{selected}}

', + data: { + options: [ 'a', 'b', 'c' ] + } + }); + + t.htmlEqual( fixture.innerHTML, '

selected: a

' ); + + ractive.set( 'selected', 'b' ); + ractive.set( 'options', [ 'd', 'e', 'f' ] ); + t.equal( ractive.get( 'selected' ), 'e' ); + t.htmlEqual( fixture.innerHTML, '

selected: e

' ); + }); + + }; + +}); diff --git a/test/node/basic.js b/test/node/basic.js index ba6356b216..726e713922 100644 --- a/test/node/basic.js +++ b/test/node/basic.js @@ -1,7 +1,7 @@ -var Ractive = require( '../../tmp/Ractive' ); +var Ractive = require( '../../tmp/ractive' ); exports[ 'Ractive loads in node.js' ] = function ( test ) { test.ok( typeof Ractive === 'function' ); test.done(); -}; \ No newline at end of file +}; diff --git a/test/node/components.js b/test/node/components.js new file mode 100644 index 0000000000..e5b7c19927 --- /dev/null +++ b/test/node/components.js @@ -0,0 +1,23 @@ +var Ractive = require( '../../tmp/ractive' ); + +exports[ 'A template can include templates in a non-DOM environment' ] = function ( t ) { + var ractive, Widget; + + Widget = Ractive.extend({ + template: '

foo-{{bar}}

' + }); + + ractive = new Ractive({ + template: '', + data: { + bar: 'baz' + }, + components: { + widget: Widget + } + }); + + t.equal( ractive.toHTML(), '

foo-baz

' ) + + t.done(); +}; diff --git a/test/node/parse.js b/test/node/parse.js index ee4924b8ae..3f96969acc 100644 --- a/test/node/parse.js +++ b/test/node/parse.js @@ -1,6 +1,6 @@ var Ractive, parseTests; -Ractive = require( '../../tmp/Ractive' ); +Ractive = require( '../../tmp/ractive' ); parseTests = require( '../samples/parse' ); parseTests.forEach( function ( theTest ) { @@ -10,4 +10,4 @@ parseTests.forEach( function ( theTest ) { test.done(); }; -}); \ No newline at end of file +}); diff --git a/test/node/toHTML.js b/test/node/toHTML.js index ded247397e..62c9421d0a 100644 --- a/test/node/toHTML.js +++ b/test/node/toHTML.js @@ -1,6 +1,6 @@ var Ractive, renderTests, cheerio, normaliseHTML; -Ractive = require( '../../tmp/Ractive' ); +Ractive = require( '../../tmp/ractive' ); renderTests = require( '../samples/render' ); cheerio = require( 'cheerio' ); @@ -10,20 +10,53 @@ normaliseHTML = function ( html ) { renderTests.forEach( function ( theTest ) { exports[ theTest.name ] = function ( test ) { - - var ractive = new Ractive({ - template: theTest.template, - data: theTest.data, - partials: theTest.partials - }); + [ false, true ].forEach( function ( magic ) { + var data, ractive; - test.equal( normaliseHTML( ractive.toHTML() ), normaliseHTML( theTest.result ) ); + data = typeof theTest.data === 'function' ? theTest.data() : deepClone( theTest.data ); - if ( theTest.new_data ) { - ractive.set( theTest.new_data ); - test.equal( normaliseHTML( ractive.toHTML() ), normaliseHTML( theTest.new_result ) ); - } + ractive = new Ractive({ + template: theTest.template, + data: data, + partials: theTest.partials, + magic: magic + }); + + test.equal( normaliseHTML( ractive.toHTML() ), normaliseHTML( theTest.result ) ); + + if ( theTest.new_data ) { + data = typeof theTest.new_data === 'function' ? theTest.new_data() : deepClone( theTest.new_data ); + + ractive.set( data ); + test.equal( normaliseHTML( ractive.toHTML() ), normaliseHTML( theTest.new_result ) ); + } + + ractive.teardown(); + }); test.done(); }; -}); \ No newline at end of file +}); + + +function deepClone ( source ) { + var target, key; + + if ( !source || typeof source !== 'object' ) { + return source; + } + + if ( Array.isArray( source ) ) { + return source.slice(); + } + + target = {}; + + for ( key in source ) { + if ( source.hasOwnProperty( key ) ) { + target[ key ] = deepClone( source[ key ] ); + } + } + + return target; +} diff --git a/test/promises-aplus-adaptor.js b/test/promises-aplus-adaptor.js new file mode 100644 index 0000000000..41e4d5190a --- /dev/null +++ b/test/promises-aplus-adaptor.js @@ -0,0 +1,36 @@ +// Adaptor for promises-aplus-tests + +var Promise; + +GLOBAL.define = function ( fun ) { + Promise = fun(); +}; + +require( '../src/utils/Promise' ); + +module.exports = { + resolved: function ( val ) { + return new Promise( function ( resolve, reject ) { + resolve( val ); + }); + }, + + rejected: function ( reason ) { + return new Promise( function ( resolve, reject ) { + reject( reason ); + }); + }, + + deferred: function () { + var obj; + + obj = {}; + + obj.promise = new Promise( function ( resolve, reject ) { + obj.resolve = resolve; + obj.reject = reject; + }); + + return obj; + } +}; diff --git a/test/samples/parse.js b/test/samples/parse.js index 3c367f9835..afcb37d2a1 100644 --- a/test/samples/parse.js +++ b/test/samples/parse.js @@ -2,7 +2,7 @@ var parseTests = [ { name: "Empty string", template: "", - parsed: [""] + parsed: [] }, { name: "Mustache-less text", @@ -52,7 +52,7 @@ var parseTests = [ { name: "Element with unquoted attributes", template: "
", - parsed: ["
"] + parsed: [{"a":{"class":"test"},"e":"div","t":7}] }, { name: "Element with unquoted attributes and a mustache", @@ -67,7 +67,7 @@ var parseTests = [ { name: "Template with blacklisted elements (sanitize)", template: "", - parsed: [""], + parsed: [], options: { sanitize: true } @@ -75,7 +75,7 @@ var parseTests = [ { name: "Template with blacklisted elements and mustaches (sanitize)", template: "", - parsed: [""], + parsed: [], options: { sanitize: true } @@ -83,7 +83,7 @@ var parseTests = [ { name: "Template with blacklisted elements (don't sanitize)", template: "", - parsed: [""], + parsed: [{"a":{"type":"text/css"},"e":"style","f":"body { font-family: 'Comic Sans MS'; }","t":7}], options: { sanitize: false } @@ -180,7 +180,7 @@ var parseTests = [ { name: "Expression with JSON object", template: "{{( fn({ foo: 1, 'bar': 2, '0foo': 3, '0bar': { baz: 'test', arr: [ 1, 2, 3 ] } }) )}}", - parsed: [{t:2,"x":{r:["fn"],"s":"${0}({foo:1,bar:2,\"0foo\":3,\"0bar\":{baz:'test',arr:[1,2,3]}})"}}] + parsed: [{t:2,"x":{r:["fn"],"s":"${0}({foo:1,bar:2,\"0foo\":3,\"0bar\":{baz:\"test\",arr:[1,2,3]}})"}}] }, { name: 'Invocation refinements', @@ -200,12 +200,12 @@ var parseTests = [ { name: 'Sloppy whitespace in tags', template: '
', - parsed: ['
'] + parsed: [{"a":{"class":"foo"},"e":"div","t":7}] }, { name: 'HTML entities are treated correctly in pure string templates', template: 'Non breaking spaces ', - parsed: ['Non breaking spaces '] + parsed: ['Non\u00A0breaking\u00A0spaces\u00A0'] }, { name: 'HTML entities are treated correctly in regular templates', @@ -215,7 +215,7 @@ var parseTests = [ { name: 'HTML entities are treated correctly in pure string templates if semi-colon is omitted', template: 'Non breaking spaces ', - parsed: ['Non breaking spaces '] + parsed: ['Non\u00A0breaking\u00A0spaces\u00A0'] }, { name: 'HTML entities are treated correctly in regular templates if semi-colon is omitted', @@ -275,7 +275,7 @@ var parseTests = [ { name: 'Comments are stripped by default', template: '

foo

', - parsed: ['

foo

'] + parsed: [{"e":"p","f":"foo","t":7}] }, { name: 'Comments are left if required (with mustache)', @@ -286,7 +286,7 @@ var parseTests = [ { name: 'Comments are left if required (with plain text)', template: '

foo

', - parsed: ['

foo

'], + parsed: [{"f":" this will not disappear ","t":9},{"e":"p","f":"foo ","t":7}], options: { stripComments: false } }, { @@ -318,6 +318,62 @@ var parseTests = [ name: 'Ampersand mustaches are treated the same as triples', template: '{{&foo}}', parsed: [{t:3,r:'foo'}] + }, + { + name: 'Backslash escapes in strings', + template: '{{ ["\\\\ \\" \\\\", \'\\\\ \\\' \\\\\'] }}', + parsed: [{t:2,x:{r:[],s:'["\\\\ \\" \\\\","\\\\ \' \\\\"]'}}] + }, + { + name: 'Unicode escapes in strings', + template: '{{ "A\\u0042C" }}', + parsed: [{t:2,x:{r:[],s:'"ABC"'}}] + }, + { + name: 'Array members in section tags', + template: '{{#foo[0]}}bar{{/foo[0]}}', + parsed: [{t:4,r:'foo.0',f:'bar'}] + }, + { + name: 'Reference this is an invalid expression', + template: '{{0.foo}}', + parsed: [{t:2,r:'0.foo'}] + }, + { + name: 'Tag with newline before attributes', + template: '', + parsed: [{t:7,e:'img',a:{src:[{t:2,r:'foo'}]}}] + }, + { + name: 'Expression section', + template: '{{#[1,2,3]}}{{.}}{{/}}', + parsed: [{"t":4,"x":{"r":[],"s":"[1,2,3]"},"f":[{"t":2,"r":"."}]}] + }, + { + name: 'Keypath expression section', + template: '{{#foo[bar]}}{{.}}{{/}}', + parsed: [{"t":4,"kx":{"r":"foo","m":[{"t":30,"n":"bar"}]},"f":[{"t":2,"r":"."}]}] + }, + { + name: 'List section with index ref and full closing', + template: '{{#foo:i}}{{.}}{{/foo:i}}', + parsed: [{"t":4,"r":"foo","i":"i","f":[{"t":2,"r":"."}]}] + }, + { + name: 'List section with index ref and ref only closing', + template: '{{#foo:i}}{{.}}{{/foo}}', + parsed: [{"t":4,"r":"foo","i":"i","f":[{"t":2,"r":"."}]}] + }, + { + name: 'List section with index ref and empty closing', + template: '{{#foo:i}}{{.}}{{/}}', + parsed: [{"t":4,"r":"foo","i":"i","f":[{"t":2,"r":"."}]}] + }, + //From GH#541: + { + name: 'Inverted list section closing', + template: '{{#steps:stepIndex}}{{^ hiddenSteps[stepIndex]}}

{{hiddenSteps[stepIndex]}}

{{/ hiddenSteps[stepIndex]}}{{/steps}}', + parsed: [{"t":4,"r":"steps","i":"stepIndex","f":[{"t":4,"n":true,"kx":{"r":"hiddenSteps","m":[{"t":30,"n":"stepIndex"}]},"f":[{"t":7,"e":"p","f":[{"t":2,"kx":{"r":"hiddenSteps","m":[{"t":30,"n":"stepIndex"}]}}]}]}]}] } ]; @@ -330,4 +386,4 @@ if ( typeof define === 'function' && define.amd ) { else if ( typeof module !== 'undefined' && module.exports ) { module.exports = parseTests; -} \ No newline at end of file +} diff --git a/test/samples/render.js b/test/samples/render.js index 84cbce9fd6..bc2764ff02 100644 --- a/test/samples/render.js +++ b/test/samples/render.js @@ -343,16 +343,50 @@ var renderTests = [ }, { name: 'Triples work correctly inside table elements', - template: '{{{row}}}
', - data: { row: 'works' }, - result: '
works
', - new_data: { row: 'still works' }, - new_result: '
still works
' + template: '{{{row}}}
' + + '{{{headerRow}}}
' + + '{{{row}}}
' + + '{{{cell}}}
' + + '
{{{cellContents}}}
' + + '
{{{cellContents}}}
', + data: { + row: 'works', + headerRow: 'works', + cell: 'works', + cellContents: 'works' + }, + result: '
works
' + + '
works
' + + '
works
' + + '
works
' + + '
works
' + + '
works
', + new_data: { + row: 'still works', + headerRow: 'still works', + cell: 'still works', + cellContents: 'still works' + }, + new_result: '
still works
' + + '
still works
' + + '
still works
' + + '
still works
' + + '
still works
' + + '
still works
' + }, + { + name: 'Triples work correctly inside select elements', + template: '', + data: { options: '' }, + result: '', + new_data: { options: '' }, + new_result: '' }, { name: 'Class name on an SVG element', template: 'foo', - result: 'foo' + result: 'foo', + svg: true }, { name: 'Multiple angle brackets are correctly escaped, both with render() and renderHTML()', @@ -402,6 +436,74 @@ var renderTests = [ template: '{{#.}}

{{name}}

{{/.}}', data: [{ name: 'Alice' }, { name: 'Bob' }, { name: 'Charles' }], result: '

Alice

Bob

Charles

' + }, + { + name: 'Setting child properties of null values creates object', + template: '{{foo.bar}}', + data: { foo: null }, + result: '', + new_data: { 'foo.bar': 'works' }, + new_result: 'works' + }, + { + name: 'Children of sections with partially resolved evaluator', + template: '{{# foo || {} }}{{bar}}{{/ foo || {} }}', + data: {}, + result: '', + new_data: { foo: { bar: 'works' } }, + new_result: 'works' + }, + { + name: 'Different expressions that share a keypath in unresolved state', + template: '{{identity(foo)}} / {{identity(bar)}}', + data: { identity: function ( val ) { return val; } }, + result: ' / ', + new_data: { foo: 'one', bar: 'two', identity: function ( val ) { return val; } }, + new_result: 'one / two' + }, + { + name: 'Properties of functions render correctly (#451)', + template: '{{foo.prop}}-{{#foo}}{{prop}}{{/foo}}', + data: function () { + var foo = function () {}, columns = [{ bar: foo }]; + foo.prop = 'works'; + return { + columns: columns, + foo: foo + }; + }, + result: 'works-works', + new_data: { 'foo.prop': 'still works' }, + new_result: 'still works-still works' + }, + + // Elements with two-way bindings should render correctly with .toHTML() - #446 + { + nodeOnly: true, + name: 'Two-way select bindings', + template: '', + data: {}, + result: '', + new_data: { foo: 'c' }, + new_result: '' + }, + { + nodeOnly: true, + name: 'Two-way multiple select bindings', + template: '', + data: {}, + result: '', + new_data: { foo: [ 'b', 'c' ] }, + new_result: '' + }, + { + nodeOnly: true, + name: 'Two-way radio buttons', + template: '', + data: { foo: 'one' }, + result: '', + new_data: { foo: 'two' }, + new_result: '' } ]; @@ -415,4 +517,4 @@ if ( typeof define === 'function' && define.amd ) { else if ( typeof module !== 'undefined' && module.exports ) { module.exports = renderTests; -} \ No newline at end of file +} diff --git a/test/source/index.html b/test/source/index.html deleted file mode 100755 index bb1db5b9ed..0000000000 --- a/test/source/index.html +++ /dev/null @@ -1,54 +0,0 @@ - - - - Ractive Test Suite - - - -
-
- - - - - - - - - diff --git a/test/testling.html b/test/testling.html deleted file mode 100755 index 7f966d5e63..0000000000 --- a/test/testling.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - Ractive Test Suite - - - -
-
- - - - - - - - - - - - - - - - - - diff --git a/test/tests/adaptors.html b/test/tests/adaptors.html new file mode 100644 index 0000000000..d474862a39 --- /dev/null +++ b/test/tests/adaptors.html @@ -0,0 +1,21 @@ + + + + Adaptors | Ractive Test Suite + + + +
+
+ + + + + + + + + + diff --git a/test/tests/arrays.html b/test/tests/arrays.html new file mode 100644 index 0000000000..1a27dc477b --- /dev/null +++ b/test/tests/arrays.html @@ -0,0 +1,21 @@ + + + + Arrays | Ractive Test Suite + + + +
+
+ + + + + + + + + + diff --git a/test/source/components.html b/test/tests/components.html similarity index 76% rename from test/source/components.html rename to test/tests/components.html index f85635ec53..e3ee9d4c91 100644 --- a/test/source/components.html +++ b/test/tests/components.html @@ -14,13 +14,9 @@ + + diff --git a/test/tests/components.js b/test/tests/components.js deleted file mode 100644 index 5a0793afd5..0000000000 --- a/test/tests/components.js +++ /dev/null @@ -1,258 +0,0 @@ -define([ 'Ractive' ], function ( Ractive ) { - - 'use strict'; - - window.Ractive = Ractive; - - return function () { - - var fixture, Foo; - - module( 'Components' ); - - // some set-up - fixture = document.getElementById( 'qunit-fixture' ); - - test( 'Static data is propagated from parent to child', function ( t ) { - var Widget, ractive, widget; - - Widget = Ractive.extend({ - template: '

{{foo}}

' - }); - - ractive = new Ractive({ - el: fixture, - template: '', - components: { - widget: Widget - } - }); - - widget = ractive.findComponent( 'widget' ); - - t.equal( widget.get( 'foo' ), 'blah' ); - t.htmlEqual( fixture.innerHTML, '

blah

' ); - }); - - test( 'Dynamic data is propagated from parent to child, and (two-way) bindings are created', function ( t ) { - var Widget, ractive, widget; - - Widget = Ractive.extend({ - template: '

{{foo}}

' - }); - - ractive = new Ractive({ - el: fixture, - template: '', - components: { - widget: Widget - }, - data: { - bar: 'blah' - } - }); - - widget = ractive.findComponent( 'widget' ); - - t.equal( widget.get( 'foo' ), 'blah' ); - t.htmlEqual( fixture.innerHTML, '

blah

' ); - - ractive.set( 'bar', 'flup' ); - t.equal( widget.get( 'foo' ), 'flup' ); - t.htmlEqual( fixture.innerHTML, '

flup

' ); - - widget.set( 'foo', 'shmup' ); - t.equal( ractive.get( 'bar' ), 'shmup' ); - t.htmlEqual( fixture.innerHTML, '

shmup

' ); - }); - - test( 'Missing data on the parent is not propagated', function ( t ) { - var Widget, ractive, widget; - - Widget = Ractive.extend({ - template: '

{{foo}}

' - }); - - ractive = new Ractive({ - el: fixture, - template: '', - components: { - widget: Widget - } - }); - - widget = ractive.findComponent( 'widget' ); - - t.ok( !( widget.data.hasOwnProperty( 'foo' ) ) ); - t.htmlEqual( fixture.innerHTML, '

' ); - }); - - test( 'Data on the child is propagated to the parent, if it is not missing', function ( t ) { - var Widget, ractive, widget; - - Widget = Ractive.extend({ - template: '

{{foo}}{{bar}}

', - data: { - foo: 'yes' - } - }); - - ractive = new Ractive({ - el: fixture, - template: '', - components: { - widget: Widget - } - }); - - widget = ractive.findComponent( 'widget' ); - - t.equal( ractive.get( 'one' ), 'yes' ); - t.ok( !( ractive.data.hasOwnProperty( 'two' ) ) ); - t.htmlEqual( fixture.innerHTML, '

yes

' ); - }); - - test( 'Parent data overrides child data during child model creation', function ( t ) { - var Widget, ractive, widget; - - Widget = Ractive.extend({ - template: '

{{foo}}{{bar}}

', - data: { - foo: 'yes', - bar: 'no' - } - }); - - ractive = new Ractive({ - el: fixture, - template: '', - components: { - widget: Widget - }, - data: { - one: 'uno', - two: 'dos' - } - }); - - widget = ractive.findComponent( 'widget' ); - - t.equal( ractive.get( 'one' ), 'uno' ); - t.equal( ractive.get( 'two' ), 'dos' ); - t.equal( widget.get( 'foo' ), 'uno' ); - t.equal( widget.get( 'bar' ), 'dos' ); - - t.htmlEqual( fixture.innerHTML, '

unodos

' ); - }); - - test( 'Components are rendered in the correct place', function ( t ) { - var Component, ractive; - - Component = Ractive.extend({ - template: '

this is a component!

' - }); - - ractive = new Ractive({ - el: fixture, - template: '

Here is a component:

(that was a component)

', - components: { - component: Component - } - }); - - t.htmlEqual( fixture.innerHTML, '

Here is a component:

this is a component!

(that was a component)

' ); - }); - - test( 'Top-level sections in components are updated correctly', function ( t ) { - var ractive, Component, component; - - Component = Ractive.extend({ - template: '{{#foo}}foo is truthy{{/foo}}{{^foo}}foo is falsy{{/foo}}' - }); - - ractive = new Ractive({ - el: fixture, - template: '', - components: { - component: Component - } - }); - - t.htmlEqual( fixture.innerHTML, 'foo is falsy' ); - - ractive.set( 'foo', true ); - t.htmlEqual( fixture.innerHTML, 'foo is truthy' ); - }); - - test( 'Element order is maintained correctly with components with multiple top-level elements', function ( t ) { - var ractive, TestComponent; - - TestComponent = Ractive.extend({ - template: '{{#bool}}TRUE{{/bool}}{{^bool}}FALSE{{/bool}}' - }); - - ractive = new Ractive({ - el: fixture, - template: '

before

after

', - components: { test: TestComponent } - }); - - t.htmlEqual( fixture.innerHTML, '

before

FALSE

after

' ); - - ractive.set( 'bool', true ); - t.htmlEqual( fixture.innerHTML, '

before

TRUE

after

' ); - - ractive.set( 'bool', false ); - t.htmlEqual( fixture.innerHTML, '

before

FALSE

after

' ); - }); - - test( 'Regression test for #317', function ( t ) { - var Widget, widget, ractive, items; - - Widget = Ractive.extend({ - template: '
    {{#items:i}}
  • {{i}}: {{.}}
  • {{/items}}
', - init: function () { - widget = this; - } - }); - - ractive = new Ractive({ - el: fixture, - template: '

{{ items.join( " " ) }}

', - data: { items: [ 'a', 'b', 'c', 'd' ] }, - components: { - widget: Widget - } - }); - - items = ractive.get( 'items' ); - - t.htmlEqual( fixture.innerHTML, '
  • 0: a
  • 1: b
  • 2: c
  • 3: d

a b c d

' ); - - items.push( 'e' ); - t.htmlEqual( fixture.innerHTML, '
  • 0: a
  • 1: b
  • 2: c
  • 3: d
  • 4: e

a b c d e

' ); - - items.splice( 2, 1 ); - t.htmlEqual( fixture.innerHTML, '
  • 0: a
  • 1: b
  • 2: d
  • 3: e

a b d e

' ); - - items.pop(); - t.htmlEqual( fixture.innerHTML, '
  • 0: a
  • 1: b
  • 2: d

a b d

' ); - - - // reset items from within widget - widget.set( 'items', widget.get( 'items' ).slice() ); - items = ractive.get( 'items' ); - - items.push( 'f' ); - t.htmlEqual( fixture.innerHTML, '
  • 0: a
  • 1: b
  • 2: d
  • 3: f

a b d f

' ); - - items.splice( 1, 1 ); - t.htmlEqual( fixture.innerHTML, '
  • 0: a
  • 1: d
  • 2: f

a d f

' ); - - items.pop(); - t.htmlEqual( fixture.innerHTML, '
  • 0: a
  • 1: d

a d

' ); - }); - - }; - -}); \ No newline at end of file diff --git a/test/tests/computations.html b/test/tests/computations.html new file mode 100644 index 0000000000..7ba07100b9 --- /dev/null +++ b/test/tests/computations.html @@ -0,0 +1,21 @@ + + + + Computations | Ractive Test Suite + + + +
+
+ + + + + + + + + + diff --git a/test/tests/css.html b/test/tests/css.html new file mode 100644 index 0000000000..b2123d81b5 --- /dev/null +++ b/test/tests/css.html @@ -0,0 +1,21 @@ + + + + CSS encapsulation | Ractive Test Suite + + + +
+
+ + + + + + + + + + diff --git a/test/tests/decorators.html b/test/tests/decorators.html new file mode 100644 index 0000000000..217f5ad3c5 --- /dev/null +++ b/test/tests/decorators.html @@ -0,0 +1,21 @@ + + + + Decorators | Ractive Test Suite + + + +
+
+ + + + + + + + + + diff --git a/test/source/events.html b/test/tests/events.html old mode 100755 new mode 100644 similarity index 77% rename from test/source/events.html rename to test/tests/events.html index e6629e63c9..a3c52a14fc --- a/test/source/events.html +++ b/test/tests/events.html @@ -14,13 +14,9 @@ + + diff --git a/test/source/find.html b/test/tests/find.html similarity index 78% rename from test/source/find.html rename to test/tests/find.html index 72a9712218..85b0a0bac6 100644 --- a/test/source/find.html +++ b/test/tests/find.html @@ -14,13 +14,9 @@ + + diff --git a/test/build/components.html b/test/tests/index.html similarity index 53% rename from test/build/components.html rename to test/tests/index.html index aafb478a7b..767bd36c4b 100644 --- a/test/build/components.html +++ b/test/tests/index.html @@ -1,7 +1,7 @@ - Components | Ractive Test Suite + Ractive Test Suite @@ -14,14 +14,29 @@ + + diff --git a/test/tests/magic.html b/test/tests/magic.html new file mode 100644 index 0000000000..ae0e838a84 --- /dev/null +++ b/test/tests/magic.html @@ -0,0 +1,21 @@ + + + + Magic mode | Ractive Test Suite + + + +
+
+ + + + + + + + + + diff --git a/test/source/merge.html b/test/tests/merge.html similarity index 78% rename from test/source/merge.html rename to test/tests/merge.html index 9001650c8c..60bf93092f 100644 --- a/test/source/merge.html +++ b/test/tests/merge.html @@ -14,13 +14,9 @@ + + diff --git a/test/source/misc.html b/test/tests/misc.html old mode 100755 new mode 100644 similarity index 79% rename from test/source/misc.html rename to test/tests/misc.html index 4649185be2..c350043740 --- a/test/source/misc.html +++ b/test/tests/misc.html @@ -14,13 +14,9 @@ + + diff --git a/test/source/mustache.html b/test/tests/mustache.html old mode 100755 new mode 100644 similarity index 77% rename from test/source/mustache.html rename to test/tests/mustache.html index 3e4109ef67..a5c606b141 --- a/test/source/mustache.html +++ b/test/tests/mustache.html @@ -14,13 +14,9 @@ + + diff --git a/test/source/observe.html b/test/tests/observe.html similarity index 77% rename from test/source/observe.html rename to test/tests/observe.html index 29d0e8e64c..c058bd632a 100644 --- a/test/source/observe.html +++ b/test/tests/observe.html @@ -14,13 +14,9 @@ + + diff --git a/test/source/parse.html b/test/tests/parse.html old mode 100755 new mode 100644 similarity index 78% rename from test/source/parse.html rename to test/tests/parse.html index 1c73947137..4ffdd0e959 --- a/test/source/parse.html +++ b/test/tests/parse.html @@ -14,13 +14,9 @@ + + diff --git a/test/tests/parse.js b/test/tests/parse.js deleted file mode 100755 index d2cd493e42..0000000000 --- a/test/tests/parse.js +++ /dev/null @@ -1,28 +0,0 @@ -// PARSING TESTS -// ============= -// -// TODO: add moar samples - -define([ 'Ractive', '../samples/parse' ], function ( Ractive, tests ) { - - window.Ractive = Ractive; - - return function () { - - module( 'Parse' ); - - runTest = function ( theTest ) { - test( theTest.name, function ( t ) { - var parsed = Ractive.parse( theTest.template, theTest.options ); - - t.deepEqual( parsed, theTest.parsed ); - }); - }; - - for ( i=0; i + + + Reassign Fragments | Ractive Test Suite + + + +
+
+ + + + + + + + + + diff --git a/test/source/render.html b/test/tests/render.html old mode 100755 new mode 100644 similarity index 78% rename from test/source/render.html rename to test/tests/render.html index f03b2270a7..3f04dd3e83 --- a/test/source/render.html +++ b/test/tests/render.html @@ -14,13 +14,9 @@ + + diff --git a/test/tests/render.js b/test/tests/render.js deleted file mode 100755 index d84a2ae39a..0000000000 --- a/test/tests/render.js +++ /dev/null @@ -1,72 +0,0 @@ -// RENDERING TESTS -// =============== -// -// TODO: add moar tests - -define([ 'Ractive', '../samples/render' ], function ( Ractive, tests ) { - - window.Ractive = Ractive; - - return function () { - - var fixture = document.getElementById( 'qunit-fixture' ), runTest, theTest, hasSvg; - - module ( 'Render' ); - - hasSvg = document.implementation.hasFeature( 'http://www.w3.org/TR/SVG11/feature#BasicStructure', '1.1' ); - - // argh IE - if ( ![].reduce ) { - Array.prototype.reduce = function ( reducer, start ) { - var i, len, reduced; - - reduced = start || 0; - - len = this.length; - for ( i=0; i - - - + + diff --git a/test/tests/runTests.js b/test/tests/runTests.js new file mode 100644 index 0000000000..eaa1fa15d3 --- /dev/null +++ b/test/tests/runTests.js @@ -0,0 +1,53 @@ +(function () { + + 'use strict'; + + var isBuild, config, i, prefixedModules = []; + + if ( /build=true/.test( window.location.search ) || /phantomjs/i.test( window.navigator.userAgent ) ) { + isBuild = true; + QUnit.config.autostart = false; + + config = { + baseUrl: '../../src/', + paths: { + ractive: '../tmp/ractive-legacy', + modules: '../test/modules', + samples: '../test/samples', + vendor: '../test/vendor' + } + }; + } else { + config = { + baseUrl: '../../src/', + paths: { + modules: '../test/modules', + samples: '../test/samples', + vendor: '../test/vendor' + } + }; + } + + require.config( config ); + + // can't use .map() because of IE... + i = _modules.length; + while ( i-- ) { + prefixedModules[i] = 'modules/' + _modules[i]; + } + + require( [ 'ractive' ].concat( prefixedModules ), function ( Ractive ) { + window.Ractive = Ractive; + + Ractive.defaults.magic = /magic=true/.test( window.location.search ); + + Array.prototype.slice.call( arguments, 1 ).forEach( function ( testSet ) { + testSet(); + }); + + if ( isBuild ) { + QUnit.start(); + } + }); + +}()); diff --git a/test/tests/transitions.html b/test/tests/transitions.html new file mode 100644 index 0000000000..3a77919e15 --- /dev/null +++ b/test/tests/transitions.html @@ -0,0 +1,21 @@ + + + + Transitions | Ractive Test Suite + + + +
+
+ + + + + + + + + + diff --git a/test/tests/twoway.html b/test/tests/twoway.html new file mode 100644 index 0000000000..75250e773f --- /dev/null +++ b/test/tests/twoway.html @@ -0,0 +1,22 @@ + + + + Two-way binding | Ractive Test Suite + + + +
+
+ + + + + + + + + + + diff --git a/test/vendor/Ractive-events-tap.js b/test/vendor/Ractive-events-tap.js index d7bc066d33..abc5594244 100644 --- a/test/vendor/Ractive-events-tap.js +++ b/test/vendor/Ractive-events-tap.js @@ -41,7 +41,7 @@ // AMD? else if ( typeof define === 'function' && define.amd ) { - define([ 'Ractive' ], factory ); + define([ 'ractive' ], factory ); } // browser global @@ -165,7 +165,7 @@ node: currentTarget, original: event }); - + cancel(); }; @@ -239,4 +239,4 @@ Ractive.events.tap = tap; -})); \ No newline at end of file +})); diff --git a/test/vendor/qunit-html.js b/test/vendor/qunit-html.js index 0d619e40ad..74d9685e10 100644 --- a/test/vendor/qunit-html.js +++ b/test/vendor/qunit-html.js @@ -9,7 +9,7 @@ message = 'HTML should be equal'; } - this.equal( normalize( actual ), normalize( expected ), message ); + this.deepEqual( normalize( actual ), normalize( expected ), message ); }; QUnit.assert.notHtmlEqual = function ( actual, expected, message ) { @@ -17,12 +17,12 @@ message = 'HTML should be equal'; } - this.notEqual( normalize( actual ), normalize( expected ), message ); + this.notDeepEqual( normalize( actual ), normalize( expected ), message ); }; function normalize ( html ) { - testDiv.innerHTML = html; - return trim( testDiv.innerHTML ); + testDiv.innerHTML = trim( html ); + return stubNode( testDiv ).children || stubNode( testDiv ).text; } function trim ( str ) { @@ -33,5 +33,40 @@ return str.replace( /^s+/, '' ).replace( /\s+$/, '' ); } + function stubNode ( node ) { + var stub, i, attr; + + if ( node.nodeType === 3 ) { + return node.data; + } + + if ( node.nodeType === 1 ) { + stub = { _tag: node.tagName }; + + if ( ( node.childNodes.length === 1 ) && ( node.childNodes[0].nodeType === 3 ) ) { + stub.text = node.childNodes[0].data; + } else { + stub.children = []; + + i = node.childNodes.length; + while ( i-- ) { + stub.children[i] = stubNode( node.childNodes[i] ); + } + } + + if ( i = node.attributes.length ) { + stub.attributes = {}; + } + + i = node.attributes.length; + while ( i-- ) { + attr = node.attributes[i]; + stub.attributes[ attr.name ] = attr.value || true; + } + + return stub; + } + } + }()); diff --git a/test/vendor/ractive-events-tap.js b/test/vendor/ractive-events-tap.js new file mode 100644 index 0000000000..abc5594244 --- /dev/null +++ b/test/vendor/ractive-events-tap.js @@ -0,0 +1,242 @@ +/* + + Ractive-events-tap + ================== + + Version <%= VERSION %>. + + << description goes here... >> + + ========================== + + Troubleshooting: If you're using a module system in your app (AMD or + something more nodey) then you may need to change the paths below, + where it says `require( 'ractive' )` or `define([ 'Ractive' ]...)`. + + ========================== + + Usage: Include this file on your page below Ractive, e.g: + + + + + Or, if you're using a module loader, require this module: + + // requiring the plugin will 'activate' it - no need to use + // the return value + require( 'Ractive-events-tap' ); + + << more specific instructions for this plugin go here... >> + +*/ + +(function ( global, factory ) { + + 'use strict'; + + // Common JS (i.e. browserify) environment + if ( typeof module !== 'undefined' && module.exports && typeof require === 'function' ) { + factory( require( 'ractive' ) ); + } + + // AMD? + else if ( typeof define === 'function' && define.amd ) { + define([ 'ractive' ], factory ); + } + + // browser global + else if ( global.Ractive ) { + factory( global.Ractive ); + } + + else { + throw new Error( 'Could not find Ractive! It must be loaded before the Ractive-events-tap plugin' ); + } + +}( typeof window !== 'undefined' ? window : this, function ( Ractive ) { + + 'use strict'; + + var tap, doc = document; + + tap = function ( node, fire ) { + var mousedown, touchstart, focusHandler, distanceThreshold, timeThreshold; + + distanceThreshold = 5; // maximum pixels pointer can move before cancel + timeThreshold = 400; // maximum milliseconds between down and up before cancel + + mousedown = function ( event ) { + var currentTarget, x, y, pointerId, up, move, cancel; + + if ( event.which !== undefined && event.which !== 1 ) { + return; + } + + x = event.clientX; + y = event.clientY; + currentTarget = this; + // This will be null for mouse events. + pointerId = event.pointerId; + + up = function ( event ) { + if ( event.pointerId != pointerId ) { + return; + } + + fire({ + node: currentTarget, + original: event + }); + + cancel(); + }; + + move = function ( event ) { + if ( event.pointerId != pointerId ) { + return; + } + + if ( ( Math.abs( event.clientX - x ) >= distanceThreshold ) || ( Math.abs( event.clientY - y ) >= distanceThreshold ) ) { + cancel(); + } + }; + + cancel = function () { + node.removeEventListener( 'MSPointerUp', up, false ); + doc.removeEventListener( 'MSPointerMove', move, false ); + doc.removeEventListener( 'MSPointerCancel', cancel, false ); + node.removeEventListener( 'pointerup', up, false ); + doc.removeEventListener( 'pointermove', move, false ); + doc.removeEventListener( 'pointercancel', cancel, false ); + node.removeEventListener( 'click', up, false ); + doc.removeEventListener( 'mousemove', move, false ); + }; + + if ( window.navigator.pointerEnabled ) { + node.addEventListener( 'pointerup', up, false ); + doc.addEventListener( 'pointermove', move, false ); + doc.addEventListener( 'pointercancel', cancel, false ); + } else if ( window.navigator.msPointerEnabled ) { + node.addEventListener( 'MSPointerUp', up, false ); + doc.addEventListener( 'MSPointerMove', move, false ); + doc.addEventListener( 'MSPointerCancel', cancel, false ); + } else { + node.addEventListener( 'click', up, false ); + doc.addEventListener( 'mousemove', move, false ); + } + + setTimeout( cancel, timeThreshold ); + }; + + if ( window.navigator.pointerEnabled ) { + node.addEventListener( 'pointerdown', mousedown, false ); + } else if ( window.navigator.msPointerEnabled ) { + node.addEventListener( 'MSPointerDown', mousedown, false ); + } else { + node.addEventListener( 'mousedown', mousedown, false ); + } + + + touchstart = function ( event ) { + var currentTarget, x, y, touch, finger, move, up, cancel; + + if ( event.touches.length !== 1 ) { + return; + } + + touch = event.touches[0]; + + x = touch.clientX; + y = touch.clientY; + currentTarget = this; + + finger = touch.identifier; + + up = function ( event ) { + var touch; + + touch = event.changedTouches[0]; + if ( touch.identifier !== finger ) { + cancel(); + } + + event.preventDefault(); // prevent compatibility mouse event + fire({ + node: currentTarget, + original: event + }); + + cancel(); + }; + + move = function ( event ) { + var touch; + + if ( event.touches.length !== 1 || event.touches[0].identifier !== finger ) { + cancel(); + } + + touch = event.touches[0]; + if ( ( Math.abs( touch.clientX - x ) >= distanceThreshold ) || ( Math.abs( touch.clientY - y ) >= distanceThreshold ) ) { + cancel(); + } + }; + + cancel = function () { + node.removeEventListener( 'touchend', up, false ); + window.removeEventListener( 'touchmove', move, false ); + window.removeEventListener( 'touchcancel', cancel, false ); + }; + + node.addEventListener( 'touchend', up, false ); + window.addEventListener( 'touchmove', move, false ); + window.addEventListener( 'touchcancel', cancel, false ); + + setTimeout( cancel, timeThreshold ); + }; + + node.addEventListener( 'touchstart', touchstart, false ); + + + // native buttons, and elements, should fire a tap event + // when the space key is pressed + if ( node.tagName === 'BUTTON' || node.type === 'button' ) { + focusHandler = function () { + var blurHandler, keydownHandler; + + keydownHandler = function ( event ) { + if ( event.which === 32 ) { // space key + fire({ + node: node, + original: event + }); + } + }; + + blurHandler = function () { + node.removeEventListener( 'keydown', keydownHandler, false ); + node.removeEventListener( 'blur', blurHandler, false ); + }; + + node.addEventListener( 'keydown', keydownHandler, false ); + node.addEventListener( 'blur', blurHandler, false ); + }; + + node.addEventListener( 'focus', focusHandler, false ); + } + + + return { + teardown: function () { + node.removeEventListener( 'pointerdown', mousedown, false ); + node.removeEventListener( 'MSPointerDown', mousedown, false ); + node.removeEventListener( 'mousedown', mousedown, false ); + node.removeEventListener( 'touchstart', touchstart, false ); + node.removeEventListener( 'focus', focusHandler, false ); + } + }; + }; + + Ractive.events.tap = tap; + +})); diff --git a/wrapper/banner.js b/wrapper/banner.js index 506120fbc2..eab6b94eca 100644 --- a/wrapper/banner.js +++ b/wrapper/banner.js @@ -1,35 +1,10 @@ /* - - Ractive - v<%= pkg.version %> - <%= grunt.template.today( 'yyyy-mm-dd' ) %> - ============================================================== + Ractive.js v<%= pkg.version %> + <%= grunt.template.today( 'yyyy-mm-dd' ) %> - commit <%= commitHash.substr( 0, 8 ) %> - Next-generation DOM manipulation - http://ractivejs.org - Follow @RactiveJS for updates - - -------------------------------------------------------------- - - Copyright <%= grunt.template.today( 'yyyy' ) %> 2013 Rich Harris and contributors - - 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. + http://ractivejs.org + http://twitter.com/RactiveJS + Released under the MIT License. */ diff --git a/wrapper/intro.js b/wrapper/intro.js index badd492e8d..4ed8394231 100644 --- a/wrapper/intro.js +++ b/wrapper/intro.js @@ -1,3 +1,6 @@ (function ( global ) { -'use strict'; + 'use strict'; + + var noConflict = global.Ractive; + diff --git a/wrapper/outro.js b/wrapper/outro.js index 3cac7e8f60..cd38b3afe8 100644 --- a/wrapper/outro.js +++ b/wrapper/outro.js @@ -12,8 +12,11 @@ else if ( typeof define === "function" && define.amd ) { } // ... or as browser global -else { - global.Ractive = Ractive; -} +global.Ractive = Ractive; + +Ractive.noConflict = function () { + global.Ractive = noConflict; + return Ractive; +}; -}( typeof window !== 'undefined' ? window : this )); \ No newline at end of file +}( typeof window !== 'undefined' ? window : this )); diff --git a/wrapper/parse-intro.js b/wrapper/parse-intro.js deleted file mode 100644 index d9496a5036..0000000000 --- a/wrapper/parse-intro.js +++ /dev/null @@ -1,18 +0,0 @@ -(function ( global ) { - -// Some of the modules herein have circular dependencies. This isn't a -// huge problem with AMD, because you can do -// -// require([ 'some/circular/dependency' ], function ( dep ) { -// dependency = dep; -// }); -// -// However we're using amdclean to get rid of define() and require() -// calls in the distributed file, and circular dependencies break -// amdclean. So we're collecting those require calls (which amdclean -// rewrites) and executing them at the end, once modules have been defined. -var loadCircularDependency = function ( callback ) { - loadCircularDependency.callbacks.push( callback ); -}; - -loadCircularDependency.callbacks = []; \ No newline at end of file diff --git a/wrapper/parse-outro.js b/wrapper/parse-outro.js deleted file mode 100644 index 61314282f4..0000000000 --- a/wrapper/parse-outro.js +++ /dev/null @@ -1,23 +0,0 @@ -while ( loadCircularDependency.callbacks.length ) { - loadCircularDependency.callbacks.pop()(); -} - - -// export as Common JS module... -if ( typeof module !== "undefined" && module.exports ) { - module.exports = parse__index; -} - -// ... or as AMD module -else if ( typeof define === "function" && define.amd ) { - define( function () { - return parse__index; - }); -} - -// ... or as browser global -else { - global.parse = parse__index; -} - -}( typeof window !== 'undefined' ? window : this )); \ No newline at end of file