{"version":3,"file":"localize.dea4189a.js","sources":["node_modules/hybrids/src/global.js","node_modules/hybrids/src/emitter.js","node_modules/hybrids/src/cache.js","node_modules/hybrids/src/utils.js","node_modules/hybrids/src/define.js","node_modules/hybrids/src/store.js","node_modules/hybrids/src/template/utils.js","node_modules/hybrids/src/template/layout.js","node_modules/hybrids/src/template/resolvers/array.js","node_modules/hybrids/src/template/resolvers/value.js","node_modules/hybrids/src/template/resolvers/node.js","node_modules/hybrids/src/template/resolvers/event.js","node_modules/hybrids/src/template/resolvers/class.js","node_modules/hybrids/src/template/resolvers/style.js","node_modules/hybrids/src/template/resolvers/property.js","node_modules/hybrids/src/template/core.js","node_modules/hybrids/src/localize.js","node_modules/hybrids/src/template/helpers.js","node_modules/hybrids/src/template/index.js"],"sourcesContent":["/* eslint-disable no-undef */\n\nexport function polyfill(global) {\n global = Object.create(global);\n\n if (!(\"requestAnimationFrame\" in global)) {\n Object.defineProperty(global, \"requestAnimationFrame\", {\n value: function requestAnimationFrame(callback) {\n return setTimeout(callback, 0);\n },\n });\n }\n\n if (!(\"HTMLElement\" in global)) {\n Object.defineProperty(global, \"HTMLElement\", {\n value: class HTMLElement {\n constructor() {\n throw Error(\n \"Current context does not support defining custom elements\",\n );\n }\n },\n });\n }\n\n if (!(\"document\" in global)) {\n Object.defineProperty(global, \"document\", {\n value: {\n importNode: () => {\n throw Error(\"Current context does not support importing nodes\");\n },\n },\n });\n }\n\n return global;\n}\n\n/* istanbul ignore next */\nexport default typeof window === \"object\" ? window : polyfill(globalThis);\n","import global from \"./global.js\";\n\nconst callbacks = new WeakMap();\nconst queue = new Set();\n\nfunction execute() {\n try {\n queue.forEach((target) => {\n try {\n callbacks.get(target)();\n queue.delete(target);\n } catch (e) {\n queue.delete(target);\n throw e;\n }\n });\n } catch (e) {\n if (queue.size) execute();\n throw e;\n }\n}\n\nexport function dispatch(target) {\n if (callbacks.has(target)) {\n if (!queue.size) {\n global.requestAnimationFrame(execute);\n }\n queue.add(target);\n }\n}\n\nexport function subscribe(target, cb) {\n callbacks.set(target, cb);\n dispatch(target);\n\n return function unsubscribe() {\n queue.delete(target);\n callbacks.delete(target);\n };\n}\n","import global from \"./global.js\";\nimport * as emitter from \"./emitter.js\";\n\nconst entries = new WeakMap();\nconst suspense = new WeakSet();\n\nexport function getEntry(target, key) {\n let targetMap = entries.get(target);\n if (!targetMap) {\n targetMap = new Map();\n entries.set(target, targetMap);\n }\n\n let entry = targetMap.get(key);\n\n if (!entry) {\n entry = {\n target,\n key,\n value: undefined,\n lastValue: undefined,\n contexts: new Set(),\n deps: new Set(),\n state: 0,\n depState: 0,\n resolved: false,\n };\n targetMap.set(key, entry);\n }\n\n return entry;\n}\n\nexport function getEntries(target) {\n const result = [];\n const targetMap = entries.get(target);\n if (targetMap) {\n targetMap.forEach((entry) => {\n result.push(entry);\n });\n }\n return result;\n}\n\nfunction cleanContexts(entry) {\n entry.contexts.forEach((contextEntry) => {\n if (suspense.has(contextEntry.target)) {\n Object.assign(contextEntry, {\n depState: 0,\n resolved: false,\n });\n\n entry.contexts.delete(contextEntry);\n\n cleanContexts(contextEntry);\n }\n });\n}\n\nfunction dispatchDeep(entry) {\n entry.resolved = false;\n\n if (!suspense.has(entry.target)) {\n emitter.dispatch(entry);\n }\n\n cleanContexts(entry);\n entry.contexts.forEach(dispatchDeep);\n}\n\nlet context = null;\nconst contexts = new Set();\nexport function get(target, key, getter) {\n const entry = getEntry(target, key);\n\n if (context && !suspense.has(context.target)) {\n context.deps.add(entry);\n entry.contexts.add(context);\n }\n\n if (!suspense.has(target)) {\n cleanContexts(entry);\n\n if (entry.resolved) {\n return entry.value;\n }\n\n if (entry.depState > entry.state) {\n let depState = entry.state;\n\n for (const depEntry of entry.deps) {\n // eslint-disable-next-line no-unused-expressions\n depEntry.target[depEntry.key];\n\n if (!depEntry.resolved) {\n depState = false;\n break;\n }\n\n depState += depEntry.state;\n }\n\n if (depState && depState === entry.depState) {\n entry.resolved = true;\n return entry.value;\n }\n }\n }\n\n const lastContext = context;\n\n try {\n if (contexts.has(entry)) {\n throw Error(`Circular get invocation is forbidden: '${key}'`);\n }\n\n entry.deps.forEach((depEntry) => {\n depEntry.contexts.delete(entry);\n });\n\n entry.deps.clear();\n context = entry;\n contexts.add(entry);\n\n const nextValue = getter(target, entry.value);\n\n context = lastContext;\n\n if (nextValue !== entry.value) {\n entry.value = nextValue;\n entry.state += 1;\n }\n\n let depState = entry.state;\n entry.deps.forEach((depEntry) => {\n depState += depEntry.state;\n });\n\n entry.depState = depState;\n entry.resolved = !suspense.has(target);\n\n contexts.delete(entry);\n } catch (e) {\n context = lastContext;\n contexts.delete(entry);\n\n entry.resolved = false;\n\n if (context && !suspense.has(context)) {\n context.deps.delete(entry);\n entry.contexts.delete(context);\n }\n\n throw e;\n }\n\n return entry.value;\n}\n\nexport function set(target, key, setter, value) {\n const entry = getEntry(target, key);\n const newValue = setter(target, value, entry.value);\n\n if (newValue !== entry.value) {\n entry.value = newValue;\n entry.state += 1;\n entry.depState = 0;\n\n dispatchDeep(entry);\n }\n}\n\nconst gcList = new Set();\nfunction deleteEntry(entry) {\n if (!gcList.size) {\n global.requestAnimationFrame(() => {\n gcList.forEach((e) => {\n if (e.contexts.size === 0) {\n e.deps.forEach((depEntry) => {\n depEntry.contexts.delete(e);\n });\n\n const targetMap = entries.get(e.target);\n targetMap.delete(e.key);\n }\n });\n gcList.clear();\n });\n }\n\n gcList.add(entry);\n}\n\nfunction invalidateEntry(entry, options) {\n entry.depState = 0;\n dispatchDeep(entry);\n\n if (options.clearValue) {\n entry.value = undefined;\n entry.lastValue = undefined;\n }\n\n if (options.deleteEntry) {\n deleteEntry(entry);\n }\n\n if (options.force) {\n entry.state += 1;\n }\n}\n\nexport function invalidate(target, key, options = {}) {\n if (contexts.size) {\n throw Error(\n `Invalidating property in chain of get calls is forbidden: '${key}'`,\n );\n }\n\n const entry = getEntry(target, key);\n invalidateEntry(entry, options);\n}\n\nexport function invalidateAll(target, options = {}) {\n if (contexts.size) {\n throw Error(\n \"Invalidating all properties in chain of get calls is forbidden\",\n );\n }\n\n const targetMap = entries.get(target);\n if (targetMap) {\n targetMap.forEach((entry) => {\n invalidateEntry(entry, options);\n });\n }\n}\n\nexport function observe(target, key, getter, fn) {\n const entry = getEntry(target, key);\n\n return emitter.subscribe(entry, () => {\n const value = get(target, key, getter);\n\n if (value !== entry.lastValue) {\n fn(target, value, entry.lastValue);\n entry.lastValue = value;\n }\n });\n}\n\nexport function suspend(target) {\n suspense.add(target);\n}\n\nexport function unsuspend(target) {\n suspense.delete(target);\n}\n","import global from \"./global.js\";\n\nconst camelToDashMap = new Map();\nexport function camelToDash(str) {\n let result = camelToDashMap.get(str);\n if (result === undefined) {\n result = str.replace(/([a-z])([A-Z])/g, \"$1-$2\").toLowerCase();\n camelToDashMap.set(str, result);\n }\n return result;\n}\n\nexport function dispatch(host, eventType, options = {}) {\n return host.dispatchEvent(\n new global.CustomEvent(eventType, { bubbles: false, ...options }),\n );\n}\n\nexport function stringifyElement(target) {\n return `<${String(target.tagName).toLowerCase()}>`;\n}\n\nexport function walkInShadow(target, cb) {\n if (target.nodeType === global.Node.ELEMENT_NODE) {\n cb(target);\n\n if (target.shadowRoot) {\n walkInShadow(target.shadowRoot, cb);\n }\n }\n\n const walker = global.document.createTreeWalker(\n target,\n global.NodeFilter.SHOW_ELEMENT,\n null,\n false,\n );\n\n while (walker.nextNode()) {\n const el = walker.currentNode;\n cb(el);\n if (el.shadowRoot) {\n walkInShadow(el.shadowRoot, cb);\n }\n }\n}\n\nexport const deferred = Promise.resolve();\nexport const storePointer = new WeakMap();\nexport const probablyDevMode = walkInShadow.name === \"walkInShadow\";\n","import global from \"./global.js\";\nimport * as cache from \"./cache.js\";\nimport { deferred, camelToDash, walkInShadow } from \"./utils.js\";\n\nconst propsMap = new WeakMap();\nconst disconnects = new WeakMap();\n\nexport const callbacksMap = new WeakMap();\n\nclass HybridsRootElement extends global.HTMLElement {\n constructor() {\n super();\n\n const props = propsMap.get(this.constructor);\n\n for (let index = 0; index < props.length; index += 1) {\n const key = props[index];\n if (hasOwnProperty.call(this, key)) {\n const value = this[key];\n delete this[key];\n this[key] = value;\n }\n }\n\n cache.suspend(this);\n }\n\n connectedCallback() {\n cache.unsuspend(this);\n\n const callbacks = callbacksMap.get(this.constructor);\n const list = [];\n\n for (let index = 0; index < callbacks.length; index += 1) {\n const cb = callbacks[index](this);\n if (cb) list.push(cb);\n }\n\n disconnects.set(this, list);\n }\n\n disconnectedCallback() {\n cache.suspend(this);\n\n const list = disconnects.get(this);\n for (let index = 0; index < list.length; index += 1) {\n list[index]();\n }\n }\n}\n\nfunction render(fn, useShadow) {\n return {\n get: useShadow\n ? (host) => {\n const updateDOM = fn(host);\n const target =\n host.shadowRoot ||\n host.attachShadow({\n mode: \"open\",\n delegatesFocus: fn.delegatesFocus || false,\n });\n return () => {\n updateDOM(host, target);\n return target;\n };\n }\n : (host) => {\n const updateDOM = fn(host);\n return () => {\n updateDOM(host, host);\n return host;\n };\n },\n observe(host, flush) { flush(); }, // prettier-ignore\n };\n}\n\nconst transforms = {\n string: String,\n number: Number,\n boolean: Boolean,\n undefined: (v) => v,\n};\n\nfunction property(key, desc) {\n const type = typeof desc.value;\n const transform = transforms[type];\n\n if (!transform) {\n throw TypeError(\n `Invalid default value for '${key}' property - it must be a string, number, boolean or undefined: ${type}`,\n );\n }\n\n const defaultValue = desc.value;\n const attrName = camelToDash(key);\n\n const setAttr = (host, value) => {\n if (\n (!value && value !== 0) ||\n (typeof value === \"object\" && value.toString() === undefined)\n ) {\n host.removeAttribute(attrName);\n } else {\n host.setAttribute(attrName, type === \"boolean\" ? \"\" : value);\n }\n return value;\n };\n\n return {\n get: (host, value) => {\n if (value === undefined) {\n if (host.hasAttribute(attrName)) {\n value = transform(type === \"boolean\" || host.getAttribute(attrName));\n } else {\n return defaultValue;\n }\n }\n return value;\n },\n set:\n type !== \"undefined\"\n ? (host, value) => setAttr(host, transform(value))\n : (host, value) => value,\n connect:\n type !== \"undefined\"\n ? (host, _, invalidate) => {\n if (!host.hasAttribute(attrName) && host[key] === defaultValue) {\n setAttr(host, defaultValue);\n }\n\n return desc.connect && desc.connect(host, _, invalidate);\n }\n : desc.connect,\n observe: desc.observe,\n };\n}\n\nfunction compile(hybrids, HybridsElement) {\n if (HybridsElement) {\n if (hybrids === HybridsElement.hybrids) return HybridsElement;\n propsMap.get(HybridsElement).forEach((key) => {\n delete HybridsElement.prototype[key];\n });\n } else {\n HybridsElement = class extends HybridsRootElement {};\n }\n\n HybridsElement.hybrids = hybrids;\n\n const callbacks = [];\n const props = Object.keys(hybrids);\n\n callbacksMap.set(HybridsElement, callbacks);\n propsMap.set(HybridsElement, props);\n\n props.forEach((key) => {\n if (key === \"tag\") return;\n\n let desc = hybrids[key];\n const type = typeof desc;\n\n if (type === \"function\") {\n if (key === \"render\") {\n desc = render(desc, true);\n } else if (key === \"content\") {\n desc = render(desc);\n } else {\n desc = { get: desc };\n }\n } else if (type !== \"object\" || desc === null) {\n desc = { value: desc };\n } else if (desc.set) {\n const attrName = camelToDash(key);\n const get = desc.get || ((host, value) => value);\n desc.get = (host, value) => {\n if (value === undefined) {\n value = desc.set(host, host.getAttribute(attrName) || value);\n }\n return get(host, value);\n };\n }\n\n if (hasOwnProperty.call(desc, \"value\")) {\n desc = property(key, desc);\n } else if (!desc.get) {\n throw TypeError(\n `Invalid descriptor for '${key}' property - it must contain 'value' or 'get' option`,\n );\n }\n\n Object.defineProperty(HybridsElement.prototype, key, {\n get: function get() {\n return cache.get(this, key, desc.get);\n },\n set:\n desc.set &&\n function set(newValue) {\n cache.set(this, key, desc.set, newValue);\n },\n enumerable: true,\n configurable: true,\n });\n\n if (desc.observe) {\n callbacks.unshift((host) =>\n cache.observe(host, key, desc.get, desc.observe),\n );\n }\n\n if (desc.connect) {\n callbacks.push((host) => {\n function invalidate(options) {\n cache.invalidate(host, key, {\n force: typeof options === \"object\" && options.force === true,\n });\n }\n return desc.connect(host, key, invalidate);\n });\n }\n });\n\n return HybridsElement;\n}\n\nconst updateQueue = new Map();\nfunction update(HybridsElement) {\n if (!updateQueue.size) {\n deferred.then(() => {\n walkInShadow(global.document.body, (node) => {\n if (updateQueue.has(node.constructor)) {\n const prevHybrids = updateQueue.get(node.constructor);\n const hybrids = node.constructor.hybrids;\n node.disconnectedCallback();\n\n Object.keys(hybrids).forEach((key) => {\n const type = typeof hybrids[key];\n const clearValue =\n type !== \"object\" &&\n type !== \"function\" &&\n hybrids[key] !== prevHybrids[key];\n cache.invalidate(node, key, { clearValue });\n });\n\n node.connectedCallback();\n }\n });\n updateQueue.clear();\n });\n }\n updateQueue.set(HybridsElement, HybridsElement.hybrids);\n}\n\nfunction define(hybrids) {\n if (!hybrids.tag) {\n throw TypeError(\n \"Error while defining hybrids: 'tag' property with dashed tag name is required\",\n );\n }\n\n const HybridsElement = global.customElements.get(hybrids.tag);\n\n if (HybridsElement) {\n if (HybridsElement.hybrids) {\n update(HybridsElement);\n compile(hybrids, HybridsElement);\n\n return Object.freeze(hybrids);\n }\n\n throw TypeError(\n `Custom element with '${hybrids.tag}' tag name already defined outside of the hybrids context`,\n );\n }\n\n global.customElements.define(hybrids.tag, compile(hybrids));\n return Object.freeze(hybrids);\n}\n\nexport default Object.freeze(\n Object.assign(define, { compile: (hybrids) => compile(hybrids) }),\n);\n","/* eslint-disable no-use-before-define */\nimport global from \"./global.js\";\nimport * as cache from \"./cache.js\";\nimport { storePointer } from \"./utils.js\";\n\nconst connect = Symbol(\"store.connect\");\n\nconst definitions = new WeakMap();\nconst stales = new WeakMap();\nconst refs = new WeakSet();\n\nfunction resolve(config, model, lastModel) {\n if (lastModel) {\n definitions.set(lastModel, null);\n stales.set(lastModel, model);\n }\n\n definitions.set(model, config);\n\n if (config.storage.observe) {\n const modelValue = model && config.isInstance(model) ? model : null;\n\n const lastModelValue =\n lastModel && config.isInstance(lastModel) ? lastModel : null;\n\n if (modelValue !== lastModelValue) {\n config.storage.observe(modelValue, lastModelValue);\n }\n }\n\n return model;\n}\n\nfunction shallowEqual(target, compare) {\n return Object.keys(target).every((key) => target[key] === compare[key]);\n}\n\nfunction resolveWithInvalidate(config, model, lastModel) {\n resolve(config, model, lastModel);\n\n if (\n config.invalidate &&\n (!lastModel ||\n error(model) ||\n !config.isInstance(lastModel) ||\n !shallowEqual(model, lastModel))\n ) {\n config.invalidate();\n }\n\n return model;\n}\n\nfunction syncCache(config, id, model, invalidate = true) {\n cache.set(config, id, invalidate ? resolveWithInvalidate : resolve, model);\n return model;\n}\n\nlet currentTimestamp;\nfunction getCurrentTimestamp() {\n if (!currentTimestamp) {\n currentTimestamp = Date.now();\n global.requestAnimationFrame(() => {\n currentTimestamp = undefined;\n });\n }\n return currentTimestamp;\n}\n\nconst timestamps = new WeakMap();\n\nfunction getTimestamp(model) {\n let timestamp = timestamps.get(model);\n\n if (!timestamp) {\n timestamp = getCurrentTimestamp();\n timestamps.set(model, timestamp);\n }\n\n return timestamp;\n}\n\nfunction setTimestamp(model) {\n timestamps.set(model, getCurrentTimestamp());\n return model;\n}\n\nfunction invalidateTimestamp(model) {\n timestamps.set(model, 1);\n return model;\n}\n\nfunction hashCode(str) {\n return global.btoa(\n Array.from(str).reduce(\n // eslint-disable-next-line no-bitwise\n (s, c) => (Math.imul(31, s) + c.charCodeAt(0)) | 0,\n 0,\n ),\n );\n}\n\nconst offlinePrefix = \"hybrids:store:cache\";\nconst offlineKeys = {};\n\nlet clearPromise;\nfunction setupOfflineKey(config, threshold) {\n const key = `${offlinePrefix}:${hashCode(JSON.stringify(config.model))}`;\n\n offlineKeys[key] = getCurrentTimestamp() + threshold;\n\n if (!clearPromise) {\n clearPromise = Promise.resolve().then(() => {\n const previousKeys =\n JSON.parse(global.localStorage.getItem(offlinePrefix)) || {};\n const timestamp = getCurrentTimestamp();\n\n Object.keys(previousKeys).forEach((k) => {\n /* istanbul ignore next */\n if (!offlineKeys[k] && previousKeys[k] < timestamp) {\n global.localStorage.removeItem(k);\n delete previousKeys[k];\n }\n });\n\n global.localStorage.setItem(\n offlinePrefix,\n JSON.stringify({ ...previousKeys, ...offlineKeys }),\n );\n clearPromise = null;\n });\n }\n\n return key;\n}\n\nconst JSON_LIKE_REGEX = /^\\{.+\\}$/;\nfunction setupStorage(config, options) {\n if (typeof options === \"function\") options = { get: options };\n\n const result = {\n cache: true,\n loose: false,\n ...options,\n };\n\n if (result.observe) {\n const fn = result.observe;\n if (typeof fn !== \"function\") {\n throw TypeError(\n `Storage 'observe' property must be a function: ${typeof result.observe}`,\n );\n }\n result.observe = (model, lastModel) => {\n try {\n let id = lastModel ? lastModel.id : model.id;\n if (JSON_LIKE_REGEX.test(id)) {\n try {\n id = JSON.parse(id);\n // istanbul ignore next\n } catch (e) {} // eslint-disable-line no-empty\n }\n\n fn(id, model, lastModel);\n } catch (e) {\n console.error(e);\n }\n };\n }\n\n if (result.cache === false || result.cache === 0) {\n result.validate = (cachedModel) =>\n !cachedModel || getTimestamp(cachedModel) === getCurrentTimestamp();\n } else if (typeof result.cache === \"number\") {\n result.validate = (cachedModel) =>\n !cachedModel ||\n getTimestamp(cachedModel) + result.cache > getCurrentTimestamp();\n } else {\n if (result.cache !== true) {\n throw TypeError(\n `Storage 'cache' property must be a boolean or number: ${typeof result.cache}`,\n );\n }\n result.validate = (cachedModel) => getTimestamp(cachedModel) !== 1;\n }\n\n if (!result.get) {\n result.get = (id) => {\n throw notFoundError(stringifyId(id));\n };\n }\n\n if (result.offline) {\n const isBool = result.offline === true;\n const threshold = isBool\n ? 1000 * 60 * 60 * 24 * 30 /* 30 days */\n : result.offline;\n const offlineKey = setupOfflineKey(config, threshold);\n\n try {\n const items = JSON.parse(global.localStorage.getItem(offlineKey)) || {};\n\n let flush;\n\n result.offline = Object.freeze({\n key: offlineKey,\n threshold,\n get: isBool\n ? (id) => {\n if (hasOwnProperty.call(items, id)) {\n return JSON.parse(items[id][1]);\n }\n return null;\n }\n : (id) => {\n if (hasOwnProperty.call(items, id)) {\n const item = items[id];\n if (item[0] + threshold < getCurrentTimestamp()) {\n delete items[id];\n return null;\n }\n return JSON.parse(item[1]);\n }\n return null;\n },\n set(id, values) {\n if (values) {\n items[id] = [\n getCurrentTimestamp(),\n JSON.stringify(values, function replacer(key, value) {\n if (value === this[\"\"]) return value;\n\n if (value && typeof value === \"object\") {\n const valueConfig = definitions.get(value);\n if (valueConfig === config && value.id === id) {\n return String(value);\n }\n\n const offline = valueConfig && valueConfig.storage.offline;\n if (offline) {\n if (valueConfig.list) {\n return value.map((model) => {\n configs\n .get(valueConfig.model)\n .storage.offline.set(model.id, model);\n return `${model}`;\n });\n }\n\n valueConfig.storage.offline.set(value.id, value);\n return `${value}`;\n }\n }\n\n return value;\n }),\n ];\n } else {\n delete items[id];\n }\n\n if (!flush) {\n flush = Promise.resolve().then(() => {\n const timestamp = getCurrentTimestamp();\n\n Object.keys(items).forEach((key) => {\n if (items[key][0] + threshold < timestamp) {\n delete items[key];\n }\n });\n\n global.localStorage.setItem(offlineKey, JSON.stringify(items));\n flush = null;\n });\n }\n\n return values;\n },\n });\n } catch (e) /* istanbul ignore next */ {\n console.error(e);\n result.offline = false;\n }\n }\n\n return Object.freeze(result);\n}\n\nfunction memoryStorage(config) {\n return {\n get: config.enumerable ? () => {} : () => config.create({}),\n set: config.enumerable\n ? (id, values) => values\n : (id, values) => (values === null ? { id } : values),\n list:\n config.enumerable &&\n function list(id) {\n if (id) {\n throw TypeError(`Memory-based model definition does not support id`);\n }\n\n return cache.getEntries(config).reduce((acc, { key, value }) => {\n if (key === config) return acc;\n if (value && !error(value)) acc.push(key);\n return acc;\n }, []);\n },\n loose: true,\n };\n}\n\nfunction bootstrap(Model, nested) {\n if (Array.isArray(Model)) {\n return setupListModel(Model[0], nested);\n }\n return setupModel(Model, nested);\n}\n\nfunction getTypeConstructor(type, key) {\n switch (type) {\n case \"string\":\n return (v) => (v !== undefined && v !== null ? String(v) : \"\");\n case \"number\":\n return Number;\n case \"boolean\":\n return Boolean;\n default:\n throw TypeError(\n `The value of the '${key}' must be a string, number or boolean: ${type}`,\n );\n }\n}\n\nconst stateSetter = (_, value, lastValue) => {\n if (value.state === \"error\") {\n return { state: \"error\", error: value.value };\n }\n\n value.error = !!lastValue && lastValue.error;\n\n return value;\n};\nfunction setModelState(model, state, value = model) {\n cache.set(model, \"state\", stateSetter, { state, value });\n return model;\n}\n\nconst stateGetter = (\n model,\n v = { state: \"ready\", value: model, error: false },\n) => v;\nfunction getModelState(model) {\n return cache.get(model, \"state\", stateGetter);\n}\n\n// UUID v4 generator thanks to https://gist.github.com/jed/982883\nfunction uuid(temp) {\n return temp\n ? // eslint-disable-next-line no-bitwise, no-mixed-operators\n (temp ^ ((Math.random() * 16) >> (temp / 4))).toString(16)\n : ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, uuid);\n}\n\nfunction ref(fn) {\n if (typeof fn !== \"function\") {\n throw TypeError(`The first argument must be a function: ${typeof fn}`);\n }\n\n refs.add(fn);\n return fn;\n}\n\nconst validationMap = new WeakMap();\nfunction resolveKey(Model, key, config) {\n let defaultValue = config.model[key];\n if (refs.has(defaultValue)) defaultValue = defaultValue();\n let type = typeof defaultValue;\n\n if (\n defaultValue instanceof String ||\n defaultValue instanceof Number ||\n defaultValue instanceof Boolean\n ) {\n const check = validationMap.get(defaultValue);\n if (!check) {\n throw TypeError(\n stringifyModel(\n Model,\n `You must use primitive ${typeof defaultValue.valueOf()} value for '${key}' property of the provided model definition`,\n ),\n );\n }\n\n defaultValue = defaultValue.valueOf();\n type = typeof defaultValue;\n\n config.checks.set(key, check);\n }\n\n return { defaultValue, type };\n}\n\nfunction stringifyModel(Model, msg) {\n return `${msg}\\n\\nModel = ${JSON.stringify(Model, null, 2)}\\n`;\n}\n\nconst resolvedPromise = Promise.resolve();\nexport const configs = new WeakMap();\nfunction setupModel(Model, nested) {\n if (typeof Model !== \"object\" || Model === null) {\n throw TypeError(`Model definition must be an object: ${typeof Model}`);\n }\n\n let config = configs.get(Model);\n\n if (config && !config.enumerable) {\n if (nested && !config.nested) {\n throw TypeError(\n stringifyModel(\n Model,\n \"Provided model definition for nested object already used as a root definition\",\n ),\n );\n }\n\n if (!nested && config.nested) {\n throw TypeError(\n stringifyModel(\n Model,\n \"Nested model definition cannot be used outside of the parent definition\",\n ),\n );\n }\n }\n\n if (!config) {\n const storage = Model[connect];\n if (typeof storage === \"object\") Object.freeze(storage);\n\n let invalidatePromise;\n const enumerable = hasOwnProperty.call(Model, \"id\");\n const external = !!storage;\n\n const checks = new Map();\n\n const proto = {\n toString() {\n return this.id || undefined;\n },\n };\n const placeholder = Object.create(proto);\n\n config = {\n model: Model,\n external,\n enumerable,\n nested: !enumerable && !external && nested,\n placeholder: (id) => {\n const model = Object.create(placeholder);\n definitions.set(model, config);\n\n if (enumerable) model.id = id;\n\n return Object.freeze(model);\n },\n isInstance: (model) => Object.getPrototypeOf(model) !== placeholder,\n invalidate: () => {\n if (!invalidatePromise) {\n invalidatePromise = resolvedPromise.then(() => {\n cache.invalidate(config, config, { clearValue: true });\n invalidatePromise = null;\n });\n }\n },\n checks,\n };\n\n configs.set(Model, config);\n\n config.storage = setupStorage(config, storage || memoryStorage(config));\n\n const transform = Object.keys(Object.freeze(Model)).map((key) => {\n if (key !== \"id\") {\n Object.defineProperty(placeholder, key, {\n get() {\n throw Error(\n `Model instance in ${\n getModelState(this).state\n } state - use store.pending(), store.error(), or store.ready() guards`,\n );\n },\n enumerable: true,\n });\n }\n\n if (key === \"id\") {\n if (Model[key] !== true) {\n throw TypeError(\n \"The 'id' property in the model definition must be set to 'true' or not defined\",\n );\n }\n return (model, data, lastModel) => {\n let id;\n if (hasOwnProperty.call(data, \"id\")) {\n id = stringifyId(data.id);\n } else if (lastModel) {\n id = lastModel.id;\n } else {\n id = uuid();\n }\n\n Object.defineProperty(model, \"id\", { value: id, enumerable: true });\n };\n }\n\n const { defaultValue, type } = resolveKey(Model, key, config);\n\n switch (type) {\n case \"function\":\n return (model) => {\n Object.defineProperty(model, key, {\n get() {\n return cache.get(this, key, () => defaultValue(this));\n },\n });\n };\n case \"object\": {\n if (defaultValue === null) {\n throw TypeError(\n `The value for the '${key}' must be an object instance: ${defaultValue}`,\n );\n }\n\n const isArray = Array.isArray(defaultValue);\n\n if (isArray) {\n const nestedType = typeof defaultValue[0];\n\n if (nestedType !== \"object\") {\n if (\n nestedType === \"function\" &&\n ![String, Number, Boolean].includes(defaultValue[0])\n ) {\n throw TypeError(\n `The array item for the '${key}' must be one of the primitive types constructor: String, Number, or Boolean`,\n );\n }\n\n const Constructor =\n nestedType === \"function\"\n ? defaultValue[0]\n : getTypeConstructor(nestedType, key);\n\n const defaultArray =\n nestedType === \"function\"\n ? []\n : Object.freeze(defaultValue.map(Constructor));\n\n return (model, data, lastModel) => {\n if (hasOwnProperty.call(data, key)) {\n if (!Array.isArray(data[key])) {\n throw TypeError(\n `The value for '${key}' property must be an array: ${typeof data[\n key\n ]}`,\n );\n }\n model[key] = Object.freeze(data[key].map(Constructor));\n } else if (lastModel && hasOwnProperty.call(lastModel, key)) {\n model[key] = lastModel[key];\n } else {\n model[key] = defaultArray;\n }\n };\n }\n\n const localConfig = bootstrap(defaultValue, true);\n\n if (\n localConfig.external &&\n config.storage.offline &&\n localConfig.storage.offline &&\n localConfig.storage.offline.threshold <\n config.storage.offline.threshold\n ) {\n throw Error(\n `External nested model for '${key}' property has lower offline threshold (${localConfig.storage.offline.threshold} ms) than the parent definition (${config.storage.offline.threshold} ms)`,\n );\n }\n\n if (localConfig.enumerable && defaultValue[1]) {\n const nestedOptions = defaultValue[1];\n if (typeof nestedOptions !== \"object\") {\n throw TypeError(\n `Options for '${key}' array property must be an object instance: ${typeof nestedOptions}`,\n );\n }\n if (nestedOptions.loose) {\n config.contexts = config.contexts || new Set();\n config.contexts.add(bootstrap(defaultValue[0]));\n }\n }\n return (model, data, lastModel) => {\n if (hasOwnProperty.call(data, key)) {\n if (!Array.isArray(data[key])) {\n throw TypeError(\n `The value for '${key}' property must be an array: ${typeof data[\n key\n ]}`,\n );\n }\n model[key] = localConfig.create(data[key], true);\n } else {\n model[key] =\n (lastModel && lastModel[key]) ||\n (!localConfig.enumerable &&\n localConfig.create(defaultValue)) ||\n [];\n }\n };\n }\n\n const nestedConfig = bootstrap(defaultValue, true);\n if (nestedConfig.enumerable || nestedConfig.external) {\n if (\n config.storage.offline &&\n nestedConfig.storage.offline &&\n nestedConfig.storage.offline.threshold <\n config.storage.offline.threshold\n ) {\n throw Error(\n `External nested model for '${key}' property has lower offline threshold (${nestedConfig.storage.offline.threshold} ms) than the parent definition (${config.storage.offline.threshold} ms)`,\n );\n }\n return (model, data, lastModel) => {\n let resultModel;\n\n if (hasOwnProperty.call(data, key)) {\n const nestedData = data[key];\n\n if (typeof nestedData !== \"object\" || nestedData === null) {\n if (nestedData !== undefined && nestedData !== null) {\n resultModel = { id: nestedData };\n }\n } else {\n const dataConfig = definitions.get(nestedData);\n if (dataConfig) {\n if (dataConfig.model !== defaultValue) {\n throw TypeError(\n \"Model instance must match the definition\",\n );\n }\n resultModel = nestedData;\n } else {\n const lastNestedModel = cache.getEntry(\n nestedConfig,\n data[key].id,\n ).value;\n resultModel = nestedConfig.create(\n nestedData,\n lastNestedModel &&\n nestedConfig.isInstance(lastNestedModel)\n ? lastNestedModel\n : undefined,\n );\n syncCache(nestedConfig, resultModel.id, resultModel);\n }\n }\n } else {\n resultModel = lastModel && lastModel[key];\n }\n\n if (resultModel) {\n const id = resultModel.id;\n Object.defineProperty(model, key, {\n get() {\n return cache.get(this, key, () => get(defaultValue, id));\n },\n enumerable: true,\n });\n } else {\n model[key] = undefined;\n }\n };\n }\n\n return (model, data, lastModel) => {\n if (hasOwnProperty.call(data, key)) {\n model[key] =\n data[key] === null\n ? nestedConfig.create({})\n : nestedConfig.create(data[key], lastModel && lastModel[key]);\n } else {\n model[key] = lastModel ? lastModel[key] : nestedConfig.create({});\n }\n };\n }\n // eslint-disable-next-line no-fallthrough\n default: {\n const Constructor = getTypeConstructor(type, key);\n return (model, data, lastModel) => {\n if (hasOwnProperty.call(data, key)) {\n model[key] = Constructor(data[key]);\n } else if (lastModel && hasOwnProperty.call(lastModel, key)) {\n model[key] = lastModel[key];\n } else {\n model[key] = defaultValue;\n }\n };\n }\n }\n });\n\n config.create = function create(data, lastModel) {\n if (data === null) return null;\n\n if (typeof data !== \"object\") {\n throw TypeError(`Model values must be an object instance: ${data}`);\n }\n\n const model = transform.reduce((acc, fn) => {\n fn(acc, data, lastModel);\n return acc;\n }, Object.create(proto));\n\n definitions.set(model, config);\n storePointer.set(model, store);\n\n return Object.freeze(model);\n };\n\n Object.freeze(placeholder);\n Object.freeze(config);\n }\n\n return config;\n}\n\nconst listPlaceholderPrototype = Object.getOwnPropertyNames(\n Array.prototype,\n).reduce((acc, key) => {\n if (key === \"length\" || key === \"constructor\") return acc;\n\n Object.defineProperty(acc, key, {\n get() {\n throw Error(\n `Model list instance in ${\n getModelState(this).state\n } state - use store.pending(), store.error(), or store.ready() guards`,\n );\n },\n });\n return acc;\n}, []);\n\nexport const lists = new WeakMap();\nfunction setupListModel(Model, nested) {\n let config = lists.get(Model);\n\n if (config && !config.enumerable) {\n if (!nested && config.nested) {\n throw TypeError(\n stringifyModel(\n Model,\n \"Nested model definition cannot be used outside of the parent definition\",\n ),\n );\n }\n }\n\n if (!config) {\n const modelConfig = setupModel(Model);\n\n const contexts = new Set();\n if (modelConfig.storage.loose) contexts.add(modelConfig);\n\n if (!nested) {\n if (!modelConfig.enumerable) {\n throw TypeError(\n stringifyModel(\n Model,\n \"Provided model definition does not support listing (it must be enumerable - set `id` property to `true`)\",\n ),\n );\n }\n if (!modelConfig.storage.list) {\n throw TypeError(\n stringifyModel(\n Model,\n \"Provided model definition storage does not support `list` action\",\n ),\n );\n }\n }\n\n nested = !modelConfig.enumerable && !modelConfig.external && nested;\n\n config = {\n list: true,\n nested,\n model: Model,\n contexts,\n enumerable: modelConfig.enumerable,\n external: modelConfig.external,\n placeholder: () => {\n const model = Object.create(listPlaceholderPrototype);\n definitions.set(model, config);\n\n return Object.freeze(model);\n },\n isInstance: (model) =>\n Object.getPrototypeOf(model) !== listPlaceholderPrototype,\n create(items, invalidate = false) {\n if (items === null) return null;\n\n const result = items.reduce((acc, data) => {\n let id = data;\n if (typeof data === \"object\" && data !== null) {\n id = data.id;\n const dataConfig = definitions.get(data);\n let model = data;\n if (dataConfig) {\n if (dataConfig.model !== Model) {\n throw TypeError(\"Model instance must match the definition\");\n }\n } else {\n const lastModel =\n modelConfig.enumerable &&\n cache.getEntry(modelConfig, data.id).value;\n model = modelConfig.create(\n data,\n lastModel && modelConfig.isInstance(lastModel)\n ? lastModel\n : undefined,\n );\n if (modelConfig.enumerable) {\n id = model.id;\n syncCache(modelConfig, id, model, invalidate);\n }\n }\n if (!modelConfig.enumerable) {\n acc.push(model);\n }\n } else if (!modelConfig.enumerable) {\n throw TypeError(`Model instance must be an object: ${typeof data}`);\n }\n if (modelConfig.enumerable) {\n const key = acc.length;\n Object.defineProperty(acc, key, {\n get() {\n return cache.get(this, key, () => get(Model, id));\n },\n enumerable: true,\n });\n }\n return acc;\n }, []);\n\n Object.defineProperty(result, \"id\", { value: items.id });\n\n definitions.set(result, config);\n storePointer.set(result, store);\n\n return Object.freeze(result);\n },\n };\n\n config.storage = Object.freeze({\n ...setupStorage(config, {\n cache: modelConfig.storage.cache,\n get: !nested && ((id) => modelConfig.storage.list(id)),\n }),\n offline: modelConfig.storage.offline && {\n threshold: modelConfig.storage.offline.threshold,\n get: (id) => {\n const result = modelConfig.storage.offline.get(\n hashCode(String(stringifyId(id))),\n );\n return result\n ? result.map((item) => modelConfig.storage.offline.get(item))\n : null;\n },\n set: (id, values) => {\n modelConfig.storage.offline.set(\n hashCode(String(stringifyId(id))),\n values.map((item) => {\n modelConfig.storage.offline.set(item.id, item);\n return item.id;\n }),\n );\n },\n },\n });\n\n lists.set(Model, Object.freeze(config));\n }\n\n return config;\n}\n\nfunction resolveTimestamp(h, v) {\n return v || getCurrentTimestamp();\n}\n\nfunction stringifyId(id) {\n switch (typeof id) {\n case \"object\":\n return JSON.stringify(\n Object.keys(id)\n .sort()\n .reduce((acc, key) => {\n if (typeof id[key] === \"object\" && id[key] !== null) {\n throw TypeError(\n `You must use primitive value for '${key}' key: ${typeof id[\n key\n ]}`,\n );\n }\n acc[key] = id[key];\n return acc;\n }, {}),\n );\n case \"undefined\":\n return undefined;\n default:\n return String(id);\n }\n}\n\nconst notFoundErrors = new WeakSet();\nfunction notFoundError(Model, stringId) {\n const err = Error(\n stringifyModel(\n Model,\n `Model instance ${\n stringId !== undefined ? `with '${stringId}' id ` : \"\"\n }does not exist`,\n ),\n );\n\n notFoundErrors.add(err);\n return err;\n}\n\nfunction mapError(model, err, suppressLog) {\n if (suppressLog !== false && !notFoundErrors.has(err)) {\n // eslint-disable-next-line no-console\n console.error(err);\n }\n\n return setModelState(model, \"error\", err);\n}\n\nfunction get(Model, id) {\n const config = bootstrap(Model);\n let stringId;\n\n if (config.enumerable) {\n stringId = stringifyId(id);\n\n if (!stringId && !config.list && !draftMap.get(config)) {\n throw TypeError(\n stringifyModel(\n Model,\n `Provided model definition requires non-empty id: \"${stringId}\"`,\n ),\n );\n }\n } else if (id !== undefined) {\n throw TypeError(\n stringifyModel(Model, \"Provided model definition does not support id\"),\n );\n }\n\n const offline = config.storage.offline;\n const validate = config.storage.validate;\n const entry = cache.getEntry(config, stringId);\n\n if (entry.value && !validate(entry.value)) {\n entry.resolved = false;\n entry.depState = 0;\n }\n\n return cache.get(config, stringId, (h, cachedModel) => {\n if (cachedModel && pending(cachedModel)) return cachedModel;\n\n let validContexts = true;\n if (config.contexts) {\n config.contexts.forEach((context) => {\n if (\n cache.get(context, context, resolveTimestamp) ===\n getCurrentTimestamp()\n ) {\n validContexts = false;\n }\n });\n }\n\n if (validContexts && cachedModel && validate(cachedModel)) {\n return cachedModel;\n }\n\n const fallback = () =>\n cachedModel ||\n (offline && config.create(offline.get(stringId))) ||\n config.placeholder(stringId);\n\n try {\n let result = config.storage.get(id);\n\n if (typeof result !== \"object\" || result === null) {\n if (offline) offline.set(stringId, null);\n throw notFoundError(Model, stringId);\n }\n\n if (result instanceof Promise) {\n result = result\n .then((data) => {\n if (typeof data !== \"object\" || data === null) {\n if (offline) offline.set(stringId, null);\n throw notFoundError(Model, stringId);\n }\n\n if (data.id !== stringId) data.id = stringId;\n const model = config.create(data);\n\n if (offline) offline.set(stringId, model);\n\n return syncCache(config, stringId, setTimestamp(model));\n })\n .catch((e) => syncCache(config, stringId, mapError(fallback(), e)));\n\n return setModelState(fallback(), \"pending\", result);\n }\n\n if (result.id !== stringId) result.id = stringId;\n const model = config.create(result);\n\n if (offline) {\n Promise.resolve().then(() => {\n offline.set(stringId, model);\n });\n }\n\n return resolve(config, setTimestamp(model), cachedModel);\n } catch (e) {\n return setTimestamp(mapError(fallback(), e));\n }\n });\n}\n\nconst draftMap = new WeakMap();\n\nfunction getValidationError(errors) {\n const keys = Object.keys(errors);\n const e = Error(\n `Model validation failed (${keys.join(\n \", \",\n )}) - read the details from 'errors' property`,\n );\n\n e.errors = errors;\n\n return e;\n}\n\nfunction set(model, values = {}) {\n let config = definitions.get(model);\n\n if (config === null) {\n model = stales.get(model);\n config = definitions.get(model);\n }\n\n if (config === null) {\n throw Error(\n \"Provided model instance has expired. Haven't you used stale value?\",\n );\n }\n\n let isInstance = !!config;\n if (!config) config = bootstrap(model);\n\n if (config.nested) {\n throw stringifyModel(\n config.model,\n TypeError(\n \"Setting provided nested model instance is not supported, use the root model instance\",\n ),\n );\n }\n\n if (config.list) {\n throw TypeError(\"Listing model definition does not support 'set' method\");\n }\n\n if (!config.storage.set) {\n throw stringifyModel(\n config.model,\n TypeError(\n \"Provided model definition storage does not support 'set' method\",\n ),\n );\n }\n\n if (!isInstance && !config.enumerable) {\n isInstance = true;\n model = get(model);\n }\n\n if (isInstance) {\n const promise = pending(model);\n if (promise) {\n return promise.then((m) => set(m, values));\n }\n }\n\n const isDraft = draftMap.get(config);\n let id;\n\n try {\n if (\n config.enumerable &&\n !isInstance &&\n (!values || typeof values !== \"object\")\n ) {\n throw TypeError(`Values must be an object instance: ${values}`);\n }\n\n if (!isDraft && values && hasOwnProperty.call(values, \"id\")) {\n throw TypeError(`Values must not contain 'id' property: ${values.id}`);\n }\n\n const localModel = config.create(values, isInstance ? model : undefined);\n const keys = values ? Object.keys(values) : [];\n\n const errors = {};\n const lastError = isInstance && isDraft && error(model);\n\n let hasErrors = false;\n\n if (localModel) {\n config.checks.forEach((fn, key) => {\n if (keys.indexOf(key) === -1) {\n if (lastError && lastError.errors && lastError.errors[key]) {\n hasErrors = true;\n errors[key] = lastError.errors[key];\n }\n\n // eslint-disable-next-line eqeqeq\n if (isDraft && localModel[key] == config.model[key]) {\n return;\n }\n }\n\n let checkResult;\n try {\n checkResult = fn(localModel[key], key, localModel);\n } catch (e) {\n checkResult = e;\n }\n\n if (checkResult !== true && checkResult !== undefined) {\n hasErrors = true;\n errors[key] = checkResult || true;\n }\n });\n\n if (hasErrors && !isDraft) {\n throw getValidationError(errors);\n }\n }\n\n id = localModel ? localModel.id : model.id;\n\n const result = Promise.resolve(\n config.storage.set(isInstance ? id : undefined, localModel, keys),\n )\n .then((data) => {\n const resultModel =\n data === localModel ? localModel : config.create(data);\n\n if (isInstance && resultModel && id !== resultModel.id) {\n throw TypeError(\n `Local and storage data must have the same id: '${id}', '${resultModel.id}'`,\n );\n }\n\n let resultId = resultModel ? resultModel.id : id;\n\n if (hasErrors && isDraft) {\n setModelState(resultModel, \"error\", getValidationError(errors));\n }\n\n if (\n isDraft &&\n isInstance &&\n hasOwnProperty.call(data, \"id\") &&\n (!localModel || localModel.id !== model.id)\n ) {\n resultId = model.id;\n } else if (config.storage.offline) {\n config.storage.offline.set(resultId, resultModel);\n }\n\n return syncCache(\n config,\n resultId,\n resultModel ||\n mapError(\n config.placeholder(resultId),\n notFoundError(config.model, id),\n false,\n ),\n true,\n );\n })\n .catch((err) => {\n err = err !== undefined ? err : Error(\"Undefined error\");\n if (isInstance) setModelState(model, \"error\", err);\n throw err;\n });\n\n if (isInstance) setModelState(model, \"pending\", result);\n\n return result;\n } catch (e) {\n if (isInstance) setModelState(model, \"error\", e);\n return Promise.reject(e);\n }\n}\n\nfunction sync(model, values) {\n if (typeof values !== \"object\") {\n throw TypeError(`Values must be an object instance: ${values}`);\n }\n\n let config = definitions.get(model);\n\n if (config === null) {\n model = stales.get(model);\n config = definitions.get(model);\n }\n\n if (config === null) {\n throw Error(\n \"Provided model instance has expired. Haven't you used stale value?\",\n );\n }\n\n if (config === undefined) {\n if (!values) {\n throw TypeError(\"Values must be defined for usage with model definition\");\n }\n config = bootstrap(model);\n model = undefined;\n } else if (values && hasOwnProperty.call(values, \"id\")) {\n throw TypeError(`Values must not contain 'id' property: ${values.id}`);\n }\n\n if (config.list) {\n throw TypeError(\"Listing model definition is not supported in sync method\");\n }\n\n const resultModel = config.create(values, model);\n const id = values ? resultModel.id : model.id;\n\n return syncCache(\n config,\n id,\n resultModel ||\n mapError(config.placeholder(id), notFoundError(config.model, id), false),\n );\n}\n\nfunction clear(model, clearValue = true) {\n if (typeof model !== \"object\" || model === null) {\n throw TypeError(\n `The first argument must be a model instance or a model definition: ${model}`,\n );\n }\n\n let config = definitions.get(model);\n\n if (config === null) {\n throw Error(\n \"Provided model instance has expired. Haven't you used stale value from the outer scope?\",\n );\n }\n\n if (config) {\n const offline = clearValue && config.storage.offline;\n if (offline) offline.set(model.id, null);\n\n invalidateTimestamp(model);\n cache.invalidate(config, model.id, { clearValue, deleteEntry: true });\n } else {\n if (!configs.get(model) && !lists.get(model[0])) {\n throw Error(\n \"Model definition must be used before - passed argument is probably not a model definition\",\n );\n }\n config = bootstrap(model);\n const offline = clearValue && config.storage.offline;\n\n cache.getEntries(config).forEach((entry) => {\n if (offline) offline.set(entry.key, null);\n if (entry.value) invalidateTimestamp(entry.value);\n });\n cache.invalidateAll(config, { clearValue, deleteEntry: true });\n }\n}\n\nfunction pending(...models) {\n let isPending = false;\n const result = models.map((model) => {\n try {\n const { state, value } = getModelState(model);\n if (state === \"pending\") {\n isPending = true;\n return value;\n }\n } catch (e) {} // eslint-disable-line no-empty\n\n return Promise.resolve(model);\n });\n\n return isPending && (models.length > 1 ? Promise.all(result) : result[0]);\n}\n\nfunction resolveToLatest(model, id) {\n model = stales.get(model) || model;\n if (!definitions.get(model)) model = get(model, id);\n\n const promise = pending(model);\n\n if (!promise) {\n const e = error(model);\n return e ? Promise.reject(e) : Promise.resolve(model);\n }\n\n return promise.then((m) => resolveToLatest(m));\n}\n\nfunction error(model, property) {\n if (model === null || typeof model !== \"object\") return false;\n const state = getModelState(model);\n\n if (property !== undefined) {\n const errors =\n typeof state.error === \"object\" && state.error && state.error.errors;\n\n return property === null ? !errors && state.error : errors[property];\n }\n\n return state.error;\n}\n\nfunction ready(...models) {\n return (\n models.length > 0 &&\n models.every((model) => {\n const config = definitions.get(model);\n return !!(config && config.isInstance(model));\n })\n );\n}\n\nfunction getValuesFromModel(model, values) {\n model = { ...model, ...values };\n delete model.id;\n return model;\n}\n\nfunction submit(draft, values = {}) {\n const config = definitions.get(draft);\n if (!config || !draftMap.has(config)) {\n throw TypeError(`Provided model instance is not a draft: ${draft}`);\n }\n\n if (pending(draft)) {\n throw Error(\"Model draft in pending state\");\n }\n\n const modelConfig = draftMap.get(config);\n let result;\n\n if (cache.getEntry(modelConfig, draft.id).value) {\n const model = get(modelConfig.model, draft.id);\n result = Promise.resolve(pending(model) || model).then((resolvedModel) =>\n set(resolvedModel, getValuesFromModel(draft, values)),\n );\n } else {\n result = set(modelConfig.model, getValuesFromModel(draft, values));\n }\n\n result = result\n .then((resultModel) => {\n setModelState(draft, \"ready\");\n return set(draft, resultModel).then(() => resultModel);\n })\n .catch((e) => {\n setModelState(draft, \"error\", e);\n return Promise.reject(e);\n });\n\n setModelState(draft, \"pending\", result);\n\n return result;\n}\n\nfunction required(value, key) {\n return !!value || `${key} is required`;\n}\n\nfunction valueWithValidation(\n defaultValue,\n validate = required,\n errorMessage = \"\",\n) {\n switch (typeof defaultValue) {\n case \"string\":\n // eslint-disable-next-line no-new-wrappers\n defaultValue = new String(defaultValue);\n break;\n case \"number\":\n // eslint-disable-next-line no-new-wrappers\n defaultValue = new Number(defaultValue);\n break;\n case \"boolean\":\n // eslint-disable-next-line no-new-wrappers\n defaultValue = new Boolean(defaultValue);\n break;\n default:\n throw TypeError(\n `Default value must be a string, number or boolean: ${typeof defaultValue}`,\n );\n }\n\n let fn;\n if (validate instanceof RegExp) {\n fn = (value) => validate.test(value) || errorMessage;\n } else if (typeof validate === \"function\") {\n fn = (...args) => {\n const result = validate(...args);\n return result !== true && result !== undefined\n ? errorMessage || result\n : result;\n };\n } else {\n throw TypeError(\n `The second argument must be a RegExp instance or a function: ${typeof validate}`,\n );\n }\n\n validationMap.set(defaultValue, fn);\n return defaultValue;\n}\n\nfunction cloneModel(model) {\n const config = definitions.get(model);\n const clone = Object.freeze(Object.create(model));\n\n definitions.set(clone, config);\n\n return clone;\n}\n\nfunction store(Model, options = {}) {\n const config = bootstrap(Model);\n\n if (options.id !== undefined && typeof options.id !== \"function\") {\n const id = options.id;\n options.id = (host) => host[id];\n }\n\n if (options.id && !config.enumerable) {\n throw TypeError(\n \"Store factory for singleton model definition does not support 'id' option\",\n );\n }\n\n let draft;\n if (options.draft) {\n if (config.list) {\n throw TypeError(\n \"Draft mode is not supported for listing model definition\",\n );\n }\n\n draft = bootstrap({\n ...Model,\n [connect]: {\n get(id) {\n const model = get(config.model, id);\n return pending(model) || model;\n },\n set(id, values) {\n return values === null ? { id } : values;\n },\n },\n });\n\n draftMap.set(draft, config);\n Model = draft.model;\n }\n\n if (!options.id && config.enumerable && !config.list) {\n return {\n get(host, value) {\n const valueConfig = definitions.get(value);\n const id = valueConfig !== undefined ? value.id : value;\n\n if (draft && (value === undefined || value === null)) {\n const draftModel = draft.create({}, { id: undefined });\n syncCache(draft, undefined, draftModel, false);\n return get(Model, undefined);\n }\n\n return value ? get(Model, id) : undefined;\n },\n set: (_, v) => v,\n connect: draft\n ? (host, key) => () => {\n const model = host[key];\n if (model && model.id) clear(model, true);\n }\n : undefined,\n };\n }\n\n return {\n get: (host, value) => {\n const valueConfig = definitions.get(value);\n const id =\n (options.id && options.id(host)) ||\n (valueConfig !== undefined ? value.id : value);\n\n if (draft && !id && (value === undefined || value === null)) {\n const draftModel = draft.create({});\n syncCache(draft, undefined, draftModel, false);\n return get(Model, undefined);\n }\n\n if (!config.list && config.enumerable && id === undefined)\n return undefined;\n\n const nextValue = get(Model, id);\n\n if (nextValue !== value && ready(value) && !ready(nextValue)) {\n const tempValue = cloneModel(value);\n cache.set(tempValue, \"state\", () => getModelState(nextValue));\n return tempValue;\n }\n\n return nextValue;\n },\n set:\n (!options.id && config.list) || (draft && !config.enumerable)\n ? (_, v) => v\n : undefined,\n connect:\n draft && config.enumerable\n ? (host, key) => () => {\n const model = host[key];\n if (model && model.id) clear(model, true);\n }\n : undefined,\n };\n}\n\nexport default Object.freeze(\n Object.assign(store, {\n // storage\n connect,\n\n // actions\n get,\n set,\n sync,\n clear,\n\n // guards\n pending,\n error,\n ready,\n\n // helpers\n submit,\n value: valueWithValidation,\n resolve: resolveToLatest,\n ref,\n }),\n);\n","import global from \"../global.js\";\n\nconst metaMap = new WeakMap();\nexport function getMeta(key) {\n let value = metaMap.get(key);\n if (value) return value;\n\n metaMap.set(key, (value = {}));\n return value;\n}\n\nexport function getTemplateEnd(node) {\n let meta;\n\n while (node && (meta = getMeta(node)) && meta.endNode) {\n node = meta.endNode;\n }\n\n return node;\n}\n\nexport function removeTemplate(target) {\n const data = getMeta(target);\n\n if (data.styles) data.styles();\n\n if (target.nodeType === global.Node.TEXT_NODE) {\n if (data.startNode) {\n const endNode = getTemplateEnd(data.endNode);\n\n let node = data.startNode;\n const lastNextSibling = endNode.nextSibling;\n\n while (node) {\n const nextSibling = node.nextSibling;\n node.parentNode.removeChild(node);\n node = nextSibling !== lastNextSibling && nextSibling;\n }\n }\n } else {\n let child = target.childNodes[0];\n while (child) {\n target.removeChild(child);\n child = target.childNodes[0];\n }\n }\n\n metaMap.delete(target);\n}\n\nconst TIMESTAMP = Date.now();\nexport const getPlaceholder = (id = 0) => `H-${TIMESTAMP}-${id}`;\n","import global from \"../global.js\";\n\nconst hasAdoptedStylesheets = !!global.document.adoptedStyleSheets;\nconst NUMBER_REGEXP = /^\\d+$/;\nconst rules = {\n // base\n block: (props, align) => ({ display: \"block\", \"text-align\": align }),\n inline: ({ display }) => ({\n display: `inline${display ? `-${display}` : \"\"}`,\n }),\n hidden: { display: \"none\" },\n\n // flexbox\n ...[\"row\", \"row-reverse\", \"column\", \"column-reverse\"].reduce((acc, type) => {\n acc[type] = (props, wrap = \"nowrap\") => ({\n display: \"flex\",\n \"flex-flow\": `${type} ${wrap}`,\n });\n return acc;\n }, {}),\n grow: (props, value = 1) => ({ \"flex-grow\": value }),\n shrink: (props, value = 1) => ({ \"flex-shrink\": value }),\n basis: (props, value) => ({ \"flex-basis\": dimension(value) }),\n order: (props, value = 0) => ({ order: value }),\n\n // grid\n grid: (props, columns = \"1\", rows = \"\", autoFlow = \"\", dense = \"\") => ({\n display: \"grid\",\n ...[\"columns\", \"rows\"].reduce((acc, type) => {\n const value = type === \"columns\" ? columns : rows;\n acc[`grid-template-${type}`] =\n value &&\n value\n .split(\"|\")\n .map((v) =>\n v.match(NUMBER_REGEXP)\n ? `repeat(${v}, minmax(0, 1fr))`\n : dimension(v),\n )\n .join(\" \");\n return acc;\n }, {}),\n \"grid-auto-flow\": `${autoFlow} ${dense && \"dense\"}`,\n }),\n area: (props, column = \"\", row = \"\") => ({\n \"grid-column\": column.match(NUMBER_REGEXP) ? `span ${column}` : column,\n \"grid-row\": row.match(NUMBER_REGEXP) ? `span ${row}` : row,\n }),\n gap: (props, column = 1, row = \"\") => ({\n \"column-gap\": dimension(column),\n \"row-gap\": dimension(row || column),\n }),\n\n // alignment\n items: (props, v1 = \"start\", v2 = \"\") => ({\n \"place-items\": `${v1} ${v2}`,\n }),\n content: (props, v1 = \"start\", v2 = \"\") => ({\n \"place-content\": `${v1} ${v2}`,\n }),\n self: (props, v1 = \"start\", v2 = \"\") => ({\n \"place-self\": `${v1} ${v2}`,\n }),\n center: { \"place-items\": \"center\", \"place-content\": \"center\" },\n\n // size\n size: (props, width, height = width) => ({\n width: dimension(width),\n height: dimension(height),\n }),\n width: (props, base, min, max) => ({\n width: dimension(base),\n \"min-width\": dimension(min),\n \"max-width\": dimension(max),\n }),\n height: (props, base, min, max) => ({\n height: dimension(base),\n \"min-height\": dimension(min),\n \"max-height\": dimension(max),\n }),\n ratio: (props, v1) => ({ \"aspect-ratio\": v1 }),\n overflow: (props, v1 = \"hidden\", v2 = \"\") => {\n const type = v2 ? `-${v1}` : \"\";\n const value = v2 ? v2 : v1;\n\n return {\n [`overflow${type}`]: value,\n ...(value === \"scroll\"\n ? {\n \"flex-basis\": 0,\n \"overscroll-behavior\": \"contain\",\n \"--webkit-overflow-scrolling\": \"touch\",\n }\n : {}),\n };\n },\n margin: (props, v1 = \"1\", v2, v3, v4) => {\n if (v1.match(/top|bottom|left|right/)) {\n return {\n [`margin-${v1}`]: dimension(v2 || \"1\"),\n };\n }\n\n return {\n margin: `${dimension(v1)} ${dimension(v2)} ${dimension(v3)} ${dimension(\n v4,\n )}`,\n };\n },\n\n // position types\n absolute: { position: \"absolute\" },\n relative: { position: \"relative\" },\n fixed: { position: \"fixed\" },\n sticky: { position: \"sticky\" },\n static: { position: \"static\" },\n\n // position values\n inset: { top: 0, right: 0, bottom: 0, left: 0 },\n top: (props, value = 0) => ({ top: dimension(value) }),\n bottom: (props, value = 0) => ({ bottom: dimension(value) }),\n left: (props, value = 0) => ({ left: dimension(value) }),\n right: (props, value = 0) => ({ right: dimension(value) }),\n\n layer: (props, value = 1) => ({ \"z-index\": value }),\n};\n\nconst dimensions = {\n min: \"min-content\",\n max: \"max-content\",\n fit: \"fit-content\",\n full: \"100%\",\n};\n\nconst queries = {\n portrait: \"orientation: portrait\",\n landscape: \"orientation: landscape\",\n};\n\nfunction dimension(value) {\n value = dimensions[value] || value;\n\n if (/^\\d+(\\.\\d+)*$/.test(String(value))) {\n return `${value * 8}px`;\n }\n\n return value || \"\";\n}\n\nlet globalSheet;\nfunction getCSSStyleSheet() {\n if (globalSheet) return globalSheet;\n\n /* istanbul ignore else */\n if (hasAdoptedStylesheets) {\n globalSheet = new global.CSSStyleSheet();\n } else {\n const el = global.document.createElement(\"style\");\n el.appendChild(global.document.createTextNode(\"\"));\n global.document.head.appendChild(el);\n\n globalSheet = el.sheet;\n }\n\n globalSheet.insertRule(\":host([hidden]) { display: none; }\");\n\n return globalSheet;\n}\n\nconst styleElements = new WeakMap();\nlet injectedTargets = new WeakSet();\n\nexport function inject(target) {\n const root = target.getRootNode();\n if (injectedTargets.has(root)) return;\n\n const sheet = getCSSStyleSheet();\n\n /* istanbul ignore else */\n if (hasAdoptedStylesheets) {\n root.adoptedStyleSheets = [...root.adoptedStyleSheets, sheet];\n } else {\n if (root === global.document) return;\n\n let el = styleElements.get(root);\n if (!el) {\n el = global.document.createElement(\"style\");\n el.appendChild(global.document.createTextNode(\"\"));\n root.appendChild(el);\n\n styleElements.set(root, el);\n }\n\n const elSheet = el.sheet;\n const cssRules = sheet.cssRules;\n\n for (var i = 0; i < cssRules.length; i++) {\n if (elSheet.cssRules[i]) {\n if (elSheet.cssRules[i].cssText === cssRules[i].cssText) {\n continue;\n }\n elSheet.removeRule(i);\n }\n\n elSheet.insertRule(cssRules[i].cssText, i);\n }\n\n for (; i < elSheet.cssRules.length; i++) {\n elSheet.removeRule(i);\n }\n }\n\n injectedTargets.add(root);\n}\n\nconst classNames = new Map();\nexport function insertRule(node, query, tokens, hostMode) {\n let className = classNames.get(node);\n if (!className) {\n className = `l-${Math.random().toString(36).substr(2, 5)}`;\n classNames.set(node, className);\n }\n\n /* istanbul ignore next */\n if (!hasAdoptedStylesheets) injectedTargets = new WeakSet();\n\n const sheet = getCSSStyleSheet();\n const [selectors, mediaQueries = \"\"] = query.split(\"@\");\n\n const cssRules = Object.entries(\n tokens.split(\" \").reduce((acc, token) => {\n const [id, ...args] = token.split(\":\");\n const rule = rules[id];\n\n if (!rule) {\n throw TypeError(`Unsupported layout rule: '${id}'`);\n }\n\n return Object.assign(\n acc,\n typeof rule === \"function\"\n ? rule(acc, ...args.map((v) => (v.match(/--.*/) ? `var(${v})` : v)))\n : rule,\n );\n }, {}),\n ).reduce(\n (acc, [key, value]) =>\n value !== undefined && value !== \"\" ? acc + `${key}: ${value};` : acc,\n \"\",\n );\n\n const mediaSelector = mediaQueries.split(\":\").reduce((acc, query) => {\n if (query === \"\") return acc;\n return acc + ` and (${queries[query] || `min-width: ${query}`})`;\n }, \"@media screen\");\n\n if (hostMode) {\n const shadowSelector = `.${className}-s${selectors}`;\n const contentSelector = `.${className}-c${selectors}`;\n\n sheet.insertRule(\n mediaQueries\n ? `${mediaSelector} { :host(${shadowSelector}) { ${cssRules} } }`\n : `:host(${shadowSelector}) { ${cssRules} }`,\n sheet.cssRules.length,\n );\n\n sheet.insertRule(\n mediaQueries\n ? `${mediaSelector} { ${contentSelector} { ${cssRules} } }`\n : `${contentSelector} { ${cssRules} }`,\n sheet.cssRules.length,\n );\n } else {\n const selector = `.${className}${selectors}`;\n\n sheet.insertRule(\n mediaQueries\n ? `${mediaSelector} { ${selector} { ${cssRules} } }`\n : `${selector} { ${cssRules} }`,\n sheet.cssRules.length,\n );\n }\n\n return className;\n}\n","import global from \"../../global.js\";\nimport { getMeta, removeTemplate, getTemplateEnd } from \"../utils.js\";\n\nexport const arrayMap = new WeakMap();\n\nfunction movePlaceholder(target, previousSibling) {\n const meta = getMeta(target);\n const startNode = meta.startNode;\n const endNode = getTemplateEnd(meta.endNode);\n\n previousSibling.parentNode.insertBefore(target, previousSibling.nextSibling);\n\n let prevNode = target;\n let node = startNode;\n while (node) {\n const nextNode = node.nextSibling;\n prevNode.parentNode.insertBefore(node, prevNode.nextSibling);\n prevNode = node;\n node = nextNode !== endNode.nextSibling && nextNode;\n }\n}\n\nexport default function resolveArray(\n host,\n target,\n value,\n resolveValue,\n isLayout,\n) {\n let lastEntries = arrayMap.get(target);\n const entries = value.map((item, index) => ({\n id: hasOwnProperty.call(item, \"id\") ? item.id : index,\n value: item,\n placeholder: null,\n available: true,\n }));\n\n arrayMap.set(target, entries);\n\n if (lastEntries) {\n const ids = new Set();\n entries.forEach((entry) => ids.add(entry.id));\n\n lastEntries = lastEntries.filter((entry) => {\n if (!ids.has(entry.id)) {\n removeTemplate(entry.placeholder);\n entry.placeholder.parentNode.removeChild(entry.placeholder);\n return false;\n }\n\n return true;\n });\n }\n\n let previousSibling = target;\n const lastIndex = value.length - 1;\n const meta = getMeta(target);\n\n for (let index = 0; index < entries.length; index += 1) {\n const entry = entries[index];\n let matchedEntry;\n if (lastEntries) {\n for (let i = 0; i < lastEntries.length; i += 1) {\n if (lastEntries[i].available && lastEntries[i].id === entry.id) {\n matchedEntry = lastEntries[i];\n break;\n }\n }\n }\n\n if (matchedEntry) {\n matchedEntry.available = false;\n entry.placeholder = matchedEntry.placeholder;\n\n if (entry.placeholder.previousSibling !== previousSibling) {\n movePlaceholder(entry.placeholder, previousSibling);\n }\n if (matchedEntry.value !== entry.value) {\n resolveValue(\n host,\n entry.placeholder,\n entry.value,\n matchedEntry.value,\n isLayout,\n );\n }\n } else {\n entry.placeholder = global.document.createTextNode(\"\");\n previousSibling.parentNode.insertBefore(\n entry.placeholder,\n previousSibling.nextSibling,\n );\n resolveValue(host, entry.placeholder, entry.value, undefined, isLayout);\n }\n\n previousSibling = getTemplateEnd(\n getMeta(entry.placeholder, {}).endNode || entry.placeholder,\n );\n\n if (index === 0) meta.startNode = entry.placeholder;\n if (index === lastIndex) meta.endNode = previousSibling;\n }\n\n if (lastEntries) {\n lastEntries.forEach((entry) => {\n if (entry.available) {\n removeTemplate(entry.placeholder);\n entry.placeholder.parentNode.removeChild(entry.placeholder);\n }\n });\n }\n}\n","import global from \"../../global.js\";\nimport { removeTemplate } from \"../utils.js\";\nimport resolveArray, { arrayMap } from \"./array.js\";\nimport resolveNode from \"./node.js\";\n\nfunction typeOf(value) {\n const type = typeof value;\n\n if (type === \"object\") {\n if (Array.isArray(value)) return \"array\";\n if (value instanceof global.Node) return \"node\";\n }\n\n return type;\n}\n\nexport default function resolveValue(\n host,\n target,\n value,\n lastValue,\n useLayout,\n) {\n const type = typeOf(value);\n const lastType = typeOf(lastValue);\n\n if (lastType !== \"undefined\" && type !== lastType) {\n if (type !== \"function\") removeTemplate(target);\n\n if (lastType === \"array\") {\n arrayMap.delete(target);\n } else if (lastType !== \"node\" && lastType !== \"function\") {\n target.textContent = \"\";\n }\n }\n\n switch (type) {\n case \"array\":\n resolveArray(host, target, value, resolveValue);\n break;\n case \"node\":\n resolveNode(host, target, value);\n break;\n case \"function\":\n if (useLayout) value.useLayout = true;\n value(host, target);\n break;\n default:\n target.textContent = type === \"number\" || value ? value : \"\";\n }\n}\n","import { removeTemplate, getMeta } from \"../utils.js\";\n\nexport default function resolveNode(host, target, value) {\n removeTemplate(target);\n\n const meta = getMeta(target);\n meta.startNode = meta.endNode = value;\n\n target.parentNode.insertBefore(value, target.nextSibling);\n}\n","const targets = new WeakMap();\n\nexport default function resolveEventListener(eventType) {\n return (host, target, value, lastValue) => {\n if (lastValue) {\n const eventMap = targets.get(target);\n if (eventMap) {\n target.removeEventListener(\n eventType,\n eventMap.get(lastValue),\n lastValue.options !== undefined ? lastValue.options : false,\n );\n }\n }\n\n if (value) {\n if (typeof value !== \"function\") {\n throw Error(`Event listener must be a function: ${typeof value}`);\n }\n\n let eventMap = targets.get(target);\n if (!eventMap) {\n eventMap = new WeakMap();\n targets.set(target, eventMap);\n }\n\n const callback = value.bind(null, host);\n eventMap.set(value, callback);\n\n target.addEventListener(\n eventType,\n callback,\n value.options !== undefined ? value.options : false,\n );\n }\n };\n}\n","function normalizeValue(value, set = new Set()) {\n if (Array.isArray(value)) {\n value.forEach((className) => set.add(className));\n } else if (value !== null && typeof value === \"object\") {\n Object.keys(value).forEach((key) => value[key] && set.add(key));\n } else {\n set.add(value);\n }\n\n return set;\n}\n\nconst classMap = new WeakMap();\n\nexport default function resolveClassList(host, target, value) {\n const previousList = classMap.get(target) || new Set();\n const list = normalizeValue(value);\n\n classMap.set(target, list);\n\n list.forEach((className) => {\n target.classList.add(className);\n previousList.delete(className);\n });\n\n previousList.forEach((className) => {\n target.classList.remove(className);\n });\n}\n","import { camelToDash, stringifyElement } from \"../../utils.js\";\n\nconst styleMap = new WeakMap();\n\nexport default function resolveStyle(host, target, value) {\n if (value === null || typeof value !== \"object\") {\n throw TypeError(\n `Style value must be an object in ${stringifyElement(target)}:`,\n value,\n );\n }\n\n const previousMap = styleMap.get(target) || new Map();\n\n const nextMap = Object.keys(value).reduce((map, key) => {\n const dashKey = camelToDash(key);\n const styleValue = value[key];\n\n if (!styleValue && styleValue !== 0) {\n target.style.removeProperty(dashKey);\n } else {\n target.style.setProperty(dashKey, styleValue);\n }\n\n map.set(dashKey, styleValue);\n previousMap.delete(dashKey);\n\n return map;\n }, new Map());\n\n previousMap.forEach((styleValue, key) => {\n target.style[key] = \"\";\n });\n\n styleMap.set(target, nextMap);\n}\n","import global from \"../../global.js\";\nimport resolveEventListener from \"./event.js\";\nimport resolveClassList from \"./class.js\";\nimport resolveStyleList from \"./style.js\";\n\nexport default function resolveProperty(attrName, propertyName, isSVG) {\n if (propertyName.substr(0, 2) === \"on\") {\n const eventType = propertyName.substr(2);\n return resolveEventListener(eventType);\n }\n\n switch (attrName) {\n case \"class\":\n return resolveClassList;\n case \"style\":\n return resolveStyleList;\n default: {\n let isProp = false;\n return (host, target, value) => {\n isProp =\n isProp ||\n (!isSVG &&\n !(target instanceof global.SVGElement) &&\n propertyName in target);\n if (isProp) {\n target[propertyName] = value;\n } else if (value === false || value === undefined || value === null) {\n target.removeAttribute(attrName);\n } else {\n const attrValue = value === true ? \"\" : String(value);\n target.setAttribute(attrName, attrValue);\n }\n };\n }\n }\n}\n","import global from \"../global.js\";\nimport { stringifyElement, probablyDevMode } from \"../utils.js\";\nimport { get as getMessage, isLocalizeEnabled } from \"../localize.js\";\n\nimport * as layout from \"./layout.js\";\nimport {\n getMeta,\n getPlaceholder,\n getTemplateEnd,\n removeTemplate,\n} from \"./utils.js\";\n\nimport resolveValue from \"./resolvers/value.js\";\nimport resolveProperty from \"./resolvers/property.js\";\n\nconst PLACEHOLDER_REGEXP_TEXT = getPlaceholder(\"(\\\\d+)\");\nconst PLACEHOLDER_REGEXP_EQUAL = new RegExp(`^${PLACEHOLDER_REGEXP_TEXT}$`);\nconst PLACEHOLDER_REGEXP_ALL = new RegExp(PLACEHOLDER_REGEXP_TEXT, \"g\");\nconst PLACEHOLDER_REGEXP_ONLY = /^[^A-Za-z]+$/;\n\nfunction createSignature(parts) {\n let signature = parts.reduce((acc, part, index) => {\n if (index === 0) {\n return part;\n }\n\n if (\n parts\n .slice(index)\n .join(\"\")\n .match(/^\\s*<\\/\\s*(table|tr|thead|tbody|tfoot|colgroup)>/)\n ) {\n return `${acc}${part}`;\n }\n\n return acc + getPlaceholder(index - 1) + part;\n }, \"\");\n\n return signature;\n}\n\nfunction getPropertyName(string) {\n return string\n .replace(/\\s*=\\s*['\"]*$/g, \"\")\n .split(/\\s+/)\n .pop();\n}\n\nfunction createWalker(context) {\n return global.document.createTreeWalker(\n context,\n // eslint-disable-next-line no-bitwise\n global.NodeFilter.SHOW_ELEMENT |\n global.NodeFilter.SHOW_TEXT |\n global.NodeFilter.SHOW_COMMENT,\n null,\n false,\n );\n}\n\nfunction normalizeWhitespace(input, startIndent = 0) {\n input = input.replace(/(^[\\n\\s\\t ]+)|([\\n\\s\\t ]+$)+/g, \"\");\n\n let i = input.indexOf(\"\\n\");\n if (i > -1) {\n let indent = 0 - startIndent - 2;\n for (i += 1; input[i] === \" \" && i < input.length; i += 1) {\n indent += 1;\n }\n return input.replace(/\\n +/g, (t) =>\n t.substr(0, Math.max(t.length - indent, 1)),\n );\n }\n\n return input;\n}\n\nfunction beautifyTemplateLog(input, index) {\n const placeholder = getPlaceholder(index);\n\n const output = normalizeWhitespace(input)\n .split(\"\\n\")\n .filter((i) => i)\n .map((line) => {\n const startIndex = line.indexOf(placeholder);\n\n if (startIndex > -1) {\n return `| ${line}\\n--${\"-\".repeat(startIndex)}${\"^\".repeat(6)}`;\n }\n\n return `| ${line}`;\n })\n .join(\"\\n\")\n // eslint-disable-next-line no-template-curly-in-string\n .replace(PLACEHOLDER_REGEXP_ALL, \"${...}\");\n\n return `${output}`;\n}\n\nconst styleSheetsMap = new Map();\nfunction setupStyleUpdater(target) {\n if (target.adoptedStyleSheets) {\n let prevStyleSheets;\n return (styleSheets) => {\n const adoptedStyleSheets = target.adoptedStyleSheets;\n\n if (styleSheets) {\n styleSheets = styleSheets.map((style) => {\n let styleSheet = style;\n if (!(styleSheet instanceof global.CSSStyleSheet)) {\n styleSheet = styleSheetsMap.get(style);\n if (!styleSheet) {\n styleSheet = new global.CSSStyleSheet();\n styleSheet.replaceSync(style);\n styleSheetsMap.set(style, styleSheet);\n }\n }\n\n return styleSheet;\n });\n\n if (\n !prevStyleSheets ||\n prevStyleSheets.some((styleSheet, i) => styleSheet !== styleSheets[i])\n ) {\n // TODO: this might change order of already applied styles\n target.adoptedStyleSheets = (\n prevStyleSheets\n ? adoptedStyleSheets.filter(\n (styleSheet) => !prevStyleSheets.includes(styleSheet),\n )\n : adoptedStyleSheets\n ).concat(styleSheets);\n }\n } else if (prevStyleSheets) {\n target.adoptedStyleSheets = adoptedStyleSheets.filter(\n (styleSheet) => !prevStyleSheets.includes(styleSheet),\n );\n }\n\n prevStyleSheets = styleSheets;\n };\n }\n\n let styleEl;\n return (styleSheets) => {\n if (styleSheets) {\n if (!styleEl) {\n styleEl = global.document.createElement(\"style\");\n target = getTemplateEnd(target);\n if (target.nodeType === global.Node.TEXT_NODE) {\n target.parentNode.insertBefore(styleEl, target.nextSibling);\n } else {\n target.appendChild(styleEl);\n }\n }\n const result = [...styleSheets].join(\"\\n/*------*/\\n\");\n\n if (styleEl.textContent !== result) {\n styleEl.textContent = result;\n }\n } else if (styleEl) {\n styleEl.parentNode.removeChild(styleEl);\n styleEl = null;\n }\n };\n}\n\nexport function compileTemplate(rawParts, isSVG, isMsg, useLayout) {\n let template = global.document.createElement(\"template\");\n const parts = {};\n\n const signature = isMsg ? rawParts : createSignature(rawParts);\n\n template.innerHTML = isSVG ? `${signature}` : signature;\n\n if (isSVG) {\n const svgRoot = template.content.firstChild;\n template.content.removeChild(svgRoot);\n Array.from(svgRoot.childNodes).forEach((node) =>\n template.content.appendChild(node),\n );\n }\n\n let hostLayout;\n const layoutTemplate = template.content.children[0];\n if (layoutTemplate instanceof global.HTMLTemplateElement) {\n Array.from(layoutTemplate.attributes).forEach((attr) => {\n const value = attr.value.trim();\n if (attr.name.startsWith(\"layout\") && value) {\n if (value.match(PLACEHOLDER_REGEXP_ALL)) {\n throw Error(\"Layout attribute cannot contain expressions\");\n }\n\n hostLayout = layout.insertRule(\n layoutTemplate,\n attr.name.substr(6),\n value,\n true,\n );\n }\n });\n\n if (hostLayout !== undefined && template.content.children.length > 1) {\n throw Error(\n \"Template, which uses layout system must have only the '