@dinoreic/fez 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/fez.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/fez/lib/n.js", "../src/fez/lib/template.js", "../src/fez/instance.js", "../src/fez/vendor/gobber.js", "../src/fez/vendor/idiomorph.js", "../src/fez/connect.js", "../src/fez/compile.js", "../src/fez/lib/global-state.js", "../src/fez/root.js", "../src/fez.js"],
4
- "sourcesContent": ["// Exposes node building method, that gets node name, attrs and body.\n// n('span', {id: id}), n('.foo', {id: id}, body), n('.foo', {id: id}, [...])\n// * you can switch places for attrs and body, and body can be list of nodes\n// * n('.foo.bar') -> n('div', { class: 'foo bar' })\n//\n// copyright @dux, 2024\n// Licence MIT\n\nexport default function n(name, attrs = {}, data) {\n if (typeof attrs === 'string') {\n [attrs, data] = [data, attrs]\n attrs ||= {}\n }\n\n if (attrs instanceof Node) {\n data = attrs\n attrs = {}\n }\n\n if (Array.isArray(name)) {\n data = name\n name = 'div'\n }\n\n if (typeof attrs !== 'object' || Array.isArray(attrs)) {\n data = attrs\n attrs = {}\n }\n\n if (name.includes('.')) {\n const parts = name.split('.')\n name = parts.shift() || 'div'\n const c = parts.join(' ');\n if (attrs.class) {\n attrs.class += ` ${c}`;\n } else {\n attrs.class = c\n }\n }\n\n const node = document.createElement(name);\n\n for (const [k, v] of Object.entries(attrs)) {\n if (typeof v === 'function') {\n node[k] = v.bind(this)\n } else {\n const value = String(v).replaceAll('fez.', this.fezHtmlRoot);\n node.setAttribute(k, value)\n }\n }\n\n if (data) {\n if (Array.isArray(data)) {\n for (const n of data) {\n node.appendChild(n)\n }\n } else if (data instanceof Node) {\n node.appendChild(data)\n } else {\n node.innerHTML = String(data)\n }\n }\n\n return node\n}\n", "function parseBlock(data, ifStack) {\n data = data\n .replace(/^#?raw/, '@html')\n .replace(/^#?html/, '@html')\n\n // Handle #if directive\n if (data.startsWith('#if') || data.startsWith('if')) {\n ifStack.push(false)\n data = data.replace(/^#?if/, '')\n return `\\${ ${data} ? \\``\n }\n else if (data.startsWith('#unless') || data.startsWith('unless')) {\n ifStack.push(false)\n data = data.replace(/^#?unless/, '')\n return `\\${ !(${data}) ? \\``\n }\n else if (data == '/block') {\n return '`) && \\'\\'}'\n }\n else if (data.startsWith('#for') || data.startsWith('for')) {\n data = data.replace(/^#?for/, '')\n const el = data.split(' in ', 2)\n return '${' + el[1] + '.map((' + el[0] + ')=>`'\n }\n else if (data.startsWith('#each') || data.startsWith('each')) {\n data = data.replace(/^#?each/, '')\n const el = data.split(' as ', 2)\n return '${' + el[0] + '.map((' + el[1] + ')=>`'\n }\n else if (data == ':else' || data == 'else') {\n ifStack[ifStack.length - 1] = true\n return '` : `'\n }\n else if (data == '/if' || data == '/unless') {\n return ifStack.pop() ? '`}' : '` : ``}'\n }\n else if (data == '/for' || data == '/each') {\n return '`).join(\"\")}'\n }\n else {\n const prefix = '@html '\n\n if (data.startsWith(prefix)) {\n data = data.replace(prefix, '')\n } else {\n data = `Fez.htmlEscape(${data})`\n }\n\n return '${' + data + '}'\n }\n}\n\n// let tpl = createTemplate(string)\n// tpl({ ... this state ...})\nexport default function createTemplate(text, opts = {}) {\n const ifStack = []\n\n // some templating engines, as GoLangs use {{ for templates. Allow usage of [[ for fez\n text = text\n .replaceAll('[[', '{{')\n .replaceAll(']]', '}}')\n\n text = text.replace(/(\\w+)=\\{\\{\\s*(.*?)\\s*\\}\\}([\\s>])/g, (match, p1, p2, p3) => {\n return `${p1}=\"{`+`{ ${p2} }`+`}\"${p3}`\n })\n\n // {{block foo}} ... {{/block}}\n // {{block:foo}}\n const blocks = {}\n text = text.replace(/\\{\\{block\\s+(\\w+)\\s*\\}\\}([^\u00A7]+)\\{\\{\\/block\\}\\}/g, (_, name, block) => {\n blocks[name] = block\n return ''\n })\n text = text.replace(/\\{\\{block:([\\w\\-]+)\\s*\\}\\}/g, (_, name) => blocks[name] || `block:${name}?`)\n\n // {{#for el in list }}}}\n // <ui-comment :comment=\"el\"></ui-comment>\n // -> :comment=\"{{ JSON.stringify(el) }}\"\n // skip attr=\"foo.bar\"\n text = text.replace(/:(\\w+)=\"([\\w\\.\\[\\]]+)\"/, (_, m1, m2) => {\n return `:${m1}=Fez.store.delete({{ Fez.store.set(${m2}) }})`\n })\n\n let result = text.replace(/{{(.*?)}}/g, (_, content) => {\n content = content.replaceAll('&#x60;', '`')\n\n content = content\n .replaceAll('&lt;', '<')\n .replaceAll('&gt;', '>')\n .replaceAll('&amp;', '&')\n const parsedData = parseBlock(content, ifStack);\n\n return parsedData\n });\n\n result = '`' + result.trim() + '`'\n\n try {\n const funcBody = `const fez = this;\n with (this) {\n return ${result}\n }\n `\n const tplFunc = new Function(funcBody);\n const outFunc = (o) => {\n try {\n return tplFunc.bind(o)()\n } catch(e) {\n e.message = `FEZ template runtime error: ${e.message}\\n\\nTemplate source: ${result}`\n console.error(e)\n }\n }\n return outFunc\n } catch(e) {\n e.message = `FEZ template compile error: ${e.message}Template source:\\n${result}`\n console.error(e)\n return ()=>Fez.error(`Template Compile Error`, true)\n }\n}\n", "// HTML node builder\nimport parseNode from './lib/n.js'\nimport createTemplate from './lib/template.js'\n\nexport default class FezBase {\n // get node attributes as object\n static getProps(node, newNode) {\n let attrs = {}\n\n // we can directly attach props to DOM node instance\n if (node.props) {\n return node.props\n }\n\n // LOG(node.nodeName, node.attributes)\n for (const attr of node.attributes) {\n attrs[attr.name] = attr.value\n }\n\n for (const [key, val] of Object.entries(attrs)) {\n if ([':'].includes(key[0])) {\n delete attrs[key]\n try {\n const newVal = new Function(`return (${val})`).bind(newNode)()\n attrs[key.replace(/[\\:_]/, '')] = newVal\n\n } catch (e) {\n console.error(`Fez: Error evaluating attribute ${key}=\"${val}\" for ${node.tagName}: ${e.message}`)\n }\n }\n }\n\n if (attrs['data-props']) {\n let data = attrs['data-props']\n\n if (typeof data == 'object') {\n return data\n }\n else {\n if (data[0] != '{') {\n data = decodeURIComponent(data)\n }\n try {\n attrs = JSON.parse(data)\n } catch (e) {\n console.error(`Fez: Invalid JSON in data-props for ${node.tagName}: ${e.message}`)\n }\n }\n }\n\n // pass props as json template\n // <script type=\"text/template\">{...}</script>\n // <foo-bar data-json-template=\"true\"></foo-bar>\n else if (attrs['data-json-template']) {\n const data = newNode.previousSibling?.textContent\n if (data) {\n try {\n attrs = JSON.parse(data)\n newNode.previousSibling.remove()\n } catch (e) {\n console.error(`Fez: Invalid JSON in template for ${node.tagName}: ${e.message}`)\n }\n }\n }\n\n return attrs\n }\n\n static formData(node) {\n const formNode = node.closest('form') || node.querySelector('form')\n if (!formNode) {\n Fez.log('No form found for formData()')\n return {}\n }\n const formData = new FormData(formNode)\n const formObject = {}\n formData.forEach((value, key) => {\n formObject[key] = value\n });\n return formObject\n }\n\n static fastBind() {\n // return true to bind without requestAnimationFrame\n // you can do this if you are sure you are not expecting innerHTML data\n return false\n }\n\n static nodeName = 'div'\n\n // instance methods\n\n constructor() {}\n\n n = parseNode\n\n // string selector for use in HTML nodes\n get fezHtmlRoot() {\n return `Fez(${this.UID}).`\n // return this.props.id ? `Fez.find(\"#${this.props.id}\").` : `Fez.find(this, \"${this.fezName}\").`\n }\n\n // checks if node is attached and clears all if not\n get isConnected() {\n if (this.root?.isConnected) {\n return true\n } else {\n this.fezRemoveSelf()\n return false\n }\n }\n\n fezRemoveSelf() {\n this._setIntervalCache ||= {}\n Object.keys(this._setIntervalCache).forEach((key)=> {\n clearInterval(this._setIntervalCache[key])\n })\n\n this.onDestroy()\n this.onDestroy = ()=> {}\n\n if (this.root) {\n this.root.fez = undefined\n }\n\n this.root = undefined\n }\n\n // get single node property\n prop(name) {\n let v = this.oldRoot[name] || this.props[name]\n if (typeof v == 'function') {\n // if this.prop('onclick'), we want \"this\" to point to this.root (dom node)\n v = v.bind(this.root)\n }\n return v\n }\n\n // copy attributes to root node\n copy() {\n for (const name of Array.from(arguments)) {\n let value = this.props[name]\n\n if (value !== undefined) {\n if (name == 'class') {\n const klass = this.root.getAttribute(name, value)\n\n if (klass) {\n value = [klass, value].join(' ')\n }\n }\n\n if (name == 'style' || !this.root[name]) {\n if (typeof value == 'string') {\n this.root.setAttribute(name, value)\n }\n else {\n this.root[name] = value\n }\n }\n }\n }\n }\n\n // helper function to execute stuff on window resize, and clean after node is not connected any more\n // if delay given, throttle, if not debounce\n onResize(func, delay) {\n let timeoutId;\n let lastRun = 0;\n\n func()\n\n const checkAndExecute = () => {\n if (!this.isConnected) {\n window.removeEventListener('resize', handleResize);\n return;\n }\n func.call(this);\n };\n\n const handleResize = () => {\n if (!this.isConnected) {\n window.removeEventListener('resize', handleResize);\n return;\n }\n\n if (delay) {\n // Throttle\n const now = Date.now();\n if (now - lastRun >= delay) {\n checkAndExecute();\n lastRun = now;\n }\n } else {\n // Debounce\n clearTimeout(timeoutId);\n timeoutId = setTimeout(checkAndExecute, 200);\n }\n };\n\n window.addEventListener('resize', handleResize);\n }\n\n // copy child nodes, natively to preserve bound events\n // if node name is SLOT insert adjacent and remove SLOT, else as a child nodes\n slot(source, target) {\n target ||= document.createElement('template')\n const isSlot = target.nodeName == 'SLOT'\n\n while (source.firstChild) {\n if (isSlot) {\n target.parentNode.insertBefore(source.lastChild, target.nextSibling);\n } else {\n target.appendChild(source.firstChild)\n }\n }\n\n if (isSlot) {\n target.parentNode.removeChild(target)\n } else {\n source.innerHTML = ''\n }\n\n return target\n }\n\n setStyle(key, value) {\n this.root.style.setProperty(key, value);\n }\n\n connect() {}\n onMount() {}\n beforeRender() {}\n afterRender() {}\n onDestroy() {}\n onStateChange() {}\n onGlobalStateChange() {}\n publish = Fez.publish\n fezBlocks = {}\n\n parseHtml(text) {\n const base = this.fezHtmlRoot.replaceAll('\"', '&quot;')\n\n text = text\n .replace(/([^\\w\\.])fez\\./g, `$1${base}`)\n .replace(/>\\s+</g, '><')\n\n return text.trim()\n }\n\n\n // pass name to have only one tick of a kind\n nextTick(func, name) {\n if (name) {\n this._nextTicks ||= {}\n this._nextTicks[name] ||= window.requestAnimationFrame(() => {\n func.bind(this)()\n this._nextTicks[name] = null\n }, name)\n } else {\n window.requestAnimationFrame(func.bind(this))\n }\n }\n\n // inject htmlString as innerHTML and replace $$. with local pointer\n // $$. will point to current fez instance\n // <slot></slot> will be replaced with current root\n // this.render('...loading')\n // this.render('.images', '...loading')\n render(template) {\n template ||= this?.class?.fezHtmlFunc\n\n if (!template || !this.root) return\n\n this.beforeRender()\n\n const newNode = document.createElement(this.class.nodeName || 'div')\n\n let renderedTpl\n if (Array.isArray(template)) {\n // array nodes this.n(...), look tabs example\n if (template[0] instanceof Node) {\n template.forEach( n => newNode.appendChild(n) )\n } else{\n renderedTpl = template.join('')\n }\n }\n else if (typeof template == 'string') {\n renderedTpl = createTemplate(template)(this)\n }\n else if (typeof template == 'function') {\n renderedTpl = template(this)\n }\n\n if (renderedTpl) {\n renderedTpl = renderedTpl.replace(/\\s\\w+=\"undefined\"/g, '')\n newNode.innerHTML = this.parseHtml(renderedTpl)\n }\n\n // this comes only from array nodes this.n(...)\n const slot = newNode.querySelector('slot')\n if (slot) {\n this.slot(this.root, slot.parentNode)\n slot.parentNode.removeChild(slot)\n }\n\n //let currentSlot = this.root.querySelector(':not(span.fez):not(div.fez) > .fez-slot, .fez-slot:not(span.fez *):not(div.fez *)');\n let currentSlot = this.find('.fez-slot')\n if (currentSlot) {\n const newSLot = newNode.querySelector('.fez-slot')\n if (newSLot) {\n newSLot.parentNode.replaceChild(currentSlot, newSLot)\n }\n }\n\n Fez.morphdom(this.root, newNode)\n\n this.renderFezPostProcess()\n\n this.afterRender()\n }\n\n renderFezPostProcess() {\n const fetchAttr = (name, func) => {\n this.root.querySelectorAll(`*[${name}]`).forEach((n)=>{\n let value = n.getAttribute(name)\n n.removeAttribute(name)\n if (value) {\n func.bind(this)(value, n)\n }\n })\n }\n\n // <button fez-this=\"button\" -> this.button = node\n fetchAttr('fez-this', (value, n) => {\n (new Function('n', `this.${value} = n`)).bind(this)(n)\n })\n\n // <button fez-use=\"animate\" -> this.animate(node]\n fetchAttr('fez-use', (value, n) => {\n const target = this[value]\n if (typeof target == 'function') {\n target(n)\n } else {\n console.error(`Fez error: \"${value}\" is not a function in ${this.fezName}`)\n }\n })\n\n // <button fez-class=\"dialog animate\" -> add class \"animate\" after node init to trigger animation\n fetchAttr('fez-class', (value, n) => {\n let classes = value.split(/\\s+/)\n let lastClass = classes.pop()\n classes.forEach((c)=> n.classList.add(c) )\n if (lastClass) {\n setTimeout(()=>{\n n.classList.add(lastClass)\n }, 300)\n }\n })\n\n // <input fez-bind=\"state.inputNode\" -> this.state.inputNode will be the value of input\n fetchAttr('fez-bind', (text, n) => {\n if (['INPUT', 'SELECT', 'TEXTAREA'].includes(n.nodeName)) {\n const value = (new Function(`return this.${text}`)).bind(this)()\n const isCb = n.type.toLowerCase() == 'checkbox'\n const eventName = ['SELECT'].includes(n.nodeName) || isCb ? 'onchange' : 'onkeyup'\n n.setAttribute(eventName, `${this.fezHtmlRoot}${text} = this.${isCb ? 'checked' : 'value'}`)\n this.val(n, value)\n } else {\n console.error(`Cant fez-bind=\"${text}\" to ${n.nodeName} (needs INPUT, SELECT or TEXTAREA. Want to use fez-this?).`)\n }\n })\n\n this.root.querySelectorAll(`*[disabled]`).forEach((n)=>{\n let value = n.getAttribute('disabled')\n if (['false'].includes(value)) {\n n.removeAttribute('disabled')\n } else {\n n.setAttribute('disabled', 'true')\n }\n })\n }\n\n // refresh single node only\n refresh(selector) {\n alert('NEEDS FIX and remove htmlTemplate')\n if (selector) {\n const n = document.createElement('div')\n n.innerHTML = this.class.htmlTemplate\n const tpl = n.querySelector(selector).innerHTML\n this.render(selector, tpl)\n } else {\n this.render()\n }\n }\n\n // run only if node is attached, clear otherwise\n setInterval(func, tick, name) {\n if (typeof func == 'number') {\n [tick, func] = [func, tick]\n }\n\n name ||= Fez.fnv1(String(func))\n\n this._setIntervalCache ||= {}\n clearInterval(this._setIntervalCache[name])\n\n this._setIntervalCache[name] = setInterval(() => {\n if (this.isConnected) {\n func()\n }\n }, tick)\n\n return this._setIntervalCache[name]\n }\n\n find(selector) {\n return typeof selector == 'string' ? this.root.querySelector(selector) : selector\n }\n\n // get or set node value\n val(selector, data) {\n const node = this.find(selector)\n\n if (node) {\n if (['INPUT', 'TEXTAREA', 'SELECT'].includes(node.nodeName)) {\n if (typeof data != 'undefined') {\n if (node.type == 'checkbox') {\n node.checked = !!data\n } else {\n node.value = data\n }\n } else {\n return node.value\n }\n } else {\n if (typeof data != 'undefined') {\n node.innerHTML = data\n } else {\n return node.innerHTML\n }\n }\n }\n }\n\n formData(node) {\n return this.class.formData(node || this.root)\n }\n\n // get or set attribute\n attr(name, value) {\n if (typeof value === 'undefined') {\n return this.root.getAttribute(name)\n } else {\n this.root.setAttribute(name, value)\n return value\n }\n }\n\n // get root node child nodes as array\n childNodes(func) {\n const children = Array.from(this.root.children)\n\n if (func) {\n // Create temporary container to avoid ancestor-parent errors\n const tmpContainer = document.createElement('div')\n tmpContainer.style.display = 'none'\n document.body.appendChild(tmpContainer)\n children.forEach(child => tmpContainer.appendChild(child))\n\n let list = Array.from(tmpContainer.children).map(func)\n document.body.removeChild(tmpContainer)\n return list\n } else {\n return children\n }\n }\n\n subscribe(channel, func) {\n Fez._subs ||= {}\n Fez._subs[channel] ||= []\n Fez._subs[channel] = Fez._subs[channel].filter((el) => el[0].isConnected)\n Fez._subs[channel].push([this, func])\n }\n\n // get and set root node ID\n rootId() {\n this.root.id ||= `fez_${this.UID}`\n return this.root.id\n }\n\n fezRegister() {\n if (this.css) {\n this.css = Fez.globalCss(this.css, {name: this.fezName, wrap: true})\n }\n\n if (this.class.css) {\n this.class.css = Fez.globalCss(this.class.css, {name: this.fezName})\n }\n\n this.state ||= this.reactiveStore()\n this.globalState = Fez.state.createProxy(this)\n this.fezRegisterBindMethods()\n }\n\n // bind all instance method to this, to avoid calling with .bind(this)\n fezRegisterBindMethods() {\n const methods = Object.getOwnPropertyNames(Object.getPrototypeOf(this))\n .filter(method => method !== 'constructor' && typeof this[method] === 'function')\n\n methods.forEach(method => this[method] = this[method].bind(this))\n }\n\n fezHide() {\n const node = this.root\n const parent = this.root.parentNode\n const fragment = document.createDocumentFragment();\n\n while (node.firstChild) {\n fragment.appendChild(node.firstChild)\n }\n\n // Replace the target element with the fragment (which contains the child elements)\n node.parentNode.replaceChild(fragment, node);\n // parent.classList.add('fez')\n // parent.classList.add(`fez-${this.fezName}`)\n this.root = parent\n return Array.from(this.root.children)\n }\n\n reactiveStore(obj, handler) {\n obj ||= {}\n\n handler ||= (o, k, v, oldValue) => {\n this.onStateChange(k, v, oldValue)\n this.nextTick(this.render, 'render')\n }\n\n handler.bind(this)\n\n // licence ? -> generated by ChatGPT 2024\n function createReactive(obj, handler) {\n if (typeof obj !== 'object' || obj === null) {\n return obj;\n }\n\n return new Proxy(obj, {\n set(target, property, value, receiver) {\n // Get the current value of the property\n const currentValue = Reflect.get(target, property, receiver);\n\n // Only proceed if the new value is different from the current value\n if (currentValue !== value) {\n if (typeof value === 'object' && value !== null) {\n value = createReactive(value, handler); // Recursively make nested objects reactive\n }\n\n // Set the new value\n const result = Reflect.set(target, property, value, receiver);\n\n // Call the handler only if the value has changed\n handler(target, property, value, currentValue);\n\n return result;\n }\n\n // If the value hasn't changed, return true (indicating success) without calling the handler\n return true;\n },\n get(target, property, receiver) {\n const value = Reflect.get(target, property, receiver);\n if (typeof value === 'object' && value !== null) {\n return createReactive(value, handler); // Recursively make nested objects reactive\n }\n return value;\n }\n });\n }\n\n return createReactive(obj, handler);\n }\n}\n", "/**\n * Skipped minification because the original files appears to be already minified.\n * Original file: /npm/goober@2.1.14/dist/goober.modern.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\nlet e={data:\"\"},t=t=>\"object\"==typeof window?((t?t.querySelector(\"#_goober\"):window._goober)||Object.assign((t||document.head).appendChild(document.createElement(\"style\")),{innerHTML:\" \",id:\"_goober\"})).firstChild:t||e,a=e=>{let a=t(e),r=a.data;return a.data=\"\",r},r=/(?:([\\u0080-\\uFFFF\\w-%@]+) *:? *([^{;]+?);|([^;}{]*?) *{)|(}\\s*)/g,l=/\\/\\*[^]*?\\*\\/| +/g,s=/\\n+/g,n=(e,t)=>{let a=\"\",r=\"\",l=\"\";for(let s in e){let o=e[s];\"@\"==s[0]?\"i\"==s[1]?a=s+\" \"+o+\";\":r+=\"f\"==s[1]?n(o,s):s+\"{\"+n(o,\"k\"==s[1]?\"\":t)+\"}\":\"object\"==typeof o?r+=n(o,t?t.replace(/([^,])+/g,(e=>s.replace(/(^:.*)|([^,])+/g,(t=>/&/.test(t)?t.replace(/&/g,e):e?e+\" \"+t:t)))):s):null!=o&&(s=/^--/.test(s)?s:s.replace(/[A-Z]/g,\"-$&\").toLowerCase(),l+=n.p?n.p(s,o):s+\":\"+o+\";\")}return a+(t&&l?t+\"{\"+l+\"}\":l)+r},o={},c=e=>{if(\"object\"==typeof e){let t=\"\";for(let a in e)t+=a+c(e[a]);return t}return e},i=(e,t,a,i,p)=>{let u=c(e),d=o[u]||(o[u]=(e=>{let t=0,a=11;for(;t<e.length;)a=101*a+e.charCodeAt(t++)>>>0;return\"go\"+a})(u));if(!o[d]){let t=u!==e?e:(e=>{let t,a,n=[{}];for(;t=r.exec(e.replace(l,\"\"));)t[4]?n.shift():t[3]?(a=t[3].replace(s,\" \").trim(),n.unshift(n[0][a]=n[0][a]||{})):n[0][t[1]]=t[2].replace(s,\" \").trim();return n[0]})(e);o[d]=n(p?{[\"@keyframes \"+d]:t}:t,a?\"\":\".\"+d)}let f=a&&o.g?o.g:null;return a&&(o.g=o[d]),((e,t,a,r)=>{r?t.data=t.data.replace(r,e):-1===t.data.indexOf(e)&&(t.data=a?e+t.data:t.data+e)})(o[d],t,i,f),d},p=(e,t,a)=>e.reduce(((e,r,l)=>{let s=t[l];if(s&&s.call){let e=s(a),t=e&&e.props&&e.props.className||/^go/.test(e)&&e;s=t?\".\"+t:e&&\"object\"==typeof e?e.props?\"\":n(e,\"\"):!1===e?\"\":e}return e+r+(null==s?\"\":s)}),\"\");function u(e){let a=this||{},r=e.call?e(a.p):e;return i(r.unshift?r.raw?p(r,[].slice.call(arguments,1),a.p):r.reduce(((e,t)=>Object.assign(e,t&&t.call?t(a.p):t)),{}):r,t(a.target),a.g,a.o,a.k)}let d,f,g,b=u.bind({g:1}),m=u.bind({k:1});function h(e,t,a,r){n.p=t,d=e,f=a,g=r}function y(e,t){let a=this||{};return function(){let r=arguments;function l(s,n){let o=Object.assign({},s),c=o.className||l.className;a.p=Object.assign({theme:f&&f()},o),a.o=/ *go\\d+/.test(c),o.className=u.apply(a,r)+(c?\" \"+c:\"\"),t&&(o.ref=n);let i=e;return e[0]&&(i=o.as||e,delete o.as),g&&i[0]&&g(o),d(i,o)}return t?t(l):l}}\nexport default { css:u, extractCss: a, glob: b, keyframes: m, setup: h, styled: y }\n", "// base IIFE to define idiomorph\nvar Idiomorph = (function () {\n 'use strict';\n\n //=============================================================================\n // AND NOW IT BEGINS...\n //=============================================================================\n let EMPTY_SET = new Set();\n\n // default configuration values, updatable by users now\n let defaults = {\n morphStyle: \"outerHTML\",\n callbacks : {\n beforeNodeAdded: noOp,\n afterNodeAdded: noOp,\n beforeNodeMorphed: noOp,\n afterNodeMorphed: noOp,\n beforeNodeRemoved: noOp,\n afterNodeRemoved: noOp,\n beforeAttributeUpdated: noOp,\n\n },\n head: {\n style: 'merge',\n shouldPreserve: function (elt) {\n return elt.getAttribute(\"im-preserve\") === \"true\";\n },\n shouldReAppend: function (elt) {\n return elt.getAttribute(\"im-re-append\") === \"true\";\n },\n shouldRemove: noOp,\n afterHeadMorphed: noOp,\n }\n };\n\n //=============================================================================\n // Core Morphing Algorithm - morph, morphNormalizedContent, morphOldNodeTo, morphChildren\n //=============================================================================\n function morph(oldNode, newContent, config = {}) {\n\n if (oldNode instanceof Document) {\n oldNode = oldNode.documentElement;\n }\n\n if (typeof newContent === 'string') {\n newContent = parseContent(newContent);\n }\n\n let normalizedContent = normalizeContent(newContent);\n\n let ctx = createMorphContext(oldNode, normalizedContent, config);\n\n return morphNormalizedContent(oldNode, normalizedContent, ctx);\n }\n\n function morphNormalizedContent(oldNode, normalizedNewContent, ctx) {\n if (ctx.head.block) {\n let oldHead = oldNode.querySelector('head');\n let newHead = normalizedNewContent.querySelector('head');\n if (oldHead && newHead) {\n let promises = handleHeadElement(newHead, oldHead, ctx);\n // when head promises resolve, call morph again, ignoring the head tag\n Promise.all(promises).then(function () {\n morphNormalizedContent(oldNode, normalizedNewContent, Object.assign(ctx, {\n head: {\n block: false,\n ignore: true\n }\n }));\n });\n return;\n }\n }\n\n if (ctx.morphStyle === \"innerHTML\") {\n\n // innerHTML, so we are only updating the children\n morphChildren(normalizedNewContent, oldNode, ctx);\n return oldNode.children;\n\n } else if (ctx.morphStyle === \"outerHTML\" || ctx.morphStyle == null) {\n // otherwise find the best element match in the new content, morph that, and merge its siblings\n // into either side of the best match\n let bestMatch = findBestNodeMatch(normalizedNewContent, oldNode, ctx);\n\n // stash the siblings that will need to be inserted on either side of the best match\n let previousSibling = bestMatch?.previousSibling;\n let nextSibling = bestMatch?.nextSibling;\n\n // morph it\n let morphedNode = morphOldNodeTo(oldNode, bestMatch, ctx);\n\n if (bestMatch) {\n // if there was a best match, merge the siblings in too and return the\n // whole bunch\n return insertSiblings(previousSibling, morphedNode, nextSibling);\n } else {\n // otherwise nothing was added to the DOM\n return []\n }\n } else {\n throw \"Do not understand how to morph style \" + ctx.morphStyle;\n }\n }\n\n\n /**\n * @param possibleActiveElement\n * @param ctx\n * @returns {boolean}\n */\n function ignoreValueOfActiveElement(possibleActiveElement, ctx) {\n return ctx.ignoreActiveValue && possibleActiveElement === document.activeElement && possibleActiveElement !== document.body;\n }\n\n /**\n * @param oldNode root node to merge content into\n * @param newContent new content to merge\n * @param ctx the merge context\n * @returns {Element} the element that ended up in the DOM\n */\n function morphOldNodeTo(oldNode, newContent, ctx) {\n if (ctx.ignoreActive && oldNode === document.activeElement) {\n // don't morph focused element\n } else if (newContent == null) {\n if (ctx.callbacks.beforeNodeRemoved(oldNode) === false) return oldNode;\n\n oldNode.remove();\n ctx.callbacks.afterNodeRemoved(oldNode);\n return null;\n } else if (!isSoftMatch(oldNode, newContent)) {\n if (ctx.callbacks.beforeNodeRemoved(oldNode) === false) return oldNode;\n if (ctx.callbacks.beforeNodeAdded(newContent) === false) return oldNode;\n\n oldNode.parentElement.replaceChild(newContent, oldNode);\n ctx.callbacks.afterNodeAdded(newContent);\n ctx.callbacks.afterNodeRemoved(oldNode);\n return newContent;\n } else {\n if (ctx.callbacks.beforeNodeMorphed(oldNode, newContent) === false) return oldNode;\n\n if (oldNode instanceof HTMLHeadElement && ctx.head.ignore) {\n // ignore the head element\n } else if (oldNode instanceof HTMLHeadElement && ctx.head.style !== \"morph\") {\n handleHeadElement(newContent, oldNode, ctx);\n } else {\n syncNodeFrom(newContent, oldNode, ctx);\n if (!ignoreValueOfActiveElement(oldNode, ctx)) {\n morphChildren(newContent, oldNode, ctx);\n }\n }\n ctx.callbacks.afterNodeMorphed(oldNode, newContent);\n return oldNode;\n }\n }\n\n /**\n * This is the core algorithm for matching up children. The idea is to use id sets to try to match up\n * nodes as faithfully as possible. We greedily match, which allows us to keep the algorithm fast, but\n * by using id sets, we are able to better match up with content deeper in the DOM.\n *\n * Basic algorithm is, for each node in the new content:\n *\n * - if we have reached the end of the old parent, append the new content\n * - if the new content has an id set match with the current insertion point, morph\n * - search for an id set match\n * - if id set match found, morph\n * - otherwise search for a \"soft\" match\n * - if a soft match is found, morph\n * - otherwise, prepend the new node before the current insertion point\n *\n * The two search algorithms terminate if competing node matches appear to outweigh what can be achieved\n * with the current node. See findIdSetMatch() and findSoftMatch() for details.\n *\n * @param {Element} newParent the parent element of the new content\n * @param {Element } oldParent the old content that we are merging the new content into\n * @param ctx the merge context\n */\n function morphChildren(newParent, oldParent, ctx) {\n\n let nextNewChild = newParent.firstChild;\n let insertionPoint = oldParent.firstChild;\n let newChild;\n\n // run through all the new content\n while (nextNewChild) {\n\n newChild = nextNewChild;\n nextNewChild = newChild.nextSibling;\n\n // if we are at the end of the exiting parent's children, just append\n if (insertionPoint == null) {\n if (ctx.callbacks.beforeNodeAdded(newChild) === false) return;\n\n oldParent.appendChild(newChild);\n ctx.callbacks.afterNodeAdded(newChild);\n removeIdsFromConsideration(ctx, newChild);\n continue;\n }\n\n // if the current node has an id set match then morph\n if (isIdSetMatch(newChild, insertionPoint, ctx)) {\n morphOldNodeTo(insertionPoint, newChild, ctx);\n insertionPoint = insertionPoint.nextSibling;\n removeIdsFromConsideration(ctx, newChild);\n continue;\n }\n\n // otherwise search forward in the existing old children for an id set match\n let idSetMatch = findIdSetMatch(newParent, oldParent, newChild, insertionPoint, ctx);\n\n // if we found a potential match, remove the nodes until that point and morph\n if (idSetMatch) {\n insertionPoint = removeNodesBetween(insertionPoint, idSetMatch, ctx);\n morphOldNodeTo(idSetMatch, newChild, ctx);\n removeIdsFromConsideration(ctx, newChild);\n continue;\n }\n\n // no id set match found, so scan forward for a soft match for the current node\n let softMatch = findSoftMatch(newParent, oldParent, newChild, insertionPoint, ctx);\n\n // if we found a soft match for the current node, morph\n if (softMatch) {\n insertionPoint = removeNodesBetween(insertionPoint, softMatch, ctx);\n morphOldNodeTo(softMatch, newChild, ctx);\n removeIdsFromConsideration(ctx, newChild);\n continue;\n }\n\n // abandon all hope of morphing, just insert the new child before the insertion point\n // and move on\n if (ctx.callbacks.beforeNodeAdded(newChild) === false) return;\n\n oldParent.insertBefore(newChild, insertionPoint);\n ctx.callbacks.afterNodeAdded(newChild);\n removeIdsFromConsideration(ctx, newChild);\n }\n\n // remove any remaining old nodes that didn't match up with new content\n while (insertionPoint !== null) {\n\n let tempNode = insertionPoint;\n insertionPoint = insertionPoint.nextSibling;\n removeNode(tempNode, ctx);\n }\n }\n\n //=============================================================================\n // Attribute Syncing Code\n //=============================================================================\n\n /**\n * @param attr {String} the attribute to be mutated\n * @param to {Element} the element that is going to be updated\n * @param updateType {(\"update\"|\"remove\")}\n * @param ctx the merge context\n * @returns {boolean} true if the attribute should be ignored, false otherwise\n */\n function ignoreAttribute(attr, to, updateType, ctx) {\n if(attr === 'value' && ctx.ignoreActiveValue && to === document.activeElement){\n return true;\n }\n return ctx.callbacks.beforeAttributeUpdated(attr, to, updateType) === false;\n }\n\n /**\n * syncs a given node with another node, copying over all attributes and\n * inner element state from the 'from' node to the 'to' node\n *\n * @param {Element} from the element to copy attributes & state from\n * @param {Element} to the element to copy attributes & state to\n * @param ctx the merge context\n */\n function syncNodeFrom(from, to, ctx) {\n let type = from.nodeType\n\n // if is an element type, sync the attributes from the\n // new node into the new node\n if (type === 1 /* element type */) {\n const fromAttributes = from.attributes;\n const toAttributes = to.attributes;\n for (const fromAttribute of fromAttributes) {\n if (ignoreAttribute(fromAttribute.name, to, 'update', ctx)) {\n continue;\n }\n\n try {\n if (to.getAttribute(fromAttribute.name) !== fromAttribute.value) {\n to.setAttribute(fromAttribute.name, fromAttribute.value);\n }\n } catch (error) {\n // dux fix\n console.error('Error setting attribute:', {\n badNode: to,\n badAttribute: fromAttribute,\n error: error.message,\n });\n }\n }\n // iterate backwards to avoid skipping over items when a delete occurs\n for (let i = toAttributes.length - 1; 0 <= i; i--) {\n const toAttribute = toAttributes[i];\n if (ignoreAttribute(toAttribute.name, to, 'remove', ctx)) {\n continue;\n }\n if (!from.hasAttribute(toAttribute.name)) {\n to.removeAttribute(toAttribute.name);\n }\n }\n }\n\n // sync text nodes\n if (type === 8 /* comment */ || type === 3 /* text */) {\n if (to.nodeValue !== from.nodeValue) {\n to.nodeValue = from.nodeValue;\n }\n }\n\n if (!ignoreValueOfActiveElement(to, ctx)) {\n // sync input values\n syncInputValue(from, to, ctx);\n }\n }\n\n /**\n * @param from {Element} element to sync the value from\n * @param to {Element} element to sync the value to\n * @param attributeName {String} the attribute name\n * @param ctx the merge context\n */\n function syncBooleanAttribute(from, to, attributeName, ctx) {\n if (from[attributeName] !== to[attributeName]) {\n let ignoreUpdate = ignoreAttribute(attributeName, to, 'update', ctx);\n if (!ignoreUpdate) {\n to[attributeName] = from[attributeName];\n }\n if (from[attributeName]) {\n if (!ignoreUpdate) {\n to.setAttribute(attributeName, from[attributeName]);\n }\n } else {\n if (!ignoreAttribute(attributeName, to, 'remove', ctx)) {\n to.removeAttribute(attributeName);\n }\n }\n }\n }\n\n /**\n * NB: many bothans died to bring us information:\n *\n * https://github.com/patrick-steele-idem/morphdom/blob/master/src/specialElHandlers.js\n * https://github.com/choojs/nanomorph/blob/master/lib/morph.jsL113\n *\n * @param from {Element} the element to sync the input value from\n * @param to {Element} the element to sync the input value to\n * @param ctx the merge context\n */\n function syncInputValue(from, to, ctx) {\n if (from instanceof HTMLInputElement &&\n to instanceof HTMLInputElement &&\n from.type !== 'file') {\n\n let fromValue = from.value;\n let toValue = to.value;\n\n // sync boolean attributes\n syncBooleanAttribute(from, to, 'checked', ctx);\n syncBooleanAttribute(from, to, 'disabled', ctx);\n\n if (!from.hasAttribute('value')) {\n if (!ignoreAttribute('value', to, 'remove', ctx)) {\n to.value = '';\n to.removeAttribute('value');\n }\n } else if (fromValue !== toValue) {\n if (!ignoreAttribute('value', to, 'update', ctx)) {\n to.setAttribute('value', fromValue);\n to.value = fromValue;\n }\n }\n } else if (from instanceof HTMLOptionElement) {\n syncBooleanAttribute(from, to, 'selected', ctx)\n } else if (from instanceof HTMLTextAreaElement && to instanceof HTMLTextAreaElement) {\n let fromValue = from.value;\n let toValue = to.value;\n if (ignoreAttribute('value', to, 'update', ctx)) {\n return;\n }\n if (fromValue !== toValue) {\n to.value = fromValue;\n }\n if (to.firstChild && to.firstChild.nodeValue !== fromValue) {\n to.firstChild.nodeValue = fromValue\n }\n }\n }\n\n //=============================================================================\n // the HEAD tag can be handled specially, either w/ a 'merge' or 'append' style\n //=============================================================================\n function handleHeadElement(newHeadTag, currentHead, ctx) {\n\n let added = []\n let removed = []\n let preserved = []\n let nodesToAppend = []\n\n let headMergeStyle = ctx.head.style;\n\n // put all new head elements into a Map, by their outerHTML\n let srcToNewHeadNodes = new Map();\n for (const newHeadChild of newHeadTag.children) {\n srcToNewHeadNodes.set(newHeadChild.outerHTML, newHeadChild);\n }\n\n // for each elt in the current head\n for (const currentHeadElt of currentHead.children) {\n\n // If the current head element is in the map\n let inNewContent = srcToNewHeadNodes.has(currentHeadElt.outerHTML);\n let isReAppended = ctx.head.shouldReAppend(currentHeadElt);\n let isPreserved = ctx.head.shouldPreserve(currentHeadElt);\n if (inNewContent || isPreserved) {\n if (isReAppended) {\n // remove the current version and let the new version replace it and re-execute\n removed.push(currentHeadElt);\n } else {\n // this element already exists and should not be re-appended, so remove it from\n // the new content map, preserving it in the DOM\n srcToNewHeadNodes.delete(currentHeadElt.outerHTML);\n preserved.push(currentHeadElt);\n }\n } else {\n if (headMergeStyle === \"append\") {\n // we are appending and this existing element is not new content\n // so if and only if it is marked for re-append do we do anything\n if (isReAppended) {\n removed.push(currentHeadElt);\n nodesToAppend.push(currentHeadElt);\n }\n } else {\n // if this is a merge, we remove this content since it is not in the new head\n if (ctx.head.shouldRemove(currentHeadElt) !== false) {\n removed.push(currentHeadElt);\n }\n }\n }\n }\n\n // Push the remaining new head elements in the Map into the\n // nodes to append to the head tag\n nodesToAppend.push(...srcToNewHeadNodes.values());\n log(\"to append: \", nodesToAppend);\n\n let promises = [];\n for (const newNode of nodesToAppend) {\n log(\"adding: \", newNode);\n let newElt = document.createRange().createContextualFragment(newNode.outerHTML).firstChild;\n log(newElt);\n if (ctx.callbacks.beforeNodeAdded(newElt) !== false) {\n if (newElt.href || newElt.src) {\n let resolve = null;\n let promise = new Promise(function (_resolve) {\n resolve = _resolve;\n });\n newElt.addEventListener('load', function () {\n resolve();\n });\n promises.push(promise);\n }\n currentHead.appendChild(newElt);\n ctx.callbacks.afterNodeAdded(newElt);\n added.push(newElt);\n }\n }\n\n // remove all removed elements, after we have appended the new elements to avoid\n // additional network requests for things like style sheets\n for (const removedElement of removed) {\n if (ctx.callbacks.beforeNodeRemoved(removedElement) !== false) {\n currentHead.removeChild(removedElement);\n ctx.callbacks.afterNodeRemoved(removedElement);\n }\n }\n\n ctx.head.afterHeadMorphed(currentHead, {added: added, kept: preserved, removed: removed});\n return promises;\n }\n\n //=============================================================================\n // Misc\n //=============================================================================\n\n function log() {\n //console.log(arguments);\n }\n\n function noOp() {\n }\n\n /*\n Deep merges the config object and the Idiomoroph.defaults object to\n produce a final configuration object\n */\n function mergeDefaults(config) {\n let finalConfig = {};\n // copy top level stuff into final config\n Object.assign(finalConfig, defaults);\n Object.assign(finalConfig, config);\n\n // copy callbacks into final config (do this to deep merge the callbacks)\n finalConfig.callbacks = {};\n Object.assign(finalConfig.callbacks, defaults.callbacks);\n Object.assign(finalConfig.callbacks, config.callbacks);\n\n // copy head config into final config (do this to deep merge the head)\n finalConfig.head = {};\n Object.assign(finalConfig.head, defaults.head);\n Object.assign(finalConfig.head, config.head);\n return finalConfig;\n }\n\n function createMorphContext(oldNode, newContent, config) {\n config = mergeDefaults(config);\n return {\n target: oldNode,\n newContent: newContent,\n config: config,\n morphStyle: config.morphStyle,\n ignoreActive: config.ignoreActive,\n ignoreActiveValue: config.ignoreActiveValue,\n idMap: createIdMap(oldNode, newContent),\n deadIds: new Set(),\n callbacks: config.callbacks,\n head: config.head\n }\n }\n\n function isIdSetMatch(node1, node2, ctx) {\n if (node1 == null || node2 == null) {\n return false;\n }\n if (node1.nodeType === node2.nodeType && node1.tagName === node2.tagName) {\n if (node1.id !== \"\" && node1.id === node2.id) {\n return true;\n } else {\n return getIdIntersectionCount(ctx, node1, node2) > 0;\n }\n }\n return false;\n }\n\n function isSoftMatch(node1, node2) {\n if (node1 == null || node2 == null) {\n return false;\n }\n return node1.nodeType === node2.nodeType && node1.tagName === node2.tagName\n }\n\n function removeNodesBetween(startInclusive, endExclusive, ctx) {\n while (startInclusive !== endExclusive) {\n let tempNode = startInclusive;\n startInclusive = startInclusive.nextSibling;\n removeNode(tempNode, ctx);\n }\n removeIdsFromConsideration(ctx, endExclusive);\n return endExclusive.nextSibling;\n }\n\n //=============================================================================\n // Scans forward from the insertionPoint in the old parent looking for a potential id match\n // for the newChild. We stop if we find a potential id match for the new child OR\n // if the number of potential id matches we are discarding is greater than the\n // potential id matches for the new child\n //=============================================================================\n function findIdSetMatch(newContent, oldParent, newChild, insertionPoint, ctx) {\n\n // max id matches we are willing to discard in our search\n let newChildPotentialIdCount = getIdIntersectionCount(ctx, newChild, oldParent);\n\n let potentialMatch = null;\n\n // only search forward if there is a possibility of an id match\n if (newChildPotentialIdCount > 0) {\n let potentialMatch = insertionPoint;\n // if there is a possibility of an id match, scan forward\n // keep track of the potential id match count we are discarding (the\n // newChildPotentialIdCount must be greater than this to make it likely\n // worth it)\n let otherMatchCount = 0;\n while (potentialMatch != null) {\n\n // If we have an id match, return the current potential match\n if (isIdSetMatch(newChild, potentialMatch, ctx)) {\n return potentialMatch;\n }\n\n // computer the other potential matches of this new content\n otherMatchCount += getIdIntersectionCount(ctx, potentialMatch, newContent);\n if (otherMatchCount > newChildPotentialIdCount) {\n // if we have more potential id matches in _other_ content, we\n // do not have a good candidate for an id match, so return null\n return null;\n }\n\n // advanced to the next old content child\n potentialMatch = potentialMatch.nextSibling;\n }\n }\n return potentialMatch;\n }\n\n //=============================================================================\n // Scans forward from the insertionPoint in the old parent looking for a potential soft match\n // for the newChild. We stop if we find a potential soft match for the new child OR\n // if we find a potential id match in the old parents children OR if we find two\n // potential soft matches for the next two pieces of new content\n //=============================================================================\n function findSoftMatch(newContent, oldParent, newChild, insertionPoint, ctx) {\n\n let potentialSoftMatch = insertionPoint;\n let nextSibling = newChild.nextSibling;\n let siblingSoftMatchCount = 0;\n\n while (potentialSoftMatch != null) {\n\n if (getIdIntersectionCount(ctx, potentialSoftMatch, newContent) > 0) {\n // the current potential soft match has a potential id set match with the remaining new\n // content so bail out of looking\n return null;\n }\n\n // if we have a soft match with the current node, return it\n if (isSoftMatch(newChild, potentialSoftMatch)) {\n return potentialSoftMatch;\n }\n\n if (isSoftMatch(nextSibling, potentialSoftMatch)) {\n // the next new node has a soft match with this node, so\n // increment the count of future soft matches\n siblingSoftMatchCount++;\n nextSibling = nextSibling.nextSibling;\n\n // If there are two future soft matches, bail to allow the siblings to soft match\n // so that we don't consume future soft matches for the sake of the current node\n if (siblingSoftMatchCount >= 2) {\n return null;\n }\n }\n\n // advanced to the next old content child\n potentialSoftMatch = potentialSoftMatch.nextSibling;\n }\n\n return potentialSoftMatch;\n }\n\n function parseContent(newContent) {\n let parser = new DOMParser();\n\n // remove svgs to avoid false-positive matches on head, etc.\n let contentWithSvgsRemoved = newContent.replace(/<svg(\\s[^>]*>|>)([\\s\\S]*?)<\\/svg>/gim, '');\n\n // if the newContent contains a html, head or body tag, we can simply parse it w/o wrapping\n if (contentWithSvgsRemoved.match(/<\\/html>/) || contentWithSvgsRemoved.match(/<\\/head>/) || contentWithSvgsRemoved.match(/<\\/body>/)) {\n let content = parser.parseFromString(newContent, \"text/html\");\n // if it is a full HTML document, return the document itself as the parent container\n if (contentWithSvgsRemoved.match(/<\\/html>/)) {\n content.generatedByIdiomorph = true;\n return content;\n } else {\n // otherwise return the html element as the parent container\n let htmlElement = content.firstChild;\n if (htmlElement) {\n htmlElement.generatedByIdiomorph = true;\n return htmlElement;\n } else {\n return null;\n }\n }\n } else {\n // if it is partial HTML, wrap it in a template tag to provide a parent element and also to help\n // deal with touchy tags like tr, tbody, etc.\n let responseDoc = parser.parseFromString(\"<body><template>\" + newContent + \"</template></body>\", \"text/html\");\n let content = responseDoc.body.querySelector('template').content;\n content.generatedByIdiomorph = true;\n return content\n }\n }\n\n function normalizeContent(newContent) {\n if (newContent == null) {\n // noinspection UnnecessaryLocalVariableJS\n const dummyParent = document.createElement('div');\n return dummyParent;\n } else if (newContent.generatedByIdiomorph) {\n // the template tag created by idiomorph parsing can serve as a dummy parent\n return newContent;\n } else if (newContent instanceof Node) {\n // a single node is added as a child to a dummy parent\n const dummyParent = document.createElement('div');\n dummyParent.append(newContent);\n return dummyParent;\n } else {\n // all nodes in the array or HTMLElement collection are consolidated under\n // a single dummy parent element\n const dummyParent = document.createElement('div');\n for (const elt of [...newContent]) {\n dummyParent.append(elt);\n }\n return dummyParent;\n }\n }\n\n function insertSiblings(previousSibling, morphedNode, nextSibling) {\n let stack = []\n let added = []\n while (previousSibling != null) {\n stack.push(previousSibling);\n previousSibling = previousSibling.previousSibling;\n }\n while (stack.length > 0) {\n let node = stack.pop();\n added.push(node); // push added preceding siblings on in order and insert\n morphedNode.parentElement.insertBefore(node, morphedNode);\n }\n added.push(morphedNode);\n while (nextSibling != null) {\n stack.push(nextSibling);\n added.push(nextSibling); // here we are going in order, so push on as we scan, rather than add\n nextSibling = nextSibling.nextSibling;\n }\n while (stack.length > 0) {\n morphedNode.parentElement.insertBefore(stack.pop(), morphedNode.nextSibling);\n }\n return added;\n }\n\n function findBestNodeMatch(newContent, oldNode, ctx) {\n let currentElement;\n currentElement = newContent.firstChild;\n let bestElement = currentElement;\n let score = 0;\n while (currentElement) {\n let newScore = scoreElement(currentElement, oldNode, ctx);\n if (newScore > score) {\n bestElement = currentElement;\n score = newScore;\n }\n currentElement = currentElement.nextSibling;\n }\n return bestElement;\n }\n\n function scoreElement(node1, node2, ctx) {\n if (isSoftMatch(node1, node2)) {\n return .5 + getIdIntersectionCount(ctx, node1, node2);\n }\n return 0;\n }\n\n function removeNode(tempNode, ctx) {\n removeIdsFromConsideration(ctx, tempNode)\n if (ctx.callbacks.beforeNodeRemoved(tempNode) === false) return;\n\n tempNode.remove();\n ctx.callbacks.afterNodeRemoved(tempNode);\n }\n\n //=============================================================================\n // ID Set Functions\n //=============================================================================\n\n function isIdInConsideration(ctx, id) {\n return !ctx.deadIds.has(id);\n }\n\n function idIsWithinNode(ctx, id, targetNode) {\n let idSet = ctx.idMap.get(targetNode) || EMPTY_SET;\n return idSet.has(id);\n }\n\n function removeIdsFromConsideration(ctx, node) {\n let idSet = ctx.idMap.get(node) || EMPTY_SET;\n for (const id of idSet) {\n ctx.deadIds.add(id);\n }\n }\n\n function getIdIntersectionCount(ctx, node1, node2) {\n let sourceSet = ctx.idMap.get(node1) || EMPTY_SET;\n let matchCount = 0;\n for (const id of sourceSet) {\n // a potential match is an id in the source and potentialIdsSet, but\n // that has not already been merged into the DOM\n if (isIdInConsideration(ctx, id) && idIsWithinNode(ctx, id, node2)) {\n ++matchCount;\n }\n }\n return matchCount;\n }\n\n /**\n * A bottom up algorithm that finds all elements with ids inside of the node\n * argument and populates id sets for those nodes and all their parents, generating\n * a set of ids contained within all nodes for the entire hierarchy in the DOM\n *\n * @param node {Element}\n * @param {Map<Node, Set<String>>} idMap\n */\n function populateIdMapForNode(node, idMap) {\n let nodeParent = node.parentElement;\n // find all elements with an id property\n let idElements = node.querySelectorAll('[id]');\n for (const elt of idElements) {\n let current = elt;\n // walk up the parent hierarchy of that element, adding the id\n // of element to the parent's id set\n while (current !== nodeParent && current != null) {\n let idSet = idMap.get(current);\n // if the id set doesn't exist, create it and insert it in the map\n if (idSet == null) {\n idSet = new Set();\n idMap.set(current, idSet);\n }\n idSet.add(elt.id);\n current = current.parentElement;\n }\n }\n }\n\n /**\n * This function computes a map of nodes to all ids contained within that node (inclusive of the\n * node). This map can be used to ask if two nodes have intersecting sets of ids, which allows\n * for a looser definition of \"matching\" than tradition id matching, and allows child nodes\n * to contribute to a parent nodes matching.\n *\n * @param {Element} oldContent the old content that will be morphed\n * @param {Element} newContent the new content to morph to\n * @returns {Map<Node, Set<String>>} a map of nodes to id sets for the\n */\n function createIdMap(oldContent, newContent) {\n let idMap = new Map();\n populateIdMapForNode(oldContent, idMap);\n populateIdMapForNode(newContent, idMap);\n return idMap;\n }\n\n //=============================================================================\n // This is what ends up becoming the Idiomorph global object\n //=============================================================================\n return {\n morph,\n defaults\n }\n })();\n\nexport {Idiomorph};\n", "// templating\nimport createTemplate from './lib/template.js'\nimport FezBase from './instance.js'\n\n// this function accepts custom tag name and class definition, creates and connects\n// Fez(name, klass)\nexport default function(name, klass) {\n const Fez = globalThis.window?.Fez || globalThis.Fez;\n // Validate custom element name format (must contain a dash)\n if (!name.includes('-')) {\n console.error(`Fez: Invalid custom element name \"${name}\". Custom element names must contain a dash (e.g., 'my-element', 'ui-button').`)\n }\n\n // to allow anonymous class and then re-attach (does not work)\n // Fez('ui-todo', class { ... # instead Fez('ui-todo', class extends FezBase {\n if (!klass.fezHtmlRoot) {\n const klassObj = new klass()\n const newKlass = class extends FezBase {}\n\n const props = Object.getOwnPropertyNames(klassObj)\n .concat(Object.getOwnPropertyNames(klass.prototype))\n .filter(el => !['constructor', 'prototype'].includes(el))\n\n props.forEach(prop => newKlass.prototype[prop] = klassObj[prop])\n\n Fez.fastBindInfo ||= {fast: [], slow: []}\n\n if (klassObj.GLOBAL) { newKlass.fezGlobal = klassObj.GLOBAL }\n if (klassObj.CSS) { newKlass.css = klassObj.CSS }\n if (klassObj.HTML) { newKlass.html = klassObj.HTML }\n if (klassObj.NAME) { newKlass.nodeName = klassObj.NAME }\n if (klassObj.FAST) {\n newKlass.fastBind = klassObj.FAST\n Fez.fastBindInfo.fast.push(typeof klassObj.FAST == 'function' ? `${name} (func)` : name)\n } else {\n Fez.fastBindInfo.slow.push(name)\n }\n\n if (klassObj.GLOBAL) {\n const func = () => document.body.appendChild(document.createElement(name))\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', func);\n } else {\n func()\n }\n }\n\n klass = newKlass\n\n let info = `${name} compiled`\n if (klassObj.FAST) info += ' (fast bind)'\n Fez.log(info)\n }\n\n if (klass.html) {\n klass.html = closeCustomTags(klass.html)\n\n // wrap slot to enable reactive re-renders. It will use existing .fez-slot if found\n klass.html = klass.html.replace(/<slot\\s*\\/>|<slot\\s*>\\s*<\\/slot>/g, () => {\n const name = klass.slotNodeName || 'div'\n return `<${name} class=\"fez-slot\"></${name}>`\n })\n\n klass.fezHtmlFunc = createTemplate(klass.html)\n }\n\n // we have to register global css on component init, because some other component can depend on it (it is global)\n if (klass.css) {\n klass.css = Fez.globalCss(klass.css, {name: name})\n }\n\n Fez.classes[name] = klass\n\n if (!customElements.get(name)) {\n customElements.define(name, class extends HTMLElement {\n connectedCallback() {\n // if you want to force fast render (prevent page flickering), add static fastBind = true or FAST = true\n // we can not fast load auto for all because that creates hard to debug problems in nested custom nodes\n // problems with events and slots (I woke up at 2AM, now it is 5AM)\n // this is usually safe for first order components, as page header or any components that do not have innerHTML or use slots\n // Example: you can add FAST as a function - render fast nodes that have name attribute\n // FAST(node) { return !!node.getAttribute('name') }\n // to inspect fast / slow components use Fez.info() in console\n if (useFastRender(this, klass)) {\n connectNode(name, this)\n } else {\n window.requestAnimationFrame(()=>{\n if (this.parentNode) {\n connectNode(name, this)\n }\n })\n }\n }\n })\n }\n}\n\n//\n\nfunction closeCustomTags(html) {\n const selfClosingTags = new Set([\n 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'source', 'track', 'wbr'\n ])\n\n return html.replace(/<([a-z-]+)\\b([^>]*)\\/>/g, (match, tagName, attributes) => {\n return selfClosingTags.has(tagName) ? match : `<${tagName}${attributes}></${tagName}>`\n })\n}\n\nfunction useFastRender(n, klass) {\n const fezFast = n.getAttribute('fez-fast')\n var isFast = typeof klass.fastBind === 'function' ? klass.fastBind(n) : klass.fastBind\n\n if (fezFast == 'false') {\n return false\n } else {\n return fezFast || isFast\n }\n}\n\nfunction connectNode(name, node) {\n const klass = Fez.classes[name]\n const parentNode = node.parentNode\n\n if (node.isConnected) {\n const nodeName = typeof klass.nodeName == 'function' ? klass.nodeName(node) : klass.nodeName\n const newNode = document.createElement(nodeName || 'div')\n\n newNode.classList.add('fez')\n newNode.classList.add(`fez-${name}`)\n\n parentNode.replaceChild(newNode, node);\n\n const fez = new klass()\n\n fez.UID = ++Fez.instanceCount\n Fez.instances.set(fez.UID, fez)\n\n fez.oldRoot = node\n fez.fezName = name\n fez.root = newNode\n fez.props = klass.getProps(node, newNode)\n fez.class = klass\n\n // copy child nodes, natively to preserve bound events\n fez.slot(node, newNode)\n\n newNode.fez = fez\n\n if (klass.fezGlobal && klass.fezGlobal != true) {\n window[klass.fezGlobal] = fez\n }\n\n if (window.$) {\n fez.$root = $(newNode)\n }\n\n if (fez.props.id) {\n newNode.setAttribute('id', fez.props.id)\n }\n\n fez.fezRegister();\n (fez.init || fez.created || fez.connect).bind(fez)(fez.props);\n\n const oldRoot = fez.root.cloneNode(true)\n\n if (fez.class.fezHtmlFunc) {\n fez.render()\n }\n\n const slot = fez.root.querySelector('.fez-slot')\n if (slot) {\n if (fez.props.html) {\n slot.innerHTML = fez.props.html\n } else {\n fez.slot(oldRoot, slot)\n }\n }\n\n if (fez.onSubmit) {\n const form = fez.root.nodeName == 'FORM' ? fez.root : fez.find('form')\n form.onsubmit = (e) => {\n e.preventDefault()\n fez.onSubmit(fez.formData())\n }\n }\n\n fez.onMount(fez.props)\n\n // if onPropsChange method defined, add observer and trigger call on all attributes once component is loaded\n if (fez.onPropsChange) {\n observer.observe(newNode, {attributes:true})\n for (const [key, value] of Object.entries(fez.props)) {\n fez.onPropsChange(key, value)\n }\n }\n }\n}\n\n//\n\nconst observer = new MutationObserver((mutationsList, _) => {\n for (const mutation of mutationsList) {\n if (mutation.type === 'attributes') {\n const fez = mutation.target.fez\n const name = mutation.attributeName\n const value = mutation.target.getAttribute(name)\n\n if (fez) {\n fez.props[name] = value\n fez.onPropsChange(name, value)\n // console.log(`The [${name}] attribute was modified to [${value}].`);\n }\n }\n }\n});\n", "const compileToClass = (html) => {\n const result = { script: '', style: '', html: '', head: '' }\n const lines = html.split('\\n')\n\n let currentBlock = []\n let currentType = ''\n\n for (var line of lines) {\n line = line.trim()\n if (line.startsWith('<script') && !result.script && currentType != 'head') {\n currentType = 'script';\n } else if (line.startsWith('<head') && !result.script) { // you must use XMP tag if you want to define <head> tag, and it has to be first\n currentType = 'head';\n } else if (line.startsWith('<style')) {\n currentType = 'style';\n } else if (line.endsWith('</script>') && currentType === 'script' && !result.script) {\n result.script = currentBlock.join('\\n');\n currentBlock = [];\n currentType = null;\n } else if (line.endsWith('</style>') && currentType === 'style') {\n result.style = currentBlock.join('\\n');\n currentBlock = [];\n currentType = null;\n } else if ((line.endsWith('</head>') || line.endsWith('</header>')) && currentType === 'head') {\n result.head = currentBlock.join('\\n');\n currentBlock = [];\n currentType = null;\n } else if (currentType) {\n currentBlock.push(line);\n } else {\n result.html += line + '\\n';\n }\n }\n\n if (result.head) {\n const container = document.createElement('div')\n container.innerHTML = result.head\n\n // Process all children of the container\n Array.from(container.children).forEach(node => {\n if (node.tagName === 'SCRIPT') {\n const script = document.createElement('script')\n // Copy all attributes\n Array.from(node.attributes).forEach(attr => {\n script.setAttribute(attr.name, attr.value)\n })\n script.type ||= 'text/javascript'\n\n if (node.src) {\n // External script - will load automatically\n document.head.appendChild(script)\n } else if (script.type.includes('javascript') || script.type == 'module') {\n // Inline script - set content and execute\n script.textContent = node.textContent\n document.head.appendChild(script)\n }\n } else {\n // For other elements (link, meta, etc.), just append them\n document.head.appendChild(node.cloneNode(true))\n }\n })\n }\n\n let klass = result.script\n\n if (!/class\\s+\\{/.test(klass)) {\n klass = `class {\\n${klass}\\n}`\n }\n\n if (String(result.style).includes(':')) {\n Object.entries(Fez._styleMacros).forEach(([key, val])=>{\n result.style = result.style.replaceAll(`:${key} `, `${val} `)\n })\n\n result.style = result.style.includes(':fez') || /(?:^|\\s)body\\s*\\{/.test(result.style) ? result.style : `:fez {\\n${result.style}\\n}`\n klass = klass.replace(/\\}\\s*$/, `\\n CSS = \\`${result.style}\\`\\n}`)\n }\n\n if (/\\w/.test(String(result.html))) {\n // escape backticks in whole template block\n result.html = result.html.replaceAll('`', '&#x60;')\n result.html = result.html.replaceAll('$', '\\\\$')\n klass = klass.replace(/\\}\\s*$/, `\\n HTML = \\`${result.html}\\`\\n}`)\n }\n\n return klass\n}\n\n// <template fez=\"ui-form\">\n// <script>\n// ...\n// Fez.compile() # compile all\n// Fez.compile(templateNode) # compile template node\n// Fez.compile('ui-form', templateNode.innerHTML) # compile string\nexport default function (tagName, html) {\n if (tagName instanceof Node) {\n const node = tagName\n node.remove()\n\n const fezName = node.getAttribute('fez')\n\n // Check if fezName contains dot or slash (indicates URL)\n if (fezName && (fezName.includes('.') || fezName.includes('/'))) {\n const url = fezName\n\n Fez.log(`Loading from ${url}`)\n\n // Load HTML content via AJAX from URL\n fetch(url)\n .then(response => {\n if (!response.ok) {\n throw new Error(`Failed to load ${url}: ${response.status}`)\n }\n return response.text()\n })\n .then(htmlContent => {\n // Check if remote HTML has template/xmp tags with fez attribute\n const parser = new DOMParser()\n const doc = parser.parseFromString(htmlContent, 'text/html')\n const fezElements = doc.querySelectorAll('template[fez], xmp[fez]')\n\n if (fezElements.length > 0) {\n // Compile each found fez element\n fezElements.forEach(el => {\n const name = el.getAttribute('fez')\n if (name && !name.includes('-') && !name.includes('.') && !name.includes('/')) {\n console.error(`Fez: Invalid custom element name \"${name}\". Custom element names must contain a dash (e.g., 'my-element', 'ui-button').`)\n }\n const content = el.innerHTML\n Fez.compile(name, content)\n })\n } else {\n // No fez elements found, use extracted name from URL\n const name = url.split('/').pop().split('.')[0]\n Fez.compile(name, htmlContent)\n }\n })\n .catch(error => {\n console.error(`FEZ template load error for \"${fezName}\": ${error.message}`)\n })\n return\n } else {\n // Validate fezName format for non-URL names\n if (fezName && !fezName.includes('-')) {\n console.error(`Fez: Invalid custom element name \"${fezName}\". Custom element names must contain a dash (e.g., 'my-element', 'ui-button').`)\n }\n html = node.innerHTML\n tagName = fezName\n }\n }\n else if (typeof html != 'string') {\n document.body.querySelectorAll('template[fez], xmp[fez]').forEach((n) => Fez.compile(n))\n return\n }\n\n // Validate element name if it's not a URL\n if (tagName && !tagName.includes('-') && !tagName.includes('.') && !tagName.includes('/')) {\n console.error(`Fez: Invalid custom element name \"${tagName}\". Custom element names must contain a dash (e.g., 'my-element', 'ui-button').`)\n }\n\n let klass = compileToClass(html)\n let parts = klass.split(/class\\s+\\{/, 2)\n\n klass = `${parts[0]};\\n\\nwindow.Fez('${tagName}', class {\\n${parts[1]})`\n\n // Add tag to global hidden styles container\n if (tagName) {\n let styleContainer = document.getElementById('fez-hidden-styles')\n if (!styleContainer) {\n styleContainer = document.createElement('style')\n styleContainer.id = 'fez-hidden-styles'\n document.head.appendChild(styleContainer)\n }\n styleContainer.textContent += `${tagName} { display: none; }\\n`\n }\n\n // we cant try/catch javascript modules (they use imports)\n if (klass.includes('import ')) {\n Fez.head({script: klass})\n\n // best we can do it inform that node did not compile, so we assume there is arrow\n setTimeout(()=>{\n if (!Fez.classes[tagName]) {\n Fez.error(`Template \"${tagName}\" possible compile error. (can be a false positive, it imports are not loaded)`)\n }\n }, 2000)\n } else {\n try {\n new Function(klass)()\n } catch(e) {\n Fez.error(`Template \"${tagName}\" compile error: ${e.message}`)\n console.log(klass)\n }\n }\n}\n", "// Global state manager with automatic component subscription\n//\n// Components access state via this.globalState proxy which automatically:\n// - Registers component as listener when reading a value\n// - Notifies component when that value changes\n// - Calls onGlobalStateChange(key, value) if defined, then render()\n//\n// Example usage:\n//\n// class Counter extends FezBase {\n// increment() {\n// this.globalState.count = (this.globalState.count || 0) + 1\n// }\n//\n// onGlobalStateChange(key, value) {\n// console.log(`State ${key} changed to ${value}`)\n// }\n//\n// render() {\n// return `<button onclick=\"fez.increment()\">\n// Count: ${this.globalState.count || 0}\n// </button>`\n// }\n// }\n//\n// External access:\n// Fez.state.set('count', 10)\n// Fez.state.get('count') // 10\n\nconst GlobalState = {\n data: {},\n listeners: new Map(), // key -> Set of components\n subscribers: new Map(), // key -> Set of functions (for subscribe method)\n globalSubscribers: new Set(), // Set of functions that listen to all changes\n\n notify(key, value, oldValue) {\n Fez.log(`Global state change for ${key}: ${value} (from ${oldValue})`)\n\n // Notify component listeners\n const listeners = this.listeners.get(key)\n if (listeners) {\n listeners.forEach(comp => {\n if (comp.isConnected) {\n comp.onGlobalStateChange(key, value, oldValue)\n comp.render()\n } else {\n listeners.delete(comp)\n }\n })\n }\n\n // Notify key-specific subscribers\n const subscribers = this.subscribers.get(key)\n if (subscribers) {\n subscribers.forEach(func => {\n try {\n func(value, oldValue, key)\n } catch (error) {\n console.error(`Error in subscriber for key ${key}:`, error)\n }\n })\n }\n\n // Notify global subscribers\n this.globalSubscribers.forEach(func => {\n try {\n func(key, value, oldValue)\n } catch (error) {\n console.error(`Error in global subscriber:`, error)\n }\n })\n },\n\n createProxy(component) {\n return new Proxy({}, {\n get: (target, key) => {\n // Skip if already listening to this key\n component._globalStateKeys ||= new Set()\n if (!component._globalStateKeys.has(key)) {\n component._globalStateKeys.add(key)\n\n if (!this.listeners.has(key)) {\n this.listeners.set(key, new Set())\n }\n this.listeners.get(key).add(component)\n }\n\n return this.data[key]\n },\n\n set: (target, key, value) => {\n const oldValue = this.data[key]\n if (oldValue !== value) {\n this.data[key] = value\n this.notify(key, value, oldValue)\n }\n return true\n }\n })\n },\n\n // Direct methods for use outside components\n set(key, value) {\n const oldValue = this.data[key]\n if (oldValue !== value) {\n this.data[key] = value\n this.notify(key, value, oldValue)\n }\n },\n\n get(key) {\n return this.data[key]\n },\n\n // Execute function for each component listening to a key\n forEach(key, func) {\n const listeners = this.listeners.get(key)\n if (listeners) {\n listeners.forEach(comp => {\n if (comp.isConnected) {\n func(comp)\n } else {\n listeners.delete(comp)\n }\n })\n }\n },\n\n // Subscribe to state changes\n // Usage: Fez.state.subscribe(func) - listen to all changes\n // Fez.state.subscribe(key, func) - listen to specific key changes\n subscribe(keyOrFunc, func) {\n if (typeof keyOrFunc === 'function') {\n // subscribe(func) - global subscription\n this.globalSubscribers.add(keyOrFunc)\n return () => this.globalSubscribers.delete(keyOrFunc)\n } else {\n // subscribe(key, func) - key-specific subscription\n const key = keyOrFunc\n if (!this.subscribers.has(key)) {\n this.subscribers.set(key, new Set())\n }\n this.subscribers.get(key).add(func)\n return () => {\n const keySubscribers = this.subscribers.get(key)\n if (keySubscribers) {\n keySubscribers.delete(func)\n if (keySubscribers.size === 0) {\n this.subscribers.delete(key)\n }\n }\n }\n }\n }\n}\n\nexport default GlobalState\n", "// runtime scss\nimport Gobber from './vendor/gobber.js'\n\n// morph dom from one state to another\nimport { Idiomorph } from './vendor/idiomorph.js'\n\nimport connect from './connect.js'\nimport compile from './compile.js'\nimport state from './lib/global-state.js'\n\n// Fez('ui-slider') # first slider\n// Fez('ui-slider', (n)=>alert(n)) # find all and execute\n// Fez(this, 'ui-slider') # first parent ui-slider\n// Fez('ui-slider', class { init() { ... }}) # create Fez dom node\nconst Fez = (name, klass) => {\n if(typeof name === 'number') {\n const fez = Fez.instances.get(name)\n if (fez) {\n return fez\n } else {\n Fez.error(`Instance with UID \"${name}\" not found.`)\n }\n }\n else if (name) {\n if (klass) {\n const isPureFn = typeof klass === 'function' && !/^\\s*class/.test(klass.toString()) && !/\\b(this|new)\\b/.test(klass.toString())\n\n if (isPureFn) {\n const list = Array\n .from(document.querySelectorAll(`.fez.fez-${name}`))\n .filter( n => n.fez )\n\n list.forEach( el => klass(el.fez) )\n return list\n } else if (typeof klass != 'function') {\n return Fez.find(name, klass)\n } else {\n return connect(name, klass)\n }\n } else {\n const node = name.nodeName ? name.closest('.fez') : (\n document.querySelector( name.includes('#') ? name : `.fez.fez-${name}` )\n )\n if (node) {\n if (node.fez) {\n return node.fez\n } else {\n Fez.error(`node \"${name}\" has no Fez attached.`)\n }\n } else {\n Fez.error(`node \"${name}\" not found.`)\n }\n }\n } else {\n Fez.error('Fez() ?')\n }\n}\n\nFez.classes = {}\nFez.instanceCount = 0\nFez.instances = new Map()\n\nFez.find = (onode, name) => {\n let node = onode\n\n if (typeof node == 'string') {\n node = document.body.querySelector(node)\n }\n\n if (typeof node.val == 'function') {\n node = node[0]\n }\n\n const klass = name ? `.fez.fez-${name}` : '.fez'\n\n const closestNode = node.closest(klass)\n if (closestNode && closestNode.fez) {\n return closestNode.fez\n } else {\n console.error('Fez node connector not found', onode, node)\n }\n}\n\nFez.cssClass = (text) => {\n return Gobber.css(text)\n}\n\nFez.globalCss = (cssClass, opts = {}) => {\n if (typeof cssClass === 'function') {\n cssClass = cssClass()\n }\n\n if (cssClass.includes(':')) {\n let text = cssClass\n .split(\"\\n\")\n .filter(line => !(/^\\s*\\/\\//.test(line)))\n .join(\"\\n\")\n\n if (opts.wrap) {\n text = `:fez { ${text} }`\n }\n\n text = text.replace(/\\:fez|\\:host/, `.fez.fez-${opts.name}`)\n\n cssClass = Fez.cssClass(text)\n }\n\n if (document.body) {\n document.body.parentElement.classList.add(cssClass)\n } else {\n document.addEventListener(\"DOMContentLoaded\", () => {\n document.body.parentElement.classList.add(cssClass)\n })\n }\n\n return cssClass\n}\n\nFez.info = () => {\n console.log(JSON.stringify(Fez.fastBindInfo, null, 2))\n}\n\nFez.morphdom = (target, newNode, opts = {}) => {\n Array.from(target.attributes).forEach(attr => {\n newNode.setAttribute(attr.name, attr.value)\n })\n\n Idiomorph.morph(target, newNode, {\n morphStyle: 'outerHTML'\n })\n\n // remove whitespace on next node, if exists (you never want this)\n const nextSibling = target.nextSibling\n if (nextSibling?.nodeType === Node.TEXT_NODE && nextSibling.textContent.trim() === '') {\n nextSibling.remove();\n }\n}\n\nFez.htmlEscape = (text) => {\n if (typeof text == 'string') {\n text = text\n // .replaceAll('&', \"&amp;\")\n .replace(/font-family\\s*:\\s*(?:&[^;]+;|[^;])*?;/gi, '')\n .replaceAll(\"'\", '&apos;')\n .replaceAll('\"', '&quot;')\n .replaceAll('<', '&lt;')\n .replaceAll('>', '&gt;')\n // .replaceAll('@', '&#64;') // needed for template escaping\n\n return text\n } else {\n return text === undefined ? '' : text\n }\n}\n\nFez.publish = (channel, ...args) => {\n Fez._subs ||= {}\n Fez._subs[channel] ||= []\n Fez._subs[channel].forEach((el) => {\n el[1].bind(el[0])(...args)\n })\n}\n\n // get unique id from string\nFez.fnv1 = (str) => {\n var FNV_OFFSET_BASIS, FNV_PRIME, hash, i, j, ref;\n FNV_OFFSET_BASIS = 2166136261;\n FNV_PRIME = 16777619;\n hash = FNV_OFFSET_BASIS;\n for (i = j = 0, ref = str.length - 1; (0 <= ref ? j <= ref : j >= ref); i = 0 <= ref ? ++j : --j) {\n hash ^= str.charCodeAt(i);\n hash *= FNV_PRIME;\n }\n return hash.toString(36).replaceAll('-', '');\n}\n\nFez.tag = (tag, opts = {}, html = '') => {\n const json = encodeURIComponent(JSON.stringify(opts))\n return `<${tag} data-props=\"${json}\">${html}</${tag}>`\n // const json = JSON.stringify(opts, null, 2)\n // const data = `<script type=\"text/template\">${json}</script><${tag} data-json-template=\"true\">${html}</${tag}>`\n // return data\n};\n\nFez.error = (text, show) => {\n text = `Fez: ${text}`\n console.error(text)\n if (show) {\n return `<span style=\"border: 1px solid red; font-size: 14px; padding: 3px 7px; background: #fee; border-radius: 4px;\">${text}</span>`\n }\n}\nFez.log = (text) => {\n if (Fez.LOG === true) {\n console.log(`Fez: ${text}`)\n }\n}\ndocument.addEventListener('DOMContentLoaded', () => {\n Fez.log('Fez.LOG === true, logging enabled.')\n})\n\n// execute function until it returns true\nFez.untilTrue = (func, pingRate) => {\n pingRate ||= 200\n\n if (!func()) {\n setTimeout(()=>{\n Fez.untilTrue(func, pingRate)\n } ,pingRate)\n }\n}\n\n// Script from URL\n// head({ js: 'https://example.com/script.js' });\n// Script with attributes\n// head({ js: 'https://example.com/script.js', type: 'module', async: true });\n// Script with callback\n// head({ js: 'https://example.com/script.js' }, () => { console.log('loaded') });\n// Module loading with auto-import to window\n// head({ js: 'https://example.com/module.js', module: 'MyModule' }); // imports and sets window.MyModule\n// CSS inclusion\n// head({ css: 'https://example.com/styles.css' });\n// CSS with additional attributes and callback\n// head({ css: 'https://example.com/styles.css', media: 'print' }, () => { console.log('CSS loaded') })\n// Inline script evaluation\n// head({ script: 'console.log(\"Hello world\")' })\nFez.head = (config, callback) => {\n if (typeof config !== 'object' || config === null) {\n throw new Error('head requires an object parameter');\n }\n\n let src, attributes = {}, elementType;\n\n if (config.script) {\n if (config.script.includes('import ')) {\n if (callback) {\n Fez.error('Fez.head callback is not supported when script with import is passed (module context).')\n }\n\n // Evaluate inline script in context in the module\n const script = document.createElement('script');\n script.type = 'module';\n script.textContent = config.script;\n document.head.appendChild(script);\n setTimeout(()=>script.remove(), 100)\n } else {\n try {\n new Function(config.script)();\n if (callback) callback();\n } catch (error) {\n Fez.error('Error executing script:', error);\n console.log(config.script);\n }\n }\n return;\n } else if (config.js) {\n src = config.js;\n elementType = 'script';\n // Copy all properties except 'js' as attributes\n for (const [key, value] of Object.entries(config)) {\n if (key !== 'js' && key !== 'module') {\n attributes[key] = value;\n }\n }\n // Handle module loading\n if (config.module) {\n attributes.type = 'module';\n }\n } else if (config.css) {\n src = config.css;\n elementType = 'link';\n attributes.rel = 'stylesheet';\n // Copy all properties except 'css' as attributes\n for (const [key, value] of Object.entries(config)) {\n if (key !== 'css') {\n attributes[key] = value;\n }\n }\n } else {\n throw new Error('head requires either \"script\", \"js\" or \"css\" property');\n }\n\n const existingNode = document.querySelector(`${elementType}[src=\"${src}\"], ${elementType}[href=\"${src}\"]`);\n if (existingNode) {\n if (callback) callback();\n return existingNode;\n }\n\n const element = document.createElement(elementType);\n\n if (elementType === 'link') {\n element.href = src;\n } else {\n element.src = src;\n }\n\n for (const [key, value] of Object.entries(attributes)) {\n element.setAttribute(key, value);\n }\n\n if (callback || config.module) {\n element.onload = () => {\n // If module name is provided, import it and assign to window\n if (config.module && elementType === 'script') {\n import(src).then(module => {\n window[config.module] = module.default || module[config.module] || module;\n }).catch(error => {\n console.error(`Error importing module ${config.module}:`, error);\n });\n }\n if (callback) callback();\n };\n }\n\n document.head.appendChild(element);\n\n return element;\n}\n\n// Fetch wrapper with automatic caching and data handling\n// Usage:\n// Fez.fetch(url) - GET request (default)\n// Fez.fetch(url, callback) - GET with callback\n// Fez.fetch(url, data) - GET with query params (?foo=bar&baz=qux)\n// Fez.fetch(url, data, callback) - GET with query params and callback\n// Fez.fetch('POST', url, data) - POST with FormData body (multipart/form-data)\n// Fez.fetch('POST', url, data, callback) - POST with FormData and callback\n// Data object is automatically converted:\n// - GET: appended as URL query parameters\n// - POST: sent as FormData (multipart/form-data) without custom headers\nFez.fetch = function(...args) {\n // Initialize cache if not exists\n Fez._fetchCache ||= {};\n\n let method = 'GET';\n let url;\n let callback;\n\n // Check if first arg is HTTP method (uppercase letters)\n if (typeof args[0] === 'string' && /^[A-Z]+$/.test(args[0])) {\n method = args.shift();\n }\n\n // URL is required\n url = args.shift();\n\n // Check for data/options object\n let opts = {};\n let data = null;\n if (typeof args[0] === 'object') {\n data = args.shift();\n }\n\n // Check for callback function\n if (typeof args[0] === 'function') {\n callback = args.shift();\n }\n\n // Handle data based on method\n if (data) {\n if (method === 'GET') {\n // For GET, append data as query parameters\n const params = new URLSearchParams(data);\n url += (url.includes('?') ? '&' : '?') + params.toString();\n } else if (method === 'POST') {\n // For POST, convert to FormData\n const formData = new FormData();\n for (const [key, value] of Object.entries(data)) {\n formData.append(key, value);\n }\n opts.body = formData;\n }\n }\n\n // Set method\n opts.method = method;\n\n // Create cache key from method, url, and stringified opts\n const cacheKey = `${method}:${url}:${JSON.stringify(opts)}`;\n\n // Check cache first\n if (Fez._fetchCache[cacheKey]) {\n const cachedData = Fez._fetchCache[cacheKey];\n Fez.log(`fetch cache hit: ${method} ${url}`);\n if (callback) {\n callback(cachedData);\n return;\n }\n return Promise.resolve(cachedData);\n }\n\n // Log live fetch\n Fez.log(`fetch live: ${method} ${url}`);\n\n // Helper to process and cache response\n const processResponse = (response) => {\n if (response.headers.get('content-type')?.includes('application/json')) {\n return response.json();\n }\n return response.text();\n };\n\n // If callback provided, execute and handle\n if (callback) {\n fetch(url, opts)\n .then(processResponse)\n .then(data => {\n Fez._fetchCache[cacheKey] = data;\n callback(data);\n })\n .catch(error => Fez.onError('fetch', error));\n return;\n }\n\n // Return promise with automatic JSON parsing\n return fetch(url, opts)\n .then(processResponse)\n .then(data => {\n Fez._fetchCache[cacheKey] = data;\n return data;\n });\n}\n\nFez.onError = (kind, message) => {\n // Ensure kind is always a string\n if (typeof kind !== 'string') {\n throw new Error('Fez.onError: kind must be a string');\n }\n\n console.error(`${kind}: ${message.toString()}`);\n}\n\n// define custom style macro\n// Fez.styleMacro('mobile', '@media (max-width: 768px)')\n// :mobile { ... } -> @media (max-width: 768px) { ... }\nFez._styleMacros = {}\nFez.styleMacro = (name, content) => {\n Fez._styleMacros[name] = content\n}\n\n// work with tmp store\nFez.store = {\n store: new Map(),\n counter: 0,\n\n set(value) {\n const key = this.counter++;\n this.store.set(key, value);\n return key;\n },\n\n get(key) {\n return this.store.get(key);\n },\n\n delete(key) {\n const value = this.store.get(key);\n this.store.delete(key)\n return value;\n }\n};\n\nFez.compile = compile\nFez.state = state\n\nexport default Fez\n", "// base class for custom dom objects\nimport FezBase from './fez/instance.js'\nif (typeof window !== 'undefined') window.FezBase = FezBase\n\n// base class for custom dom objects\nimport Fez from './fez/root.js'\nif (typeof window !== 'undefined') window.Fez = Fez\n\n// clear all unattached nodes\nsetInterval(() => {\n for (const [key, el] of Fez.instances) {\n if (!el?.isConnected) {\n // Fez.error(`Found junk instance that is not connected ${el.fezName}`)\n el.fez?.fezRemoveSelf()\n Fez.instances.delete(key)\n }\n }\n}, 5_000)\n\n// define Fez observer\nconst observer = new MutationObserver((mutations) => {\n for (const { addedNodes, removedNodes } of mutations) {\n addedNodes.forEach((node) => {\n if (node.nodeType !== 1) return; // only elements\n // check the node itself\n if (node.matches('template[fez], xmp[fez], script[fez]')) {\n window.requestAnimationFrame(()=>{\n Fez.compile(node);\n node.remove();\n })\n }\n });\n\n removedNodes.forEach((node) => {\n if (node.nodeType === 1 && node.querySelectorAll) {\n // check both the node itself and its descendants\n const fezElements = node.querySelectorAll('.fez, :scope.fez');\n fezElements\n .forEach(el => {\n if (el.fez && el.root) {\n Fez.instances.delete(el.fez.UID)\n el.fez.fezRemoveSelf()\n }\n });\n }\n });\n }\n});\n\n// start observing the whole document\nobserver.observe(document.documentElement, {\n childList: true,\n subtree: true\n});\n\n// fez custom tags\n\n//<fez-component name=\"some-node\" :props=\"fez.props\"></fez-node>\nFez('fez-component', class {\n init(props) {\n const tag = document.createElement(props.name)\n tag.props = props.props || props['data-props'] || props\n\n while (this.root.firstChild) {\n this.root.parentNode.insertBefore(this.root.lastChild, tag.nextSibling);\n }\n\n this.root.innerHTML = ''\n this.root.appendChild(tag)\n }\n})\n\nexport default Fez\n"],
4
+ "sourcesContent": ["// Exposes node building method, that gets node name, attrs and body.\n// n('span', {id: id}), n('.foo', {id: id}, body), n('.foo', {id: id}, [...])\n// * you can switch places for attrs and body, and body can be list of nodes\n// * n('.foo.bar') -> n('div', { class: 'foo bar' })\n//\n// copyright @dux, 2024\n// Licence MIT\n\nexport default function n(name, attrs = {}, data) {\n if (typeof attrs === 'string') {\n [attrs, data] = [data, attrs]\n attrs ||= {}\n }\n\n if (attrs instanceof Node) {\n data = attrs\n attrs = {}\n }\n\n if (Array.isArray(name)) {\n data = name\n name = 'div'\n }\n\n if (typeof attrs !== 'object' || Array.isArray(attrs)) {\n data = attrs\n attrs = {}\n }\n\n if (name.includes('.')) {\n const parts = name.split('.')\n name = parts.shift() || 'div'\n const c = parts.join(' ');\n if (attrs.class) {\n attrs.class += ` ${c}`;\n } else {\n attrs.class = c\n }\n }\n\n const node = document.createElement(name);\n\n for (const [k, v] of Object.entries(attrs)) {\n if (typeof v === 'function') {\n node[k] = v.bind(this)\n } else {\n const value = String(v).replaceAll('fez.', this.fezHtmlRoot);\n node.setAttribute(k, value)\n }\n }\n\n if (data) {\n if (Array.isArray(data)) {\n for (const n of data) {\n node.appendChild(n)\n }\n } else if (data instanceof Node) {\n node.appendChild(data)\n } else {\n node.innerHTML = String(data)\n }\n }\n\n return node\n}\n", "function parseBlock(data, ifStack) {\n data = data\n .replace(/^#?raw/, '@html')\n .replace(/^#?html/, '@html')\n\n // Handle #if directive\n if (data.startsWith('#if') || data.startsWith('if')) {\n ifStack.push(false)\n data = data.replace(/^#?if/, '')\n return `\\${ ${data} ? \\``\n }\n else if (data.startsWith('#unless') || data.startsWith('unless')) {\n ifStack.push(false)\n data = data.replace(/^#?unless/, '')\n return `\\${ !(${data}) ? \\``\n }\n else if (data == '/block') {\n return '`) && \\'\\'}'\n }\n else if (data.startsWith('#for') || data.startsWith('for')) {\n data = data.replace(/^#?for/, '')\n const el = data.split(' in ', 2)\n return '${' + el[1] + '.map((' + el[0] + ')=>`'\n }\n else if (data.startsWith('#each') || data.startsWith('each')) {\n data = data.replace(/^#?each/, '')\n const el = data.split(' as ', 2)\n return '${' + el[0] + '.map((' + el[1] + ')=>`'\n }\n else if (data == ':else' || data == 'else') {\n ifStack[ifStack.length - 1] = true\n return '` : `'\n }\n else if (data == '/if' || data == '/unless') {\n return ifStack.pop() ? '`}' : '` : ``}'\n }\n else if (data == '/for' || data == '/each') {\n return '`).join(\"\")}'\n }\n else {\n const prefix = '@html '\n\n if (data.startsWith(prefix)) {\n data = data.replace(prefix, '')\n } else {\n data = `Fez.htmlEscape(${data})`\n }\n\n return '${' + data + '}'\n }\n}\n\n// let tpl = createTemplate(string)\n// tpl({ ... this state ...})\nexport default function createTemplate(text, opts = {}) {\n const ifStack = []\n\n // some templating engines, as GoLangs use {{ for templates. Allow usage of [[ for fez\n text = text\n .replaceAll('[[', '{{')\n .replaceAll(']]', '}}')\n\n text = text.replace(/(\\w+)=\\{\\{\\s*(.*?)\\s*\\}\\}([\\s>])/g, (match, p1, p2, p3) => {\n return `${p1}=\"{`+`{ ${p2} }`+`}\"${p3}`\n })\n\n // {{block foo}} ... {{/block}}\n // {{block:foo}}\n const blocks = {}\n text = text.replace(/\\{\\{block\\s+(\\w+)\\s*\\}\\}([^\u00A7]+)\\{\\{\\/block\\}\\}/g, (_, name, block) => {\n blocks[name] = block\n return ''\n })\n text = text.replace(/\\{\\{block:([\\w\\-]+)\\s*\\}\\}/g, (_, name) => blocks[name] || `block:${name}?`)\n\n // {{#for el in list }}}}\n // <ui-comment :comment=\"el\"></ui-comment>\n // -> :comment=\"{{ JSON.stringify(el) }}\"\n // skip attr=\"foo.bar\"\n text = text.replace(/:(\\w+)=\"([\\w\\.\\[\\]]+)\"/, (_, m1, m2) => {\n return `:${m1}=Fez.store.delete({{ Fez.store.set(${m2}) }})`\n })\n\n let result = text.replace(/{{(.*?)}}/g, (_, content) => {\n content = content.replaceAll('&#x60;', '`')\n\n content = content\n .replaceAll('&lt;', '<')\n .replaceAll('&gt;', '>')\n .replaceAll('&amp;', '&')\n const parsedData = parseBlock(content, ifStack);\n\n return parsedData\n });\n\n result = '`' + result.trim() + '`'\n\n try {\n const funcBody = `const fez = this;\n with (this) {\n return ${result}\n }\n `\n const tplFunc = new Function(funcBody);\n const outFunc = (o) => {\n try {\n return tplFunc.bind(o)()\n } catch(e) {\n e.message = `FEZ template runtime error: ${e.message}\\n\\nTemplate source: ${result}`\n console.error(e)\n }\n }\n return outFunc\n } catch(e) {\n e.message = `FEZ template compile error: ${e.message}Template source:\\n${result}`\n console.error(e)\n return ()=>Fez.error(`Template Compile Error`, true)\n }\n}\n", "// HTML node builder\nimport parseNode from './lib/n.js'\nimport createTemplate from './lib/template.js'\n\nexport default class FezBase {\n // get node attributes as object\n static getProps(node, newNode) {\n let attrs = {}\n\n // we can directly attach props to DOM node instance\n if (node.props) {\n return node.props\n }\n\n // LOG(node.nodeName, node.attributes)\n for (const attr of node.attributes) {\n attrs[attr.name] = attr.value\n }\n\n for (const [key, val] of Object.entries(attrs)) {\n if ([':'].includes(key[0])) {\n delete attrs[key]\n try {\n const newVal = new Function(`return (${val})`).bind(newNode)()\n attrs[key.replace(/[\\:_]/, '')] = newVal\n\n } catch (e) {\n console.error(`Fez: Error evaluating attribute ${key}=\"${val}\" for ${node.tagName}: ${e.message}`)\n }\n }\n }\n\n if (attrs['data-props']) {\n let data = attrs['data-props']\n\n if (typeof data == 'object') {\n return data\n }\n else {\n if (data[0] != '{') {\n data = decodeURIComponent(data)\n }\n try {\n attrs = JSON.parse(data)\n } catch (e) {\n console.error(`Fez: Invalid JSON in data-props for ${node.tagName}: ${e.message}`)\n }\n }\n }\n\n // pass props as json template\n // <script type=\"text/template\">{...}</script>\n // <foo-bar data-json-template=\"true\"></foo-bar>\n else if (attrs['data-json-template']) {\n const data = newNode.previousSibling?.textContent\n if (data) {\n try {\n attrs = JSON.parse(data)\n newNode.previousSibling.remove()\n } catch (e) {\n console.error(`Fez: Invalid JSON in template for ${node.tagName}: ${e.message}`)\n }\n }\n }\n\n return attrs\n }\n\n static formData(node) {\n const formNode = node.closest('form') || node.querySelector('form')\n if (!formNode) {\n Fez.log('No form found for formData()')\n return {}\n }\n const formData = new FormData(formNode)\n const formObject = {}\n formData.forEach((value, key) => {\n formObject[key] = value\n });\n return formObject\n }\n\n static fastBind() {\n // return true to bind without requestAnimationFrame\n // you can do this if you are sure you are not expecting innerHTML data\n return false\n }\n\n static nodeName = 'div'\n\n // instance methods\n\n constructor() {}\n\n n = parseNode\n\n // string selector for use in HTML nodes\n get fezHtmlRoot() {\n return `Fez(${this.UID}).`\n // return this.props.id ? `Fez.find(\"#${this.props.id}\").` : `Fez.find(this, \"${this.fezName}\").`\n }\n\n // checks if node is attached and clears all if not\n get isConnected() {\n if (this.root?.isConnected) {\n return true\n } else {\n this.fezRemoveSelf()\n return false\n }\n }\n\n fezRemoveSelf() {\n this._setIntervalCache ||= {}\n Object.keys(this._setIntervalCache).forEach((key)=> {\n clearInterval(this._setIntervalCache[key])\n })\n\n this.onDestroy()\n this.onDestroy = ()=> {}\n\n if (this.root) {\n this.root.fez = undefined\n }\n\n this.root = undefined\n }\n\n // get single node property\n prop(name) {\n let v = this.oldRoot[name] || this.props[name]\n if (typeof v == 'function') {\n // if this.prop('onclick'), we want \"this\" to point to this.root (dom node)\n v = v.bind(this.root)\n }\n return v\n }\n\n // copy attributes to root node\n copy() {\n for (const name of Array.from(arguments)) {\n let value = this.props[name]\n\n if (value !== undefined) {\n if (name == 'class') {\n const klass = this.root.getAttribute(name, value)\n\n if (klass) {\n value = [klass, value].join(' ')\n }\n }\n\n if (name == 'style' || !this.root[name]) {\n if (typeof value == 'string') {\n this.root.setAttribute(name, value)\n }\n else {\n this.root[name] = value\n }\n }\n }\n }\n }\n\n // helper function to execute stuff on window resize, and clean after node is not connected any more\n // if delay given, throttle, if not debounce\n onResize(func, delay) {\n let timeoutId;\n let lastRun = 0;\n\n func()\n\n const checkAndExecute = () => {\n if (!this.isConnected) {\n window.removeEventListener('resize', handleResize);\n return;\n }\n func.call(this);\n };\n\n const handleResize = () => {\n if (!this.isConnected) {\n window.removeEventListener('resize', handleResize);\n return;\n }\n\n if (delay) {\n // Throttle\n const now = Date.now();\n if (now - lastRun >= delay) {\n checkAndExecute();\n lastRun = now;\n }\n } else {\n // Debounce\n clearTimeout(timeoutId);\n timeoutId = setTimeout(checkAndExecute, 200);\n }\n };\n\n window.addEventListener('resize', handleResize);\n }\n\n // copy child nodes, natively to preserve bound events\n // if node name is SLOT insert adjacent and remove SLOT, else as a child nodes\n slot(source, target) {\n target ||= document.createElement('template')\n const isSlot = target.nodeName == 'SLOT'\n\n while (source.firstChild) {\n if (isSlot) {\n target.parentNode.insertBefore(source.lastChild, target.nextSibling);\n } else {\n target.appendChild(source.firstChild)\n }\n }\n\n if (isSlot) {\n target.parentNode.removeChild(target)\n } else {\n source.innerHTML = ''\n }\n\n return target\n }\n\n setStyle(key, value) {\n this.root.style.setProperty(key, value);\n }\n\n connect() {}\n onMount() {}\n beforeRender() {}\n afterRender() {}\n onDestroy() {}\n onStateChange() {}\n onGlobalStateChange() {}\n publish = Fez.publish\n fezBlocks = {}\n\n parseHtml(text) {\n const base = this.fezHtmlRoot.replaceAll('\"', '&quot;')\n\n text = text\n .replace(/([^\\w\\.])fez\\./g, `$1${base}`)\n .replace(/>\\s+</g, '><')\n\n return text.trim()\n }\n\n\n // pass name to have only one tick of a kind\n nextTick(func, name) {\n if (name) {\n this._nextTicks ||= {}\n this._nextTicks[name] ||= window.requestAnimationFrame(() => {\n func.bind(this)()\n this._nextTicks[name] = null\n }, name)\n } else {\n window.requestAnimationFrame(func.bind(this))\n }\n }\n\n // inject htmlString as innerHTML and replace $$. with local pointer\n // $$. will point to current fez instance\n // <slot></slot> will be replaced with current root\n // this.render('...loading')\n // this.render('.images', '...loading')\n render(template) {\n template ||= this?.class?.fezHtmlFunc\n\n if (!template || !this.root) return\n\n this.beforeRender()\n\n const newNode = document.createElement(this.class.nodeName || 'div')\n\n let renderedTpl\n if (Array.isArray(template)) {\n // array nodes this.n(...), look tabs example\n if (template[0] instanceof Node) {\n template.forEach( n => newNode.appendChild(n) )\n } else{\n renderedTpl = template.join('')\n }\n }\n else if (typeof template == 'string') {\n renderedTpl = createTemplate(template)(this)\n }\n else if (typeof template == 'function') {\n renderedTpl = template(this)\n }\n\n if (renderedTpl) {\n renderedTpl = renderedTpl.replace(/\\s\\w+=\"undefined\"/g, '')\n newNode.innerHTML = this.parseHtml(renderedTpl)\n }\n\n // this comes only from array nodes this.n(...)\n const slot = newNode.querySelector('slot')\n if (slot) {\n this.slot(this.root, slot.parentNode)\n slot.parentNode.removeChild(slot)\n }\n\n //let currentSlot = this.root.querySelector(':not(span.fez):not(div.fez) > .fez-slot, .fez-slot:not(span.fez *):not(div.fez *)');\n let currentSlot = this.find('.fez-slot')\n if (currentSlot) {\n const newSLot = newNode.querySelector('.fez-slot')\n if (newSLot) {\n newSLot.parentNode.replaceChild(currentSlot, newSLot)\n }\n }\n\n Fez.morphdom(this.root, newNode)\n\n this.renderFezPostProcess()\n\n this.afterRender()\n }\n\n renderFezPostProcess() {\n const fetchAttr = (name, func) => {\n this.root.querySelectorAll(`*[${name}]`).forEach((n)=>{\n let value = n.getAttribute(name)\n n.removeAttribute(name)\n if (value) {\n func.bind(this)(value, n)\n }\n })\n }\n\n // <button fez-this=\"button\" -> this.button = node\n fetchAttr('fez-this', (value, n) => {\n (new Function('n', `this.${value} = n`)).bind(this)(n)\n })\n\n // <button fez-use=\"animate\" -> this.animate(node]\n fetchAttr('fez-use', (value, n) => {\n const target = this[value]\n if (typeof target == 'function') {\n target(n)\n } else {\n console.error(`Fez error: \"${value}\" is not a function in ${this.fezName}`)\n }\n })\n\n // <button fez-class=\"dialog animate\" -> add class \"animate\" after node init to trigger animation\n fetchAttr('fez-class', (value, n) => {\n let classes = value.split(/\\s+/)\n let lastClass = classes.pop()\n classes.forEach((c)=> n.classList.add(c) )\n if (lastClass) {\n setTimeout(()=>{\n n.classList.add(lastClass)\n }, 300)\n }\n })\n\n // <input fez-bind=\"state.inputNode\" -> this.state.inputNode will be the value of input\n fetchAttr('fez-bind', (text, n) => {\n if (['INPUT', 'SELECT', 'TEXTAREA'].includes(n.nodeName)) {\n const value = (new Function(`return this.${text}`)).bind(this)()\n const isCb = n.type.toLowerCase() == 'checkbox'\n const eventName = ['SELECT'].includes(n.nodeName) || isCb ? 'onchange' : 'onkeyup'\n n.setAttribute(eventName, `${this.fezHtmlRoot}${text} = this.${isCb ? 'checked' : 'value'}`)\n this.val(n, value)\n } else {\n console.error(`Cant fez-bind=\"${text}\" to ${n.nodeName} (needs INPUT, SELECT or TEXTAREA. Want to use fez-this?).`)\n }\n })\n\n this.root.querySelectorAll(`*[disabled]`).forEach((n)=>{\n let value = n.getAttribute('disabled')\n if (['false'].includes(value)) {\n n.removeAttribute('disabled')\n } else {\n n.setAttribute('disabled', 'true')\n }\n })\n }\n\n // refresh single node only\n refresh(selector) {\n alert('NEEDS FIX and remove htmlTemplate')\n if (selector) {\n const n = document.createElement('div')\n n.innerHTML = this.class.htmlTemplate\n const tpl = n.querySelector(selector).innerHTML\n this.render(selector, tpl)\n } else {\n this.render()\n }\n }\n\n // run only if node is attached, clear otherwise\n setInterval(func, tick, name) {\n if (typeof func == 'number') {\n [tick, func] = [func, tick]\n }\n\n name ||= Fez.fnv1(String(func))\n\n this._setIntervalCache ||= {}\n clearInterval(this._setIntervalCache[name])\n\n this._setIntervalCache[name] = setInterval(() => {\n if (this.isConnected) {\n func()\n }\n }, tick)\n\n return this._setIntervalCache[name]\n }\n\n find(selector) {\n return typeof selector == 'string' ? this.root.querySelector(selector) : selector\n }\n\n // get or set node value\n val(selector, data) {\n const node = this.find(selector)\n\n if (node) {\n if (['INPUT', 'TEXTAREA', 'SELECT'].includes(node.nodeName)) {\n if (typeof data != 'undefined') {\n if (node.type == 'checkbox') {\n node.checked = !!data\n } else {\n node.value = data\n }\n } else {\n return node.value\n }\n } else {\n if (typeof data != 'undefined') {\n node.innerHTML = data\n } else {\n return node.innerHTML\n }\n }\n }\n }\n\n formData(node) {\n return this.class.formData(node || this.root)\n }\n\n // get or set attribute\n attr(name, value) {\n if (typeof value === 'undefined') {\n return this.root.getAttribute(name)\n } else {\n this.root.setAttribute(name, value)\n return value\n }\n }\n\n // get root node child nodes as array\n childNodes(func) {\n const children = Array.from(this.root.children)\n\n if (func) {\n // Create temporary container to avoid ancestor-parent errors\n const tmpContainer = document.createElement('div')\n tmpContainer.style.display = 'none'\n document.body.appendChild(tmpContainer)\n children.forEach(child => tmpContainer.appendChild(child))\n\n let list = Array.from(tmpContainer.children).map(func)\n document.body.removeChild(tmpContainer)\n return list\n } else {\n return children\n }\n }\n\n subscribe(channel, func) {\n Fez._subs ||= {}\n Fez._subs[channel] ||= []\n Fez._subs[channel] = Fez._subs[channel].filter((el) => el[0].isConnected)\n Fez._subs[channel].push([this, func])\n }\n\n // get and set root node ID\n rootId() {\n this.root.id ||= `fez_${this.UID}`\n return this.root.id\n }\n\n fezRegister() {\n if (this.css) {\n this.css = Fez.globalCss(this.css, {name: this.fezName, wrap: true})\n }\n\n if (this.class.css) {\n this.class.css = Fez.globalCss(this.class.css, {name: this.fezName})\n }\n\n this.state ||= this.reactiveStore()\n this.globalState = Fez.state.createProxy(this)\n this.fezRegisterBindMethods()\n }\n\n // bind all instance method to this, to avoid calling with .bind(this)\n fezRegisterBindMethods() {\n const methods = Object.getOwnPropertyNames(Object.getPrototypeOf(this))\n .filter(method => method !== 'constructor' && typeof this[method] === 'function')\n\n methods.forEach(method => this[method] = this[method].bind(this))\n }\n\n fezHide() {\n const node = this.root\n const parent = this.root.parentNode\n const fragment = document.createDocumentFragment();\n\n while (node.firstChild) {\n fragment.appendChild(node.firstChild)\n }\n\n // Replace the target element with the fragment (which contains the child elements)\n node.parentNode.replaceChild(fragment, node);\n // parent.classList.add('fez')\n // parent.classList.add(`fez-${this.fezName}`)\n this.root = parent\n return Array.from(this.root.children)\n }\n\n reactiveStore(obj, handler) {\n obj ||= {}\n\n handler ||= (o, k, v, oldValue) => {\n this.onStateChange(k, v, oldValue)\n this.nextTick(this.render, 'render')\n }\n\n handler.bind(this)\n\n // licence ? -> generated by ChatGPT 2024\n function createReactive(obj, handler) {\n if (typeof obj !== 'object' || obj === null) {\n return obj;\n }\n\n return new Proxy(obj, {\n set(target, property, value, receiver) {\n // Get the current value of the property\n const currentValue = Reflect.get(target, property, receiver);\n\n // Only proceed if the new value is different from the current value\n if (currentValue !== value) {\n if (typeof value === 'object' && value !== null) {\n value = createReactive(value, handler); // Recursively make nested objects reactive\n }\n\n // Set the new value\n const result = Reflect.set(target, property, value, receiver);\n\n // Call the handler only if the value has changed\n handler(target, property, value, currentValue);\n\n return result;\n }\n\n // If the value hasn't changed, return true (indicating success) without calling the handler\n return true;\n },\n get(target, property, receiver) {\n const value = Reflect.get(target, property, receiver);\n if (typeof value === 'object' && value !== null) {\n return createReactive(value, handler); // Recursively make nested objects reactive\n }\n return value;\n }\n });\n }\n\n return createReactive(obj, handler);\n }\n}\n", "/**\n * Skipped minification because the original files appears to be already minified.\n * Original file: /npm/goober@2.1.14/dist/goober.modern.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\nlet e={data:\"\"},t=t=>\"object\"==typeof window?((t?t.querySelector(\"#_goober\"):window._goober)||Object.assign((t||document.head).appendChild(document.createElement(\"style\")),{innerHTML:\" \",id:\"_goober\"})).firstChild:t||e,a=e=>{let a=t(e),r=a.data;return a.data=\"\",r},r=/(?:([\\u0080-\\uFFFF\\w-%@]+) *:? *([^{;]+?);|([^;}{]*?) *{)|(}\\s*)/g,l=/\\/\\*[^]*?\\*\\/| +/g,s=/\\n+/g,n=(e,t)=>{let a=\"\",r=\"\",l=\"\";for(let s in e){let o=e[s];\"@\"==s[0]?\"i\"==s[1]?a=s+\" \"+o+\";\":r+=\"f\"==s[1]?n(o,s):s+\"{\"+n(o,\"k\"==s[1]?\"\":t)+\"}\":\"object\"==typeof o?r+=n(o,t?t.replace(/([^,])+/g,(e=>s.replace(/(^:.*)|([^,])+/g,(t=>/&/.test(t)?t.replace(/&/g,e):e?e+\" \"+t:t)))):s):null!=o&&(s=/^--/.test(s)?s:s.replace(/[A-Z]/g,\"-$&\").toLowerCase(),l+=n.p?n.p(s,o):s+\":\"+o+\";\")}return a+(t&&l?t+\"{\"+l+\"}\":l)+r},o={},c=e=>{if(\"object\"==typeof e){let t=\"\";for(let a in e)t+=a+c(e[a]);return t}return e},i=(e,t,a,i,p)=>{let u=c(e),d=o[u]||(o[u]=(e=>{let t=0,a=11;for(;t<e.length;)a=101*a+e.charCodeAt(t++)>>>0;return\"go\"+a})(u));if(!o[d]){let t=u!==e?e:(e=>{let t,a,n=[{}];for(;t=r.exec(e.replace(l,\"\"));)t[4]?n.shift():t[3]?(a=t[3].replace(s,\" \").trim(),n.unshift(n[0][a]=n[0][a]||{})):n[0][t[1]]=t[2].replace(s,\" \").trim();return n[0]})(e);o[d]=n(p?{[\"@keyframes \"+d]:t}:t,a?\"\":\".\"+d)}let f=a&&o.g?o.g:null;return a&&(o.g=o[d]),((e,t,a,r)=>{r?t.data=t.data.replace(r,e):-1===t.data.indexOf(e)&&(t.data=a?e+t.data:t.data+e)})(o[d],t,i,f),d},p=(e,t,a)=>e.reduce(((e,r,l)=>{let s=t[l];if(s&&s.call){let e=s(a),t=e&&e.props&&e.props.className||/^go/.test(e)&&e;s=t?\".\"+t:e&&\"object\"==typeof e?e.props?\"\":n(e,\"\"):!1===e?\"\":e}return e+r+(null==s?\"\":s)}),\"\");function u(e){let a=this||{},r=e.call?e(a.p):e;return i(r.unshift?r.raw?p(r,[].slice.call(arguments,1),a.p):r.reduce(((e,t)=>Object.assign(e,t&&t.call?t(a.p):t)),{}):r,t(a.target),a.g,a.o,a.k)}let d,f,g,b=u.bind({g:1}),m=u.bind({k:1});function h(e,t,a,r){n.p=t,d=e,f=a,g=r}function y(e,t){let a=this||{};return function(){let r=arguments;function l(s,n){let o=Object.assign({},s),c=o.className||l.className;a.p=Object.assign({theme:f&&f()},o),a.o=/ *go\\d+/.test(c),o.className=u.apply(a,r)+(c?\" \"+c:\"\"),t&&(o.ref=n);let i=e;return e[0]&&(i=o.as||e,delete o.as),g&&i[0]&&g(o),d(i,o)}return t?t(l):l}}\nexport default { css:u, extractCss: a, glob: b, keyframes: m, setup: h, styled: y }\n", "// base IIFE to define idiomorph\nvar Idiomorph = (function () {\n 'use strict';\n\n //=============================================================================\n // AND NOW IT BEGINS...\n //=============================================================================\n let EMPTY_SET = new Set();\n\n // default configuration values, updatable by users now\n let defaults = {\n morphStyle: \"outerHTML\",\n callbacks : {\n beforeNodeAdded: noOp,\n afterNodeAdded: noOp,\n beforeNodeMorphed: noOp,\n afterNodeMorphed: noOp,\n beforeNodeRemoved: noOp,\n afterNodeRemoved: noOp,\n beforeAttributeUpdated: noOp,\n\n },\n head: {\n style: 'merge',\n shouldPreserve: function (elt) {\n return elt.getAttribute(\"im-preserve\") === \"true\";\n },\n shouldReAppend: function (elt) {\n return elt.getAttribute(\"im-re-append\") === \"true\";\n },\n shouldRemove: noOp,\n afterHeadMorphed: noOp,\n }\n };\n\n //=============================================================================\n // Core Morphing Algorithm - morph, morphNormalizedContent, morphOldNodeTo, morphChildren\n //=============================================================================\n function morph(oldNode, newContent, config = {}) {\n\n if (oldNode instanceof Document) {\n oldNode = oldNode.documentElement;\n }\n\n if (typeof newContent === 'string') {\n newContent = parseContent(newContent);\n }\n\n let normalizedContent = normalizeContent(newContent);\n\n let ctx = createMorphContext(oldNode, normalizedContent, config);\n\n return morphNormalizedContent(oldNode, normalizedContent, ctx);\n }\n\n function morphNormalizedContent(oldNode, normalizedNewContent, ctx) {\n if (ctx.head.block) {\n let oldHead = oldNode.querySelector('head');\n let newHead = normalizedNewContent.querySelector('head');\n if (oldHead && newHead) {\n let promises = handleHeadElement(newHead, oldHead, ctx);\n // when head promises resolve, call morph again, ignoring the head tag\n Promise.all(promises).then(function () {\n morphNormalizedContent(oldNode, normalizedNewContent, Object.assign(ctx, {\n head: {\n block: false,\n ignore: true\n }\n }));\n });\n return;\n }\n }\n\n if (ctx.morphStyle === \"innerHTML\") {\n\n // innerHTML, so we are only updating the children\n morphChildren(normalizedNewContent, oldNode, ctx);\n return oldNode.children;\n\n } else if (ctx.morphStyle === \"outerHTML\" || ctx.morphStyle == null) {\n // otherwise find the best element match in the new content, morph that, and merge its siblings\n // into either side of the best match\n let bestMatch = findBestNodeMatch(normalizedNewContent, oldNode, ctx);\n\n // stash the siblings that will need to be inserted on either side of the best match\n let previousSibling = bestMatch?.previousSibling;\n let nextSibling = bestMatch?.nextSibling;\n\n // morph it\n let morphedNode = morphOldNodeTo(oldNode, bestMatch, ctx);\n\n if (bestMatch) {\n // if there was a best match, merge the siblings in too and return the\n // whole bunch\n return insertSiblings(previousSibling, morphedNode, nextSibling);\n } else {\n // otherwise nothing was added to the DOM\n return []\n }\n } else {\n throw \"Do not understand how to morph style \" + ctx.morphStyle;\n }\n }\n\n\n /**\n * @param possibleActiveElement\n * @param ctx\n * @returns {boolean}\n */\n function ignoreValueOfActiveElement(possibleActiveElement, ctx) {\n return ctx.ignoreActiveValue && possibleActiveElement === document.activeElement && possibleActiveElement !== document.body;\n }\n\n /**\n * @param oldNode root node to merge content into\n * @param newContent new content to merge\n * @param ctx the merge context\n * @returns {Element} the element that ended up in the DOM\n */\n function morphOldNodeTo(oldNode, newContent, ctx) {\n if (ctx.ignoreActive && oldNode === document.activeElement) {\n // don't morph focused element\n } else if (newContent == null) {\n if (ctx.callbacks.beforeNodeRemoved(oldNode) === false) return oldNode;\n\n oldNode.remove();\n ctx.callbacks.afterNodeRemoved(oldNode);\n return null;\n } else if (!isSoftMatch(oldNode, newContent)) {\n if (ctx.callbacks.beforeNodeRemoved(oldNode) === false) return oldNode;\n if (ctx.callbacks.beforeNodeAdded(newContent) === false) return oldNode;\n\n oldNode.parentElement.replaceChild(newContent, oldNode);\n ctx.callbacks.afterNodeAdded(newContent);\n ctx.callbacks.afterNodeRemoved(oldNode);\n return newContent;\n } else {\n if (ctx.callbacks.beforeNodeMorphed(oldNode, newContent) === false) return oldNode;\n\n if (oldNode instanceof HTMLHeadElement && ctx.head.ignore) {\n // ignore the head element\n } else if (oldNode instanceof HTMLHeadElement && ctx.head.style !== \"morph\") {\n handleHeadElement(newContent, oldNode, ctx);\n } else {\n syncNodeFrom(newContent, oldNode, ctx);\n if (!ignoreValueOfActiveElement(oldNode, ctx)) {\n morphChildren(newContent, oldNode, ctx);\n }\n }\n ctx.callbacks.afterNodeMorphed(oldNode, newContent);\n return oldNode;\n }\n }\n\n /**\n * This is the core algorithm for matching up children. The idea is to use id sets to try to match up\n * nodes as faithfully as possible. We greedily match, which allows us to keep the algorithm fast, but\n * by using id sets, we are able to better match up with content deeper in the DOM.\n *\n * Basic algorithm is, for each node in the new content:\n *\n * - if we have reached the end of the old parent, append the new content\n * - if the new content has an id set match with the current insertion point, morph\n * - search for an id set match\n * - if id set match found, morph\n * - otherwise search for a \"soft\" match\n * - if a soft match is found, morph\n * - otherwise, prepend the new node before the current insertion point\n *\n * The two search algorithms terminate if competing node matches appear to outweigh what can be achieved\n * with the current node. See findIdSetMatch() and findSoftMatch() for details.\n *\n * @param {Element} newParent the parent element of the new content\n * @param {Element } oldParent the old content that we are merging the new content into\n * @param ctx the merge context\n */\n function morphChildren(newParent, oldParent, ctx) {\n\n let nextNewChild = newParent.firstChild;\n let insertionPoint = oldParent.firstChild;\n let newChild;\n\n // run through all the new content\n while (nextNewChild) {\n\n newChild = nextNewChild;\n nextNewChild = newChild.nextSibling;\n\n // if we are at the end of the exiting parent's children, just append\n if (insertionPoint == null) {\n if (ctx.callbacks.beforeNodeAdded(newChild) === false) return;\n\n oldParent.appendChild(newChild);\n ctx.callbacks.afterNodeAdded(newChild);\n removeIdsFromConsideration(ctx, newChild);\n continue;\n }\n\n // if the current node has an id set match then morph\n if (isIdSetMatch(newChild, insertionPoint, ctx)) {\n morphOldNodeTo(insertionPoint, newChild, ctx);\n insertionPoint = insertionPoint.nextSibling;\n removeIdsFromConsideration(ctx, newChild);\n continue;\n }\n\n // otherwise search forward in the existing old children for an id set match\n let idSetMatch = findIdSetMatch(newParent, oldParent, newChild, insertionPoint, ctx);\n\n // if we found a potential match, remove the nodes until that point and morph\n if (idSetMatch) {\n insertionPoint = removeNodesBetween(insertionPoint, idSetMatch, ctx);\n morphOldNodeTo(idSetMatch, newChild, ctx);\n removeIdsFromConsideration(ctx, newChild);\n continue;\n }\n\n // no id set match found, so scan forward for a soft match for the current node\n let softMatch = findSoftMatch(newParent, oldParent, newChild, insertionPoint, ctx);\n\n // if we found a soft match for the current node, morph\n if (softMatch) {\n insertionPoint = removeNodesBetween(insertionPoint, softMatch, ctx);\n morphOldNodeTo(softMatch, newChild, ctx);\n removeIdsFromConsideration(ctx, newChild);\n continue;\n }\n\n // abandon all hope of morphing, just insert the new child before the insertion point\n // and move on\n if (ctx.callbacks.beforeNodeAdded(newChild) === false) return;\n\n oldParent.insertBefore(newChild, insertionPoint);\n ctx.callbacks.afterNodeAdded(newChild);\n removeIdsFromConsideration(ctx, newChild);\n }\n\n // remove any remaining old nodes that didn't match up with new content\n while (insertionPoint !== null) {\n\n let tempNode = insertionPoint;\n insertionPoint = insertionPoint.nextSibling;\n removeNode(tempNode, ctx);\n }\n }\n\n //=============================================================================\n // Attribute Syncing Code\n //=============================================================================\n\n /**\n * @param attr {String} the attribute to be mutated\n * @param to {Element} the element that is going to be updated\n * @param updateType {(\"update\"|\"remove\")}\n * @param ctx the merge context\n * @returns {boolean} true if the attribute should be ignored, false otherwise\n */\n function ignoreAttribute(attr, to, updateType, ctx) {\n if(attr === 'value' && ctx.ignoreActiveValue && to === document.activeElement){\n return true;\n }\n return ctx.callbacks.beforeAttributeUpdated(attr, to, updateType) === false;\n }\n\n /**\n * syncs a given node with another node, copying over all attributes and\n * inner element state from the 'from' node to the 'to' node\n *\n * @param {Element} from the element to copy attributes & state from\n * @param {Element} to the element to copy attributes & state to\n * @param ctx the merge context\n */\n function syncNodeFrom(from, to, ctx) {\n let type = from.nodeType\n\n // if is an element type, sync the attributes from the\n // new node into the new node\n if (type === 1 /* element type */) {\n const fromAttributes = from.attributes;\n const toAttributes = to.attributes;\n for (const fromAttribute of fromAttributes) {\n if (ignoreAttribute(fromAttribute.name, to, 'update', ctx)) {\n continue;\n }\n\n try {\n if (to.getAttribute(fromAttribute.name) !== fromAttribute.value) {\n to.setAttribute(fromAttribute.name, fromAttribute.value);\n }\n } catch (error) {\n // dux fix\n console.error('Error setting attribute:', {\n badNode: to,\n badAttribute: fromAttribute,\n error: error.message,\n });\n }\n }\n // iterate backwards to avoid skipping over items when a delete occurs\n for (let i = toAttributes.length - 1; 0 <= i; i--) {\n const toAttribute = toAttributes[i];\n if (ignoreAttribute(toAttribute.name, to, 'remove', ctx)) {\n continue;\n }\n if (!from.hasAttribute(toAttribute.name)) {\n to.removeAttribute(toAttribute.name);\n }\n }\n }\n\n // sync text nodes\n if (type === 8 /* comment */ || type === 3 /* text */) {\n if (to.nodeValue !== from.nodeValue) {\n to.nodeValue = from.nodeValue;\n }\n }\n\n if (!ignoreValueOfActiveElement(to, ctx)) {\n // sync input values\n syncInputValue(from, to, ctx);\n }\n }\n\n /**\n * @param from {Element} element to sync the value from\n * @param to {Element} element to sync the value to\n * @param attributeName {String} the attribute name\n * @param ctx the merge context\n */\n function syncBooleanAttribute(from, to, attributeName, ctx) {\n if (from[attributeName] !== to[attributeName]) {\n let ignoreUpdate = ignoreAttribute(attributeName, to, 'update', ctx);\n if (!ignoreUpdate) {\n to[attributeName] = from[attributeName];\n }\n if (from[attributeName]) {\n if (!ignoreUpdate) {\n to.setAttribute(attributeName, from[attributeName]);\n }\n } else {\n if (!ignoreAttribute(attributeName, to, 'remove', ctx)) {\n to.removeAttribute(attributeName);\n }\n }\n }\n }\n\n /**\n * NB: many bothans died to bring us information:\n *\n * https://github.com/patrick-steele-idem/morphdom/blob/master/src/specialElHandlers.js\n * https://github.com/choojs/nanomorph/blob/master/lib/morph.jsL113\n *\n * @param from {Element} the element to sync the input value from\n * @param to {Element} the element to sync the input value to\n * @param ctx the merge context\n */\n function syncInputValue(from, to, ctx) {\n if (from instanceof HTMLInputElement &&\n to instanceof HTMLInputElement &&\n from.type !== 'file') {\n\n let fromValue = from.value;\n let toValue = to.value;\n\n // sync boolean attributes\n syncBooleanAttribute(from, to, 'checked', ctx);\n syncBooleanAttribute(from, to, 'disabled', ctx);\n\n if (!from.hasAttribute('value')) {\n if (!ignoreAttribute('value', to, 'remove', ctx)) {\n to.value = '';\n to.removeAttribute('value');\n }\n } else if (fromValue !== toValue) {\n if (!ignoreAttribute('value', to, 'update', ctx)) {\n to.setAttribute('value', fromValue);\n to.value = fromValue;\n }\n }\n } else if (from instanceof HTMLOptionElement) {\n syncBooleanAttribute(from, to, 'selected', ctx)\n } else if (from instanceof HTMLTextAreaElement && to instanceof HTMLTextAreaElement) {\n let fromValue = from.value;\n let toValue = to.value;\n if (ignoreAttribute('value', to, 'update', ctx)) {\n return;\n }\n if (fromValue !== toValue) {\n to.value = fromValue;\n }\n if (to.firstChild && to.firstChild.nodeValue !== fromValue) {\n to.firstChild.nodeValue = fromValue\n }\n }\n }\n\n //=============================================================================\n // the HEAD tag can be handled specially, either w/ a 'merge' or 'append' style\n //=============================================================================\n function handleHeadElement(newHeadTag, currentHead, ctx) {\n\n let added = []\n let removed = []\n let preserved = []\n let nodesToAppend = []\n\n let headMergeStyle = ctx.head.style;\n\n // put all new head elements into a Map, by their outerHTML\n let srcToNewHeadNodes = new Map();\n for (const newHeadChild of newHeadTag.children) {\n srcToNewHeadNodes.set(newHeadChild.outerHTML, newHeadChild);\n }\n\n // for each elt in the current head\n for (const currentHeadElt of currentHead.children) {\n\n // If the current head element is in the map\n let inNewContent = srcToNewHeadNodes.has(currentHeadElt.outerHTML);\n let isReAppended = ctx.head.shouldReAppend(currentHeadElt);\n let isPreserved = ctx.head.shouldPreserve(currentHeadElt);\n if (inNewContent || isPreserved) {\n if (isReAppended) {\n // remove the current version and let the new version replace it and re-execute\n removed.push(currentHeadElt);\n } else {\n // this element already exists and should not be re-appended, so remove it from\n // the new content map, preserving it in the DOM\n srcToNewHeadNodes.delete(currentHeadElt.outerHTML);\n preserved.push(currentHeadElt);\n }\n } else {\n if (headMergeStyle === \"append\") {\n // we are appending and this existing element is not new content\n // so if and only if it is marked for re-append do we do anything\n if (isReAppended) {\n removed.push(currentHeadElt);\n nodesToAppend.push(currentHeadElt);\n }\n } else {\n // if this is a merge, we remove this content since it is not in the new head\n if (ctx.head.shouldRemove(currentHeadElt) !== false) {\n removed.push(currentHeadElt);\n }\n }\n }\n }\n\n // Push the remaining new head elements in the Map into the\n // nodes to append to the head tag\n nodesToAppend.push(...srcToNewHeadNodes.values());\n log(\"to append: \", nodesToAppend);\n\n let promises = [];\n for (const newNode of nodesToAppend) {\n log(\"adding: \", newNode);\n let newElt = document.createRange().createContextualFragment(newNode.outerHTML).firstChild;\n log(newElt);\n if (ctx.callbacks.beforeNodeAdded(newElt) !== false) {\n if (newElt.href || newElt.src) {\n let resolve = null;\n let promise = new Promise(function (_resolve) {\n resolve = _resolve;\n });\n newElt.addEventListener('load', function () {\n resolve();\n });\n promises.push(promise);\n }\n currentHead.appendChild(newElt);\n ctx.callbacks.afterNodeAdded(newElt);\n added.push(newElt);\n }\n }\n\n // remove all removed elements, after we have appended the new elements to avoid\n // additional network requests for things like style sheets\n for (const removedElement of removed) {\n if (ctx.callbacks.beforeNodeRemoved(removedElement) !== false) {\n currentHead.removeChild(removedElement);\n ctx.callbacks.afterNodeRemoved(removedElement);\n }\n }\n\n ctx.head.afterHeadMorphed(currentHead, {added: added, kept: preserved, removed: removed});\n return promises;\n }\n\n //=============================================================================\n // Misc\n //=============================================================================\n\n function log() {\n //console.log(arguments);\n }\n\n function noOp() {\n }\n\n /*\n Deep merges the config object and the Idiomoroph.defaults object to\n produce a final configuration object\n */\n function mergeDefaults(config) {\n let finalConfig = {};\n // copy top level stuff into final config\n Object.assign(finalConfig, defaults);\n Object.assign(finalConfig, config);\n\n // copy callbacks into final config (do this to deep merge the callbacks)\n finalConfig.callbacks = {};\n Object.assign(finalConfig.callbacks, defaults.callbacks);\n Object.assign(finalConfig.callbacks, config.callbacks);\n\n // copy head config into final config (do this to deep merge the head)\n finalConfig.head = {};\n Object.assign(finalConfig.head, defaults.head);\n Object.assign(finalConfig.head, config.head);\n return finalConfig;\n }\n\n function createMorphContext(oldNode, newContent, config) {\n config = mergeDefaults(config);\n return {\n target: oldNode,\n newContent: newContent,\n config: config,\n morphStyle: config.morphStyle,\n ignoreActive: config.ignoreActive,\n ignoreActiveValue: config.ignoreActiveValue,\n idMap: createIdMap(oldNode, newContent),\n deadIds: new Set(),\n callbacks: config.callbacks,\n head: config.head\n }\n }\n\n function isIdSetMatch(node1, node2, ctx) {\n if (node1 == null || node2 == null) {\n return false;\n }\n if (node1.nodeType === node2.nodeType && node1.tagName === node2.tagName) {\n if (node1.id !== \"\" && node1.id === node2.id) {\n return true;\n } else {\n return getIdIntersectionCount(ctx, node1, node2) > 0;\n }\n }\n return false;\n }\n\n function isSoftMatch(node1, node2) {\n if (node1 == null || node2 == null) {\n return false;\n }\n return node1.nodeType === node2.nodeType && node1.tagName === node2.tagName\n }\n\n function removeNodesBetween(startInclusive, endExclusive, ctx) {\n while (startInclusive !== endExclusive) {\n let tempNode = startInclusive;\n startInclusive = startInclusive.nextSibling;\n removeNode(tempNode, ctx);\n }\n removeIdsFromConsideration(ctx, endExclusive);\n return endExclusive.nextSibling;\n }\n\n //=============================================================================\n // Scans forward from the insertionPoint in the old parent looking for a potential id match\n // for the newChild. We stop if we find a potential id match for the new child OR\n // if the number of potential id matches we are discarding is greater than the\n // potential id matches for the new child\n //=============================================================================\n function findIdSetMatch(newContent, oldParent, newChild, insertionPoint, ctx) {\n\n // max id matches we are willing to discard in our search\n let newChildPotentialIdCount = getIdIntersectionCount(ctx, newChild, oldParent);\n\n let potentialMatch = null;\n\n // only search forward if there is a possibility of an id match\n if (newChildPotentialIdCount > 0) {\n let potentialMatch = insertionPoint;\n // if there is a possibility of an id match, scan forward\n // keep track of the potential id match count we are discarding (the\n // newChildPotentialIdCount must be greater than this to make it likely\n // worth it)\n let otherMatchCount = 0;\n while (potentialMatch != null) {\n\n // If we have an id match, return the current potential match\n if (isIdSetMatch(newChild, potentialMatch, ctx)) {\n return potentialMatch;\n }\n\n // computer the other potential matches of this new content\n otherMatchCount += getIdIntersectionCount(ctx, potentialMatch, newContent);\n if (otherMatchCount > newChildPotentialIdCount) {\n // if we have more potential id matches in _other_ content, we\n // do not have a good candidate for an id match, so return null\n return null;\n }\n\n // advanced to the next old content child\n potentialMatch = potentialMatch.nextSibling;\n }\n }\n return potentialMatch;\n }\n\n //=============================================================================\n // Scans forward from the insertionPoint in the old parent looking for a potential soft match\n // for the newChild. We stop if we find a potential soft match for the new child OR\n // if we find a potential id match in the old parents children OR if we find two\n // potential soft matches for the next two pieces of new content\n //=============================================================================\n function findSoftMatch(newContent, oldParent, newChild, insertionPoint, ctx) {\n\n let potentialSoftMatch = insertionPoint;\n let nextSibling = newChild.nextSibling;\n let siblingSoftMatchCount = 0;\n\n while (potentialSoftMatch != null) {\n\n if (getIdIntersectionCount(ctx, potentialSoftMatch, newContent) > 0) {\n // the current potential soft match has a potential id set match with the remaining new\n // content so bail out of looking\n return null;\n }\n\n // if we have a soft match with the current node, return it\n if (isSoftMatch(newChild, potentialSoftMatch)) {\n return potentialSoftMatch;\n }\n\n if (isSoftMatch(nextSibling, potentialSoftMatch)) {\n // the next new node has a soft match with this node, so\n // increment the count of future soft matches\n siblingSoftMatchCount++;\n nextSibling = nextSibling.nextSibling;\n\n // If there are two future soft matches, bail to allow the siblings to soft match\n // so that we don't consume future soft matches for the sake of the current node\n if (siblingSoftMatchCount >= 2) {\n return null;\n }\n }\n\n // advanced to the next old content child\n potentialSoftMatch = potentialSoftMatch.nextSibling;\n }\n\n return potentialSoftMatch;\n }\n\n function parseContent(newContent) {\n let parser = new DOMParser();\n\n // remove svgs to avoid false-positive matches on head, etc.\n let contentWithSvgsRemoved = newContent.replace(/<svg(\\s[^>]*>|>)([\\s\\S]*?)<\\/svg>/gim, '');\n\n // if the newContent contains a html, head or body tag, we can simply parse it w/o wrapping\n if (contentWithSvgsRemoved.match(/<\\/html>/) || contentWithSvgsRemoved.match(/<\\/head>/) || contentWithSvgsRemoved.match(/<\\/body>/)) {\n let content = parser.parseFromString(newContent, \"text/html\");\n // if it is a full HTML document, return the document itself as the parent container\n if (contentWithSvgsRemoved.match(/<\\/html>/)) {\n content.generatedByIdiomorph = true;\n return content;\n } else {\n // otherwise return the html element as the parent container\n let htmlElement = content.firstChild;\n if (htmlElement) {\n htmlElement.generatedByIdiomorph = true;\n return htmlElement;\n } else {\n return null;\n }\n }\n } else {\n // if it is partial HTML, wrap it in a template tag to provide a parent element and also to help\n // deal with touchy tags like tr, tbody, etc.\n let responseDoc = parser.parseFromString(\"<body><template>\" + newContent + \"</template></body>\", \"text/html\");\n let content = responseDoc.body.querySelector('template').content;\n content.generatedByIdiomorph = true;\n return content\n }\n }\n\n function normalizeContent(newContent) {\n if (newContent == null) {\n // noinspection UnnecessaryLocalVariableJS\n const dummyParent = document.createElement('div');\n return dummyParent;\n } else if (newContent.generatedByIdiomorph) {\n // the template tag created by idiomorph parsing can serve as a dummy parent\n return newContent;\n } else if (newContent instanceof Node) {\n // a single node is added as a child to a dummy parent\n const dummyParent = document.createElement('div');\n dummyParent.append(newContent);\n return dummyParent;\n } else {\n // all nodes in the array or HTMLElement collection are consolidated under\n // a single dummy parent element\n const dummyParent = document.createElement('div');\n for (const elt of [...newContent]) {\n dummyParent.append(elt);\n }\n return dummyParent;\n }\n }\n\n function insertSiblings(previousSibling, morphedNode, nextSibling) {\n let stack = []\n let added = []\n while (previousSibling != null) {\n stack.push(previousSibling);\n previousSibling = previousSibling.previousSibling;\n }\n while (stack.length > 0) {\n let node = stack.pop();\n added.push(node); // push added preceding siblings on in order and insert\n morphedNode.parentElement.insertBefore(node, morphedNode);\n }\n added.push(morphedNode);\n while (nextSibling != null) {\n stack.push(nextSibling);\n added.push(nextSibling); // here we are going in order, so push on as we scan, rather than add\n nextSibling = nextSibling.nextSibling;\n }\n while (stack.length > 0) {\n morphedNode.parentElement.insertBefore(stack.pop(), morphedNode.nextSibling);\n }\n return added;\n }\n\n function findBestNodeMatch(newContent, oldNode, ctx) {\n let currentElement;\n currentElement = newContent.firstChild;\n let bestElement = currentElement;\n let score = 0;\n while (currentElement) {\n let newScore = scoreElement(currentElement, oldNode, ctx);\n if (newScore > score) {\n bestElement = currentElement;\n score = newScore;\n }\n currentElement = currentElement.nextSibling;\n }\n return bestElement;\n }\n\n function scoreElement(node1, node2, ctx) {\n if (isSoftMatch(node1, node2)) {\n return .5 + getIdIntersectionCount(ctx, node1, node2);\n }\n return 0;\n }\n\n function removeNode(tempNode, ctx) {\n removeIdsFromConsideration(ctx, tempNode)\n if (ctx.callbacks.beforeNodeRemoved(tempNode) === false) return;\n\n tempNode.remove();\n ctx.callbacks.afterNodeRemoved(tempNode);\n }\n\n //=============================================================================\n // ID Set Functions\n //=============================================================================\n\n function isIdInConsideration(ctx, id) {\n return !ctx.deadIds.has(id);\n }\n\n function idIsWithinNode(ctx, id, targetNode) {\n let idSet = ctx.idMap.get(targetNode) || EMPTY_SET;\n return idSet.has(id);\n }\n\n function removeIdsFromConsideration(ctx, node) {\n let idSet = ctx.idMap.get(node) || EMPTY_SET;\n for (const id of idSet) {\n ctx.deadIds.add(id);\n }\n }\n\n function getIdIntersectionCount(ctx, node1, node2) {\n let sourceSet = ctx.idMap.get(node1) || EMPTY_SET;\n let matchCount = 0;\n for (const id of sourceSet) {\n // a potential match is an id in the source and potentialIdsSet, but\n // that has not already been merged into the DOM\n if (isIdInConsideration(ctx, id) && idIsWithinNode(ctx, id, node2)) {\n ++matchCount;\n }\n }\n return matchCount;\n }\n\n /**\n * A bottom up algorithm that finds all elements with ids inside of the node\n * argument and populates id sets for those nodes and all their parents, generating\n * a set of ids contained within all nodes for the entire hierarchy in the DOM\n *\n * @param node {Element}\n * @param {Map<Node, Set<String>>} idMap\n */\n function populateIdMapForNode(node, idMap) {\n let nodeParent = node.parentElement;\n // find all elements with an id property\n let idElements = node.querySelectorAll('[id]');\n for (const elt of idElements) {\n let current = elt;\n // walk up the parent hierarchy of that element, adding the id\n // of element to the parent's id set\n while (current !== nodeParent && current != null) {\n let idSet = idMap.get(current);\n // if the id set doesn't exist, create it and insert it in the map\n if (idSet == null) {\n idSet = new Set();\n idMap.set(current, idSet);\n }\n idSet.add(elt.id);\n current = current.parentElement;\n }\n }\n }\n\n /**\n * This function computes a map of nodes to all ids contained within that node (inclusive of the\n * node). This map can be used to ask if two nodes have intersecting sets of ids, which allows\n * for a looser definition of \"matching\" than tradition id matching, and allows child nodes\n * to contribute to a parent nodes matching.\n *\n * @param {Element} oldContent the old content that will be morphed\n * @param {Element} newContent the new content to morph to\n * @returns {Map<Node, Set<String>>} a map of nodes to id sets for the\n */\n function createIdMap(oldContent, newContent) {\n let idMap = new Map();\n populateIdMapForNode(oldContent, idMap);\n populateIdMapForNode(newContent, idMap);\n return idMap;\n }\n\n //=============================================================================\n // This is what ends up becoming the Idiomorph global object\n //=============================================================================\n return {\n morph,\n defaults\n }\n })();\n\nexport {Idiomorph};\n", "// templating\nimport createTemplate from './lib/template.js'\nimport FezBase from './instance.js'\n\n// this function accepts custom tag name and class definition, creates and connects\n// Fez(name, klass)\nexport default function(name, klass) {\n const Fez = globalThis.window?.Fez || globalThis.Fez;\n // Validate custom element name format (must contain a dash)\n if (!name.includes('-')) {\n console.error(`Fez: Invalid custom element name \"${name}\". Custom element names must contain a dash (e.g., 'my-element', 'ui-button').`)\n }\n\n // to allow anonymous class and then re-attach (does not work)\n // Fez('ui-todo', class { ... # instead Fez('ui-todo', class extends FezBase {\n if (!klass.fezHtmlRoot) {\n const klassObj = new klass()\n const newKlass = class extends FezBase {}\n\n const props = Object.getOwnPropertyNames(klassObj)\n .concat(Object.getOwnPropertyNames(klass.prototype))\n .filter(el => !['constructor', 'prototype'].includes(el))\n\n props.forEach(prop => newKlass.prototype[prop] = klassObj[prop])\n\n Fez.fastBindInfo ||= {fast: [], slow: []}\n\n if (klassObj.GLOBAL) { newKlass.fezGlobal = klassObj.GLOBAL }\n if (klassObj.CSS) { newKlass.css = klassObj.CSS }\n if (klassObj.HTML) { newKlass.html = klassObj.HTML }\n if (klassObj.NAME) { newKlass.nodeName = klassObj.NAME }\n if (klassObj.FAST) {\n newKlass.fastBind = klassObj.FAST\n Fez.fastBindInfo.fast.push(typeof klassObj.FAST == 'function' ? `${name} (func)` : name)\n } else {\n Fez.fastBindInfo.slow.push(name)\n }\n\n if (klassObj.GLOBAL) {\n const func = () => document.body.appendChild(document.createElement(name))\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', func);\n } else {\n func()\n }\n }\n\n klass = newKlass\n\n let info = `${name} compiled`\n if (klassObj.FAST) info += ' (fast bind)'\n Fez.log(info)\n }\n\n if (klass.html) {\n klass.html = closeCustomTags(klass.html)\n\n // wrap slot to enable reactive re-renders. It will use existing .fez-slot if found\n klass.html = klass.html.replace(/<slot\\s*\\/>|<slot\\s*>\\s*<\\/slot>/g, () => {\n const name = klass.slotNodeName || 'div'\n return `<${name} class=\"fez-slot\"></${name}>`\n })\n\n klass.fezHtmlFunc = createTemplate(klass.html)\n }\n\n // we have to register global css on component init, because some other component can depend on it (it is global)\n if (klass.css) {\n klass.css = Fez.globalCss(klass.css, {name: name})\n }\n\n Fez.classes[name] = klass\n\n if (!customElements.get(name)) {\n customElements.define(name, class extends HTMLElement {\n connectedCallback() {\n // if you want to force fast render (prevent page flickering), add static fastBind = true or FAST = true\n // we can not fast load auto for all because that creates hard to debug problems in nested custom nodes\n // problems with events and slots (I woke up at 2AM, now it is 5AM)\n // this is usually safe for first order components, as page header or any components that do not have innerHTML or use slots\n // Example: you can add FAST as a function - render fast nodes that have name attribute\n // FAST(node) { return !!node.getAttribute('name') }\n // to inspect fast / slow components use Fez.info() in console\n if (useFastRender(this, klass)) {\n connectNode(name, this)\n } else {\n window.requestAnimationFrame(()=>{\n if (this.parentNode) {\n connectNode(name, this)\n }\n })\n }\n }\n })\n }\n}\n\n//\n\nfunction closeCustomTags(html) {\n const selfClosingTags = new Set([\n 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'source', 'track', 'wbr'\n ])\n\n return html.replace(/<([a-z-]+)\\b([^>]*)\\/>/g, (match, tagName, attributes) => {\n return selfClosingTags.has(tagName) ? match : `<${tagName}${attributes}></${tagName}>`\n })\n}\n\nfunction useFastRender(n, klass) {\n const fezFast = n.getAttribute('fez-fast')\n var isFast = typeof klass.fastBind === 'function' ? klass.fastBind(n) : klass.fastBind\n\n if (fezFast == 'false') {\n return false\n } else {\n return fezFast || isFast\n }\n}\n\nfunction connectNode(name, node) {\n const klass = Fez.classes[name]\n const parentNode = node.parentNode\n\n if (node.isConnected) {\n const nodeName = typeof klass.nodeName == 'function' ? klass.nodeName(node) : klass.nodeName\n const newNode = document.createElement(nodeName || 'div')\n\n newNode.classList.add('fez')\n newNode.classList.add(`fez-${name}`)\n\n parentNode.replaceChild(newNode, node);\n\n const fez = new klass()\n\n fez.UID = ++Fez.instanceCount\n Fez.instances.set(fez.UID, fez)\n\n fez.oldRoot = node\n fez.fezName = name\n fez.root = newNode\n fez.props = klass.getProps(node, newNode)\n fez.class = klass\n\n // copy child nodes, natively to preserve bound events\n fez.slot(node, newNode)\n\n newNode.fez = fez\n\n if (klass.fezGlobal && klass.fezGlobal != true) {\n window[klass.fezGlobal] = fez\n }\n\n if (window.$) {\n fez.$root = $(newNode)\n }\n\n if (fez.props.id) {\n newNode.setAttribute('id', fez.props.id)\n }\n\n fez.fezRegister();\n (fez.init || fez.created || fez.connect).bind(fez)(fez.props);\n\n const oldRoot = fez.root.cloneNode(true)\n\n if (fez.class.fezHtmlFunc) {\n fez.render()\n }\n\n const slot = fez.root.querySelector('.fez-slot')\n if (slot) {\n if (fez.props.html) {\n slot.innerHTML = fez.props.html\n } else {\n fez.slot(oldRoot, slot)\n }\n }\n\n if (fez.onSubmit) {\n const form = fez.root.nodeName == 'FORM' ? fez.root : fez.find('form')\n form.onsubmit = (e) => {\n e.preventDefault()\n fez.onSubmit(fez.formData())\n }\n }\n\n fez.onMount(fez.props)\n\n // if onPropsChange method defined, add observer and trigger call on all attributes once component is loaded\n if (fez.onPropsChange) {\n observer.observe(newNode, {attributes:true})\n for (const [key, value] of Object.entries(fez.props)) {\n fez.onPropsChange(key, value)\n }\n }\n }\n}\n\n//\n\nconst observer = new MutationObserver((mutationsList, _) => {\n for (const mutation of mutationsList) {\n if (mutation.type === 'attributes') {\n const fez = mutation.target.fez\n const name = mutation.attributeName\n const value = mutation.target.getAttribute(name)\n\n if (fez) {\n fez.props[name] = value\n fez.onPropsChange(name, value)\n // console.log(`The [${name}] attribute was modified to [${value}].`);\n }\n }\n }\n});\n", "const compileToClass = (html) => {\n const result = { script: '', style: '', html: '', head: '' }\n const lines = html.split('\\n')\n\n let currentBlock = []\n let currentType = ''\n\n for (var line of lines) {\n line = line.trim()\n if (line.startsWith('<script') && !result.script && currentType != 'head') {\n currentType = 'script';\n } else if (line.startsWith('<head') && !result.script) { // you must use XMP tag if you want to define <head> tag, and it has to be first\n currentType = 'head';\n } else if (line.startsWith('<style')) {\n currentType = 'style';\n } else if (line.endsWith('</script>') && currentType === 'script' && !result.script) {\n result.script = currentBlock.join('\\n');\n currentBlock = [];\n currentType = null;\n } else if (line.endsWith('</style>') && currentType === 'style') {\n result.style = currentBlock.join('\\n');\n currentBlock = [];\n currentType = null;\n } else if ((line.endsWith('</head>') || line.endsWith('</header>')) && currentType === 'head') {\n result.head = currentBlock.join('\\n');\n currentBlock = [];\n currentType = null;\n } else if (currentType) {\n currentBlock.push(line);\n } else {\n result.html += line + '\\n';\n }\n }\n\n if (result.head) {\n const container = document.createElement('div')\n container.innerHTML = result.head\n\n // Process all children of the container\n Array.from(container.children).forEach(node => {\n if (node.tagName === 'SCRIPT') {\n const script = document.createElement('script')\n // Copy all attributes\n Array.from(node.attributes).forEach(attr => {\n script.setAttribute(attr.name, attr.value)\n })\n script.type ||= 'text/javascript'\n\n if (node.src) {\n // External script - will load automatically\n document.head.appendChild(script)\n } else if (script.type.includes('javascript') || script.type == 'module') {\n // Inline script - set content and execute\n script.textContent = node.textContent\n document.head.appendChild(script)\n }\n } else {\n // For other elements (link, meta, etc.), just append them\n document.head.appendChild(node.cloneNode(true))\n }\n })\n }\n\n let klass = result.script\n\n if (!/class\\s+\\{/.test(klass)) {\n klass = `class {\\n${klass}\\n}`\n }\n\n if (String(result.style).includes(':')) {\n Object.entries(Fez._styleMacros).forEach(([key, val])=>{\n result.style = result.style.replaceAll(`:${key} `, `${val} `)\n })\n\n result.style = result.style.includes(':fez') || /(?:^|\\s)body\\s*\\{/.test(result.style) ? result.style : `:fez {\\n${result.style}\\n}`\n klass = klass.replace(/\\}\\s*$/, `\\n CSS = \\`${result.style}\\`\\n}`)\n }\n\n if (/\\w/.test(String(result.html))) {\n // escape backticks in whole template block\n result.html = result.html.replaceAll('`', '&#x60;')\n result.html = result.html.replaceAll('$', '\\\\$')\n klass = klass.replace(/\\}\\s*$/, `\\n HTML = \\`${result.html}\\`\\n}`)\n }\n\n return klass\n}\n\n// <template fez=\"ui-form\">\n// <script>\n// ...\n// Fez.compile() # compile all\n// Fez.compile(templateNode) # compile template node\n// Fez.compile('ui-form', templateNode.innerHTML) # compile string\nexport default function (tagName, html) {\n if (tagName instanceof Node) {\n const node = tagName\n node.remove()\n\n const fezName = node.getAttribute('fez')\n\n // Check if fezName contains dot or slash (indicates URL)\n if (fezName && (fezName.includes('.') || fezName.includes('/'))) {\n const url = fezName\n\n Fez.log(`Loading from ${url}`)\n\n // Load HTML content via AJAX from URL\n fetch(url)\n .then(response => {\n if (!response.ok) {\n throw new Error(`Failed to load ${url}: ${response.status}`)\n }\n return response.text()\n })\n .then(htmlContent => {\n // Check if remote HTML has template/xmp tags with fez attribute\n const parser = new DOMParser()\n const doc = parser.parseFromString(htmlContent, 'text/html')\n const fezElements = doc.querySelectorAll('template[fez], xmp[fez]')\n\n if (fezElements.length > 0) {\n // Compile each found fez element\n fezElements.forEach(el => {\n const name = el.getAttribute('fez')\n if (name && !name.includes('-') && !name.includes('.') && !name.includes('/')) {\n console.error(`Fez: Invalid custom element name \"${name}\". Custom element names must contain a dash (e.g., 'my-element', 'ui-button').`)\n }\n const content = el.innerHTML\n Fez.compile(name, content)\n })\n } else {\n // No fez elements found, use extracted name from URL\n const name = url.split('/').pop().split('.')[0]\n Fez.compile(name, htmlContent)\n }\n })\n .catch(error => {\n console.error(`FEZ template load error for \"${fezName}\": ${error.message}`)\n })\n return\n } else {\n // Validate fezName format for non-URL names\n if (fezName && !fezName.includes('-')) {\n console.error(`Fez: Invalid custom element name \"${fezName}\". Custom element names must contain a dash (e.g., 'my-element', 'ui-button').`)\n }\n html = node.innerHTML\n tagName = fezName\n }\n }\n else if (typeof html != 'string') {\n document.body.querySelectorAll('template[fez], xmp[fez]').forEach((n) => Fez.compile(n))\n return\n }\n\n // Validate element name if it's not a URL\n if (tagName && !tagName.includes('-') && !tagName.includes('.') && !tagName.includes('/')) {\n console.error(`Fez: Invalid custom element name \"${tagName}\". Custom element names must contain a dash (e.g., 'my-element', 'ui-button').`)\n }\n\n let klass = compileToClass(html)\n let parts = klass.split(/class\\s+\\{/, 2)\n\n klass = `${parts[0]};\\n\\nwindow.Fez('${tagName}', class {\\n${parts[1]})`\n\n // Add tag to global hidden styles container\n if (tagName) {\n let styleContainer = document.getElementById('fez-hidden-styles')\n if (!styleContainer) {\n styleContainer = document.createElement('style')\n styleContainer.id = 'fez-hidden-styles'\n document.head.appendChild(styleContainer)\n }\n styleContainer.textContent += `${tagName} { display: none; }\\n`\n }\n\n // we cant try/catch javascript modules (they use imports)\n if (klass.includes('import ')) {\n Fez.head({script: klass})\n\n // best we can do it inform that node did not compile, so we assume there is arrow\n setTimeout(()=>{\n if (!Fez.classes[tagName]) {\n Fez.error(`Template \"${tagName}\" possible compile error. (can be a false positive, it imports are not loaded)`)\n }\n }, 2000)\n } else {\n try {\n new Function(klass)()\n } catch(e) {\n Fez.error(`Template \"${tagName}\" compile error: ${e.message}`)\n console.log(klass)\n }\n }\n}\n", "// Global state manager with automatic component subscription\n//\n// Components access state via this.globalState proxy which automatically:\n// - Registers component as listener when reading a value\n// - Notifies component when that value changes\n// - Calls onGlobalStateChange(key, value) if defined, then render()\n//\n// Example usage:\n//\n// class Counter extends FezBase {\n// increment() {\n// this.globalState.count = (this.globalState.count || 0) + 1\n// }\n//\n// onGlobalStateChange(key, value) {\n// console.log(`State ${key} changed to ${value}`)\n// }\n//\n// render() {\n// return `<button onclick=\"fez.increment()\">\n// Count: ${this.globalState.count || 0}\n// </button>`\n// }\n// }\n//\n// External access:\n// Fez.state.set('count', 10)\n// Fez.state.get('count') // 10\n\nconst GlobalState = {\n data: {},\n listeners: new Map(), // key -> Set of components\n subscribers: new Map(), // key -> Set of functions (for subscribe method)\n globalSubscribers: new Set(), // Set of functions that listen to all changes\n\n notify(key, value, oldValue) {\n Fez.log(`Global state change for ${key}: ${value} (from ${oldValue})`)\n\n // Notify component listeners\n const listeners = this.listeners.get(key)\n if (listeners) {\n listeners.forEach(comp => {\n if (comp.isConnected) {\n comp.onGlobalStateChange(key, value, oldValue)\n comp.render()\n } else {\n listeners.delete(comp)\n }\n })\n }\n\n // Notify key-specific subscribers\n const subscribers = this.subscribers.get(key)\n if (subscribers) {\n subscribers.forEach(func => {\n try {\n func(value, oldValue, key)\n } catch (error) {\n console.error(`Error in subscriber for key ${key}:`, error)\n }\n })\n }\n\n // Notify global subscribers\n this.globalSubscribers.forEach(func => {\n try {\n func(key, value, oldValue)\n } catch (error) {\n console.error(`Error in global subscriber:`, error)\n }\n })\n },\n\n createProxy(component) {\n return new Proxy({}, {\n get: (target, key) => {\n // Skip if already listening to this key\n component._globalStateKeys ||= new Set()\n if (!component._globalStateKeys.has(key)) {\n component._globalStateKeys.add(key)\n\n if (!this.listeners.has(key)) {\n this.listeners.set(key, new Set())\n }\n this.listeners.get(key).add(component)\n }\n\n return this.data[key]\n },\n\n set: (target, key, value) => {\n const oldValue = this.data[key]\n if (oldValue !== value) {\n this.data[key] = value\n this.notify(key, value, oldValue)\n }\n return true\n }\n })\n },\n\n // Direct methods for use outside components\n set(key, value) {\n const oldValue = this.data[key]\n if (oldValue !== value) {\n this.data[key] = value\n this.notify(key, value, oldValue)\n }\n },\n\n get(key) {\n return this.data[key]\n },\n\n // Execute function for each component listening to a key\n forEach(key, func) {\n const listeners = this.listeners.get(key)\n if (listeners) {\n listeners.forEach(comp => {\n if (comp.isConnected) {\n func(comp)\n } else {\n listeners.delete(comp)\n }\n })\n }\n },\n\n // Subscribe to state changes\n // Usage: Fez.state.subscribe(func) - listen to all changes\n // Fez.state.subscribe(key, func) - listen to specific key changes\n subscribe(keyOrFunc, func) {\n if (typeof keyOrFunc === 'function') {\n // subscribe(func) - global subscription\n this.globalSubscribers.add(keyOrFunc)\n return () => this.globalSubscribers.delete(keyOrFunc)\n } else {\n // subscribe(key, func) - key-specific subscription\n const key = keyOrFunc\n if (!this.subscribers.has(key)) {\n this.subscribers.set(key, new Set())\n }\n this.subscribers.get(key).add(func)\n return () => {\n const keySubscribers = this.subscribers.get(key)\n if (keySubscribers) {\n keySubscribers.delete(func)\n if (keySubscribers.size === 0) {\n this.subscribers.delete(key)\n }\n }\n }\n }\n }\n}\n\nexport default GlobalState\n", "// runtime scss\nimport Gobber from './vendor/gobber.js'\n\n// morph dom from one state to another\nimport { Idiomorph } from './vendor/idiomorph.js'\n\nimport connect from './connect.js'\nimport compile from './compile.js'\nimport state from './lib/global-state.js'\n\n// Fez('ui-slider') # first slider\n// Fez('ui-slider', (n)=>alert(n)) # find all and execute\n// Fez(this, 'ui-slider') # first parent ui-slider\n// Fez('ui-slider', class { init() { ... }}) # create Fez dom node\nconst Fez = (name, klass) => {\n if(typeof name === 'number') {\n const fez = Fez.instances.get(name)\n if (fez) {\n return fez\n } else {\n Fez.error(`Instance with UID \"${name}\" not found.`)\n }\n }\n else if (name) {\n if (klass) {\n const isPureFn = typeof klass === 'function' && !/^\\s*class/.test(klass.toString()) && !/\\b(this|new)\\b/.test(klass.toString())\n\n if (isPureFn) {\n const list = Array\n .from(document.querySelectorAll(`.fez.fez-${name}`))\n .filter( n => n.fez )\n\n list.forEach( el => klass(el.fez) )\n return list\n } else if (typeof klass != 'function') {\n return Fez.find(name, klass)\n } else {\n return connect(name, klass)\n }\n } else {\n const node = name.nodeName ? name.closest('.fez') : (\n document.querySelector( name.includes('#') ? name : `.fez.fez-${name}` )\n )\n if (node) {\n if (node.fez) {\n return node.fez\n } else {\n Fez.error(`node \"${name}\" has no Fez attached.`)\n }\n } else {\n Fez.error(`node \"${name}\" not found.`)\n }\n }\n } else {\n Fez.error('Fez() ?')\n }\n}\n\nFez.classes = {}\nFez.instanceCount = 0\nFez.instances = new Map()\n\nFez.find = (onode, name) => {\n let node = onode\n\n if (typeof node == 'string') {\n node = document.body.querySelector(node)\n }\n\n if (typeof node.val == 'function') {\n node = node[0]\n }\n\n const klass = name ? `.fez.fez-${name}` : '.fez'\n\n const closestNode = node.closest(klass)\n if (closestNode && closestNode.fez) {\n return closestNode.fez\n } else {\n console.error('Fez node connector not found', onode, node)\n }\n}\n\nFez.cssClass = (text) => {\n return Gobber.css(text)\n}\n\nFez.globalCss = (cssClass, opts = {}) => {\n if (typeof cssClass === 'function') {\n cssClass = cssClass()\n }\n\n if (cssClass.includes(':')) {\n let text = cssClass\n .split(\"\\n\")\n .filter(line => !(/^\\s*\\/\\//.test(line)))\n .join(\"\\n\")\n\n if (opts.wrap) {\n text = `:fez { ${text} }`\n }\n\n text = text.replace(/\\:fez|\\:host/, `.fez.fez-${opts.name}`)\n\n cssClass = Fez.cssClass(text)\n }\n\n if (document.body) {\n document.body.parentElement.classList.add(cssClass)\n } else {\n document.addEventListener(\"DOMContentLoaded\", () => {\n document.body.parentElement.classList.add(cssClass)\n })\n }\n\n return cssClass\n}\n\nFez.info = () => {\n console.log(JSON.stringify(Fez.fastBindInfo, null, 2))\n}\n\nFez.morphdom = (target, newNode, opts = {}) => {\n Array.from(target.attributes).forEach(attr => {\n newNode.setAttribute(attr.name, attr.value)\n })\n\n Idiomorph.morph(target, newNode, {\n morphStyle: 'outerHTML'\n })\n\n // remove whitespace on next node, if exists (you never want this)\n const nextSibling = target.nextSibling\n if (nextSibling?.nodeType === Node.TEXT_NODE && nextSibling.textContent.trim() === '') {\n nextSibling.remove();\n }\n}\n\nFez.htmlEscape = (text) => {\n if (typeof text == 'string') {\n text = text\n // .replaceAll('&', \"&amp;\")\n .replace(/font-family\\s*:\\s*(?:&[^;]+;|[^;])*?;/gi, '')\n .replaceAll(\"'\", '&apos;')\n .replaceAll('\"', '&quot;')\n .replaceAll('<', '&lt;')\n .replaceAll('>', '&gt;')\n // .replaceAll('@', '&#64;') // needed for template escaping\n\n return text\n } else {\n return text === undefined ? '' : text\n }\n}\n\nFez.publish = (channel, ...args) => {\n Fez._subs ||= {}\n Fez._subs[channel] ||= []\n Fez._subs[channel].forEach((el) => {\n el[1].bind(el[0])(...args)\n })\n}\n\n // get unique id from string\nFez.fnv1 = (str) => {\n var FNV_OFFSET_BASIS, FNV_PRIME, hash, i, j, ref;\n FNV_OFFSET_BASIS = 2166136261;\n FNV_PRIME = 16777619;\n hash = FNV_OFFSET_BASIS;\n for (i = j = 0, ref = str.length - 1; (0 <= ref ? j <= ref : j >= ref); i = 0 <= ref ? ++j : --j) {\n hash ^= str.charCodeAt(i);\n hash *= FNV_PRIME;\n }\n return hash.toString(36).replaceAll('-', '');\n}\n\nFez.tag = (tag, opts = {}, html = '') => {\n const json = encodeURIComponent(JSON.stringify(opts))\n return `<${tag} data-props=\"${json}\">${html}</${tag}>`\n // const json = JSON.stringify(opts, null, 2)\n // const data = `<script type=\"text/template\">${json}</script><${tag} data-json-template=\"true\">${html}</${tag}>`\n // return data\n};\n\nFez.error = (text, show) => {\n text = `Fez: ${text}`\n console.error(text)\n if (show) {\n return `<span style=\"border: 1px solid red; font-size: 14px; padding: 3px 7px; background: #fee; border-radius: 4px;\">${text}</span>`\n }\n}\nFez.log = (text) => {\n if (Fez.LOG === true) {\n console.log(`Fez: ${text}`)\n }\n}\ndocument.addEventListener('DOMContentLoaded', () => {\n Fez.log('Fez.LOG === true, logging enabled.')\n})\n\n// execute function until it returns true\nFez.untilTrue = (func, pingRate) => {\n pingRate ||= 200\n\n if (!func()) {\n setTimeout(()=>{\n Fez.untilTrue(func, pingRate)\n } ,pingRate)\n }\n}\n\n// Script from URL\n// head({ js: 'https://example.com/script.js' });\n// Script with attributes\n// head({ js: 'https://example.com/script.js', type: 'module', async: true });\n// Script with callback\n// head({ js: 'https://example.com/script.js' }, () => { console.log('loaded') });\n// Module loading with auto-import to window\n// head({ js: 'https://example.com/module.js', module: 'MyModule' }); // imports and sets window.MyModule\n// CSS inclusion\n// head({ css: 'https://example.com/styles.css' });\n// CSS with additional attributes and callback\n// head({ css: 'https://example.com/styles.css', media: 'print' }, () => { console.log('CSS loaded') })\n// Inline script evaluation\n// head({ script: 'console.log(\"Hello world\")' })\nFez.head = (config, callback) => {\n if (typeof config !== 'object' || config === null) {\n throw new Error('head requires an object parameter');\n }\n\n let src, attributes = {}, elementType;\n\n if (config.script) {\n if (config.script.includes('import ')) {\n if (callback) {\n Fez.error('Fez.head callback is not supported when script with import is passed (module context).')\n }\n\n // Evaluate inline script in context in the module\n const script = document.createElement('script');\n script.type = 'module';\n script.textContent = config.script;\n document.head.appendChild(script);\n setTimeout(()=>script.remove(), 100)\n } else {\n try {\n new Function(config.script)();\n if (callback) callback();\n } catch (error) {\n Fez.error('Error executing script:', error);\n console.log(config.script);\n }\n }\n return;\n } else if (config.js) {\n src = config.js;\n elementType = 'script';\n // Copy all properties except 'js' as attributes\n for (const [key, value] of Object.entries(config)) {\n if (key !== 'js' && key !== 'module') {\n attributes[key] = value;\n }\n }\n // Handle module loading\n if (config.module) {\n attributes.type = 'module';\n }\n } else if (config.css) {\n src = config.css;\n elementType = 'link';\n attributes.rel = 'stylesheet';\n // Copy all properties except 'css' as attributes\n for (const [key, value] of Object.entries(config)) {\n if (key !== 'css') {\n attributes[key] = value;\n }\n }\n } else {\n throw new Error('head requires either \"script\", \"js\" or \"css\" property');\n }\n\n const existingNode = document.querySelector(`${elementType}[src=\"${src}\"], ${elementType}[href=\"${src}\"]`);\n if (existingNode) {\n if (callback) callback();\n return existingNode;\n }\n\n const element = document.createElement(elementType);\n\n if (elementType === 'link') {\n element.href = src;\n } else {\n element.src = src;\n }\n\n for (const [key, value] of Object.entries(attributes)) {\n element.setAttribute(key, value);\n }\n\n if (callback || config.module) {\n element.onload = () => {\n // If module name is provided, import it and assign to window\n if (config.module && elementType === 'script') {\n import(src).then(module => {\n window[config.module] = module.default || module[config.module] || module;\n }).catch(error => {\n console.error(`Error importing module ${config.module}:`, error);\n });\n }\n if (callback) callback();\n };\n }\n\n document.head.appendChild(element);\n\n return element;\n}\n\n// Fetch wrapper with automatic caching and data handling\n// Usage:\n// Fez.fetch(url) - GET request (default)\n// Fez.fetch(url, callback) - GET with callback\n// Fez.fetch(url, data) - GET with query params (?foo=bar&baz=qux)\n// Fez.fetch(url, data, callback) - GET with query params and callback\n// Fez.fetch('POST', url, data) - POST with FormData body (multipart/form-data)\n// Fez.fetch('POST', url, data, callback) - POST with FormData and callback\n// Data object is automatically converted:\n// - GET: appended as URL query parameters\n// - POST: sent as FormData (multipart/form-data) without custom headers\nFez.fetch = function(...args) {\n // Initialize cache if not exists\n Fez._fetchCache ||= {};\n\n let method = 'GET';\n let url;\n let callback;\n\n // Check if first arg is HTTP method (uppercase letters)\n if (typeof args[0] === 'string' && /^[A-Z]+$/.test(args[0])) {\n method = args.shift();\n }\n\n // URL is required\n url = args.shift();\n\n // Check for data/options object\n let opts = {};\n let data = null;\n if (typeof args[0] === 'object') {\n data = args.shift();\n }\n\n // Check for callback function\n if (typeof args[0] === 'function') {\n callback = args.shift();\n }\n\n // Handle data based on method\n if (data) {\n if (method === 'GET') {\n // For GET, append data as query parameters\n const params = new URLSearchParams(data);\n url += (url.includes('?') ? '&' : '?') + params.toString();\n } else if (method === 'POST') {\n // For POST, convert to FormData\n const formData = new FormData();\n for (const [key, value] of Object.entries(data)) {\n formData.append(key, value);\n }\n opts.body = formData;\n }\n }\n\n // Set method\n opts.method = method;\n\n // Create cache key from method, url, and stringified opts\n const cacheKey = `${method}:${url}:${JSON.stringify(opts)}`;\n\n // Check cache first\n if (Fez._fetchCache[cacheKey]) {\n const cachedData = Fez._fetchCache[cacheKey];\n Fez.log(`fetch cache hit: ${method} ${url}`);\n if (callback) {\n callback(cachedData);\n return;\n }\n return Promise.resolve(cachedData);\n }\n\n // Log live fetch\n Fez.log(`fetch live: ${method} ${url}`);\n\n // Helper to process and cache response\n const processResponse = (response) => {\n if (response.headers.get('content-type')?.includes('application/json')) {\n return response.json();\n }\n return response.text();\n };\n\n // If callback provided, execute and handle\n if (callback) {\n fetch(url, opts)\n .then(processResponse)\n .then(data => {\n Fez._fetchCache[cacheKey] = data;\n callback(data);\n })\n .catch(error => Fez.onError('fetch', error));\n return;\n }\n\n // Return promise with automatic JSON parsing\n return fetch(url, opts)\n .then(processResponse)\n .then(data => {\n Fez._fetchCache[cacheKey] = data;\n return data;\n });\n}\n\nFez.onError = (kind, message) => {\n // Ensure kind is always a string\n if (typeof kind !== 'string') {\n throw new Error('Fez.onError: kind must be a string');\n }\n\n console.error(`${kind}: ${message.toString()}`);\n}\n\n// define custom style macro\n// Fez.styleMacro('mobile', '@media (max-width: 768px)')\n// :mobile { ... } -> @media (max-width: 768px) { ... }\nFez._styleMacros = {}\nFez.styleMacro = (name, content) => {\n Fez._styleMacros[name] = content\n}\n\n// work with tmp store\nFez.store = {\n store: new Map(),\n counter: 0,\n\n set(value) {\n const key = this.counter++;\n this.store.set(key, value);\n return key;\n },\n\n get(key) {\n return this.store.get(key);\n },\n\n delete(key) {\n const value = this.store.get(key);\n this.store.delete(key)\n return value;\n }\n};\n\nFez.compile = compile\nFez.state = state\n\nexport default Fez\n", "// base class for custom dom objects\nimport FezBase from './fez/instance.js'\nif (typeof window !== 'undefined') window.FezBase = FezBase\n\n// base class for custom dom objects\nimport Fez from './fez/root.js'\nif (typeof window !== 'undefined') window.Fez = Fez\n\n// clear all unattached nodes\nsetInterval(() => {\n for (const [key, el] of Fez.instances) {\n if (!el?.isConnected) {\n // Fez.error(`Found junk instance that is not connected ${el.fezName}`)\n el.fez?.fezRemoveSelf()\n Fez.instances.delete(key)\n }\n }\n}, 5_000)\n\n// define Fez observer\nconst observer = new MutationObserver((mutations) => {\n for (const { addedNodes, removedNodes } of mutations) {\n addedNodes.forEach((node) => {\n if (node.nodeType !== 1) return; // only elements\n // check the node itself\n if (node.matches('template[fez], xmp[fez], script[fez]')) {\n window.requestAnimationFrame(()=>{\n Fez.compile(node);\n node.remove();\n })\n }\n });\n\n removedNodes.forEach((node) => {\n if (node.nodeType === 1 && node.querySelectorAll) {\n // check both the node itself and its descendants\n const fezElements = node.querySelectorAll('.fez, :scope.fez');\n fezElements\n .forEach(el => {\n if (el.fez && el.root) {\n Fez.instances.delete(el.fez.UID)\n el.fez.fezRemoveSelf()\n }\n });\n }\n });\n }\n});\n\n// start observing the whole document\nobserver.observe(document.documentElement, {\n childList: true,\n subtree: true\n});\n\n// fez custom tags\n\n//<fez-component name=\"some-node\" :props=\"fez.props\"></fez-node>\nFez('fez-component', class {\n init(props) {\n const tag = document.createElement(props.name)\n tag.props = props.props || props['data-props'] || props\n\n while (this.root.firstChild) {\n this.root.parentNode.insertBefore(this.root.lastChild, tag.nextSibling);\n }\n\n this.root.innerHTML = ''\n this.root.appendChild(tag)\n }\n})\n\nexport default Fez\nexport { Fez }\n"],
5
5
  "mappings": "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",
6
6
  "names": ["n", "name", "attrs", "data", "parts", "c", "node", "k", "v", "value", "parseBlock", "data", "ifStack", "el", "prefix", "createTemplate", "text", "opts", "match", "p1", "p2", "p3", "blocks", "_", "name", "block", "m1", "m2", "result", "content", "funcBody", "tplFunc", "o", "e", "FezBase", "node", "newNode", "attrs", "attr", "key", "val", "newVal", "e", "data", "formNode", "formData", "formObject", "value", "n", "name", "v", "klass", "func", "delay", "timeoutId", "lastRun", "checkAndExecute", "handleResize", "now", "source", "target", "isSlot", "text", "base", "template", "renderedTpl", "createTemplate", "slot", "currentSlot", "newSLot", "fetchAttr", "classes", "lastClass", "c", "isCb", "eventName", "selector", "tpl", "tick", "children", "tmpContainer", "child", "list", "channel", "el", "method", "parent", "fragment", "obj", "handler", "o", "k", "oldValue", "createReactive", "property", "receiver", "currentValue", "result", "e", "t", "a", "r", "l", "s", "n", "o", "c", "i", "p", "u", "d", "f", "g", "b", "m", "h", "y", "gobber_default", "Idiomorph", "EMPTY_SET", "defaults", "noOp", "elt", "morph", "oldNode", "newContent", "config", "parseContent", "normalizedContent", "normalizeContent", "ctx", "createMorphContext", "morphNormalizedContent", "normalizedNewContent", "oldHead", "newHead", "promises", "handleHeadElement", "morphChildren", "bestMatch", "findBestNodeMatch", "previousSibling", "nextSibling", "morphedNode", "morphOldNodeTo", "insertSiblings", "ignoreValueOfActiveElement", "possibleActiveElement", "isSoftMatch", "syncNodeFrom", "newParent", "oldParent", "nextNewChild", "insertionPoint", "newChild", "removeIdsFromConsideration", "isIdSetMatch", "idSetMatch", "findIdSetMatch", "removeNodesBetween", "softMatch", "findSoftMatch", "tempNode", "removeNode", "ignoreAttribute", "attr", "to", "updateType", "from", "type", "fromAttributes", "toAttributes", "fromAttribute", "error", "i", "toAttribute", "syncInputValue", "syncBooleanAttribute", "attributeName", "ignoreUpdate", "fromValue", "toValue", "newHeadTag", "currentHead", "added", "removed", "preserved", "nodesToAppend", "headMergeStyle", "srcToNewHeadNodes", "newHeadChild", "currentHeadElt", "inNewContent", "isReAppended", "isPreserved", "newNode", "newElt", "resolve", "promise", "_resolve", "removedElement", "log", "mergeDefaults", "finalConfig", "createIdMap", "node1", "node2", "getIdIntersectionCount", "startInclusive", "endExclusive", "newChildPotentialIdCount", "potentialMatch", "otherMatchCount", "potentialSoftMatch", "siblingSoftMatchCount", "parser", "contentWithSvgsRemoved", "content", "htmlElement", "dummyParent", "stack", "node", "currentElement", "bestElement", "score", "newScore", "scoreElement", "isIdInConsideration", "id", "idIsWithinNode", "targetNode", "idSet", "sourceSet", "matchCount", "populateIdMapForNode", "idMap", "nodeParent", "idElements", "current", "oldContent", "connect_default", "name", "klass", "Fez", "klassObj", "newKlass", "FezBase", "el", "prop", "func", "info", "closeCustomTags", "createTemplate", "useFastRender", "connectNode", "html", "selfClosingTags", "match", "tagName", "attributes", "n", "fezFast", "isFast", "node", "parentNode", "nodeName", "newNode", "fez", "oldRoot", "slot", "form", "e", "observer", "key", "value", "mutationsList", "_", "mutation", "compileToClass", "html", "result", "lines", "currentBlock", "currentType", "line", "container", "node", "script", "attr", "klass", "key", "val", "compile_default", "tagName", "fezName", "url", "response", "htmlContent", "fezElements", "el", "name", "content", "error", "parts", "styleContainer", "e", "GlobalState", "key", "value", "oldValue", "listeners", "comp", "subscribers", "func", "error", "component", "target", "keyOrFunc", "keySubscribers", "global_state_default", "Fez", "name", "klass", "fez", "list", "el", "connect_default", "node", "onode", "closestNode", "text", "gobber_default", "cssClass", "opts", "line", "target", "newNode", "attr", "Idiomorph", "nextSibling", "channel", "args", "str", "FNV_OFFSET_BASIS", "FNV_PRIME", "hash", "i", "j", "ref", "tag", "html", "json", "show", "func", "pingRate", "config", "callback", "src", "attributes", "elementType", "script", "error", "key", "value", "existingNode", "element", "module", "method", "url", "data", "params", "formData", "cacheKey", "cachedData", "processResponse", "response", "kind", "message", "content", "compile_default", "global_state_default", "root_default", "FezBase", "root_default", "key", "el", "observer", "mutations", "addedNodes", "removedNodes", "node", "props", "tag", "fez_default"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dinoreic/fez",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Runtime custom dom elements",
5
5
  "main": "dist/fez.js",
6
6
  "type": "module",
@@ -12,7 +12,8 @@
12
12
  "./rollup": {
13
13
  "import": "./src/rollup.js",
14
14
  "require": "./src/rollup.js"
15
- }
15
+ },
16
+ "./package.json": "./package.json"
16
17
  },
17
18
  "files": [
18
19
  "dist",
@@ -28,8 +29,8 @@
28
29
  "server": "bun run lib/server.js",
29
30
  "dev": "sh -c 'bun run server & SERVER_PID=$!; trap \"kill $SERVER_PID\" EXIT; find src demo lib| entr -c sh -c \"bun run pages && bun run b\"'",
30
31
  "test": "bun test",
31
- "push": "bun run build && bun run test",
32
- "prepublishOnly": "bun run build && bun run test"
32
+ "prepublishOnly": "bun run build && bun run test",
33
+ "publish": "bun prepublishOnly && npm publish --access public"
33
34
  },
34
35
  "keywords": [
35
36
  "dom",
package/src/fez.js CHANGED
@@ -71,3 +71,4 @@ Fez('fez-component', class {
71
71
  })
72
72
 
73
73
  export default Fez
74
+ export { Fez }