{"version":3,"file":"ractive.min.js","sources":["../src/view/items/Partial.js","../src/model/specials/KeyModel.js","../src/view/RepeatedFragment.js","../src/view/items/Section.js","../src/view/items/element/specials/Select.js","../src/view/items/element/specials/Textarea.js","../src/view/items/Text.js","../src/config/visibility.js","../src/view/items/element/transitions/prefix.js","../src/view/items/element/transitions/createTransitions.js","../src/view/items/element/transitions/hyphenate.js","../src/view/items/element/Transition.js","../src/view/items/triple/insertHtml.js","../src/view/items/Triple.js","../src/view/items/createItem.js","../src/view/Fragment.js","../src/Ractive/prototype/reset.js","../src/Ractive/prototype/reverse.js","../src/Ractive/prototype/shift.js","../src/Ractive/prototype/sort.js","../src/Ractive/prototype/splice.js","../src/Ractive/prototype/unshift.js","../src/Ractive/prototype.js","../src/Ractive/static/styles.js","../src/extend/_extend.js","../src/Ractive.js","../src/view/items/element/Decorator.js","../src/view/items/Doctype.js","../src/view/items/element/binding/Binding.js","../src/view/items/element/binding/CheckboxBinding.js","../src/view/items/element/binding/getBindingGroup.js","../src/view/items/element/binding/CheckboxNameBinding.js","../src/view/items/element/binding/ContentEditableBinding.js","../src/view/items/element/binding/GenericBinding.js","../src/view/items/element/binding/FileBinding.js","../src/view/items/element/binding/MultipleSelectBinding.js","../src/view/items/element/binding/NumericBinding.js","../src/view/items/element/binding/RadioBinding.js","../src/view/items/element/binding/RadioNameBinding.js","../src/view/items/element/binding/SingleSelectBinding.js","../src/view/items/Element.js","../src/view/items/element/specials/Form.js","../src/view/items/element/ElementEvents.js","../src/view/items/component/RactiveEvent.js","../src/view/items/shared/EventDirective.js","../src/view/items/shared/Mustache.js","../src/view/items/Interpolator.js","../src/view/items/element/specials/Input.js","../src/utils/parseJSON.js","../src/view/items/component/Mapping.js","../src/view/items/element/specials/Option.js","../src/utils/dom.js","../src/Ractive/prototype/observe/Observer.js","../src/Ractive/prototype/observe/Pattern.js","../src/Ractive/prototype/observe/Array.js","../src/Ractive/prototype/observeOnce.js","../src/Ractive/prototype/shared/trim.js","../src/Ractive/prototype/shared/notEmptyString.js","../src/Ractive/prototype/pop.js","../src/Ractive/prototype/push.js","../src/global/css.js","../src/Ractive/config/custom/adapt.js","../src/utils/cleanCss.js","../src/Ractive/config/custom/css/transform.js","../src/model/specials/CSSModel.js","../src/Ractive/config/custom/css/css.js","../src/Ractive/config/custom/data.js","../src/Ractive/config/custom/template.js","../src/Ractive/config/registries.js","../src/Ractive/config/config.js","../src/view/items/shared/Item.js","../src/model/ComputationChild.js","../src/model/Computation.js","../src/view/resolvers/ExpressionProxy.js","../src/view/resolvers/ReferenceExpressionProxy.js","../src/view/items/Alias.js","../src/view/helpers/specialAttrs.js","../src/view/items/element/attribute/getUpdateDelegate.js","../src/view/items/element/attribute/propertyNames.js","../src/view/items/element/ConditionalAttribute.js","../src/view/items/element/Attribute.js","../src/view/items/element/BindingFlag.js","../src/view/items/Comment.js","../src/model/specials/RactiveModel.js","../src/model/RootModel.js","../src/Ractive/construct.js","../src/view/items/Component.js","../src/model/ModelBase.js","../src/global/capture.js","../src/model/LinkModel.js","../src/shared/getFunction.js","../src/config/template.js","../src/parse/Parser.js","../src/config/types.js","../src/parse/converters/expressions/readTypeof.js","../src/parse/converters/mustache/readDelimiterChange.js","../src/parse/converters/expressions/primary/literal/readRegexpLiteral.js","../src/utils/escapeRegExp.js","../src/parse/converters/utils/getLowestIndex.js","../src/utils/html.js","../src/parse/converters/expressions/shared/errors.js","../src/parse/converters/expressions/primary/literal/readNumberLiteral.js","../src/parse/converters/expressions/primary/literal/stringLiteral/makeQuotedStringMatcher.js","../src/parse/converters/expressions/primary/literal/readStringLiteral.js","../src/parse/converters/expressions/primary/literal/readTemplateStringLiteral.js","../src/parse/converters/expressions/shared/patterns.js","../src/parse/converters/expressions/shared/readKey.js","../src/parse/converters/expressions/primary/readReference.js","../src/parse/converters/expressions/readLogicalOr.js","../src/parse/converters/element/readAttribute.js","../src/parse/converters/readMustache.js","../src/parse/converters/mustache/readAliases.js","../src/parse/converters/mustache/section/readInlineBlock.js","../src/parse/converters/mustache/handlebarsBlockCodes.js","../src/parse/converters/mustache/readSection.js","../src/parse/converters/readHtmlComment.js","../src/parse/utils/stripStandalones.js","../src/parse/utils/cleanup.js","../src/parse/converters/element/readClosingTag.js","../src/parse/converters/readElement.js","../src/parse/converters/readPartialDefinitionSection.js","../src/Ractive/shared.js","../src/parse/_parse.js","../src/Ractive/config/runtime-parser.js","../src/global/TransitionManager.js","../src/global/runloop.js","../src/shared/Ticker.js","../src/model/helpers/getPrefixer.js","../src/model/Model.js","../src/model/specials/SharedModel.js","../src/view/resolvers/resolveReference.js","../src/shared/getRactiveContext.js","../src/shared/set.js","../src/Ractive/prototype/shared/add.js","../src/Ractive/prototype/animate.js","../src/events/fireEvent.js","../src/events/Hook.js","../src/Ractive/prototype/shared/makeArrayMethod.js","../src/shared/Context.js","../src/Ractive/static/getContext.js","../src/config/namespaces.js","../src/Ractive/helpers/subscribe.js","../src/view/items/shared/directiveArgs.js","../src/view/items/element/binding/handleDomEvent.js","../src/utils/getSelectedOptions.js","../src/view/items/element/binding/selectBinding.js","../src/view/items/shared/progressiveText.js","../src/view/items/partial/getPartialTemplate.js","../src/view/items/component/getComponentConstructor.js","../src/view/items/asyncProxy.js","../src/view/items/Await.js","../src/view/helpers/processItems.js","../src/Ractive/initialise.js","../src/Ractive/render.js","../src/Ractive/prototype/render.js","../src/Ractive/prototype/resetPartial.js","../src/Ractive/prototype/resetTemplate.js","../src/Ractive/prototype/set.js","../src/Ractive/prototype/subtract.js","../src/Ractive/prototype/toggle.js","../src/Ractive/prototype/toCSS.js","../src/Ractive/prototype/toHTML.js","../src/Ractive/prototype/toText.js","../src/Ractive/prototype/transition.js","../src/Ractive/prototype/unlink.js","../src/Ractive/prototype/unrender.js","../src/Ractive/prototype/updateModel.js","../src/Ractive/prototype/use.js","../src/Ractive/static/isInstance.js","../src/Ractive/static/styleGet.js","../src/Ractive/static/sharedSet.js","../src/Ractive/static/sharedGet.js","../src/Ractive/static/use.js","../src/extend/_macro.js","../src/Ractive/static/keypaths.js","../src/Ractive/static/findPlugin.js","../src/polyfills/Object.assign.js","../src/utils/object.js","../src/utils/is.js","../src/polyfills/performance.now.js","../src/polyfills/array.find.js","../src/polyfills/node.contains.js","../src/polyfills/Promise.js","../src/polyfills/requestAnimationFrame.js","../src/Ractive/config/defaults.js","../src/utils/log.js","../src/Ractive/static/easing.js","../src/config/environment.js","../src/config/errors.js","../src/Ractive/static/interpolators.js","../src/shared/keypaths.js","../src/utils/bind.js","../src/Ractive/prototype/add.js","../src/events/eventStack.js","../src/shared/anchors.js","../src/Ractive/prototype/attachChild.js","../src/Ractive/prototype/compute.js","../src/Ractive/prototype/detach.js","../src/Ractive/prototype/detachChild.js","../src/Ractive/prototype/find.js","../src/Ractive/prototype/findAll.js","../src/Ractive/prototype/findAllComponents.js","../src/Ractive/prototype/findComponent.js","../src/Ractive/prototype/findContainer.js","../src/Ractive/prototype/findParent.js","../src/view/items/shared/findElement.js","../src/shared/getNewIndices.js","../src/Ractive/prototype/update.js","../src/Ractive/prototype/fire.js","../src/Ractive/prototype/get.js","../src/Ractive/prototype/getContext.js","../src/Ractive/prototype/insert.js","../src/Ractive/prototype/link.js","../src/Ractive/prototype/observe.js","../src/Ractive/prototype/off.js","../src/Ractive/prototype/on.js","../src/Ractive/prototype/once.js","../src/Ractive/prototype/readLink.js","../src/utils/id.js","../src/Ractive/static/styleSet.js","../src/Ractive/config/wrapPrototypeMethod.js","../src/Ractive/config/deprecate.js","../src/view/resolvers/resolve.js","../src/Ractive/prototype/teardown.js","../src/utils/noop.js","../src/shared/registry.js","../src/shared/interpolate.js","../src/utils/array.js","../src/shared/methodCallers.js","../src/shared/rebind.js","../src/parse/utils/createFunction.js","../src/parse/converters/expressions/primary/literal/readBooleanLiteral.js","../src/parse/converters/expressions/primary/literal/objectLiteral/keyValuePair.js","../src/parse/converters/expressions/primary/literal/objectLiteral/keyValuePairs.js","../src/parse/converters/expressions/primary/literal/readObjectLiteral.js","../src/parse/converters/expressions/primary/literal/readArrayLiteral.js","../src/parse/converters/expressions/primary/readLiteral.js","../src/parse/converters/expressions/primary/readBracketedExpression.js","../src/parse/converters/expressions/readPrimary.js","../src/parse/converters/expressions/shared/readRefinement.js","../src/parse/converters/expressions/readMemberOrInvocation.js","../src/parse/converters/expressions/readConditional.js","../src/parse/converters/readExpression.js","../src/parse/converters/expressions/shared/readExpressionList.js","../src/parse/converters/readExpressionOrReference.js","../src/parse/utils/flattenExpression.js","../src/parse/utils/refineExpression.js","../src/parse/converters/mustache/readTriple.js","../src/parse/converters/mustache/readUnescaped.js","../src/parse/converters/mustache/readPartial.js","../src/parse/converters/mustache/readMustacheComment.js","../src/parse/converters/mustache/readInterpolator.js","../src/parse/converters/mustache/section/readClosing.js","../src/parse/utils/trimWhitespace.js","../src/utils/hyphenateCamel.js","../src/parse/converters/readText.js","../src/parse/converters/readTemplate.js","../src/parse/utils/insertExpressions.js","../src/Ractive/helpers/getComputationSignature.js"],"sourcesContent":["import { ELEMENT, PARTIAL, SECTION, SECTION_WITH, YIELDER } from 'config/types';\nimport { assign, create, hasOwn, keys } from 'utils/object';\nimport { isArray, isFunction, isObjectType, isString } from 'utils/is';\nimport noop from 'utils/noop';\nimport { MustacheContainer } from './shared/Mustache';\nimport Fragment from '../Fragment';\nimport getPartialTemplate from './partial/getPartialTemplate';\nimport { resolveAliases } from './Alias';\nimport { warnOnceIfDebug, warnIfDebug } from 'utils/log';\nimport parser from 'src/Ractive/config/runtime-parser';\nimport runloop from 'src/global/runloop';\nimport { applyCSS } from 'src/global/css';\nimport { splitKeypath } from 'shared/keypaths';\n\nexport default function Partial(options) {\n MustacheContainer.call(this, options);\n\n const tpl = options.template;\n\n // yielder is a special form of partial that will later require special handling\n if (tpl.t === YIELDER) {\n this.yielder = 1;\n } else if (tpl.t === ELEMENT) {\n // this is a macro partial, complete with macro constructor\n // leaving this as an element will confuse up-template searches\n this.type = PARTIAL;\n this.macro = options.macro;\n }\n}\n\nconst proto = (Partial.prototype = create(MustacheContainer.prototype));\n\nassign(proto, {\n constructor: Partial,\n\n bind() {\n const template = this.template;\n\n if (this.yielder) {\n // the container is the instance that owns this node\n this.container = this.up.ractive;\n this.component = this.container.component;\n this.containerFragment = this.up;\n\n // normal component\n if (this.component) {\n // yields skip the owning instance and go straight to the surrounding context\n this.up = this.component.up;\n\n // {{yield}} is equivalent to {{yield content}}\n if (!template.r && !template.x && !template.tx) this.refName = 'content';\n } else {\n // plain-ish instance that may be attached to a parent later\n this.fragment = new Fragment({\n owner: this,\n template: []\n });\n this.fragment.bind();\n return;\n }\n }\n\n // this is a macro/super partial\n if (this.macro) {\n this.fn = this.macro;\n } else {\n // this is a plain partial or yielder\n if (!this.refName) this.refName = template.r;\n\n // if the refName exists as a partial, this is a plain old partial reference where no model binding will happen\n if (this.refName) {\n partialFromValue(this, this.refName);\n }\n\n // this is a dynamic/inline partial\n if (!this.partial && !this.fn) {\n MustacheContainer.prototype.bind.call(this);\n if (this.model) partialFromValue(this, this.model.get());\n }\n }\n\n if (!this.partial && !this.fn) {\n warnOnceIfDebug(`Could not find template for partial '${this.name}'`);\n }\n\n createFragment(this, this.partial || []);\n\n // macro/super partial\n if (this.fn) initMacro(this);\n\n this.fragment.bind();\n },\n\n bubble() {\n if (!this.dirty) {\n this.dirty = true;\n\n if (this.yielder) {\n this.containerFragment.bubble();\n } else {\n this.up.bubble();\n }\n }\n },\n\n findNextNode() {\n return (this.containerFragment || this.up).findNextNode(this);\n },\n\n handleChange() {\n this.dirtyTemplate = true;\n this.externalChange = true;\n this.bubble();\n },\n\n rebound(update) {\n const aliases = this.fragment && this.fragment.aliases;\n if (aliases) {\n for (const k in aliases) {\n if (aliases[k].rebound) aliases[k].rebound(update);\n else {\n aliases[k].unreference();\n aliases[k] = 0;\n }\n }\n if (this.template.z) {\n resolveAliases(this.template.z, this.containerFragment || this.up, aliases);\n }\n }\n if (this._attrs) {\n keys(this._attrs).forEach(k => this._attrs[k].rebound(update));\n }\n MustacheContainer.prototype.rebound.call(this, update);\n },\n\n refreshAttrs() {\n keys(this._attrs).forEach(k => {\n this.handle.attributes[k] = !this._attrs[k].items.length || this._attrs[k].valueOf();\n });\n },\n\n resetTemplate() {\n if (this.fn && this.proxy) {\n if (this.externalChange) {\n if (isFunction(this.proxy.teardown)) this.proxy.teardown();\n this.fn = this.proxy = null;\n } else {\n this.partial = this.fnTemplate;\n return true;\n }\n }\n\n const partial = this.partial;\n this.partial = null;\n\n if (this.refName) {\n this.partial = getPartialTemplate(this.ractive, this.refName, this.up);\n }\n\n if (!this.partial && this.model) {\n partialFromValue(this, this.model.get());\n }\n\n if (!this.fn && partial === this.partial) return false;\n\n this.unbindAttrs();\n\n if (this.fn) {\n initMacro(this);\n if (isFunction(this.proxy.render)) runloop.scheduleTask(() => this.proxy.render());\n } else if (!this.partial) {\n warnOnceIfDebug(`Could not find template for partial '${this.name}'`);\n }\n\n return true;\n },\n\n render(target, occupants) {\n if (this.fn && this.fn._cssDef && !this.fn._cssDef.applied) applyCSS();\n\n this.fragment.render(target, occupants);\n\n if (this.proxy && isFunction(this.proxy.render)) this.proxy.render();\n },\n\n unbind() {\n this.fragment.unbind();\n\n this.fragment.aliases = null;\n\n this.unbindAttrs();\n\n MustacheContainer.prototype.unbind.call(this);\n },\n\n unbindAttrs() {\n if (this._attrs) {\n keys(this._attrs).forEach(k => {\n this._attrs[k].unbind();\n });\n }\n },\n\n unrender(shouldDestroy) {\n if (this.proxy && isFunction(this.proxy.teardown)) this.proxy.teardown();\n\n this.fragment.unrender(shouldDestroy);\n },\n\n update() {\n const proxy = this.proxy;\n this.updating = 1;\n\n if (this.dirtyAttrs) {\n this.dirtyAttrs = false;\n keys(this._attrs).forEach(k => this._attrs[k].update());\n this.refreshAttrs();\n if (isFunction(proxy.update)) proxy.update(this.handle.attributes);\n }\n\n if (this.dirtyTemplate) {\n this.dirtyTemplate = false;\n this.resetTemplate() && this.fragment.resetTemplate(this.partial || []);\n }\n\n if (this.dirty) {\n this.dirty = false;\n if (proxy && isFunction(proxy.invalidate)) proxy.invalidate();\n this.fragment.update();\n }\n\n this.externalChange = false;\n this.updating = 0;\n }\n});\n\nfunction createFragment(self, partial) {\n self.partial = partial;\n contextifyTemplate(self);\n\n const options = {\n owner: self,\n template: self.partial\n };\n\n if (self.yielder) options.ractive = self.container.parent;\n\n if (self.fn) options.cssIds = self.fn._cssIds;\n\n const fragment = (self.fragment = new Fragment(options));\n\n // partials may have aliases that need to be in place before binding\n if (self.template.z) {\n fragment.aliases = resolveAliases(self.template.z, self.containerFragment || self.up);\n }\n}\n\nfunction contextifyTemplate(self) {\n if (self.template.c) {\n self.partial = [{ t: SECTION, n: SECTION_WITH, f: self.partial }];\n assign(self.partial[0], self.template.c);\n if (self.yielder) self.partial[0].y = self;\n }\n}\n\nfunction partialFromValue(self, value, okToParse) {\n let tpl = value;\n\n if (isArray(tpl)) {\n self.partial = tpl;\n } else if (tpl && isObjectType(tpl)) {\n if (isArray(tpl.t)) self.partial = tpl.t;\n else if (isString(tpl.template))\n self.partial = parsePartial(tpl.template, tpl.template, self.ractive).t;\n } else if (isFunction(tpl) && tpl.styleSet) {\n self.fn = tpl;\n if (self.fragment) self.fragment.cssIds = tpl._cssIds;\n } else if (tpl != null) {\n tpl = getPartialTemplate(self.ractive, '' + tpl, self.containerFragment || self.up);\n if (tpl) {\n self.name = value;\n if (tpl.styleSet) {\n self.fn = tpl;\n if (self.fragment) self.fragment.cssIds = tpl._cssIds;\n } else self.partial = tpl;\n } else if (okToParse) {\n self.partial = parsePartial('' + value, '' + value, self.ractive).t;\n } else {\n self.name = value;\n }\n }\n\n return self.partial;\n}\n\nfunction setTemplate(template) {\n partialFromValue(this, template, true);\n\n if (!this.initing) {\n this.dirtyTemplate = true;\n this.fnTemplate = this.partial;\n\n if (this.updating) {\n this.bubble();\n runloop.promise();\n } else {\n const promise = runloop.start();\n\n this.bubble();\n runloop.end();\n\n return promise;\n }\n }\n}\n\nfunction aliasLocal(ref, name) {\n const aliases = this.fragment.aliases || (this.fragment.aliases = {});\n if (!name) {\n aliases[ref] = this._data;\n } else {\n aliases[name] = this._data.joinAll(splitKeypath(ref));\n }\n}\n\nconst extras = 'extra-attributes';\n\nfunction initMacro(self) {\n const fn = self.fn;\n const fragment = self.fragment;\n\n // defensively copy the template in case it changes\n const template = (self.template = assign({}, self.template));\n const handle = (self.handle = fragment.getContext({\n proxy: self,\n aliasLocal,\n name: self.template.e || self.name,\n attributes: {},\n setTemplate: setTemplate.bind(self),\n template\n }));\n\n if (!template.p) template.p = {};\n template.p = handle.partials = assign({}, template.p);\n if (!hasOwn(template.p, 'content')) template.p.content = template.f || [];\n\n if (isArray(fn.attributes)) {\n self._attrs = {};\n\n const invalidate = function() {\n this.dirty = true;\n self.dirtyAttrs = true;\n self.bubble();\n };\n\n if (isArray(template.m)) {\n const attrs = template.m;\n template.p[extras] = template.m = attrs.filter(a => !~fn.attributes.indexOf(a.n));\n attrs.filter(a => ~fn.attributes.indexOf(a.n)).forEach(a => {\n const fragment = new Fragment({\n template: a.f,\n owner: self\n });\n fragment.bubble = invalidate;\n fragment.findFirstNode = noop;\n self._attrs[a.n] = fragment;\n });\n } else {\n template.p[extras] = [];\n }\n } else {\n template.p[extras] = template.m;\n }\n\n if (self._attrs) {\n keys(self._attrs).forEach(k => {\n self._attrs[k].bind();\n });\n self.refreshAttrs();\n }\n\n self.initing = 1;\n self.proxy = fn(handle, handle.attributes) || {};\n if (!self.partial) self.partial = [];\n self.fnTemplate = self.partial;\n self.initing = 0;\n\n contextifyTemplate(self);\n fragment.resetTemplate(self.partial);\n}\n\nfunction parsePartial(name, partial, ractive) {\n let parsed;\n\n try {\n parsed = parser.parse(partial, parser.getParseOptions(ractive));\n } catch (e) {\n warnIfDebug(`Could not parse partial from expression '${name}'\\n${e.message}`);\n }\n\n return parsed || { t: [] };\n}\n","import { addToArray, removeFromArray } from 'utils/array';\nimport { unescapeKey } from 'shared/keypaths';\nimport { capture } from 'src/global/capture';\nimport { handleChange } from 'src/shared/methodCallers';\nimport noop from 'utils/noop';\n\nexport default class KeyModel {\n constructor(value, context, instance) {\n this.value = this.key = value;\n this.context = context;\n this.isReadonly = this.isKey = true;\n this.deps = [];\n this.links = [];\n this.children = [];\n this.instance = instance;\n }\n\n applyValue(value) {\n if (value !== this.value) {\n this.value = this.key = value;\n this.deps.forEach(handleChange);\n this.links.forEach(handleChange);\n this.children.forEach(c => {\n c.applyValue(c.context.getKeypath(c.instance));\n });\n }\n }\n\n destroyed() {\n if (this.upstream) this.upstream.unregisterChild(this);\n }\n\n get(shouldCapture) {\n if (shouldCapture) capture(this);\n return unescapeKey(this.value);\n }\n\n getKeypath() {\n return unescapeKey(this.value);\n }\n\n has() {\n return false;\n }\n\n rebind(next, previous) {\n let i = this.deps.length;\n while (i--) this.deps[i].rebind(next, previous, false);\n\n i = this.links.length;\n while (i--) this.links[i].relinking(next, false);\n }\n\n register(dependant) {\n this.deps.push(dependant);\n }\n\n registerChild(child) {\n addToArray(this.children, child);\n child.upstream = this;\n }\n\n registerLink(link) {\n addToArray(this.links, link);\n }\n\n unregister(dependant) {\n removeFromArray(this.deps, dependant);\n }\n\n unregisterChild(child) {\n removeFromArray(this.children, child);\n }\n\n unregisterLink(link) {\n removeFromArray(this.links, link);\n }\n}\n\nKeyModel.prototype.reference = noop;\nKeyModel.prototype.unreference = noop;\n","import { createDocumentFragment } from 'utils/dom';\nimport { isArray, isObject, isObjectType } from 'utils/is';\nimport { findMap, buildNewIndices } from 'utils/array';\nimport { toEscapedString, toString, shuffled } from 'shared/methodCallers';\nimport Fragment, { getKeypath } from './Fragment';\nimport { ELEMENT } from 'config/types';\nimport { getContext } from 'shared/getRactiveContext';\nimport { keys } from 'utils/object';\nimport KeyModel from 'src/model/specials/KeyModel';\nimport { splitKeypath } from '../shared/keypaths';\nimport resolve from './resolvers/resolve';\n\nconst keypathString = /^\"(\\\\\"|[^\"])+\"$/;\n\nexport default class RepeatedFragment {\n constructor(options) {\n this.parent = options.owner.up;\n\n // bit of a hack, so reference resolution works without another\n // layer of indirection\n this.up = this;\n this.owner = options.owner;\n this.ractive = this.parent.ractive;\n this.delegate =\n this.ractive.delegate !== false && (this.parent.delegate || findDelegate(this.parent));\n // delegation disabled by directive\n if (this.delegate && this.delegate.delegate === false) this.delegate = false;\n // let the element know it's a delegate handler\n if (this.delegate) this.delegate.delegate = this.delegate;\n\n // encapsulated styles should be inherited until they get applied by an element\n this.cssIds = 'cssIds' in options ? options.cssIds : this.parent ? this.parent.cssIds : null;\n\n this.context = null;\n this.rendered = false;\n this.iterations = [];\n\n this.template = options.template;\n\n this.indexRef = options.indexRef;\n this.keyRef = options.keyRef;\n\n this.pendingNewIndices = null;\n this.previousIterations = null;\n\n // track array versus object so updates of type rest\n this.isArray = false;\n }\n\n bind(context) {\n this.context = context;\n this.bound = true;\n const value = context.get();\n\n const aliases = (this.aliases = this.owner.template.z && this.owner.template.z.slice());\n\n const shuffler = aliases && aliases.find(a => a.n === 'shuffle');\n if (shuffler && shuffler.x && shuffler.x.x) {\n if (shuffler.x.x.s === 'true') this.shuffler = true;\n else if (keypathString.test(shuffler.x.x.s))\n this.shuffler = splitKeypath(shuffler.x.x.s.slice(1, -1));\n }\n\n if (this.shuffler) this.values = shuffleValues(this, this.shuffler);\n\n if (this.source) this.source.model.unbind(this.source);\n const source = context.isComputed && aliases && aliases.find(a => a.n === 'source');\n if (source && source.x && source.x.r) {\n const model = resolve(this, source.x);\n this.source = {\n handleChange() {},\n rebind(next) {\n this.model.unregister(this);\n this.model = next;\n next.register(this);\n }\n };\n this.source.model = model;\n model.register(this.source);\n }\n\n // {{#each array}}...\n if ((this.isArray = isArray(value))) {\n // we can't use map, because of sparse arrays\n this.iterations = [];\n const max = (this.length = value.length);\n for (let i = 0; i < max; i += 1) {\n this.iterations[i] = this.createIteration(i, i);\n }\n } else if (isObject(value)) {\n // {{#each object}}...\n this.isArray = false;\n\n // TODO this is a dreadful hack. There must be a neater way\n if (this.indexRef) {\n const refs = this.indexRef.split(',');\n this.keyRef = refs[0];\n this.indexRef = refs[1];\n }\n\n const ks = keys(value);\n this.length = ks.length;\n\n this.iterations = ks.map((key, index) => {\n return this.createIteration(key, index);\n });\n }\n\n return this;\n }\n\n bubble(index) {\n if (!this.bubbled) this.bubbled = [];\n this.bubbled.push(index);\n\n if (!this.rebounding) this.owner.bubble();\n }\n\n createIteration(key, index) {\n const fragment = new Fragment({\n owner: this,\n template: this.template\n });\n\n fragment.isIteration = true;\n fragment.delegate = this.delegate;\n\n if (this.aliases) fragment.aliases = {};\n swizzleFragment(this, fragment, key, index);\n\n return fragment.bind(fragment.context);\n }\n\n destroyed() {\n const len = this.iterations.length;\n for (let i = 0; i < len; i++) this.iterations[i].destroyed();\n if (this.pathModel) this.pathModel.destroyed();\n if (this.rootModel) this.rootModel.destroyed();\n }\n\n detach() {\n const docFrag = createDocumentFragment();\n this.iterations.forEach(fragment => docFrag.appendChild(fragment.detach()));\n return docFrag;\n }\n\n find(selector, options) {\n return findMap(this.iterations, i => i.find(selector, options));\n }\n\n findAll(selector, options) {\n return this.iterations.forEach(i => i.findAll(selector, options));\n }\n\n findAllComponents(name, options) {\n return this.iterations.forEach(i => i.findAllComponents(name, options));\n }\n\n findComponent(name, options) {\n return findMap(this.iterations, i => i.findComponent(name, options));\n }\n\n findContext() {\n return this.context;\n }\n\n findNextNode(iteration) {\n if (iteration.index < this.iterations.length - 1) {\n for (let i = iteration.index + 1; i < this.iterations.length; i++) {\n const node = this.iterations[i].firstNode(true);\n if (node) return node;\n }\n }\n\n return this.owner.findNextNode();\n }\n\n firstNode(skipParent) {\n return this.iterations[0] ? this.iterations[0].firstNode(skipParent) : null;\n }\n\n getLast() {\n return this.lastModel || (this.lastModel = new KeyModel(this.length - 1));\n }\n\n rebind(next) {\n this.context = next;\n if (this.source) return;\n this.iterations.forEach(fragment => {\n swizzleFragment(this, fragment, fragment.key, fragment.index);\n });\n }\n\n rebound(update) {\n this.context = this.owner.model;\n this.iterations.forEach((f, i) => {\n f.context = contextFor(this, f, i);\n f.rebound(update);\n });\n }\n\n render(target, occupants) {\n const xs = this.iterations;\n if (xs) {\n const len = xs.length;\n for (let i = 0; i < len; i++) {\n xs[i].render(target, occupants);\n }\n }\n\n this.rendered = true;\n }\n\n shuffle(newIndices, merge) {\n if (!this.pendingNewIndices) this.previousIterations = this.iterations.slice();\n\n if (!this.pendingNewIndices) this.pendingNewIndices = [];\n\n this.pendingNewIndices.push(newIndices);\n\n const iterations = [];\n\n newIndices.forEach((newIndex, oldIndex) => {\n if (newIndex === -1) return;\n\n const fragment = this.iterations[oldIndex];\n iterations[newIndex] = fragment;\n\n if (newIndex !== oldIndex && fragment) {\n fragment.dirty = true;\n if (merge) fragment.shouldRebind = 1;\n }\n });\n\n this.iterations = iterations;\n\n // if merging, we're in the midst of an update already\n if (!merge) this.bubble();\n }\n\n shuffled() {\n this.iterations.forEach(shuffled);\n }\n\n toString(escape) {\n return this.iterations ? this.iterations.map(escape ? toEscapedString : toString).join('') : '';\n }\n\n unbind() {\n this.bound = false;\n if (this.source) this.source.model.unregister(this.source);\n const len = this.iterations.length;\n for (let i = 0; i < len; i++) this.iterations[i].unbind();\n return this;\n }\n\n unrender(shouldDestroy) {\n let len = this.iterations.length;\n for (let i = 0; i < len; i++) this.iterations[i].unrender(shouldDestroy);\n if (this.pendingNewIndices && this.previousIterations) {\n len = this.previousIterations.length;\n for (let i = 0; i < len; i++) this.previousIterations[i].unrender(shouldDestroy);\n }\n this.rendered = false;\n }\n\n update() {\n if (this.pendingNewIndices) {\n this.bubbled.length = 0;\n this.updatePostShuffle();\n return;\n }\n\n if (this.updating) return;\n this.updating = true;\n\n if (this.shuffler) {\n const values = shuffleValues(this, this.shuffler);\n this.shuffle(buildNewIndices(this.values, values), true);\n this.updatePostShuffle();\n } else {\n let len = this.iterations.length;\n for (let i = 0; i < len; i++) {\n const f = this.iterations[i];\n f && f.idxModel && f.idxModel.applyValue(i);\n }\n\n const value = this.context.get();\n const wasArray = this.isArray;\n\n let toRemove;\n let oldKeys;\n let reset = true;\n let i;\n\n if ((this.isArray = isArray(value))) {\n // if there's a source to map back to, make sure everything stays bound correctly\n if (this.source) {\n this.rebounding = 1;\n const source = this.source.model.get();\n this.iterations.forEach((f, c) => {\n if (c < value.length && f.lastValue !== value[c] && ~(i = source.indexOf(value[c]))) {\n swizzleFragment(this, f, c, c);\n f.rebound(true);\n }\n });\n this.rebounding = 0;\n }\n\n if (wasArray) {\n reset = false;\n if (this.iterations.length > value.length) {\n toRemove = this.iterations.splice(value.length);\n }\n }\n } else if (isObject(value) && !wasArray) {\n reset = false;\n toRemove = [];\n oldKeys = {};\n i = this.iterations.length;\n\n while (i--) {\n const fragment = this.iterations[i];\n if (fragment.key in value) {\n oldKeys[fragment.key] = true;\n } else {\n this.iterations.splice(i, 1);\n toRemove.push(fragment);\n }\n }\n }\n\n const newLength = isArray(value) ? value.length : isObject(value) ? keys(value).length : 0;\n this.length = newLength;\n this.updateLast();\n\n if (reset) {\n toRemove = this.iterations;\n this.iterations = [];\n }\n\n if (toRemove) {\n len = toRemove.length;\n for (let i = 0; i < len; i++) toRemove[i].unbind().unrender(true);\n }\n\n // update the remaining ones\n if (!reset && this.isArray && this.bubbled && this.bubbled.length) {\n const bubbled = this.bubbled;\n this.bubbled = [];\n len = bubbled.length;\n for (let i = 0; i < len; i++)\n this.iterations[bubbled[i]] && this.iterations[bubbled[i]].update();\n } else {\n len = this.iterations.length;\n for (let i = 0; i < len; i++) this.iterations[i].update();\n }\n\n // add new iterations\n let docFrag;\n let fragment;\n\n if (newLength > this.iterations.length) {\n docFrag = this.rendered ? createDocumentFragment() : null;\n i = this.iterations.length;\n\n if (isArray(value)) {\n while (i < value.length) {\n fragment = this.createIteration(i, i);\n\n this.iterations.push(fragment);\n if (this.rendered) fragment.render(docFrag);\n\n i += 1;\n }\n } else if (isObject(value)) {\n // TODO this is a dreadful hack. There must be a neater way\n if (this.indexRef && !this.keyRef) {\n const refs = this.indexRef.split(',');\n this.keyRef = refs[0];\n this.indexRef = refs[1];\n }\n\n keys(value).forEach(key => {\n if (!oldKeys || !(key in oldKeys)) {\n fragment = this.createIteration(key, i);\n\n this.iterations.push(fragment);\n if (this.rendered) fragment.render(docFrag);\n\n i += 1;\n }\n });\n }\n\n if (this.rendered) {\n const parentNode = this.parent.findParentNode();\n const anchor = this.parent.findNextNode(this.owner);\n\n parentNode.insertBefore(docFrag, anchor);\n }\n }\n }\n\n this.updating = false;\n }\n\n updateLast() {\n if (this.lastModel) this.lastModel.applyValue(this.length - 1);\n }\n\n updatePostShuffle() {\n const newIndices = this.pendingNewIndices[0];\n const parentNode = this.rendered ? this.parent.findParentNode() : null;\n const nextNode = parentNode && this.owner.findNextNode();\n const docFrag = parentNode ? createDocumentFragment() : null;\n\n // map first shuffle through\n this.pendingNewIndices.slice(1).forEach(indices => {\n newIndices.forEach((newIndex, oldIndex) => {\n newIndices[oldIndex] = indices[newIndex];\n });\n });\n\n const len = (this.length = this.context.get().length);\n const prev = this.previousIterations;\n const iters = this.iterations;\n const value = this.context.get();\n const stash = {};\n let idx, dest, pos, next, anchor, rebound;\n\n const map = new Array(newIndices.length);\n newIndices.forEach((e, i) => (map[e] = i));\n\n this.updateLast();\n\n idx = pos = 0;\n while (idx < len) {\n dest = newIndices[pos];\n next = null;\n rebound = false;\n\n if (dest === -1) {\n // drop it like it's hot\n prev[pos].unbind().unrender(true);\n prev[pos++] = 0;\n } else if (dest > idx) {\n // need to stash or pull one up\n next = newIndices[pos + 1]; // TODO: maybe a shouldMove function that tracks multiple entries?\n if (next <= dest) {\n stash[dest] = prev[pos];\n prev[pos++] = null;\n } else {\n next = stash[idx] || prev[map[idx]];\n prev[map[idx]] = null;\n anchor = prev[nextRendered(pos, newIndices, prev)];\n anchor = (anchor && parentNode && anchor.firstNode()) || nextNode;\n\n if (next) {\n rebound = this.source && next.lastValue !== value[idx];\n swizzleFragment(this, next, idx, idx);\n if (parentNode) parentNode.insertBefore(next.detach(), anchor);\n } else {\n next = iters[idx] = this.createIteration(idx, idx);\n if (parentNode) {\n next.render(docFrag);\n parentNode.insertBefore(docFrag, anchor);\n }\n }\n\n idx++;\n }\n } else {\n // all is well\n next = iters[idx];\n anchor = prev[nextRendered(pos, newIndices, prev)];\n anchor = (anchor && parentNode && anchor.firstNode()) || nextNode;\n if (!next) {\n next = iters[idx] = this.createIteration(idx, idx);\n if (parentNode) {\n next.render(docFrag);\n parentNode.insertBefore(docFrag, anchor);\n }\n } else if (pos !== idx || stash[idx]) {\n rebound = this.source && next.lastValue !== value[idx];\n swizzleFragment(this, next, idx, idx);\n if (stash[idx] && parentNode) parentNode.insertBefore(next.detach(), anchor);\n }\n\n idx++;\n prev[pos++] = null;\n }\n\n if (next && isObjectType(next)) {\n if (next.shouldRebind || rebound) {\n next.rebound(rebound);\n next.shouldRebind = 0;\n }\n next.update();\n next.shuffled();\n }\n }\n\n // clean up any stragglers\n const plen = prev.length;\n for (let i = 0; i < plen; i++) prev[i] && prev[i].unbind().unrender(true);\n\n if (this.shuffler) this.values = shuffleValues(this, this.shuffler);\n\n this.pendingNewIndices = null;\n this.previousIterations = null;\n }\n}\n\nRepeatedFragment.prototype.getContext = getContext;\nRepeatedFragment.prototype.getKeypath = getKeypath;\n\n// find the topmost delegate\nfunction findDelegate(start) {\n let frag = start;\n let delegate, el;\n\n out: while (frag) {\n // find next element\n el = 0;\n while (!el && frag) {\n if (frag.owner.type === ELEMENT) el = frag.owner;\n if (frag.owner.ractive && frag.owner.ractive.delegate === false) break out;\n frag = frag.parent || frag.componentParent;\n }\n\n if (el.delegate === false) break out;\n delegate = el.delegate || el;\n\n // find next repeated fragment\n while (frag) {\n if (frag.iterations) break;\n if (frag.owner.ractive && frag.owner.ractive.delegate === false) break out;\n frag = frag.parent || frag.componentParent;\n }\n }\n\n return delegate;\n}\n\nfunction nextRendered(start, newIndices, frags) {\n const len = newIndices.length;\n for (let i = start; i < len; i++) {\n if (~newIndices[i] && frags[i] && frags[i].rendered) return i;\n }\n}\n\nfunction swizzleFragment(section, fragment, key, idx) {\n const model = section.context ? contextFor(section, fragment, key) : undefined;\n\n fragment.key = key;\n fragment.index = idx;\n fragment.context = model;\n if (section.source) fragment.lastValue = model && model.get();\n\n if (fragment.idxModel) fragment.idxModel.applyValue(idx);\n if (fragment.keyModel) fragment.keyModel.applyValue(key);\n if (fragment.pathModel) {\n fragment.pathModel.context = model;\n fragment.pathModel.applyValue(model.getKeypath());\n }\n if (fragment.rootModel) {\n fragment.rootModel.context = model;\n fragment.rootModel.applyValue(model.getKeypath(fragment.ractive.root));\n }\n\n // handle any aliases\n const aliases = fragment.aliases;\n section.aliases &&\n section.aliases.forEach(a => {\n if (a.x.r === '.') aliases[a.n] = model;\n else if (a.x.r === '@index') aliases[a.n] = fragment.getIndex();\n else if (a.x.r === '@key') aliases[a.n] = fragment.getKey();\n else if (a.x.r === '@keypath') aliases[a.n] = fragment.getKeypath();\n else if (a.x.r === '@rootpath') aliases[a.n] = fragment.getKeypath(true);\n });\n}\n\nfunction shuffleValues(section, shuffler) {\n if (shuffler === true) {\n return section.context.get().slice();\n } else {\n return section.context.get().map(v => shuffler.reduce((a, c) => a && a[c], v));\n }\n}\n\nfunction contextFor(section, fragment, key) {\n if (section.source) {\n let idx;\n const source = section.source.model.get();\n if (source.indexOf && ~(idx = source.indexOf(section.context.joinKey(key).get())))\n return section.source.model.joinKey(idx);\n }\n\n return section.context.joinKey(key);\n}\n","import {\n SECTION_EACH,\n SECTION_IF,\n SECTION_IF_WITH,\n SECTION_UNLESS,\n SECTION_WITH\n} from 'config/types';\nimport { createDocumentFragment } from 'utils/dom';\nimport { isArray, isObject, isObjectLike } from 'utils/is';\nimport { keep } from 'shared/set';\nimport runloop from 'src/global/runloop';\nimport Fragment from '../Fragment';\nimport RepeatedFragment from '../RepeatedFragment';\nimport { MustacheContainer } from './shared/Mustache';\nimport { keys } from 'utils/object';\n\nfunction isEmpty(value) {\n return (\n !value ||\n (isArray(value) && value.length === 0) ||\n (isObject(value) && keys(value).length === 0)\n );\n}\n\nfunction getType(value, hasIndexRef) {\n if (hasIndexRef || isArray(value)) return SECTION_EACH;\n if (isObjectLike(value)) return SECTION_IF_WITH;\n if (value === undefined) return null;\n return SECTION_IF;\n}\n\nexport default class Section extends MustacheContainer {\n constructor(options) {\n super(options);\n\n this.sectionType = options.template.n || null;\n this.templateSectionType = this.sectionType;\n this.subordinate = options.template.l === 1;\n this.fragment = null;\n }\n\n bind() {\n super.bind();\n\n if (this.subordinate) {\n this.sibling = this.up.items[this.up.items.indexOf(this) - 1];\n this.sibling.nextSibling = this;\n }\n\n // if we managed to bind, we need to create children\n if (this.model) {\n this.dirty = true;\n this.update();\n } else if (\n this.sectionType &&\n this.sectionType === SECTION_UNLESS &&\n (!this.sibling || !this.sibling.isTruthy())\n ) {\n this.fragment = new Fragment({\n owner: this,\n template: this.template.f\n }).bind();\n }\n }\n\n detach() {\n const frag = this.fragment || this.detached;\n return frag ? frag.detach() : super.detach();\n }\n\n isTruthy() {\n if (this.subordinate && this.sibling.isTruthy()) return true;\n const value = !this.model ? undefined : this.model.isRoot ? this.model.value : this.model.get();\n return !!value && (this.templateSectionType === SECTION_IF_WITH || !isEmpty(value));\n }\n\n rebind(next, previous, safe) {\n if (super.rebind(next, previous, safe)) {\n if (this.fragment && this.sectionType !== SECTION_IF && this.sectionType !== SECTION_UNLESS) {\n this.fragment.rebind(next);\n }\n }\n }\n\n rebound(update) {\n if (this.model) {\n if (this.model.rebound) this.model.rebound(update);\n else {\n super.unbind();\n super.bind();\n if (\n this.sectionType === SECTION_WITH ||\n this.sectionType === SECTION_IF_WITH ||\n this.sectionType === SECTION_EACH\n ) {\n if (this.fragment) this.fragment.rebind(this.model);\n }\n\n if (update) this.bubble();\n }\n }\n if (this.fragment) this.fragment.rebound(update);\n }\n\n render(target, occupants) {\n this.rendered = true;\n if (this.fragment) this.fragment.render(target, occupants);\n }\n\n shuffle(newIndices) {\n if (this.fragment && this.sectionType === SECTION_EACH) {\n this.fragment.shuffle(newIndices);\n }\n }\n\n unbind() {\n super.unbind();\n if (this.fragment) this.fragment.unbind();\n }\n\n unrender(shouldDestroy) {\n if (this.rendered && this.fragment) this.fragment.unrender(shouldDestroy);\n this.rendered = false;\n }\n\n update() {\n if (!this.dirty) return;\n\n if (this.fragment && this.sectionType !== SECTION_IF && this.sectionType !== SECTION_UNLESS) {\n this.fragment.context = this.model;\n }\n\n if (!this.model && this.sectionType !== SECTION_UNLESS) return;\n\n this.dirty = false;\n\n const value = !this.model ? undefined : this.model.isRoot ? this.model.value : this.model.get();\n const siblingFalsey = !this.subordinate || !this.sibling.isTruthy();\n const lastType = this.sectionType;\n\n // watch for switching section types\n if (this.sectionType === null || this.templateSectionType === null)\n this.sectionType = getType(value, this.template.i);\n if (lastType && lastType !== this.sectionType && this.fragment) {\n if (this.rendered) {\n this.fragment.unbind().unrender(true);\n }\n\n this.fragment = null;\n }\n\n let newFragment;\n\n const fragmentShouldExist =\n this.sectionType === SECTION_EACH || // each always gets a fragment, which may have no iterations\n this.sectionType === SECTION_WITH || // with (partial context) always gets a fragment\n (siblingFalsey && (this.sectionType === SECTION_UNLESS ? !this.isTruthy() : this.isTruthy())); // if, unless, and if-with depend on siblings and the condition\n\n if (fragmentShouldExist) {\n if (!this.fragment) this.fragment = this.detached;\n\n if (this.fragment) {\n // check for detached fragment\n if (this.detached) {\n attach(this, this.fragment);\n this.detached = false;\n this.rendered = true;\n }\n\n if (!this.fragment.bound) this.fragment.bind(this.model);\n this.fragment.update();\n } else {\n if (this.sectionType === SECTION_EACH) {\n newFragment = new RepeatedFragment({\n owner: this,\n template: this.template.f,\n indexRef: this.template.i\n }).bind(this.model);\n } else {\n // only with and if-with provide context - if and unless do not\n const context =\n this.sectionType !== SECTION_IF && this.sectionType !== SECTION_UNLESS\n ? this.model\n : null;\n newFragment = new Fragment({\n owner: this,\n template: this.template.f\n }).bind(context);\n }\n }\n } else {\n if (this.fragment && this.rendered) {\n if (keep !== true) {\n this.fragment.unbind().unrender(true);\n } else {\n this.unrender(false);\n this.detached = this.fragment;\n runloop.promise().then(() => {\n if (this.detached) this.detach();\n });\n }\n } else if (this.fragment) {\n this.fragment.unbind();\n }\n\n this.fragment = null;\n }\n\n if (newFragment) {\n if (this.rendered) {\n attach(this, newFragment);\n }\n\n this.fragment = newFragment;\n }\n\n if (this.nextSibling) {\n this.nextSibling.dirty = true;\n this.nextSibling.update();\n }\n }\n}\n\nfunction attach(section, fragment) {\n const anchor = section.up.findNextNode(section);\n\n if (anchor) {\n const docFrag = createDocumentFragment();\n fragment.render(docFrag);\n\n anchor.parentNode.insertBefore(docFrag, anchor);\n } else {\n fragment.render(section.up.findParentNode());\n }\n}\n","import { toArray } from 'utils/array';\nimport getSelectedOptions from 'utils/getSelectedOptions';\nimport Element from '../../Element';\nimport { isArray, isFunction } from 'utils/is';\n\nexport default class Select extends Element {\n constructor(options) {\n super(options);\n this.options = [];\n }\n\n foundNode(node) {\n if (this.binding) {\n const selectedOptions = getSelectedOptions(node);\n\n if (selectedOptions.length > 0) {\n this.selectedOptions = selectedOptions;\n }\n }\n }\n\n render(target, occupants) {\n super.render(target, occupants);\n this.sync();\n\n const node = this.node;\n\n let i = node.options.length;\n while (i--) {\n node.options[i].defaultSelected = node.options[i].selected;\n }\n\n this.rendered = true;\n }\n\n sync() {\n const selectNode = this.node;\n\n if (!selectNode) return;\n\n const options = toArray(selectNode.options);\n\n if (this.selectedOptions) {\n options.forEach(o => {\n if (this.selectedOptions.indexOf(o) >= 0) o.selected = true;\n else o.selected = false;\n });\n this.binding.setFromNode(selectNode);\n delete this.selectedOptions;\n return;\n }\n\n const selectValue = this.getAttribute('value');\n const isMultiple = this.getAttribute('multiple');\n const array = isMultiple && isArray(selectValue);\n\n // If the ', '']\n };\n}\n\nexport default function(html, node) {\n const nodes = [];\n\n // render 0 and false\n if (html == null || html === '') return nodes;\n\n let container;\n let wrapper;\n let selectedOption;\n\n /* istanbul ignore if */\n if (ieBug && (wrapper = ieBlacklist[node.tagName])) {\n container = element('DIV');\n container.innerHTML = wrapper[0] + html + wrapper[1];\n container = container.querySelector('.x');\n\n if (container.tagName === 'SELECT') {\n selectedOption = container.options[container.selectedIndex];\n }\n } else if (node.namespaceURI === svg) {\n container = element('DIV');\n container.innerHTML = '' + html + '';\n container = container.querySelector('.x');\n } else if (node.tagName === 'TEXTAREA') {\n container = createElement('div');\n\n if (typeof container.textContent !== 'undefined') {\n container.textContent = html;\n } else {\n container.innerHTML = html;\n }\n } else {\n container = element(node.tagName);\n container.innerHTML = html;\n\n if (container.tagName === 'SELECT') {\n selectedOption = container.options[container.selectedIndex];\n }\n }\n\n let child;\n while ((child = container.firstChild)) {\n nodes.push(child);\n container.removeChild(child);\n }\n\n // This is really annoying. Extracting