diff --git a/client/dist/hyperbole.js b/client/dist/hyperbole.js
--- a/client/dist/hyperbole.js
+++ b/client/dist/hyperbole.js
@@ -1,3 +1,21 @@
-/*! For license information please see hyperbole.js.LICENSE.txt */
-(()=>{var e={296:e=>{function t(e,t=100,n={}){if("function"!=typeof e)throw new TypeError(`Expected the first parameter to be a function, got \`${typeof e}\`.`);if(t<0)throw new RangeError("`wait` must not be negative.");const{immediate:o}="boolean"==typeof n?{immediate:n}:n;let r,i,a,s,c;function u(){const t=r,n=i;return r=void 0,i=void 0,c=e.apply(t,n),c}function d(){const e=Date.now()-s;e<t&&e>=0?a=setTimeout(d,t-e):(a=void 0,o||(c=u()))}const l=function(...e){if(r&&this!==r&&Object.getPrototypeOf(this)===Object.getPrototypeOf(r))throw new Error("Debounced method called with different contexts of the same prototype.");r=this,i=e,s=Date.now();const n=o&&!a;return a||(a=setTimeout(d,t)),n&&(c=u()),c};return Object.defineProperty(l,"isPending",{get:()=>void 0!==a}),l.clear=()=>{a&&(clearTimeout(a),a=void 0)},l.flush=()=>{a&&l.trigger()},l.trigger=()=>{c=u(),l.clear()},l}e.exports.debounce=t,e.exports=t},147:e=>{"use strict";e.exports=JSON.parse('{"name":"web-ui","version":"0.6.0","description":"Development -----------","main":"index.js","directories":{"client":"client"},"scripts":{"build":"npx webpack"},"author":"","license":"ISC","devDependencies":{"ts-loader":"^9.4.1","typescript":"^4.8.3","uglify":"^0.1.5","webpack":"^5.88.2","webpack-cli":"^4.10.0"},"dependencies":{"omdomdom":"^0.3.2","debounce":"^2.2.0"}}')}},t={};function n(o){var r=t[o];if(void 0!==r)return r.exports;var i=t[o]={exports:{}};return e[o](i,i.exports,n),i.exports}(()=>{"use strict";var e=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t=function(e,t){var n=e.length,o=-1;if(n)for(;++o<n&&!1!==t(e[o],o););},o=function(e,t,n){return e.node.insertBefore(t.node,n)};function r(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var o,r,i,a,s=[],c=!0,u=!1;try{if(i=(n=n.call(e)).next,0===t){if(Object(n)!==n)return;c=!1}else for(;!(c=(o=i.call(n)).done)&&(s.push(o.value),s.length!==t);c=!0);}catch(e){u=!0,r=e}finally{try{if(!c&&null!=n.return&&(a=n.return(),Object(a)!==a))return}finally{if(u)throw r}}return s}}(e,t)||function(e,t){if(e){if("string"==typeof e)return i(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?i(e,t):void 0}}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function i(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,o=new Array(t);n<t;n++)o[n]=e[n];return o}var a="string",s="number",c="boolean",u={},d=function(e,t,n){return{attrName:e,propName:t,type:n}};t([["style","cssText"],["class","className"]],(function(e){var t=r(e,2),n=t[0],o=t[1];u[n]=d(n,o||n,a)})),t(["autofocus","draggable","hidden","checked","multiple","muted","selected"],(function(e){u[e]=d(e,e,c)})),t([["tabindex","tabIndex"]],(function(e){var t=r(e,2),n=t[0],o=t[1];u[n]=d(n,o,s)}));var l="xlink:",f="http://www.w3.org/1999/xlink",v="xml:",p="http://www.w3.org/XML/1998/namespace",h=function(e,t,n,o){switch(t){case a:n===u.style.propName?e.style[n]=null===o?"":o:e[n]=null===o?"":o;break;case s:if(null===o){var r=n.toLowerCase();e.removeAttribute(r)}else if("0"===o)e[n]=0;else if("-1"===o)e[n]=-1;else{var i=parseInt(o,10);isNaN(i)||(e[n]=i)}break;case c:["","true"].indexOf(o)<0?e[n]=!1:e[n]=!0}},m=function n(r,i,s){if(r&&i){s=s||i.node.parentNode;var c=r.content&&r.content!==i.content;if(r.type!==i.type||c)return s.replaceChild(r.node,i.node),function(e,t){for(var n in e)t[n]=e[n]}(r,i);(function(n,o){var r=[],i={};for(var s in o.attributes){var c=o.attributes[s],d=n.attributes[s];c!==d&&void 0===d&&r.push(s)}for(var m in n.attributes){var y=o.attributes[m],g=n.attributes[m];y!==g&&void 0!==g&&(i[m]=g)}!function(n,o){t(o,(function(t){if(e(u,t)){var o=u[t];h(n.node,o.type,o.propName,null)}else t in n.node&&h(n.node,a,t,null),n.node.removeAttribute(t);delete n.attributes[t]}))}(o,r),function(t,n){for(var o in n){var r=n[o];if(t.attributes[o]=r,e(u,o)){var i=u[o];h(t.node,i.type,i.propName,r)}else o.startsWith(l)?t.node.setAttributeNS(f,o,r):o.startsWith(v)?t.node.setAttributeNS(p,o,r):(o in t.node&&h(t.node,a,o,r),t.node.setAttribute(o,r||""))}}(o,i)})(r,i),function(n,r,i){var a=n.children.length,s=r.children.length;if(a||s){var c=function(n){var o={};for(var r in t(n,(function(t){var n=t.attributes["data-key"];(function(t,n){return!(!n||e(t,n)&&(console.warn("[OmDomDom]: Children with duplicate keys detected. Children with duplicate keys will be skipped, resulting in dropped node references. Keys must be unique and non-indexed."),1))})(o,n)&&(o[n]=t)})),o)return o}(r.children),u=Array(a);t(n.children,void 0!==c?function(e,t){var n=r.node.childNodes,a=e.attributes["data-key"];if(Object.prototype.hasOwnProperty.call(c,a)){var s=c[a];Array.prototype.indexOf.call(n,s.node)!==t&&o(r,s,n[t]),u[t]=s,delete c[a],i(e,u[t])}else o(r,e,n[t]),u[t]=e}:function(e,t){var n=r.children[t];void 0!==n?(i(e,n),u[t]=n):(r.node.appendChild(e.node),u[t]=e)}),r.children=u;var d=r.node.childNodes.length,l=d-a;if(l>0)for(;l>0;)r.node.removeChild(r.node.childNodes[d-1]),d--,l--}}(r,i,n)}},y=function n(o){var r,i=arguments.length>1&&void 0!==arguments[1]&&arguments[1];"string"==typeof o&&(r=o.trim().replace(/\s+</g,"<").replace(/>\s+/g,">"),o=(new DOMParser).parseFromString(r,"text/html").body);var a="BODY"===o.tagName,s=o.childNodes,c=s?s.length:0;if(a){if(c>1)throw new Error("[OmDomDom]: Your element should not have more than one root node.");if(0===c)throw new Error("[OmDomDom]: Your element should have at least one root node.");return n(s[0])}var d=3===o.nodeType?"text":8===o.nodeType?"comment":o.tagName.toLowerCase(),l=i||"svg"===d,f=1===o.nodeType?function(t){var n=function(t){return Array.prototype.reduce.call(t.attributes,(function(t,n){return e(u,n.name)||(t[n.name]=n.value),t}),{})}(t);return function(e,t){for(var n in u){var o=u[n].propName,r=e.getAttribute(n);n===u.style.attrName?t[n]=e.style[o]:"string"==typeof r&&(t[n]=r)}}(t,n),n}(o):{},v=c>0?null:o.textContent,p=Array(c);return t(s,(function(e,t){p[t]=n(e,l)})),{type:d,attributes:f,children:p,content:v,node:o,isSVGContext:l}};function g(e,t){var n=[];for(var o of t){let t=e(o);if(!t)break;n.push(t)}return n}function w(e){return{cookies:e.filter((e=>"Cookie"==e.key)).map((e=>e.value)),error:E("Error",e),query:E("Query",e),pageTitle:E("PageTitle",e),events:C("Event",e).map(q),actions:C("Trigger",e).map(I)}}function b(e){return w(g(k,e.trim().split("\n")))}function E(e,t){return t.find((t=>t.key==e))?.value}function C(e,t){return t.filter((t=>t.key==e)).map((e=>e.value))}function k(e){let t=e.match(/^(\w+)\: (.*)$/);if(t)return{key:t[1],value:t[2]}}function q(e){let[t,n]=S(e);return{name:t,detail:JSON.parse(n)}}function I(e){let[t,n]=S(e);return[t,n]}function S(e){let t=e.indexOf("|");if(-1===t){let t=new Error("Bad Encoding, Expected Segment");throw t.message=e,t}return[e.slice(0,t),e.slice(t+1)]}function A(e){if(!e)return;const t=new URLSearchParams;return e.forEach(((e,n)=>{t.append(n,e)})),t}let x=0;function L(e,t){return e+" "+function(e){return""==e?"|":e.replace(/_/g,"\\_").replace(/\s+/g,"_")}(t)}const T=`${"https:"===window.location.protocol?"wss:":"ws:"}//${window.location.host}${window.location.pathname}`;class D extends Error{constructor(e,t){super(e+"\n"+t),this.name="ProtocolError"}}var R=n(296);function O(e,t){document.addEventListener(e.toLowerCase(),(function(n){let o=n.target,r="on"+e+n.key,i=o.dataset[r];i&&(n.preventDefault(),t(V(o),i))}))}function N(e,t){document.addEventListener(e,(function(n){let o=n.target.closest("[data-on"+e+"]");if(!o)return;n.preventDefault();let r=V(o);t(r,o.dataset["on"+e])}))}function M(e){e.querySelectorAll("[data-onload]").forEach((e=>{let t=parseInt(e.dataset.delay)||0,n=e.dataset.onload;setTimeout((()=>{let t=V(e);if(e.dataset.onload!=n)return;const o=new CustomEvent("hyp-load",{bubbles:!0,detail:{target:t,onLoad:n}});e.dispatchEvent(o)}),t)}))}function j(e){e.querySelectorAll("[data-onmouseenter]").forEach((e=>{let t=e.dataset.onmouseenter,n=V(e);e.onmouseenter=()=>{const o=new CustomEvent("hyp-mouseenter",{bubbles:!0,detail:{target:n,onMouseEnter:t}});e.dispatchEvent(o)}}))}function P(e){e.querySelectorAll("[data-onmouseleave]").forEach((e=>{let t=e.dataset.onmouseleave,n=V(e);e.onmouseleave=()=>{const o=new CustomEvent("hyp-mouseleave",{bubbles:!0,detail:{target:n,onMouseLeave:t}});e.dispatchEvent(o)}}))}function V(e){let t=function(e){let t=e.closest("[data-target]");return t?.dataset.target||e.closest("[id]")?.id}(e),n=document.getElementById(t);if(n)return n;console.error("Cannot find target: ",t,e)}let B,U=n(147);console.log("Hyperbole "+U.version+"b");let Q=new Set;async function $(e,t,n){if(void 0===e)return void console.error("Undefined HyperView!",t);if(void 0===t)return void console.error("Undefined Action!",e.id);if(e.activeRequest&&!e.activeRequest?.isCancelled&&"Drop"==e.concurrency)return void console.warn("Drop action overlapping with active request ("+e.activeRequest+")",t);e._timeout=setTimeout((()=>{e.classList.add("hyp-loading")}),100);let o=e.dataset.state,r={requestId:++x,isCancelled:!1},i=function(e,t,n,o,r){return{viewId:e,action:t,state:n,requestId:o,meta:[{key:"Cookie",value:decodeURI(document.cookie)},{key:"Query",value:window.location.search}],form:A(r)}}(e.id,t,o,r.requestId,n);e.activeRequest=r,Y.sendAction(i)}function H(e){let t=e.targetViewId||e.viewId,n=document.getElementById(t);if(!n)return console.error("Missing Update Target: ",t,e),n;if(e.requestId<n.activeRequest?.requestId)return console.warn("Ignore Stale Action ("+e.requestId+") vs ("+n.activeRequest.requestId+"): "+e.action),n;if(n.activeRequest?.isCancelled)return console.warn("Cancelled request",n.activeRequest?.requestId),delete n.activeRequest,n;let o=function(e){const t=(new DOMParser).parseFromString(e,"text/html"),n=t.querySelector("style");return{content:t.querySelector("div"),css:n}}(e.body);if(!o.content)return console.error("Empty Response!",e.body),n;!function(e){if(!e)return;const t=e.sheet.cssRules;for(const e of t)0==Q.has(e.cssText)&&(B.sheet.insertRule(e.cssText),Q.add(e.cssText))}(o.css);const r=y(n);let i=y(o.content),a=i.attributes["data-state"];i.attributes=r.attributes,m(i,r);let s=document.getElementById(n.id);return J(s),s?(s.dataset.state=a,_(e.meta,s),W(e.meta.cookies),M(s),j(s),P(s),function(e){let t=e.querySelector("[autofocus]");t?.focus&&t.focus(),e.querySelectorAll("input[value]").forEach((e=>{let t=e.getAttribute("value");void 0!==t&&(e.value=t)})),e.querySelectorAll("input[type=checkbox]").forEach((e=>{let t="True"==e.dataset.checked;e.checked=t}))}(s),F(s),n):(console.warn("Target Missing: ",n.id),n)}function W(e){e.forEach((e=>{console.log("SetCookie: ",e),document.cookie=e}))}function _(e,t){null!=e.query&&function(e){if(e!=function(){const e=window.location.search;return e.startsWith("?")?e.substring(1):e}()){""!=e&&(e="?"+e);let t=location.pathname+e;window.history.replaceState({},"",t)}}(e.query),null!=e.pageTitle&&(document.title=e.pageTitle),e.events.forEach((e=>{setTimeout((()=>{let n=new CustomEvent(e.name,{bubbles:!0,detail:e.detail});(t||document).dispatchEvent(n)}),10)})),e.actions.forEach((([e,t])=>{setTimeout((()=>{let n=window.Hyperbole.hyperView(e);n&&$(n,t)}),10)}))}function F(e){e.querySelectorAll("[id]").forEach((t=>{t.runAction=function(e){$(this,e)}.bind(t),t.concurrency=t.dataset.concurrency||"Drop",t.cancelActiveRequest=function(){t.activeRequest&&!t.activeRequest?.isCancelled&&(t.activeRequest.isCancelled=!0)},J(e)}))}function J(e){let t=new Event("hyp-content",{bubbles:!0});e.dispatchEvent(t)}document.addEventListener("DOMContentLoaded",(function(){var e;_(b(document.getElementById("hyp.metadata").innerText)),B=document.body.querySelector("style"),B||(console.warn("rootStyles missing from page, creating..."),B=document.createElement("style"),B.type="text/css",document.body.appendChild(B)),e=async function(e,t){$(e,t)},document.addEventListener("hyp-load",(function(t){let n=t.detail.onLoad,o=t.detail.target;e(o,n)})),document.addEventListener("hyp-mouseenter",(function(t){let n=t.detail.onMouseEnter,o=t.detail.target;e(o,n)})),document.addEventListener("hyp-mouseleave",(function(t){let n=t.detail.onMouseLeave,o=t.detail.target;e(o,n)})),M(document.body),j(document.body),P(document.body),F(document.body),N("click",(async function(e,t){$(e,t)})),N("dblclick",(async function(e,t){$(e,t)})),O("keydown",(async function(e,t){$(e,t)})),O("keyup",(async function(e,t){$(e,t)})),document.addEventListener("submit",(function(e){let t=e.target;if(!t?.dataset.onsubmit)return void console.error("Missing onSubmit: ",t);e.preventDefault();let n=V(t);const o=new FormData(t);!async function(e,t,n){$(e,t,n)}(n,t.dataset.onsubmit,o)})),document.addEventListener("change",(function(e){let t=e.target.closest("[data-onchange]");t&&(e.preventDefault(),null!=t.value?async function(e,t){$(e,t)}(V(t),L(t.dataset.onchange,t.value)):console.error("Missing input value:",t))})),document.addEventListener("input",(function(e){let t=e.target.closest("[data-oninput]");if(!t)return;let n=parseInt(t.dataset.delay)||250;if(n<250&&console.warn("Input delay < 250 can result in poor performance."),!t?.dataset.oninput)return void console.error("Missing onInput: ",t);e.preventDefault();let o=V(t);(function(e){"Replace"==e.concurrency&&e.cancelActiveRequest()})(o),t.debouncedCallback||(t.debouncedCallback=R((()=>{let e=L(t.dataset.oninput,t.value);!async function(e,t){$(e,t)}(o,e)}),n)),t.debouncedCallback()}))}));const Y=new class{constructor(){this.hasEverConnected=!1,this.isConnected=!1,this.reconnectDelay=0,this.queue=[],this.events=new EventTarget}connect(e=T){const t=new WebSocket(e);function n(e){console.error("Connect Error",e)}function o(e){console.error("Socket Error",e)}this.socket=t,t.addEventListener("error",n),t.addEventListener("open",(e=>{console.log("Websocket Connected"),this.hasEverConnected&&document.dispatchEvent(new Event("hyp-socket-reconnect")),this.isConnected=!0,this.hasEverConnected=!0,this.reconnectDelay=1e3,t.removeEventListener("error",n),t.addEventListener("error",o),document.dispatchEvent(new Event("hyp-socket-connect")),this.runQueue()})),t.addEventListener("close",(n=>{console.log("CLOSE SOCKET"),this.isConnected&&document.dispatchEvent(new Event("hyp-socket-disconnect")),this.isConnected=!1,t.removeEventListener("error",o),this.hasEverConnected&&(console.log("Reconnecting in "+this.reconnectDelay/1e3+"s"),setTimeout((()=>this.connect(e)),this.reconnectDelay)),t.removeEventListener("error",o)})),t.addEventListener("message",(e=>this.onMessage(e)))}async sendAction(e){if(this.isConnected){let t=function(e){let t=["|ACTION|","ViewId: "+e.viewId,"Action: "+e.action];return e.state&&t.push("State: "+e.state),t.push("RequestId: "+e.requestId),[t.join("\n"),(o=e.meta,o.map((e=>e.key+": "+e.value)).join("\n"))].join("\n")+((n=e.form)?"\n\n"+n:"");var n,o}(e);this.socket.send(t)}else this.queue.push(e)}runQueue(){let e=this.queue.pop();e&&(console.log("runQueue: ",e),this.sendAction(e),this.runQueue())}onMessage(e){let{command:t,metas:n,rest:o}=function(e){let t=e.split("\n"),n=t[0],o=g(k,t.slice(1));return{command:n,metas:o,rest:function(e,t){let n=0;for(;n<t.length&&""==t[n];)n++;return t.slice(n)}(0,t.slice(o.length+1))}}(e.data),r=parseInt(i("RequestId"),0);function i(t){let o=E(t,n);if(!o)throw new D("Missing Required Metadata: "+t,e.data);return o}function a(e){let t=i("ViewId"),o=i("Action");return{requestId:r,targetViewId:void 0,viewId:t,action:o,meta:w(n),body:e.join("\n")}}switch(t){case"|UPDATE|":return this.dispatchEvent(new CustomEvent("update",{detail:function(e){let t=a(e);return t.targetViewId=E("TargetViewId",n),t}(o)}));case"|RESPONSE|":return this.dispatchEvent(new CustomEvent("response",{detail:a(o)}));case"|REDIRECT|":return this.dispatchEvent(new CustomEvent("redirect",{detail:function(e){let t=e[0];return{requestId:r,meta:w(n),url:t}}(o)}))}}addEventListener(e,t){this.events.addEventListener(e,t)}dispatchEvent(e){this.events.dispatchEvent(e)}disconnect(){this.isConnected=!1,this.hasEverConnected=!1,this.socket.close()}};Y.connect(),Y.addEventListener("update",(e=>H(e.detail))),Y.addEventListener("response",(e=>function(e){let t=H(e);delete t.activeRequest,clearTimeout(t._timeout),t.classList.remove("hyp-loading")}(e.detail))),Y.addEventListener("redirect",(e=>{return t=e.detail,console.log("REDIRECT",t),W(t.meta.cookies),void(window.location.href=t.url);var t})),window.Hyperbole={runAction:$,parseMetadata:b,action:function(e,...t){return e+t.reduce(((e,t)=>e+" "+JSON.stringify(t)),"")},hyperView:function(e){let t=document.getElementById(e);if(t?.runAction)return t;console.error("Element id="+e+" was not a HyperView")},socket:Y}})()})();
+"use strict";(()=>{var Ce="data-key",A=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},Re=function(e,n){return n?A(e,n)?(console.warn("[OmDomDom]: Children with duplicate keys detected. Children with duplicate keys will be skipped, resulting in dropped node references. Keys must be unique and non-indexed."),!1):!0:!1},y=function(e,n){var r=e.length,i=-1;if(r)for(;++i<r&&n(e[i],i)!==!1;);},Ve=function(e){var n={};y(e,function(i){var o=i.attributes[Ce];Re(n,o)&&(n[o]=i)});for(var r in n)return n},$=function(e,n,r){return e.node.insertBefore(n.node,r)},He=function(e,n){for(var r in e)n[r]=e[r]},ke=function(e){var n=e.trim().replace(/\s+</g,"<").replace(/>\s+/g,">"),r=new DOMParser,i=r.parseFromString(n,"text/html");return i.body};function Se(t,e){var n=t==null?null:typeof Symbol<"u"&&t[Symbol.iterator]||t["@@iterator"];if(n!=null){var r,i,o,s,c=[],a=!0,l=!1;try{if(o=(n=n.call(t)).next,e===0){if(Object(n)!==n)return;a=!1}else for(;!(a=(r=o.call(n)).done)&&(c.push(r.value),c.length!==e);a=!0);}catch(d){l=!0,i=d}finally{try{if(!a&&n.return!=null&&(s=n.return(),Object(s)!==s))return}finally{if(l)throw i}}return c}}function Y(t,e){return qe(t)||Se(t,e)||De(t,e)||Oe()}function qe(t){if(Array.isArray(t))return t}function De(t,e){if(t){if(typeof t=="string")return _(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);if(n==="Object"&&t.constructor&&(n=t.constructor.name),n==="Map"||n==="Set")return Array.from(t);if(n==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return _(t,e)}}function _(t,e){(e==null||e>t.length)&&(e=t.length);for(var n=0,r=new Array(e);n<e;n++)r[n]=t[n];return r}function Oe(){throw new TypeError(`Invalid attempt to destructure non-iterable instance.
+In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}var m={STRING:"string",INT:"number",BOOL:"boolean"},g={},S=function(e,n,r){return{attrName:e,propName:n,type:r}},Pe=[["style","cssText"],["class","className"]];y(Pe,function(t){var e=Y(t,2),n=e[0],r=e[1];g[n]=S(n,r||n,m.STRING)});var Ue=["autofocus","draggable","hidden","checked","multiple","muted","selected"];y(Ue,function(t){g[t]=S(t,t,m.BOOL)});var Be=[["tabindex","tabIndex"]];y(Be,function(t){var e=Y(t,2),n=e[0],r=e[1];g[n]=S(n,r,m.INT)});var I={xlink:{prefix:"xlink:",resource:"http://www.w3.org/1999/xlink"},xml:{prefix:"xml:",resource:"http://www.w3.org/XML/1998/namespace"}},x=function(e,n,r,i){switch(n){case m.STRING:{r===g.style.propName?i===null?e.style[r]="":e.style[r]=i:i===null?e[r]="":e[r]=i;break}case m.INT:{if(i===null){var o=r.toLowerCase();e.removeAttribute(o)}else if(i==="0")e[r]=0;else if(i==="-1")e[r]=-1;else{var s=parseInt(i,10);isNaN(s)||(e[r]=s)}break}case m.BOOL:{["","true"].indexOf(i)<0?e[r]=!1:e[r]=!0;break}}},Ke=function(e,n){y(n,function(r){if(A(g,r)){var i=g[r];x(e.node,i.type,i.propName,null)}else r in e.node&&x(e.node,m.STRING,r,null),e.node.removeAttribute(r);delete e.attributes[r]})},je=function(e,n){for(var r in n){var i=n[r];if(e.attributes[r]=i,A(g,r)){var o=g[r];x(e.node,o.type,o.propName,i);continue}if(r.startsWith(I.xlink.prefix)){e.node.setAttributeNS(I.xlink.resource,r,i);continue}if(r.startsWith(I.xml.prefix)){e.node.setAttributeNS(I.xml.resource,r,i);continue}r in e.node&&x(e.node,m.STRING,r,i),e.node.setAttribute(r,i||"")}},Fe=function(e,n){for(var r in g){var i=g[r],o=i.propName,s=e.getAttribute(r);r===g.style.attrName?n[r]=e.style[o]:typeof s=="string"&&(n[r]=s)}},We=function(e){return Array.prototype.reduce.call(e.attributes,function(n,r){return A(g,r.name)||(n[r.name]=r.value),n},{})},Ge=function(e){var n=We(e);return Fe(e,n),n},Qe=function(e,n){var r=[],i={};for(var o in n.attributes){var s=n.attributes[o],c=e.attributes[o];s!==c&&typeof c>"u"&&r.push(o)}for(var a in e.attributes){var l=n.attributes[a],d=e.attributes[a];l!==d&&typeof d<"u"&&(i[a]=d)}Ke(n,r),je(n,i)},Je="data-key";function $e(t,e,n){var r=t.children.length,i=e.children.length;if(!(!r&&!i)){var o=Ve(e.children),s=Array(r);o!==void 0?y(t.children,function(l,d){var f=e.node.childNodes,u=l.attributes[Je];if(Object.prototype.hasOwnProperty.call(o,u)){var p=o[u];Array.prototype.indexOf.call(f,p.node)!==d&&$(e,p,f[d]),s[d]=p,delete o[u],n(l,s[d])}else $(e,l,f[d]),s[d]=l}):y(t.children,function(l,d){var f=e.children[d];typeof f<"u"?(n(l,f),s[d]=f):(e.node.appendChild(l.node),s[d]=l)}),e.children=s;var c=e.node.childNodes.length,a=c-r;if(a>0)for(;a>0;)e.node.removeChild(e.node.childNodes[c-1]),c--,a--}}var z=function t(e,n,r){if(!(!e||!n)){r=r||n.node.parentNode;var i=e.content&&e.content!==n.content;if(e.type!==n.type||i)return r.replaceChild(e.node,n.node),He(e,n);Qe(e,n),$e(e,n,t)}};var q=function t(e){var n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;typeof e=="string"&&(e=ke(e));var r=e.tagName==="BODY",i=e.childNodes,o=i?i.length:0;if(r){if(o>1)throw new Error("[OmDomDom]: Your element should not have more than one root node.");if(o===0)throw new Error("[OmDomDom]: Your element should have at least one root node.");return t(i[0])}var s=e.nodeType===3?"text":e.nodeType===8?"comment":e.tagName.toLowerCase(),c=n||s==="svg",a=e.nodeType===1?Ge(e):{},l=o>0?null:e.textContent,d=Array(o);return y(i,function(f,u){d[u]=t(f,c)}),{type:s,attributes:a,children:d,content:l,node:e,isSVGContext:c}};function D(t,e){var n=[];for(var r of e){let i=t(r);if(i)n.push(i);else break}return n}function X(t,e){let n=0;for(;n<e.length&&t(e[n]);)n++;return e.slice(n)}function N(t){return t.map(e=>e.key+": "+e.value).join(`
+`)}function L(t){return{cookies:t.filter(e=>e.key=="Cookie").map(e=>e.value),error:E("Error",t),query:E("Query",t),pageTitle:E("PageTitle",t),events:Z("Event",t).map(P),actions:Z("Trigger",t).map(U)}}function O(t){let e=D(te,t.trim().split(`
+`));return L(e)}function E(t,e){return e.find(n=>n.key==t)?.value}function Z(t,e){return e.filter(n=>n.key==t).map(n=>n.value)}function ee(t){let e=t.split(`
+`),n=e[0],r=D(te,e.slice(1)),i=X(o=>o=="",e.slice(r.length+1));return{command:n,metas:r,rest:i}}function te(t){let e=t.match(/^(\w+)\: (.*)$/);if(e)return{key:e[1],value:e[2]}}function P(t){let[e,n]=ne(t);return{name:e,detail:JSON.parse(n)}}function U(t){let[e,n]=ne(t);return[e,n]}function ne(t){let e=t.indexOf("|");if(e===-1){let n=new Error("Bad Encoding, Expected Segment");throw n.message=t,n}return[t.slice(0,e),t.slice(e+1)]}function ie(t,e,n,r,i){let o=[{key:"Cookie",value:decodeURI(document.cookie)},{key:"Query",value:window.location.search}];return{viewId:t,action:e,state:n,requestId:r,meta:o,form:_e(i)}}function _e(t){if(!t)return;let e=new URLSearchParams;return t.forEach((n,r)=>{e.append(r,n)}),e}function oe(t){let e=["|ACTION|","ViewId: "+t.viewId,"Action: "+t.action];return t.state&&e.push("State: "+t.state),e.push("RequestId: "+t.requestId),[e.join(`
+`),N(t.meta)].join(`
+`)+Ye(t.form)}function Ye(t){return t?`
+
+`+t:""}var ze=0;function se(){return{requestId:++ze,isCancelled:!1}}function B(t,e){return t+" "+Xe(e)}function Xe(t){return t==""?"|":t.replace(/_/g,"\\_").replace(/\s+/g,"_")}var Ze=window.location.protocol==="https:"?"wss:":"ws:",ae=`${Ze}//${window.location.host}${window.location.pathname}`,C=class{constructor(e=ae){this.hasEverConnected=!1;this.isConnected=!1;this.reconnectDelay=0;this.queue=[];this.events=new EventTarget;let n=new WebSocket(e);this.socket=n}connect(e=ae,n=!1){let r=n?new WebSocket(e):this.socket;this.socket=r;function i(s){console.error("Connect Error",s)}function o(s){console.error("Socket Error",s)}r.addEventListener("error",i),r.addEventListener("open",s=>{console.log("Websocket Connected"),this.hasEverConnected&&document.dispatchEvent(new Event("hyp-socket-reconnect")),this.isConnected=!0,this.hasEverConnected=!0,this.reconnectDelay=1e3,r.removeEventListener("error",i),r.addEventListener("error",o),document.dispatchEvent(new Event("hyp-socket-connect")),this.runQueue()}),r.addEventListener("close",s=>{console.log("CLOSE SOCKET"),this.isConnected&&document.dispatchEvent(new Event("hyp-socket-disconnect")),this.isConnected=!1,r.removeEventListener("error",o),this.hasEverConnected&&(console.log("Reconnecting in "+this.reconnectDelay/1e3+"s"),setTimeout(()=>this.connect(e,!0),this.reconnectDelay)),r.removeEventListener("error",o)}),r.addEventListener("message",s=>this.onMessage(s))}async sendAction(e){if(this.isConnected){let n=oe(e);this.socket.send(n)}else this.queue.push(e)}runQueue(){let e=this.queue.pop();e&&(console.log("runQueue: ",e),this.sendAction(e),this.runQueue())}onMessage(e){let{command:n,metas:r,rest:i}=ee(e.data),o=parseInt(s("RequestId"),0);function s(u){let p=E(u,r);if(!p)throw new R("Missing Required Metadata: "+u,e.data);return p}function c(u){let p=s("ViewId"),M=s("Action");return{requestId:o,targetViewId:void 0,viewId:p,action:M,meta:L(r),body:u.join(`
+`)}}function a(u){let p=c(u);return p.targetViewId=E("TargetViewId",r),p}function l(u){let p=u[0];return{requestId:o,meta:L(r),url:p}}function d(u){let{requestId:p,meta:M,viewId:V,action:H}=c(u),[k,Le]=U(s("Trigger"));return{requestId:p,meta:M,viewId:V,action:H,targetViewId:k,targetAction:Le}}function f(u){let{requestId:p,meta:M,viewId:V,action:H}=c(u),k=P(s("Event"));return{requestId:p,meta:M,viewId:V,action:H,event:k}}switch(n){case"|UPDATE|":return this.dispatchEvent(new CustomEvent("update",{detail:a(i)}));case"|RESPONSE|":return this.dispatchEvent(new CustomEvent("response",{detail:c(i)}));case"|REDIRECT|":return this.dispatchEvent(new CustomEvent("redirect",{detail:l(i)}));case"|TRIGGER|":return this.dispatchEvent(new CustomEvent("trigger",{detail:d(i)}));case"|EVENT|":return this.dispatchEvent(new CustomEvent("event",{detail:f(i)}));default:throw new R("Unknown Server Command: "+n,e.data)}}addEventListener(e,n){this.events.addEventListener(e,n)}dispatchEvent(e){this.events.dispatchEvent(e)}disconnect(){this.isConnected=!1,this.hasEverConnected=!1,this.socket.close()}},R=class extends Error{constructor(e,n){super(e+`
+`+n),this.name="ProtocolError"}};function K(t,e=100,n={}){if(typeof t!="function")throw new TypeError(`Expected the first parameter to be a function, got \`${typeof t}\`.`);if(e<0)throw new RangeError("`wait` must not be negative.");if(typeof n=="boolean")throw new TypeError("The `options` parameter must be an object, not a boolean. Use `{immediate: true}` instead.");let{immediate:r}=n,i,o,s,c,a;function l(){let u=i,p=o;return i=void 0,o=void 0,a=t.apply(u,p),a}function d(){let u=Date.now()-c;u<e&&u>=0?s=setTimeout(d,e-u):(s=void 0,r||(a=l()))}let f=function(...u){if(i&&this!==i&&Object.getPrototypeOf(this)===Object.getPrototypeOf(i))throw new Error("Debounced method called with different contexts of the same prototype.");i=this,o=u,c=Date.now();let p=r&&!s;if(s||(s=setTimeout(d,e)),p)return a=l(),a};return Object.defineProperty(f,"isPending",{get(){return s!==void 0}}),f.clear=()=>{s&&(clearTimeout(s),s=void 0,i=void 0,o=void 0)},f.flush=()=>{s&&f.trigger()},f.trigger=()=>{a=l(),f.clear()},f}var T=t=>t?.runAction!==void 0;function j(t){let e=new Event("hyp-content",{bubbles:!0});t.dispatchEvent(e)}function F(t,e){t.querySelectorAll("[id]").forEach(n=>{n.runAction=function(r){return e(n,r)},n.concurrency=n.dataset.concurrency||"Drop",n.cancelActiveRequest=function(){n.activeRequest&&!n.activeRequest?.isCancelled&&(n.activeRequest.isCancelled=!0)},j(t)})}function ce(t){de("keydown",t)}function ue(t){de("keyup",t)}function de(t,e){document.addEventListener(t,function(n){if(!(n.target instanceof HTMLElement)){console.warn("listenKeyEvent received event with non HTMLElment as EventTarget: %o",n);return}let r=n.target,i="on"+t+n.key,o=r.dataset[i];if(!o)return;n.preventDefault();let s=w(r);if(!s){console.error("Missing target: ",r);return}e(s,o)})}function le(t,e){document.addEventListener(t,function(n){if(!(n.target instanceof HTMLElement)){console.warn("listenBubblingEvent received an event with non HTMLElment as EventTarget: %o",n);return}let i=n.target.closest("[data-on"+t+"]");if(!i)return;n.preventDefault();let o=w(i);if(!o){console.error("Missing target: ",i);return}let s=i.dataset["on"+t];if(s===void 0){console.error("Missing action: ",i,t);return}e(o,s)})}function pe(t){le("click",t)}function fe(t){le("dblclick",t)}function ge(t){document.addEventListener("hyp-load",function(e){let n=e.detail.onLoad,r=e.detail.target;t(r,n)}),document.addEventListener("hyp-mouseenter",function(e){let n=e.detail.onMouseEnter,r=e.detail.target;t(r,n)}),document.addEventListener("hyp-mouseleave",function(e){let n=e.detail.onMouseLeave,r=e.detail.target;t(r,n)})}function W(t){t.querySelectorAll("[data-onload]").forEach(e=>{let n=parseInt(e.dataset.delay||"")||0,r=e.dataset.onload;setTimeout(()=>{let i=w(e);if(e.dataset.onload!=r)return;let o=new CustomEvent("hyp-load",{bubbles:!0,detail:{target:i,onLoad:r}});e.dispatchEvent(o)},n)})}function G(t){t.querySelectorAll("[data-onmouseenter]").forEach(e=>{let n=e.dataset.onmouseenter,r=J(e);e.onmouseenter=()=>{let i=new CustomEvent("hyp-mouseenter",{bubbles:!0,detail:{target:r,onMouseEnter:n}});e.dispatchEvent(i)}})}function Q(t){t.querySelectorAll("[data-onmouseleave]").forEach(e=>{let n=e.dataset.onmouseleave,r=J(e);e.onmouseleave=()=>{let i=new CustomEvent("hyp-mouseleave",{bubbles:!0,detail:{target:r,onMouseLeave:n}});e.dispatchEvent(i)}})}function ve(t){document.addEventListener("change",function(e){if(!(e.target instanceof HTMLElement)){console.warn("listenChange received an event with non HTMLElment as EventTarget: %o",e);return}let r=e.target.closest("[data-onchange]");if(!r)return;if(e.preventDefault(),r.value===null){console.error("Missing input value:",r);return}let i=w(r);if(!i){console.error("Missing target: listenChange");return}if(!r.dataset.onchange){console.error("Missing onchange: ",r);return}let o=B(r.dataset.onchange,r.value);t(i,o)})}function me(t,e){document.addEventListener("input",function(n){if(!(n.target instanceof HTMLElement)){console.warn("listenInput received an event with non HTMLElment as EventTarget: %o",n);return}let i=n.target.closest("[data-oninput]");if(!i)return;let o=parseInt(i.dataset.delay||"")||250;o<250&&console.warn("Input delay < 250 can result in poor performance."),n.preventDefault();let s=w(i);if(!s){console.error("Missing target: ",i);return}t(s),i.debouncedCallback||(i.debouncedCallback=K(()=>{if(!i.dataset.oninput){console.error("Missing onInput: ",i);return}let c=B(i.dataset.oninput,i.value);e(s,c)},o)),i.debouncedCallback()})}function ye(t){document.addEventListener("submit",function(e){if(!(e.target instanceof HTMLFormElement)){console.warn("listenFormSubmit received an event with non HTMLElment as EventTarget: %o",e);return}let n=e.target;if(!n.dataset.onsubmit){console.error("Missing onSubmit: ",n);return}e.preventDefault();let r=w(n),i=new FormData(n);if(!r){console.error("Missing target: ",n);return}t(r,n.dataset.onsubmit,i)})}function Ne(t){return t.closest("[data-target]")?.dataset.target||t.closest("[id]")?.id}function w(t){let e=J(t);if(!T(e)){console.error("Non HyperView target: ",e);return}return e}function J(t){let e=Ne(t),n=e&&document.getElementById(e);if(!n){console.error("Cannot find target: ",e,t);return}return n}function he(t){if(t!=et()){t!=""&&(t="?"+t);let e=location.pathname+t;window.history.replaceState({},"",e)}}function et(){let t=window.location.search;return t.startsWith("?")?t.substring(1):t}function Ee(t){let n=new DOMParser().parseFromString(t,"text/html"),r=n.querySelector("style");return{content:n.querySelector("div"),css:r}}var we={name:"web-ui",version:"0.6.0",description:"Development -----------",main:"index.js",directories:{client:"client"},scripts:{build:"esbuild src/index.ts --bundle --minify --sourcemap --outfile=dist/hyperbole.js",dev:"esbuild src/index.ts --bundle --minify --sourcemap --watch=forever --outfile=dist/hyperbole.js",check:"tsc --noEmit --preserveWatchOutput --watch"},author:"",license:"ISC",devDependencies:{esbuild:"^0.28.0",typescript:"^6.0.3"},dependencies:{omdomdom:"^0.3.2",debounce:"^3.0.0"}};console.log("Hyperbole "+we.version+"b");var b,be=new Set;async function v(t,e,n){if(t.activeRequest&&!t.activeRequest?.isCancelled&&t.concurrency=="Drop"){console.warn("Drop action overlapping with active request ("+t.activeRequest+")",e);return}t._timeout=window.setTimeout(()=>{t.classList.add("hyp-loading")},100);let r=t.dataset.state,i=se(),o=ie(t.id,e,r,i.requestId,n);t.activeRequest=i,h.sendAction(o)}function nt(t){Ae(t.targetViewId,t.targetAction)}function rt(t){let e=document.getElementById(t.viewId);xe(t.event,e)}function it(t){console.log("REDIRECT",t),Te(t.meta.cookies??[]),window.location.href=t.url}function ot(t){let e=Me(t);e&&(delete e.activeRequest,clearTimeout(e._timeout),e.classList.remove("hyp-loading"))}function Me(t){let e=t.targetViewId||t.viewId,n=document.getElementById(e);if(!T(n)){console.error("Missing Update HyperView Target: ",e,t);return}if(n.activeRequest?.requestId&&t.requestId<n.activeRequest.requestId)return console.warn("Ignore Stale Action ("+t.requestId+") vs ("+n.activeRequest.requestId+"): "+t.action),n;if(n.activeRequest?.isCancelled)return console.warn("Cancelled request",n.activeRequest?.requestId),delete n.activeRequest,n;let r=Ee(t.body);if(!r.content)return console.error("Empty Response!",t.body),n;at(r.css);let i=q(n),o=q(r.content),s=o.attributes;if(!t.meta.error&&s.id!=n.id){console.error("Mismatched ViewId in update - ",s.id," target:",n.id);return}let c=s["data-state"];o.attributes=i.attributes,z(o,i);let a=document.getElementById(n.id);return a?(j(a),c===void 0||c=="()"?delete a.dataset.state:a.dataset.state=c,Ie(t.meta,a),Te(t.meta.cookies??[]),W(a),G(a),Q(a),st(a),F(a,v),n):(console.warn("Target Missing: ",n.id),n)}function Te(t){t.forEach(e=>{console.log("SetCookie: ",e),document.cookie=e})}function Ie(t,e){t.query!=null&&he(t.query),t.pageTitle!=null&&(document.title=t.pageTitle),t.events?.forEach(n=>{xe(n,e)}),t.actions?.forEach(([n,r])=>{Ae(n,r)})}function xe(t,e){setTimeout(()=>{let n=new CustomEvent(t.name,{bubbles:!0,detail:t.detail});(e||document).dispatchEvent(n)},10)}function Ae(t,e){setTimeout(()=>{let n=window.Hyperbole?.hyperView(t);n&&v(n,e)},10)}function st(t){let e=t.querySelector("[autofocus]");e?.focus&&e.focus(),t.querySelectorAll("input[value]").forEach(n=>{let r=n.getAttribute("value");r!==null&&(n.value=r)}),t.querySelectorAll("input[type=checkbox]").forEach(n=>{let r=n.dataset.checked=="True";n.checked=r})}function at(t){if(!t)return;let e=t.sheet?.cssRules;if(e)for(let n=0;n<e.length;n++){let r=e.item(n);r&&be.has(r.cssText)==!1&&b.sheet&&(b.sheet.insertRule(r.cssText),be.add(r.cssText))}}function ct(){let t=O(document.getElementById("hyp.metadata")?.innerText??"");Ie(t,null);let e=document.body.querySelector("style");e!==null?b=e:(console.warn("rootStyles missing from page, creating..."),b=document.createElement("style"),b.type="text/css",document.body.appendChild(b)),ge(async function(r,i){v(r,i)}),W(document.body),G(document.body),Q(document.body),F(document.body,v),pe(async function(r,i){v(r,i)}),fe(async function(r,i){v(r,i)}),ce(async function(r,i){v(r,i)}),ue(async function(r,i){v(r,i)}),ye(async function(r,i,o){v(r,i,o)}),ve(async function(r,i){v(r,i)});function n(r){r.concurrency=="Replace"&&r.cancelActiveRequest()}me(n,async function(r,i){v(r,i)})}document.addEventListener("DOMContentLoaded",ct);var h=new C;h.connect();h.addEventListener("update",t=>{Me(t.detail)});h.addEventListener("response",t=>ot(t.detail));h.addEventListener("redirect",t=>it(t.detail));h.addEventListener("trigger",t=>nt(t.detail));h.addEventListener("event",t=>rt(t.detail));window.Hyperbole={runAction:v,parseMetadata:O,action:function(t,...e){return e.reduce((n,r)=>n+" "+JSON.stringify(r),t)},hyperView:function(t){let e=document.getElementById(t);if(!T(e)){console.error("Element id="+t+" was not a HyperView");return}return e},socket:h};})();
+/*! Bundled license information:
+
+omdomdom/lib/omdomdom.es.js:
+  (*!
+    * @license MIT (https://github.com/geotrev/omdomdom/blob/master/LICENSE)
+    * Omdomdom v0.3.2 (https://github.com/geotrev/omdomdom)
+    * Copyright 2023 George Treviranus <geowtrev@gmail.com>
+    *)
+*/
 //# sourceMappingURL=hyperbole.js.map
diff --git a/client/dist/hyperbole.js.map b/client/dist/hyperbole.js.map
--- a/client/dist/hyperbole.js.map
+++ b/client/dist/hyperbole.js.map
@@ -1,1 +1,7 @@
-{"version":3,"file":"hyperbole.js","mappings":"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","sources":["webpack://web-ui/./node_modules/debounce/index.js","webpack://web-ui/webpack/bootstrap","webpack://web-ui/./node_modules/omdomdom/lib/omdomdom.es.js","webpack://web-ui/./src/lib.ts","webpack://web-ui/./src/message.ts","webpack://web-ui/./src/action.ts","webpack://web-ui/./src/sockets.ts","webpack://web-ui/./src/events.ts","webpack://web-ui/./src/index.ts","webpack://web-ui/./src/response.ts","webpack://web-ui/./src/browser.ts"],"sourcesContent":["function debounce(function_, wait = 100, options = {}) {\n\tif (typeof function_ !== 'function') {\n\t\tthrow new TypeError(`Expected the first parameter to be a function, got \\`${typeof function_}\\`.`);\n\t}\n\n\tif (wait < 0) {\n\t\tthrow new RangeError('`wait` must not be negative.');\n\t}\n\n\t// TODO: Deprecate the boolean parameter at some point.\n\tconst {immediate} = typeof options === 'boolean' ? {immediate: options} : options;\n\n\tlet storedContext;\n\tlet storedArguments;\n\tlet timeoutId;\n\tlet timestamp;\n\tlet result;\n\n\tfunction run() {\n\t\tconst callContext = storedContext;\n\t\tconst callArguments = storedArguments;\n\t\tstoredContext = undefined;\n\t\tstoredArguments = undefined;\n\t\tresult = function_.apply(callContext, callArguments);\n\t\treturn result;\n\t}\n\n\tfunction later() {\n\t\tconst last = Date.now() - timestamp;\n\n\t\tif (last < wait && last >= 0) {\n\t\t\ttimeoutId = setTimeout(later, wait - last);\n\t\t} else {\n\t\t\ttimeoutId = undefined;\n\n\t\t\tif (!immediate) {\n\t\t\t\tresult = run();\n\t\t\t}\n\t\t}\n\t}\n\n\tconst debounced = function (...arguments_) {\n\t\tif (\n\t\t\tstoredContext\n\t\t\t&& this !== storedContext\n\t\t\t&& Object.getPrototypeOf(this) === Object.getPrototypeOf(storedContext)\n\t\t) {\n\t\t\tthrow new Error('Debounced method called with different contexts of the same prototype.');\n\t\t}\n\n\t\tstoredContext = this; // eslint-disable-line unicorn/no-this-assignment\n\t\tstoredArguments = arguments_;\n\t\ttimestamp = Date.now();\n\n\t\tconst callNow = immediate && !timeoutId;\n\n\t\tif (!timeoutId) {\n\t\t\ttimeoutId = setTimeout(later, wait);\n\t\t}\n\n\t\tif (callNow) {\n\t\t\tresult = run();\n\t\t}\n\n\t\treturn result;\n\t};\n\n\tObject.defineProperty(debounced, 'isPending', {\n\t\tget() {\n\t\t\treturn timeoutId !== undefined;\n\t\t},\n\t});\n\n\tdebounced.clear = () => {\n\t\tif (!timeoutId) {\n\t\t\treturn;\n\t\t}\n\n\t\tclearTimeout(timeoutId);\n\t\ttimeoutId = undefined;\n\t};\n\n\tdebounced.flush = () => {\n\t\tif (!timeoutId) {\n\t\t\treturn;\n\t\t}\n\n\t\tdebounced.trigger();\n\t};\n\n\tdebounced.trigger = () => {\n\t\tresult = run();\n\n\t\tdebounced.clear();\n\t};\n\n\treturn debounced;\n}\n\n// Adds compatibility for ES modules\nmodule.exports.debounce = debounce;\n\nmodule.exports = debounce;\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","/*!\n  * @license MIT (https://github.com/geotrev/omdomdom/blob/master/LICENSE)\n  * Omdomdom v0.3.2 (https://github.com/geotrev/omdomdom)\n  * Copyright 2023 George Treviranus <geowtrev@gmail.com>\n  */\nvar DATA_KEY_ATTRIBUTE$1 = \"data-key\";\nvar hasProperty = function hasProperty(obj, prop) {\n  return Object.prototype.hasOwnProperty.call(obj, prop);\n};\nvar keyIsValid = function keyIsValid(map, key) {\n  if (!key) return false;\n  if (hasProperty(map, key)) {\n    console.warn(\"[OmDomDom]: Children with duplicate keys detected. Children with duplicate keys will be skipped, resulting in dropped node references. Keys must be unique and non-indexed.\");\n    return false;\n  }\n  return true;\n};\nvar forEach = function forEach(items, fn) {\n  var length = items.length;\n  var idx = -1;\n  if (!length) return;\n  while (++idx < length) {\n    if (fn(items[idx], idx) === false) break;\n  }\n};\nvar createKeyMap = function createKeyMap(children) {\n  var map = {};\n  forEach(children, function (child) {\n    var key = child.attributes[DATA_KEY_ATTRIBUTE$1];\n    if (keyIsValid(map, key)) {\n      map[key] = child;\n    }\n  });\n  for (var _ in map) {\n    return map;\n  }\n};\nvar insertBefore = function insertBefore(parent, child, refNode) {\n  return parent.node.insertBefore(child.node, refNode);\n};\nvar assignVNode = function assignVNode(template, vNode) {\n  for (var property in template) {\n    vNode[property] = template[property];\n  }\n};\n\nvar toHTML = function toHTML(htmlString) {\n  var processedDOMString = htmlString.trim().replace(/\\s+</g, \"<\").replace(/>\\s+/g, \">\");\n  var parser = new DOMParser();\n  var context = parser.parseFromString(processedDOMString, \"text/html\");\n  return context.body;\n};\n\nfunction _iterableToArrayLimit(arr, i) {\n  var _i = null == arr ? null : \"undefined\" != typeof Symbol && arr[Symbol.iterator] || arr[\"@@iterator\"];\n  if (null != _i) {\n    var _s,\n      _e,\n      _x,\n      _r,\n      _arr = [],\n      _n = !0,\n      _d = !1;\n    try {\n      if (_x = (_i = _i.call(arr)).next, 0 === i) {\n        if (Object(_i) !== _i) return;\n        _n = !1;\n      } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0);\n    } catch (err) {\n      _d = !0, _e = err;\n    } finally {\n      try {\n        if (!_n && null != _i.return && (_r = _i.return(), Object(_r) !== _r)) return;\n      } finally {\n        if (_d) throw _e;\n      }\n    }\n    return _arr;\n  }\n}\nfunction _slicedToArray(arr, i) {\n  return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();\n}\nfunction _arrayWithHoles(arr) {\n  if (Array.isArray(arr)) return arr;\n}\nfunction _unsupportedIterableToArray(o, minLen) {\n  if (!o) return;\n  if (typeof o === \"string\") return _arrayLikeToArray(o, minLen);\n  var n = Object.prototype.toString.call(o).slice(8, -1);\n  if (n === \"Object\" && o.constructor) n = o.constructor.name;\n  if (n === \"Map\" || n === \"Set\") return Array.from(o);\n  if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);\n}\nfunction _arrayLikeToArray(arr, len) {\n  if (len == null || len > arr.length) len = arr.length;\n  for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];\n  return arr2;\n}\nfunction _nonIterableRest() {\n  throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n}\n\nvar Types = {\n  STRING: \"string\",\n  INT: \"number\",\n  BOOL: \"boolean\"\n};\nvar DomProperties = {};\nvar createRecord = function createRecord(attrName, propName, type) {\n  return {\n    attrName: attrName,\n    propName: propName,\n    type: type\n  };\n};\nvar stringProps = [[\"style\", \"cssText\"], [\"class\", \"className\"]];\nforEach(stringProps, function (_ref) {\n  var _ref2 = _slicedToArray(_ref, 2),\n    attr = _ref2[0],\n    property = _ref2[1];\n  DomProperties[attr] = createRecord(attr, property || attr, Types.STRING);\n});\nvar booleanProps = [\"autofocus\", \"draggable\", \"hidden\", \"checked\", \"multiple\", \"muted\", \"selected\"];\nforEach(booleanProps, function (attr) {\n  DomProperties[attr] = createRecord(attr, attr, Types.BOOL);\n});\nvar integerProps = [[\"tabindex\", \"tabIndex\"]];\nforEach(integerProps, function (_ref3) {\n  var _ref4 = _slicedToArray(_ref3, 2),\n    attr = _ref4[0],\n    property = _ref4[1];\n  DomProperties[attr] = createRecord(attr, property, Types.INT);\n});\nvar Namespace = {\n  xlink: {\n    prefix: \"xlink:\",\n    resource: \"http://www.w3.org/1999/xlink\"\n  },\n  xml: {\n    prefix: \"xml:\",\n    resource: \"http://www.w3.org/XML/1998/namespace\"\n  }\n};\n\nvar setProperty = function setProperty(element, type, prop, value) {\n  switch (type) {\n    case Types.STRING:\n      {\n        if (prop === DomProperties.style.propName) {\n          if (value === null) {\n            element.style[prop] = \"\";\n          } else {\n            element.style[prop] = value;\n          }\n        } else if (value === null) {\n          element[prop] = \"\";\n        } else {\n          element[prop] = value;\n        }\n        break;\n      }\n    case Types.INT:\n      {\n        if (value === null) {\n          var attr = prop.toLowerCase();\n          element.removeAttribute(attr);\n        } else if (value === \"0\") {\n          element[prop] = 0;\n        } else if (value === \"-1\") {\n          element[prop] = -1;\n        } else {\n          var parsed = parseInt(value, 10);\n          if (!isNaN(parsed)) {\n            element[prop] = parsed;\n          }\n        }\n        break;\n      }\n    case Types.BOOL:\n      {\n        if ([\"\", \"true\"].indexOf(value) < 0) {\n          element[prop] = false;\n        } else {\n          element[prop] = true;\n        }\n        break;\n      }\n  }\n};\n\nvar removeAttributes = function removeAttributes(vNode, attributes) {\n  forEach(attributes, function (attrName) {\n    if (hasProperty(DomProperties, attrName)) {\n      var propertyRecord = DomProperties[attrName];\n      setProperty(vNode.node, propertyRecord.type, propertyRecord.propName, null);\n    } else {\n      if (attrName in vNode.node) {\n        setProperty(vNode.node, Types.STRING, attrName, null);\n      }\n      vNode.node.removeAttribute(attrName);\n    }\n    delete vNode.attributes[attrName];\n  });\n};\nvar setAttributes = function setAttributes(vNode, attributes) {\n  for (var attrName in attributes) {\n    var value = attributes[attrName];\n    vNode.attributes[attrName] = value;\n    if (hasProperty(DomProperties, attrName)) {\n      var propertyRecord = DomProperties[attrName];\n      setProperty(vNode.node, propertyRecord.type, propertyRecord.propName, value);\n      continue;\n    }\n    if (attrName.startsWith(Namespace.xlink.prefix)) {\n      vNode.node.setAttributeNS(Namespace.xlink.resource, attrName, value);\n      continue;\n    }\n    if (attrName.startsWith(Namespace.xml.prefix)) {\n      vNode.node.setAttributeNS(Namespace.xml.resource, attrName, value);\n      continue;\n    }\n    if (attrName in vNode.node) {\n      setProperty(vNode.node, Types.STRING, attrName, value);\n    }\n    vNode.node.setAttribute(attrName, value || \"\");\n  }\n};\nvar getPropertyValues = function getPropertyValues(element, attributes) {\n  for (var attrName in DomProperties) {\n    var propertyRecord = DomProperties[attrName];\n    var propName = propertyRecord.propName;\n    var attrValue = element.getAttribute(attrName);\n    if (attrName === DomProperties.style.attrName) {\n      attributes[attrName] = element.style[propName];\n    } else if (typeof attrValue === \"string\") {\n      attributes[attrName] = attrValue;\n    }\n  }\n};\nvar getBaseAttributes = function getBaseAttributes(element) {\n  return Array.prototype.reduce.call(element.attributes, function (attributes, attrName) {\n    if (!hasProperty(DomProperties, attrName.name)) {\n      attributes[attrName.name] = attrName.value;\n    }\n    return attributes;\n  }, {});\n};\nvar getAttributes = function getAttributes(element) {\n  var attributes = getBaseAttributes(element);\n  getPropertyValues(element, attributes);\n  return attributes;\n};\nvar updateAttributes = function updateAttributes(template, vNode) {\n  var removedAttributes = [];\n  var changedAttributes = {};\n  for (var attrName in vNode.attributes) {\n    var oldValue = vNode.attributes[attrName];\n    var nextValue = template.attributes[attrName];\n    if (oldValue === nextValue) continue;\n    if (typeof nextValue === \"undefined\") {\n      removedAttributes.push(attrName);\n    }\n  }\n  for (var _attrName in template.attributes) {\n    var _oldValue = vNode.attributes[_attrName];\n    var _nextValue = template.attributes[_attrName];\n    if (_oldValue === _nextValue) continue;\n    if (typeof _nextValue !== \"undefined\") {\n      changedAttributes[_attrName] = _nextValue;\n    }\n  }\n  removeAttributes(vNode, removedAttributes);\n  setAttributes(vNode, changedAttributes);\n};\n\nvar DATA_KEY_ATTRIBUTE = \"data-key\";\nfunction patchChildren(template, vNode, patch) {\n  var templateChildrenLength = template.children.length;\n  var vNodeChildrenLength = vNode.children.length;\n  if (!templateChildrenLength && !vNodeChildrenLength) return;\n  var vNodeKeyMap = createKeyMap(vNode.children);\n  var nextChildren = Array(templateChildrenLength);\n  if (vNodeKeyMap !== undefined) {\n    forEach(template.children, function (templateChild, idx) {\n      var childNodes = vNode.node.childNodes;\n      var key = templateChild.attributes[DATA_KEY_ATTRIBUTE];\n      if (Object.prototype.hasOwnProperty.call(vNodeKeyMap, key)) {\n        var keyedChild = vNodeKeyMap[key];\n        if (Array.prototype.indexOf.call(childNodes, keyedChild.node) !== idx) {\n          insertBefore(vNode, keyedChild, childNodes[idx]);\n        }\n        nextChildren[idx] = keyedChild;\n        delete vNodeKeyMap[key];\n        patch(templateChild, nextChildren[idx]);\n      } else {\n        insertBefore(vNode, templateChild, childNodes[idx]);\n        nextChildren[idx] = templateChild;\n      }\n    });\n  } else {\n    forEach(template.children, function (templateChild, idx) {\n      var vNodeChild = vNode.children[idx];\n      if (typeof vNodeChild !== \"undefined\") {\n        patch(templateChild, vNodeChild);\n        nextChildren[idx] = vNodeChild;\n      } else {\n        vNode.node.appendChild(templateChild.node);\n        nextChildren[idx] = templateChild;\n      }\n    });\n  }\n  vNode.children = nextChildren;\n  var childNodesLength = vNode.node.childNodes.length;\n  var delta = childNodesLength - templateChildrenLength;\n  if (delta > 0) {\n    while (delta > 0) {\n      vNode.node.removeChild(vNode.node.childNodes[childNodesLength - 1]);\n      childNodesLength--;\n      delta--;\n    }\n  }\n}\n\nvar patch = function patch(template, vNode, rootNode) {\n  if (!template || !vNode) return;\n  rootNode = rootNode || vNode.node.parentNode;\n  var contentChanged = template.content && template.content !== vNode.content;\n  if (template.type !== vNode.type || contentChanged) {\n    rootNode.replaceChild(template.node, vNode.node);\n    return assignVNode(template, vNode);\n  }\n  updateAttributes(template, vNode);\n  patchChildren(template, vNode, patch);\n};\nvar render = function render(vNode, root) {\n  root.appendChild(vNode.node);\n};\nvar create = function create(node) {\n  var isSVGContext = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n  if (typeof node === \"string\") {\n    node = toHTML(node);\n  }\n  var isRoot = node.tagName === \"BODY\";\n  var childNodes = node.childNodes;\n  var numChildNodes = childNodes ? childNodes.length : 0;\n  if (isRoot) {\n    if (numChildNodes > 1) {\n      throw new Error(\"[OmDomDom]: Your element should not have more than one root node.\");\n    } else if (numChildNodes === 0) {\n      throw new Error(\"[OmDomDom]: Your element should have at least one root node.\");\n    } else {\n      return create(childNodes[0]);\n    }\n  }\n  var type = node.nodeType === 3 ? \"text\" : node.nodeType === 8 ? \"comment\" : node.tagName.toLowerCase();\n  var isSVG = isSVGContext || type === \"svg\";\n  var attributes = node.nodeType === 1 ? getAttributes(node) : {};\n  var content = numChildNodes > 0 ? null : node.textContent;\n  var children = Array(numChildNodes);\n  forEach(childNodes, function (child, idx) {\n    children[idx] = create(child, isSVG);\n  });\n  return {\n    type: type,\n    attributes: attributes,\n    children: children,\n    content: content,\n    node: node,\n    isSVGContext: isSVG\n  };\n};\n\nexport { create, patch, render };\n//# sourceMappingURL=omdomdom.es.js.map\n","\n\nexport function takeWhileMap<T, A>(pred: (val: T) => A | undefined, lines: T[]): A[] {\n  var output = []\n  for (var line of lines) {\n    let a = pred(line)\n    if (a)\n      output.push(a)\n    else\n      break;\n  }\n\n  return output\n}\n\nexport function dropWhile<T, A>(pred: (val: T) => A | undefined, lines: T[]): T[] {\n  let index = 0;\n  while (index < lines.length && pred(lines[index])) {\n    index++;\n  }\n  return lines.slice(index);\n}\n\n","\nimport { takeWhileMap, dropWhile } from \"./lib\"\n\n\n\nexport type Meta = { key: string, value: string }\nexport type ViewId = string\nexport type RequestId = number\nexport type EncodedAction = string\nexport type ViewState = string\n\ntype RemoteEvent = { name: string, detail: any }\n\n\nexport function renderMetas(meta: Meta[]): string {\n  return meta.map(m => m.key + \": \" + m.value).join('\\n')\n}\n\nexport type Metadata = {\n  cookies?: string[]\n  // redirect?: string\n  error?: string\n  query?: string\n  events?: RemoteEvent[]\n  actions?: [ViewId, string][],\n  pageTitle?: string\n}\n\n\nexport function toMetadata(meta: Meta[]): Metadata {\n\n  return {\n    cookies: meta.filter(m => m.key == \"Cookie\").map(m => m.value),\n    // redirect: metaValue(\"Redirect\", meta),\n    error: metaValue(\"Error\", meta),\n    query: metaValue(\"Query\", meta),\n    pageTitle: metaValue(\"PageTitle\", meta),\n    events: metaValuesAll(\"Event\", meta).map(parseRemoteEvent),\n    actions: metaValuesAll(\"Trigger\", meta).map(parseAction),\n  }\n}\n\n// viewId: meta.find(m => m.key == \"VIEW-ID\")?.value,\n\nexport function parseMetadata(input: string): Metadata {\n  let metas = takeWhileMap(parseMeta, input.trim().split(\"\\n\"))\n  return toMetadata(metas)\n}\n\n\nexport function metaValue(key: string, metas: Meta[]): string | undefined {\n  return metas.find(m => m.key == key)?.value\n}\n\nexport function metaValuesAll(key: string, metas: Meta[]): string[] {\n  return metas.filter(m => m.key == key).map(m => m.value)\n}\n\nexport type SplitMessage = {\n  command: string,\n  metas: Meta[],\n  rest: string[]\n}\n\n\nexport function splitMessage(message: string): SplitMessage {\n  let lines = message.split(\"\\n\")\n  let command: string = lines[0]\n  let metas: Meta[] = takeWhileMap(parseMeta, lines.slice(1))\n  // console.log(\"Split Metadata\", lines.length)\n  // console.log(\" [0]\", lines[0])\n  // console.log(\" [1]\", lines[1])\n  let rest = dropWhile(l => l == \"\", lines.slice(metas.length + 1))\n\n  return { command, metas, rest }\n}\n\nexport function parseMeta(line: string): Meta | undefined {\n  let match = line.match(/^(\\w+)\\: (.*)$/)\n  if (match) {\n    return {\n      key: match[1],\n      value: match[2]\n    }\n  }\n}\n\n\nexport function parseRemoteEvent(input: string): RemoteEvent {\n  let [name, data] = breakNextSegment(input)\n  return {\n    name,\n    detail: JSON.parse(data)\n  }\n}\n\nexport function parseAction(input: string): [ViewId, string] {\n  let [viewId, action] = breakNextSegment(input)\n  return [viewId, action]\n}\n\nfunction breakNextSegment(input: string): [string, string] | undefined {\n  let ix = input.indexOf('|')\n  if (ix === -1) {\n    let err = new Error(\"Bad Encoding, Expected Segment\")\n    err.message = input\n    throw err\n  }\n  return [input.slice(0, ix), input.slice(ix + 1)]\n}\n\n","\nimport { takeWhileMap } from \"./lib\"\nimport { Meta, ViewId, RequestId, EncodedAction, ViewState } from \"./message\"\nimport * as message from \"./message\"\n\n\n\nexport type ActionMessage = {\n  viewId: ViewId\n  action: EncodedAction\n  requestId: RequestId\n  state?: ViewState\n  meta: Meta[]\n  form: URLSearchParams | undefined\n}\n\n\n\n\nexport function actionMessage(id: ViewId, action: EncodedAction, state: ViewState | undefined, reqId: RequestId, form?: FormData): ActionMessage {\n  let meta: Meta[] = [\n    { key: \"Cookie\", value: decodeURI(document.cookie) },\n    { key: \"Query\", value: window.location.search }\n  ]\n\n  return { viewId: id, action, state, requestId: reqId, meta, form: toSearch(form) }\n}\n\nexport function toSearch(form?: FormData): URLSearchParams | undefined {\n  if (!form) return undefined\n\n  const params = new URLSearchParams()\n\n  form.forEach((value, key) => {\n    params.append(key, value as string)\n  })\n\n  return params\n}\n\nexport function renderActionMessage(msg: ActionMessage): string {\n  let header = [\n    \"|ACTION|\",\n    \"ViewId: \" + msg.viewId,\n    \"Action: \" + msg.action,\n  ]\n\n\n  if (msg.state) {\n    header.push(\"State: \" + msg.state)\n  }\n\n  header.push(\"RequestId: \" + msg.requestId)\n\n  return [\n    header.join('\\n'),\n    message.renderMetas(msg.meta),\n  ].join('\\n') + renderForm(msg.form)\n}\n\n\nexport function renderForm(form: URLSearchParams | undefined): string {\n  if (!form) return \"\"\n  return \"\\n\\n\" + form\n}\n\nlet globalRequestId: RequestId = 0\n\nexport type Request = {\n  requestId: RequestId\n  isCancelled: boolean\n}\n\nexport function newRequest(): Request {\n  let requestId = ++globalRequestId\n  return { requestId, isCancelled: false }\n}\n\n\n\n// Sanitized Encoding ------------------------------------\n\nexport function encodedParam(action: string, param: string): string {\n  return action + ' ' + sanitizeParam(param)\n}\n\nfunction sanitizeParam(param: string): string {\n  if (param == \"\") {\n    return \"|\"\n  }\n\n  return param.replace(/_/g, \"\\\\_\").replace(/\\s+/g, \"_\")\n}\n","import { ActionMessage, renderActionMessage } from './action'\nimport { ResponseBody } from \"./response\"\nimport * as message from \"./message\"\nimport { ViewId, RequestId, EncodedAction, metaValue, Metadata } from \"./message\"\n\nconst protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';\nconst defaultAddress = `${protocol}//${window.location.host}${window.location.pathname}`\n\n\n\nexport class SocketConnection {\n  socket: WebSocket\n\n  hasEverConnected: Boolean = false\n  isConnected: Boolean = false\n  reconnectDelay: number = 0\n  queue: ActionMessage[] = []\n  events: EventTarget\n\n  constructor() {\n    this.events = new EventTarget()\n  }\n\n  connect(addr = defaultAddress) {\n    const sock = new WebSocket(addr)\n    this.socket = sock\n\n    function onConnectError(ev: Event) {\n      console.error(\"Connect Error\", ev)\n    }\n\n    function onSocketError(ev: Event) {\n      console.error(\"Socket Error\", ev)\n    }\n\n\n    // initial connection errors\n    sock.addEventListener('error', onConnectError)\n\n    sock.addEventListener('open', (_event) => {\n      console.log(\"Websocket Connected\")\n\n      if (this.hasEverConnected) {\n        document.dispatchEvent(new Event(\"hyp-socket-reconnect\"))\n      }\n\n      this.isConnected = true\n      this.hasEverConnected = true\n      this.reconnectDelay = 1000\n      sock.removeEventListener('error', onConnectError)\n      sock.addEventListener('error', onSocketError)\n\n      document.dispatchEvent(new Event(\"hyp-socket-connect\"))\n\n      this.runQueue()\n    })\n\n    sock.addEventListener('close', _ => {\n      console.log(\"CLOSE SOCKET\")\n      if (this.isConnected) {\n        document.dispatchEvent(new Event(\"hyp-socket-disconnect\"))\n      }\n\n      this.isConnected = false\n      sock.removeEventListener('error', onSocketError)\n\n      // attempt to reconnect in 1s\n      if (this.hasEverConnected) {\n        console.log(\"Reconnecting in \" + (this.reconnectDelay / 1000) + \"s\")\n        setTimeout(() => this.connect(addr), this.reconnectDelay)\n      }\n\n      sock.removeEventListener('error', onSocketError)\n    })\n\n    sock.addEventListener('message', ev => this.onMessage(ev))\n  }\n\n  async sendAction(action: ActionMessage) {\n    if (this.isConnected) {\n      let msg = renderActionMessage(action)\n      this.socket.send(msg)\n    }\n    else {\n      this.queue.push(action)\n    }\n  }\n\n  private runQueue() {\n    // send all messages queued while disconnected \n    let next: ActionMessage | null = this.queue.pop()\n    if (next) {\n      console.log(\"runQueue: \", next)\n      this.sendAction(next)\n      this.runQueue()\n    }\n  }\n\n\n  // full responses will never be sent over!\n  private onMessage(event: MessageEvent) {\n    let { command, metas, rest } = message.splitMessage(event.data)\n    // console.log(\"MESSAGE\", command, metas, rest)\n\n    let requestId = parseInt(requireMeta(\"RequestId\"), 0)\n\n    function requireMeta(key: string): string {\n      let val = metaValue(key, metas)\n      if (!val) throw new ProtocolError(\"Missing Required Metadata: \" + key, event.data)\n      return val\n    }\n\n    function parseResponse(rest: string[]): Update {\n      let viewId = requireMeta(\"ViewId\")\n      let action = requireMeta(\"Action\")\n      return {\n        requestId,\n        targetViewId: undefined,\n        viewId,\n        action,\n        meta: message.toMetadata(metas),\n        body: rest.join(\"\\n\"),\n      }\n    }\n\n    function parseUpdate(rest: string[]): Update {\n      let up = parseResponse(rest)\n      // add the TargetViewId\n      up.targetViewId = metaValue(\"TargetViewId\", metas)\n      return up\n    }\n\n    function parseRedirect(rest: string[]): Redirect {\n      let url = rest[0]\n      return {\n        requestId,\n        meta: message.toMetadata(metas),\n        url\n      }\n    }\n\n    switch (command) {\n\n      case \"|UPDATE|\":\n        return this.dispatchEvent(new CustomEvent(\"update\", { detail: parseUpdate(rest) }))\n\n      case \"|RESPONSE|\":\n        return this.dispatchEvent(new CustomEvent(\"response\", { detail: parseResponse(rest) }))\n\n      case \"|REDIRECT|\":\n        return this.dispatchEvent(new CustomEvent(\"redirect\", { detail: parseRedirect(rest) }))\n    }\n  }\n\n\n  // so what if they send remote events in the page? trigger, redirect, page title, etc...\n  // we aren't connected yet on a page thing\n\n  // private async waitMessage(reqId: RequestId, id: ViewId): Promise<ParsedResponse> {\n  //   return new Promise((resolve, reject) => {\n  //     const onMessage = (event: MessageEvent) => {\n  //       let data: string = event.data\n  //       let lines = data.split(\"\\n\").slice(1)  // drop the command line\n  //\n  //       let parsed = splitMetadata(lines)\n  //       let metadata: Metadata = parsed.metadata\n  //\n  //       if (!metadata.requestId) {\n  //         console.error(\"Missing RequestId!\", metadata, event.data)\n  //         return\n  //       }\n  //\n  //       if (metadata.requestId != reqId) {\n  //         // skip, it's not us!\n  //         return\n  //       }\n  //\n  //\n  //       // We have found our message. Remove the listener\n  //       this.socket.removeEventListener('message', onMessage)\n  //\n  //       // set the cookies. These happen automatically in http\n  //       metadata.cookies.forEach((cookie: string) => {\n  //         document.cookie = cookie\n  //       })\n  //\n  //       if (metadata.error) {\n  //         reject(new FetchError(id, metadata.error, parsed.rest.join('\\n')))\n  //         return\n  //       }\n  //\n  //       resolve(parsed)\n  //     }\n  //\n  //     this.socket.addEventListener('message', onMessage)\n  //     this.socket.addEventListener('error', reject)\n  //   })\n  // }\n\n  addEventListener(e: string, cb: EventListenerOrEventListenerObject) {\n    this.events.addEventListener(e, cb)\n  }\n\n  dispatchEvent(e: Event) {\n    this.events.dispatchEvent(e)\n  }\n\n  disconnect() {\n    this.isConnected = false\n    this.hasEverConnected = false\n    this.socket.close()\n  }\n}\n\n\nexport type Update = {\n  requestId: RequestId\n  meta: Metadata\n  viewId: ViewId\n  targetViewId?: ViewId\n  action: EncodedAction\n  body: ResponseBody\n}\n\nexport type Redirect = {\n  requestId: RequestId\n  meta: Metadata\n  url: string\n}\n\nexport type MessageType = string\n\n\n// PARSING MESSAGE  ---------------------------------------\n\nexport class ProtocolError extends Error {\n  constructor(description: string, body: string) {\n    super(description + \"\\n\" + body)\n    this.name = \"ProtocolError\"\n  }\n}\n","\nimport * as debounce from 'debounce'\nimport { encodedParam } from './action'\n\nexport type UrlFragment = string\n\nexport function listenKeydown(cb: (target: HTMLElement, action: string) => void): void {\n  listenKeyEvent(\"keydown\", cb)\n}\n\nexport function listenKeyup(cb: (target: HTMLElement, action: string) => void): void {\n  listenKeyEvent(\"keyup\", cb)\n}\n\nexport function listenKeyEvent(event: string, cb: (target: HTMLElement, action: string) => void): void {\n  document.addEventListener(event.toLowerCase(), function(e: KeyboardEvent) {\n    let source = e.target as HTMLInputElement\n\n    let datasetKey = \"on\" + event + e.key\n    let action = source.dataset[datasetKey]\n    if (!action) return\n\n    e.preventDefault()\n    cb(nearestTarget(source), action)\n  })\n}\n\nexport function listenBubblingEvent(event: string, cb: (target: HTMLElement, action: string) => void): void {\n  document.addEventListener(event, function(e) {\n    let el = e.target as HTMLInputElement\n\n    // clicks can fire on internal elements. Find the parent with a click handler\n    let source = el.closest(\"[data-on\" + event + \"]\") as HTMLElement\n    if (!source) return\n\n    e.preventDefault()\n    let target = nearestTarget(source)\n    cb(target, source.dataset[\"on\" + event])\n  })\n}\n\nexport function listenClick(cb: (target: HTMLElement, action: string) => void): void {\n  listenBubblingEvent(\"click\", cb)\n}\n\nexport function listenDblClick(cb: (target: HTMLElement, action: string) => void): void {\n  listenBubblingEvent(\"dblclick\", cb)\n}\n\n\nexport function listenTopLevel(cb: (target: HTMLElement, action: string) => void): void {\n  document.addEventListener(\"hyp-load\", function(e: CustomEvent) {\n    let action = e.detail.onLoad\n    let target = e.detail.target\n    cb(target, action)\n  })\n\n  document.addEventListener(\"hyp-mouseenter\", function(e: CustomEvent) {\n    let action = e.detail.onMouseEnter\n    let target = e.detail.target\n    cb(target, action)\n  })\n\n  document.addEventListener(\"hyp-mouseleave\", function(e: CustomEvent) {\n    let action = e.detail.onMouseLeave\n    let target = e.detail.target\n    cb(target, action)\n  })\n}\n\n\nexport function listenLoad(node: HTMLElement): void {\n\n  // it doesn't really matter WHO runs this except that it should have target\n  node.querySelectorAll(\"[data-onload]\").forEach((load: HTMLElement) => {\n    let delay = parseInt(load.dataset.delay) || 0\n    let onLoad = load.dataset.onload\n    // console.log(\"load start\", load.dataset.onLoad)\n\n    // load no longer exists!\n    // we should clear the timeout or back out if the dom is replaced in the interem\n    setTimeout(() => {\n      let target = nearestTarget(load)\n      // console.log(\"load go\", load.dataset.onLoad)\n\n      if (load.dataset.onload != onLoad) {\n        // the onLoad no longer exists\n        return\n      }\n\n      const event = new CustomEvent(\"hyp-load\", { bubbles: true, detail: { target, onLoad } })\n      load.dispatchEvent(event)\n    }, delay)\n  })\n}\n\nexport function listenMouseEnter(node: HTMLElement): void {\n  node.querySelectorAll(\"[data-onmouseenter]\").forEach((node: HTMLElement) => {\n    let onMouseEnter = node.dataset.onmouseenter\n\n    let target = nearestTarget(node)\n\n    node.onmouseenter = () => {\n      const event = new CustomEvent(\"hyp-mouseenter\", { bubbles: true, detail: { target, onMouseEnter } })\n      node.dispatchEvent(event)\n    }\n  })\n}\n\nexport function listenMouseLeave(node: HTMLElement): void {\n  node.querySelectorAll(\"[data-onmouseleave]\").forEach((node: HTMLElement) => {\n    let onMouseLeave = node.dataset.onmouseleave\n\n    let target = nearestTarget(node)\n\n    node.onmouseleave = () => {\n      const event = new CustomEvent(\"hyp-mouseleave\", { bubbles: true, detail: { target, onMouseLeave } })\n      node.dispatchEvent(event)\n    }\n  })\n}\n\n\nexport function listenChange(cb: (target: HTMLElement, action: string) => void): void {\n  document.addEventListener(\"change\", function(e) {\n    let el = e.target as HTMLElement\n\n    let source = el.closest(\"[data-onchange]\") as HTMLInputElement\n\n    if (!source) return\n    e.preventDefault()\n\n    if (source.value == null) {\n      console.error(\"Missing input value:\", source)\n      return\n    }\n\n    let target = nearestTarget(source)\n    let action = encodedParam(source.dataset.onchange, source.value)\n    cb(target, action)\n  })\n}\n\ninterface LiveInputElement extends HTMLInputElement {\n  debouncedCallback?: Function;\n}\n\nexport function listenInput(startedTyping: (target: HTMLElement) => void, cb: (target: HTMLElement, action: string) => void): void {\n  document.addEventListener(\"input\", function(e) {\n    let el = e.target as HTMLElement\n    let source = el.closest(\"[data-oninput]\") as LiveInputElement\n\n    if (!source) return\n\n    let delay = parseInt(source.dataset.delay) || 250\n    if (delay < 250) {\n      console.warn(\"Input delay < 250 can result in poor performance.\")\n    }\n\n    if (!source?.dataset.oninput) {\n      console.error(\"Missing onInput: \", source)\n      return\n    }\n\n    e.preventDefault()\n\n    let target = nearestTarget(source)\n\n    // I want to CANCEL the active request as soon as we start typing\n    startedTyping(target)\n\n    if (!source.debouncedCallback) {\n      source.debouncedCallback = debounce(() => {\n        let action = encodedParam(source.dataset.oninput, source.value)\n        cb(target, action)\n      }, delay)\n    }\n\n    source.debouncedCallback()\n  })\n}\n\n\n\nexport function listenFormSubmit(cb: (target: HTMLElement, action: string, form: FormData) => void): void {\n  document.addEventListener(\"submit\", function(e) {\n    let form = e.target as HTMLFormElement\n\n    if (!form?.dataset.onsubmit) {\n      console.error(\"Missing onSubmit: \", form)\n      return\n    }\n\n    e.preventDefault()\n\n    let target = nearestTarget(form)\n    const formData = new FormData(form)\n    cb(target, form.dataset.onsubmit, formData)\n  })\n}\n\nfunction nearestTargetId(node: HTMLElement): string | undefined {\n  let targetData = node.closest(\"[data-target]\") as HTMLElement | undefined\n  return targetData?.dataset.target || node.closest(\"[id]\")?.id\n}\n\nfunction nearestTarget(node: HTMLElement): HTMLElement {\n  let targetId = nearestTargetId(node)\n  let target = document.getElementById(targetId)\n\n  if (!target) {\n    console.error(\"Cannot find target: \", targetId, node)\n    return\n  }\n\n  return target\n}\n","import { patch, create } from \"omdomdom/lib/omdomdom.es.js\"\nimport { SocketConnection, Update, Redirect } from './sockets'\nimport { listenChange, listenClick, listenDblClick, listenFormSubmit, listenLoad, listenTopLevel, listenInput, listenKeydown, listenKeyup, listenMouseEnter, listenMouseLeave } from './events'\nimport { actionMessage, ActionMessage, Request, newRequest } from './action'\nimport { ViewId, Metadata, parseMetadata, ViewState } from './message'\nimport { setQuery } from \"./browser\"\nimport { parseResponse, Response, LiveUpdate } from './response'\n\nlet PACKAGE = require('../package.json');\n\n\n// console.log(\"VERSION 2\", INIT_PAGE, INIT_STATE)\nconsole.log(\"Hyperbole \" + PACKAGE.version + \"b\")\n\n\nlet rootStyles: HTMLStyleElement;\nlet addedRulesIndex = new Set();\n\n\n\n\n\n// Run an action in a given HyperView\nasync function runAction(target: HyperView, action: string, form?: FormData) {\n  if (target === undefined) {\n    console.error(\"Undefined HyperView!\", action)\n    return\n  }\n\n  if (action === undefined) {\n    console.error(\"Undefined Action!\", target.id)\n    return\n  }\n\n  if (target.activeRequest && !target.activeRequest?.isCancelled) {\n    // Active Request!\n    if (target.concurrency == \"Drop\") {\n      console.warn(\"Drop action overlapping with active request (\" + target.activeRequest + \")\", action)\n      return\n    }\n  }\n\n  target._timeout = setTimeout(() => {\n    // add loading after 100ms, not right away\n    // if it runs shorter than that we probably don't want to show the user any loading feedback\n    target.classList.add(\"hyp-loading\")\n  }, 100)\n\n  let state = target.dataset.state\n\n  let req = newRequest()\n  let msg = actionMessage(target.id, action, state, req.requestId, form)\n\n  // Set the requestId\n  target.activeRequest = req\n\n  sock.sendAction(msg)\n}\n\n\n// TODO: redirect concurrency\nfunction handleRedirect(red: Redirect) {\n  console.log(\"REDIRECT\", red)\n\n  // the other metdata doesn't apply, they are all specific to the page\n  applyCookies(red.meta.cookies)\n\n  window.location.href = red.url\n}\n\n// in-process update\nfunction handleResponse(res: Update) {\n  // console.log(\"Handle Response\", res)\n  let target = handleUpdate(res)\n\n  // clean up the request\n  delete target.activeRequest\n  clearTimeout(target._timeout)\n  target.classList.remove(\"hyp-loading\")\n}\n\nfunction handleUpdate(res: Update): HyperView {\n  // console.log(\"|UPDATE|\", res)\n\n  let targetViewId = res.targetViewId || res.viewId\n  let target = document.getElementById(targetViewId) as HyperView\n\n\n  if (!target) {\n    console.error(\"Missing Update Target: \", targetViewId, res)\n    return target\n  }\n\n  if (res.requestId < target.activeRequest?.requestId) {\n    // this should only happen on Replace, since other requests should be dropped\n    // but it's safe to assume we never want to apply an old requestId\n    console.warn(\"Ignore Stale Action (\" + res.requestId + \") vs (\" + target.activeRequest.requestId + \"): \" + res.action)\n    return target\n  }\n  else if (target.activeRequest?.isCancelled) {\n    console.warn(\"Cancelled request\", target.activeRequest?.requestId)\n    delete target.activeRequest\n    return target\n  }\n\n  let update: LiveUpdate = parseResponse(res.body)\n\n  if (!update.content) {\n    console.error(\"Empty Response!\", res.body)\n    return target\n  }\n\n  // First, update the stylesheet\n  addCSS(update.css)\n\n\n  // Patch the node\n  const old: VNode = create(target)\n  let next: VNode = create(update.content)\n  let state = (next.attributes as any)[\"data-state\"]\n  next.attributes = old.attributes\n  patch(next, old)\n\n\n  // Emit relevant events\n  let newTarget = document.getElementById(target.id)\n  dispatchContent(newTarget)\n\n  if (!newTarget) {\n    console.warn(\"Target Missing: \", target.id)\n    return target\n  }\n\n  // re-add state attribute \n  newTarget.dataset.state = state\n\n  // execute the metadata, anything that doesn't interrupt the dom update\n  runMetadata(res.meta, newTarget)\n  applyCookies(res.meta.cookies)\n\n  // now way for these to bubble)\n  listenLoad(newTarget)\n  listenMouseEnter(newTarget)\n  listenMouseLeave(newTarget)\n  fixInputs(newTarget)\n  enrichHyperViews(newTarget)\n\n  return target\n}\n// catch (err) {\n//   console.error(\"Caught Error in HyperView (\" + target.id + \"):\\n\", err)\n//\n//   // Hyperbole catches handler errors, and the server controls what to display to the user on an error\n//   //  but if you manage to crash your parent server process somehow, the response may be empty\n//   target.innerHTML = err.body || \"<div style='background:red;color:white;padding:10px'>Hyperbole Internal Error</div>\"\n// }\n\nfunction applyCookies(cookies: string[]) {\n  cookies.forEach((cookie: string) => {\n    console.log(\"SetCookie: \", cookie)\n    document.cookie = cookie\n  })\n}\n\nfunction runMetadata(meta: Metadata, target?: HTMLElement) {\n  if (meta.query != null) {\n    setQuery(meta.query)\n  }\n\n  if (meta.pageTitle != null) {\n    document.title = meta.pageTitle\n  }\n\n  meta.events.forEach((remoteEvent) => {\n    setTimeout(() => {\n      let event = new CustomEvent(remoteEvent.name, { bubbles: true, detail: remoteEvent.detail })\n      let eventTarget = target || document\n      eventTarget.dispatchEvent(event)\n    }, 10)\n  })\n\n  meta.actions.forEach(([viewId, action]) => {\n    setTimeout(() => {\n      let view = window.Hyperbole.hyperView(viewId)\n      if (view) {\n        runAction(view, action)\n      }\n    }, 10)\n  })\n}\n\n\nfunction fixInputs(target: HTMLElement) {\n  let focused = target.querySelector(\"[autofocus]\") as HTMLInputElement\n  if (focused?.focus) {\n    focused.focus()\n  }\n\n  target.querySelectorAll(\"input[value]\").forEach((input: HTMLInputElement) => {\n    let val = input.getAttribute(\"value\")\n    if (val !== undefined) {\n      input.value = val\n    }\n  })\n\n  target.querySelectorAll(\"input[type=checkbox]\").forEach((checkbox: HTMLInputElement) => {\n    let checked = checkbox.dataset.checked == \"True\"\n    checkbox.checked = checked\n  })\n}\n\nfunction addCSS(src: HTMLStyleElement | null) {\n  if (!src) return;\n  const rules: any = src.sheet.cssRules\n  for (const rule of rules) {\n    if (addedRulesIndex.has(rule.cssText) == false) {\n      rootStyles.sheet.insertRule(rule.cssText);\n      addedRulesIndex.add(rule.cssText);\n    }\n  }\n}\n\n\n\n\nfunction init() {\n  // metadata attached to initial page loads need to be executed\n  let meta = parseMetadata(document.getElementById(\"hyp.metadata\").innerText)\n  // runMetadataImmediate(meta)\n  runMetadata(meta)\n\n  rootStyles = document.body.querySelector('style')\n\n  if (!rootStyles) {\n    console.warn(\"rootStyles missing from page, creating...\")\n    rootStyles = document.createElement(\"style\")\n    rootStyles.type = \"text/css\"\n    document.body.appendChild(rootStyles)\n  }\n\n  listenTopLevel(async function(target: HyperView, action: string) {\n    runAction(target, action)\n  })\n\n  listenLoad(document.body)\n  listenMouseEnter(document.body)\n  listenMouseLeave(document.body)\n  enrichHyperViews(document.body)\n\n\n  listenClick(async function(target: HyperView, action: string) {\n    // console.log(\"CLICK\", target.id, action)\n    runAction(target, action)\n  })\n\n  listenDblClick(async function(target: HyperView, action: string) {\n    // console.log(\"DBLCLICK\", target.id, action)\n    runAction(target, action)\n  })\n\n  listenKeydown(async function(target: HyperView, action: string) {\n    // console.log(\"KEYDOWN\", target.id, action)\n    runAction(target, action)\n  })\n\n  listenKeyup(async function(target: HyperView, action: string) {\n    // console.log(\"KEYUP\", target.id, action)\n    runAction(target, action)\n  })\n\n  listenFormSubmit(async function(target: HyperView, action: string, form: FormData) {\n    // console.log(\"FORM\", target.id, action, form)\n    runAction(target, action, form)\n  })\n\n  listenChange(async function(target: HyperView, action: string) {\n    runAction(target, action)\n  })\n\n  function onStartedTyping(target: HyperView) {\n    if (target.concurrency == \"Replace\") {\n      target.cancelActiveRequest()\n    }\n  }\n\n  listenInput(onStartedTyping, async function(target: HyperView, action: string) {\n    runAction(target, action)\n  })\n}\n\n\n\nfunction enrichHyperViews(node: HTMLElement): void {\n  // enrich all the hyperviews\n  node.querySelectorAll(\"[id]\").forEach((element: HyperView) => {\n    element.runAction = function(action: string) {\n      runAction(this, action)\n    }.bind(element)\n\n    element.concurrency = element.dataset.concurrency || \"Drop\"\n\n    element.cancelActiveRequest = function() {\n      if (element.activeRequest && !element.activeRequest?.isCancelled) {\n        element.activeRequest.isCancelled = true\n      }\n    }\n\n    dispatchContent(node)\n  })\n}\n\nfunction dispatchContent(node: HTMLElement): void {\n  let event = new Event(\"hyp-content\", { bubbles: true })\n  node.dispatchEvent(event)\n}\n\ndocument.addEventListener(\"DOMContentLoaded\", init)\n\n\n\n\n// Should we connect to the socket or not?\nconst sock = new SocketConnection()\nsock.connect()\nsock.addEventListener(\"update\", (ev: CustomEvent<Update>) => handleUpdate(ev.detail))\nsock.addEventListener(\"response\", (ev: CustomEvent<Update>) => handleResponse(ev.detail))\nsock.addEventListener(\"redirect\", (ev: CustomEvent<Redirect>) => handleRedirect(ev.detail))\n\n\n\n\n\ntype VNode = {\n  // One of three value types are used:\n  // - The tag name of the element\n  // - \"text\" if text node\n  // - \"comment\" if comment node\n  type: string\n\n  // An object whose key/value pairs are the attribute\n  // name and value, respectively\n  attributes: [string: string]\n\n  // Is set to `true` if a node is an `svg`, which tells\n  // Omdomdom to treat it, and its children, as such\n  isSVGContext: Boolean\n\n  // The content of a \"text\" or \"comment\" node\n  content: string\n\n  // An array of virtual node children\n  children: Array<VNode>\n\n  // The real DOM node\n  node: Node\n}\n\n\n\n\n\ndeclare global {\n  interface Window {\n    Hyperbole?: HyperboleAPI;\n  }\n}\n\nexport interface HyperboleAPI {\n  runAction(target: HTMLElement, action: string, form?: FormData): Promise<void>\n  action(con: string, ...params: any[]): string\n  hyperView(viewId: ViewId): HyperView | undefined\n  parseMetadata(input: string): Metadata\n  socket: SocketConnection\n}\n\n\n\n\nexport interface HyperView extends HTMLElement {\n  runAction(target: HTMLElement, action: string, form?: FormData): Promise<void>\n  activeRequest?: Request\n  cancelActiveRequest(): void\n  concurrency: ConcurrencyMode\n  _timeout?: any\n}\n\ntype ConcurrencyMode = string\n\n\nwindow.Hyperbole =\n{\n  runAction: runAction,\n  parseMetadata: parseMetadata,\n  action: function(con, ...params: any[]) {\n    let ps = params.reduce((str, param) => str + \" \" + JSON.stringify(param), \"\")\n    return con + ps\n  },\n  hyperView: function(viewId) {\n    let element = document.getElementById(viewId) as any\n    if (!element?.runAction) {\n      console.error(\"Element id=\" + viewId + \" was not a HyperView\")\n      return undefined\n    }\n    return element\n  },\n  socket: sock\n}\n","\nimport { ViewId, Metadata } from './message'\n\n\n\nexport type Response = {\n  meta: Metadata\n  body: ResponseBody\n}\n\nexport type ResponseBody = string\n\nexport function parseResponse(res: ResponseBody): LiveUpdate {\n  const parser = new DOMParser()\n  const doc = parser.parseFromString(res, 'text/html')\n  const css = doc.querySelector(\"style\") as HTMLStyleElement\n  const content = doc.querySelector(\"div\") as HTMLElement\n\n  return {\n    content: content,\n    css: css\n  }\n}\n\nexport type LiveUpdate = {\n  content: HTMLElement\n  css: HTMLStyleElement | null\n}\n\n\nexport class FetchError extends Error {\n  viewId: ViewId\n  body: string\n  constructor(viewId: ViewId, msg: string, body: string) {\n    super(msg)\n    this.viewId = viewId\n    this.name = \"Fetch Error\"\n    this.body = body\n  }\n}\n","\nexport function setQuery(query: string) {\n  if (query != currentQuery()) {\n    if (query != \"\") query = \"?\" + query\n    let url = location.pathname + query\n    // console.log(\"history.replaceState(\", url, \")\")\n    window.history.replaceState({}, \"\", url)\n  }\n}\n\nfunction currentQuery(): string {\n  const query = window.location.search;\n  return query.startsWith('?') ? query.substring(1) : query;\n}\n"],"names":["debounce","function_","wait","options","TypeError","RangeError","immediate","storedContext","storedArguments","timeoutId","timestamp","result","run","callContext","callArguments","undefined","apply","later","last","Date","now","setTimeout","debounced","arguments_","this","Object","getPrototypeOf","Error","callNow","defineProperty","get","clear","clearTimeout","flush","trigger","module","exports","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","__webpack_modules__","hasProperty","obj","prop","prototype","hasOwnProperty","call","forEach","items","fn","length","idx","insertBefore","parent","child","refNode","node","_slicedToArray","arr","i","Array","isArray","_arrayWithHoles","_i","Symbol","iterator","_s","_e","_x","_r","_arr","_n","_d","next","done","push","value","err","return","_iterableToArrayLimit","o","minLen","_arrayLikeToArray","n","toString","slice","constructor","name","from","test","_unsupportedIterableToArray","_nonIterableRest","len","arr2","Types","DomProperties","createRecord","attrName","propName","type","_ref","_ref2","attr","property","_ref3","_ref4","Namespace","setProperty","element","style","toLowerCase","removeAttribute","parsed","parseInt","isNaN","indexOf","patch","template","vNode","rootNode","parentNode","contentChanged","content","replaceChild","assignVNode","removedAttributes","changedAttributes","attributes","oldValue","nextValue","_attrName","_oldValue","_nextValue","propertyRecord","removeAttributes","startsWith","setAttributeNS","setAttribute","setAttributes","updateAttributes","templateChildrenLength","children","vNodeChildrenLength","vNodeKeyMap","map","_","key","console","warn","keyIsValid","createKeyMap","nextChildren","templateChild","childNodes","keyedChild","vNodeChild","appendChild","childNodesLength","delta","removeChild","patchChildren","create","processedDOMString","isSVGContext","arguments","trim","replace","DOMParser","parseFromString","body","isRoot","tagName","numChildNodes","nodeType","isSVG","reduce","getBaseAttributes","attrValue","getAttribute","getPropertyValues","getAttributes","textContent","takeWhileMap","pred","lines","output","line","a","toMetadata","meta","cookies","filter","m","error","metaValue","query","pageTitle","events","metaValuesAll","parseRemoteEvent","actions","parseAction","parseMetadata","input","parseMeta","split","metas","find","match","data","breakNextSegment","detail","JSON","parse","viewId","action","ix","message","toSearch","form","params","URLSearchParams","append","globalRequestId","encodedParam","param","sanitizeParam","defaultAddress","window","location","protocol","host","pathname","ProtocolError","description","super","listenKeyEvent","event","cb","document","addEventListener","e","source","target","datasetKey","dataset","preventDefault","nearestTarget","listenBubblingEvent","closest","listenLoad","querySelectorAll","load","delay","onLoad","onload","CustomEvent","bubbles","dispatchEvent","listenMouseEnter","onMouseEnter","onmouseenter","listenMouseLeave","onMouseLeave","onmouseleave","targetId","targetData","id","nearestTargetId","getElementById","rootStyles","PACKAGE","log","version","addedRulesIndex","Set","async","runAction","activeRequest","isCancelled","concurrency","_timeout","classList","add","state","req","requestId","msg","reqId","decodeURI","cookie","search","actionMessage","sock","sendAction","handleUpdate","res","targetViewId","update","doc","css","querySelector","parseResponse","src","rules","sheet","cssRules","rule","has","cssText","insertRule","addCSS","old","newTarget","dispatchContent","runMetadata","applyCookies","focused","focus","val","checkbox","checked","fixInputs","enrichHyperViews","substring","currentQuery","url","history","replaceState","setQuery","title","remoteEvent","view","Hyperbole","hyperView","bind","cancelActiveRequest","Event","innerText","createElement","onsubmit","formData","FormData","onchange","oninput","startedTyping","debouncedCallback","hasEverConnected","isConnected","reconnectDelay","queue","EventTarget","connect","addr","WebSocket","onConnectError","ev","onSocketError","socket","_event","removeEventListener","runQueue","onMessage","header","join","renderActionMessage","send","pop","command","rest","index","dropWhile","l","requireMeta","up","parseUpdate","parseRedirect","disconnect","close","remove","handleResponse","handleRedirect","red","href","con","str","stringify"],"sourceRoot":""}
+{
+  "version": 3,
+  "sources": ["../node_modules/omdomdom/src/utilities/index.js", "../node_modules/omdomdom/src/parsers/index.js", "../node_modules/omdomdom/src/attributes/records.js", "../node_modules/omdomdom/src/attributes/set-property.js", "../node_modules/omdomdom/src/attributes/index.js", "../node_modules/omdomdom/src/children/index.js", "../node_modules/omdomdom/src/omdomdom.js", "../src/lib.ts", "../src/message.ts", "../src/action.ts", "../src/sockets.ts", "../node_modules/debounce/index.js", "../src/hyperview.ts", "../src/events.ts", "../src/browser.ts", "../src/response.ts", "../package.json", "../src/index.ts"],
+  "sourcesContent": ["const DATA_KEY_ATTRIBUTE = \"data-key\"\n\n/**\n * Checks if the object property exists.\n * @param {Object.<string, any>} obj\n * @param {string} prop\n * @returns {boolean}\n */\nexport const hasProperty = (obj, prop) =>\n  Object.prototype.hasOwnProperty.call(obj, prop)\n\n/**\n * Checks if a property in a keyMap is unique. if not, it's skipped.\n * @param {Object.<string, VirtualNode>} map\n * @param {string} key\n * @returns {boolean}\n */\nconst keyIsValid = (map, key) => {\n  if (!key) return false\n\n  if (hasProperty(map, key)) {\n    // eslint-disable-next-line no-console\n    console.warn(\n      \"[OmDomDom]: Children with duplicate keys detected. Children with duplicate keys will be skipped, resulting in dropped node references. Keys must be unique and non-indexed.\"\n    )\n    return false\n  }\n\n  return true\n}\n\n/**\n * lodash forEach, basically.\n * If `false` is explicitly returned, break the loop.\n * @param {[]} items\n * @param fn\n */\nexport const forEach = (items, fn) => {\n  const length = items.length\n  let idx = -1\n\n  if (!length) return\n\n  while (++idx < length) {\n    if (fn(items[idx], idx) === false) break\n  }\n}\n\n/**\n * Generates a <key: vNode> map of a virtual node list.\n * @param {VirtualNode[]} children\n * @returns {Object.<string, VirtualNode>|undefined}\n */\nexport const createKeyMap = (children) => {\n  const map = {}\n\n  forEach(children, (child) => {\n    const key = child.attributes[DATA_KEY_ATTRIBUTE]\n    if (keyIsValid(map, key)) {\n      map[key] = child\n    }\n  })\n\n  // Cheap way to check if the map contains keys,\n  // and if so, returns the map on the first iteration.\n  for (const _ in map) {\n    return map\n  }\n}\n\nexport const insertBefore = (parent, child, refNode) => {\n  return parent.node.insertBefore(child.node, refNode)\n}\n\n/**\n * Transfers properties from one virtual node to another.\n * @param {VirtualNode} template\n * @param {VirtualNode} vNode\n */\nexport const assignVNode = (template, vNode) => {\n  for (let property in template) {\n    vNode[property] = template[property]\n  }\n}\n", "/**\n * Convert stringified HTML into valid HTML, stripping all extra spaces.\n * @param {string} htmlString\n */\nexport const toHTML = (htmlString) => {\n  /**\n   * Remove all extraneous whitespace:\n   * - From the beginning + end of the document fragment\n   * - If there's more than one space before a left tag bracket, replace them with one\n   * - If there's more than one space before a right tag bracket, replace them with one\n   */\n  const processedDOMString = htmlString\n    .trim()\n    .replace(/\\s+</g, \"<\")\n    .replace(/>\\s+/g, \">\")\n\n  const parser = new DOMParser()\n  const context = parser.parseFromString(processedDOMString, \"text/html\")\n\n  return context.body\n}\n", "import { forEach } from \"../utilities\"\n\nconst Types = { STRING: \"string\", INT: \"number\", BOOL: \"boolean\" }\nconst DomProperties = {}\n\n/**\n * Creates a new record for DomProperties\n * @param {string} attrName\n * @param {string} propName\n * @param {string} type\n */\nconst createRecord = (attrName, propName, type) => ({\n  attrName,\n  propName,\n  type,\n})\n\n// Set string records\nconst stringProps = [\n  // Style is a special snowflake, and needs an extra property to set its text\n  // value. This is less confusing and achieves the same result with one reflow,\n  // compared to a new reflow for each Element.style[styleProperty] setter.\n  [\"style\", \"cssText\"],\n  [\"class\", \"className\"],\n]\nforEach(stringProps, ([attr, property]) => {\n  DomProperties[attr] = createRecord(attr, property || attr, Types.STRING)\n})\n\n// Set boolean records\nconst booleanProps = [\n  \"autofocus\",\n  \"draggable\",\n  \"hidden\",\n  \"checked\",\n  \"multiple\",\n  \"muted\",\n  \"selected\",\n]\nforEach(booleanProps, (attr) => {\n  DomProperties[attr] = createRecord(attr, attr, Types.BOOL)\n})\n\n// Set Integer records\nconst integerProps = [[\"tabindex\", \"tabIndex\"]]\nforEach(integerProps, ([attr, property]) => {\n  DomProperties[attr] = createRecord(attr, property, Types.INT)\n})\n\n/**\n * Attributes with these namespaces require `setAttributeNS`\n * @type {Object.<string, string>}\n */\nconst Namespace = {\n  xlink: {\n    prefix: \"xlink:\",\n    resource: \"http://www.w3.org/1999/xlink\",\n  },\n  xml: {\n    prefix: \"xml:\",\n    resource: \"http://www.w3.org/XML/1998/namespace\",\n  },\n}\n\nexport { Types, Namespace, DomProperties }\n", "import { Types, DomProperties } from \"./records\"\n\n/**\n * Set a given attribute as a property, if it has a property equivalent\n * @param {HTMLElement} node\n * @param {string|number|boolean} type\n * @param {string} prop\n * @param {*} value\n */\nexport const setProperty = (element, type, prop, value) => {\n  switch (type) {\n    case Types.STRING: {\n      if (prop === DomProperties.style.propName) {\n        if (value === null) {\n          element.style[prop] = \"\"\n        } else {\n          element.style[prop] = value\n        }\n      } else if (value === null) {\n        element[prop] = \"\"\n      } else {\n        element[prop] = value\n      }\n      break\n    }\n\n    case Types.INT: {\n      if (value === null) {\n        const attr = prop.toLowerCase()\n        // The attribute needs to be removed to reset the property,\n        // otherwise the value coerced + reflected onto the attribute.\n        element.removeAttribute(attr)\n      } else if (value === \"0\") {\n        element[prop] = 0\n      } else if (value === \"-1\") {\n        element[prop] = -1\n      } else {\n        const parsed = parseInt(value, 10)\n        if (!isNaN(parsed)) {\n          element[prop] = parsed\n        }\n      }\n      break\n    }\n\n    case Types.BOOL: {\n      if ([\"\", \"true\"].indexOf(value) < 0) {\n        element[prop] = false\n      } else {\n        element[prop] = true\n      }\n      break\n    }\n\n    default:\n      break\n  }\n}\n", "import { hasProperty, forEach } from \"../utilities\"\nimport { Namespace, DomProperties, Types } from \"./records\"\nimport { setProperty } from \"./set-property\"\n\n/**\n * Removes stale attributes from the element.\n * @param {HTMLElement} vNode\n * @param {string[]} attributes\n */\nconst removeAttributes = (vNode, attributes) => {\n  forEach(attributes, (attrName) => {\n    if (hasProperty(DomProperties, attrName)) {\n      const propertyRecord = DomProperties[attrName]\n      setProperty(\n        vNode.node,\n        propertyRecord.type,\n        propertyRecord.propName,\n        null\n      )\n    } else {\n      if (attrName in vNode.node) {\n        setProperty(vNode.node, Types.STRING, attrName, null)\n      }\n      vNode.node.removeAttribute(attrName)\n    }\n\n    delete vNode.attributes[attrName]\n  })\n}\n\n/**\n * Adds attributes to the element.\n * @param {VirtualNode} vNode\n * @param {Object.<string, string>} attributes\n */\nconst setAttributes = (vNode, attributes) => {\n  for (let attrName in attributes) {\n    const value = attributes[attrName]\n    vNode.attributes[attrName] = value\n\n    if (hasProperty(DomProperties, attrName)) {\n      const propertyRecord = DomProperties[attrName]\n      setProperty(\n        vNode.node,\n        propertyRecord.type,\n        propertyRecord.propName,\n        value\n      )\n      continue\n    }\n\n    // Set namespaced properties using setAttributeNS\n    if (attrName.startsWith(Namespace.xlink.prefix)) {\n      vNode.node.setAttributeNS(Namespace.xlink.resource, attrName, value)\n      continue\n    }\n\n    if (attrName.startsWith(Namespace.xml.prefix)) {\n      vNode.node.setAttributeNS(Namespace.xml.resource, attrName, value)\n      continue\n    }\n\n    if (attrName in vNode.node) {\n      setProperty(vNode.node, Types.STRING, attrName, value)\n    }\n    vNode.node.setAttribute(attrName, value || \"\")\n  }\n}\n\n/**\n * Checks property-based attributes. If the attribute exists,\n * then we should set its property value.\n * @param {HTMLElement} element\n * @param {Object.<string, string>} attributes\n */\nconst getPropertyValues = (element, attributes) => {\n  for (let attrName in DomProperties) {\n    const propertyRecord = DomProperties[attrName]\n    const propName = propertyRecord.propName\n    const attrValue = element.getAttribute(attrName)\n\n    if (attrName === DomProperties.style.attrName) {\n      attributes[attrName] = element.style[propName]\n    } else if (typeof attrValue === \"string\") {\n      attributes[attrName] = attrValue\n    }\n  }\n}\n\n/**\n * Gets non-property attributes.\n * @param {HTMLElement} element\n * @returns {Object.<string, string>}\n */\nconst getBaseAttributes = (element) => {\n  return Array.prototype.reduce.call(\n    element.attributes,\n    (attributes, attrName) => {\n      if (!hasProperty(DomProperties, attrName.name)) {\n        attributes[attrName.name] = attrName.value\n      }\n      return attributes\n    },\n    {}\n  )\n}\n\n/**\n * Gets all attributes.\n * @param {HTMLElement} element\n * @returns {Object.<string, string>}\n */\nexport const getAttributes = (element) => {\n  const attributes = getBaseAttributes(element)\n  getPropertyValues(element, attributes)\n\n  return attributes\n}\n\n/**\n * Reconcile attributes from vNode to template\n * @param {VirtualNode} template\n * @param {VirtualNode} vNode\n */\nexport const updateAttributes = (template, vNode) => {\n  let removedAttributes = []\n  let changedAttributes = {}\n\n  // Get stale attributes\n  for (let attrName in vNode.attributes) {\n    const oldValue = vNode.attributes[attrName]\n    const nextValue = template.attributes[attrName]\n    if (oldValue === nextValue) continue\n\n    if (typeof nextValue === \"undefined\") {\n      removedAttributes.push(attrName)\n    }\n  }\n\n  // Get changed or new attributes\n  for (let attrName in template.attributes) {\n    const oldValue = vNode.attributes[attrName]\n    const nextValue = template.attributes[attrName]\n    if (oldValue === nextValue) continue\n\n    if (typeof nextValue !== \"undefined\") {\n      changedAttributes[attrName] = nextValue\n    }\n  }\n\n  // Add and remove attributes\n  removeAttributes(vNode, removedAttributes)\n  setAttributes(vNode, changedAttributes)\n}\n", "import { forEach, createKeyMap, insertBefore } from \"../utilities\"\n\nconst DATA_KEY_ATTRIBUTE = \"data-key\"\n\n/**\n * Both template and vNode have arrays of virtual nodes. Diff them.\n * @param {VirtualNode} template - new virtual node tree.\n * @param {VirtualNode} vNode - existing virtual node tree.\n */\nexport function patchChildren(template, vNode, patch) {\n  const templateChildrenLength = template.children.length\n  const vNodeChildrenLength = vNode.children.length\n\n  if (!templateChildrenLength && !vNodeChildrenLength) return\n\n  const vNodeKeyMap = createKeyMap(vNode.children)\n  let nextChildren = Array(templateChildrenLength)\n\n  if (vNodeKeyMap !== undefined) {\n    forEach(template.children, (templateChild, idx) => {\n      const childNodes = vNode.node.childNodes\n      const key = templateChild.attributes[DATA_KEY_ATTRIBUTE]\n\n      if (Object.prototype.hasOwnProperty.call(vNodeKeyMap, key)) {\n        const keyedChild = vNodeKeyMap[key]\n\n        if (Array.prototype.indexOf.call(childNodes, keyedChild.node) !== idx) {\n          insertBefore(vNode, keyedChild, childNodes[idx])\n        }\n\n        nextChildren[idx] = keyedChild\n\n        // Remove entry to prevent dupes\n        delete vNodeKeyMap[key]\n        patch(templateChild, nextChildren[idx])\n      } else {\n        insertBefore(vNode, templateChild, childNodes[idx])\n        nextChildren[idx] = templateChild\n      }\n    })\n  } else {\n    forEach(template.children, (templateChild, idx) => {\n      const vNodeChild = vNode.children[idx]\n\n      if (typeof vNodeChild !== \"undefined\") {\n        patch(templateChild, vNodeChild)\n        nextChildren[idx] = vNodeChild\n      } else {\n        vNode.node.appendChild(templateChild.node)\n        nextChildren[idx] = templateChild\n      }\n    })\n  }\n\n  vNode.children = nextChildren\n\n  // Remove any real nodes that are left over from the diff\n  let childNodesLength = vNode.node.childNodes.length\n  let delta = childNodesLength - templateChildrenLength\n\n  if (delta > 0) {\n    while (delta > 0) {\n      vNode.node.removeChild(vNode.node.childNodes[childNodesLength - 1])\n      childNodesLength--\n      delta--\n    }\n  }\n}\n", "import { forEach, assignVNode } from \"./utilities\"\nimport { toHTML } from \"./parsers\"\nimport { updateAttributes, getAttributes } from \"./attributes\"\nimport { patchChildren } from \"./children\"\n\n/**\n * Object representation of a DOM element.\n * @typedef VirtualNode\n * @type {Object}\n * @property {string} type - The type of node. E.g., tag name, \"comment\", or \"text\".\n * @property {Object.<string, string>} attributes - List of attributes, if any.\n * @property {TextNode|CommentNode} content - Text or comment content, if any.\n * @property {VirtualNode[]} children - Child virtual nodes, if any.\n * @property {HTMLElement} node - The corresponding DOM element.\n * @property {boolean} isSVGContext\n */\n\n/**\n * Reconcile differences between two virtual DOM trees.\n * @param {VirtualNode} template - new virtual node tree.\n * @param {VirtualNode} vNode - existing virtual node tree.\n * @param {Node} rootNode - the HTML element containing the current node context\n */\nexport const patch = (template, vNode, rootNode) => {\n  // This came happen if a null result is given for either\n  // template or vNode. Impossible to compare - return.\n  if (!template || !vNode) return\n\n  rootNode = rootNode || vNode.node.parentNode\n  const contentChanged = template.content && template.content !== vNode.content\n\n  // If the type or content changed, replace the node completely\n  if (template.type !== vNode.type || contentChanged) {\n    rootNode.replaceChild(template.node, vNode.node)\n    return assignVNode(template, vNode)\n  }\n\n  // Update attributes, if any\n  updateAttributes(template, vNode)\n\n  // Diff child nodes recursively\n  patchChildren(template, vNode, patch)\n}\n\n/**\n * Renders a node into the given root context. This happens one time,\n * when a component is first rendered.\n * All subsequent renders are the result of reconciliation.\n * @param {VirtualNode} vDOM\n * @param {ShadowRoot|HTMLElement} root\n */\nexport const render = (vNode, root) => {\n  root.appendChild(vNode.node)\n}\n\n/**\n * Creates a new virtual DOM from a root node.\n * @param {HTMLElement|ShadowRoot|HTMLBodyElement} node\n * @param {boolean} isSVGContext\n * @returns {VirtualNode}\n */\nexport const create = (node, isSVGContext = false) => {\n  if (typeof node === \"string\") {\n    node = toHTML(node)\n  }\n\n  const isRoot = node.tagName === \"BODY\"\n  const childNodes = node.childNodes\n  const numChildNodes = childNodes ? childNodes.length : 0\n\n  // toHTML returns a `body` tag as its root node, but we want the first child only\n  if (isRoot) {\n    if (numChildNodes > 1) {\n      throw new Error(\n        \"[OmDomDom]: Your element should not have more than one root node.\"\n      )\n    } else if (numChildNodes === 0) {\n      throw new Error(\n        \"[OmDomDom]: Your element should have at least one root node.\"\n      )\n    } else {\n      return create(childNodes[0])\n    }\n  }\n\n  const type =\n    node.nodeType === 3\n      ? \"text\"\n      : node.nodeType === 8\n      ? \"comment\"\n      : node.tagName.toLowerCase()\n  const isSVG = isSVGContext || type === \"svg\"\n  const attributes = node.nodeType === 1 ? getAttributes(node) : {}\n  const content = numChildNodes > 0 ? null : node.textContent\n\n  // Recursively build children\n  const children = Array(numChildNodes)\n  forEach(childNodes, (child, idx) => {\n    children[idx] = create(child, isSVG)\n  })\n\n  return { type, attributes, children, content, node, isSVGContext: isSVG }\n}\n", "\n\nexport function takeWhileMap<T, A>(pred: (val: T) => A | undefined, lines: T[]): A[] {\n  var output = []\n  for (var line of lines) {\n    let a = pred(line)\n    if (a)\n      output.push(a)\n    else\n      break;\n  }\n\n  return output\n}\n\nexport function dropWhile<T, A>(pred: (val: T) => A | undefined, lines: T[]): T[] {\n  let index = 0;\n  while (index < lines.length && pred(lines[index])) {\n    index++;\n  }\n  return lines.slice(index);\n}\n\n", "\nimport { takeWhileMap, dropWhile } from \"./lib\"\n\n\n\nexport type Meta = { key: string, value: string }\nexport type ViewId = string\nexport type RequestId = number\nexport type EncodedAction = string\nexport type ViewState = string\n\nexport type RemoteEvent = { name: string, detail: unknown }\n\n\nexport function renderMetas(meta: Meta[]): string {\n  return meta.map(m => m.key + \": \" + m.value).join('\\n')\n}\n\nexport type Metadata = {\n  cookies?: string[]\n  // redirect?: string\n  error?: string\n  query?: string\n  events?: RemoteEvent[]\n  actions?: [ViewId, EncodedAction][],\n  pageTitle?: string\n}\n\n\nexport function toMetadata(meta: Meta[]): Metadata {\n\n  return {\n    cookies: meta.filter(m => m.key == \"Cookie\").map(m => m.value),\n    // redirect: metaValue(\"Redirect\", meta),\n    error: metaValue(\"Error\", meta),\n    query: metaValue(\"Query\", meta),\n    pageTitle: metaValue(\"PageTitle\", meta),\n    events: metaValuesAll(\"Event\", meta).map(parseRemoteEvent),\n    actions: metaValuesAll(\"Trigger\", meta).map(parseAction),\n  }\n}\n\n// viewId: meta.find(m => m.key == \"VIEW-ID\")?.value,\n\nexport function parseMetadata(input: string): Metadata {\n  let metas = takeWhileMap(parseMeta, input.trim().split(\"\\n\"))\n  return toMetadata(metas)\n}\n\n\nexport function metaValue(key: string, metas: Meta[]): string | undefined {\n  return metas.find(m => m.key == key)?.value\n}\n\nexport function metaValuesAll(key: string, metas: Meta[]): string[] {\n  return metas.filter(m => m.key == key).map(m => m.value)\n}\n\nexport type SplitMessage = {\n  command: string,\n  metas: Meta[],\n  rest: string[]\n}\n\n\nexport function splitMessage(message: string): SplitMessage {\n  let lines = message.split(\"\\n\")\n  let command: string = lines[0]\n  let metas: Meta[] = takeWhileMap(parseMeta, lines.slice(1))\n  // console.log(\"Split Metadata\", lines.length)\n  // console.log(\" [0]\", lines[0])\n  // console.log(\" [1]\", lines[1])\n  let rest = dropWhile(l => l == \"\", lines.slice(metas.length + 1))\n\n  return { command, metas, rest }\n}\n\nexport function parseMeta(line: string): Meta | undefined {\n  let match = line.match(/^(\\w+)\\: (.*)$/)\n  if (match) {\n    return {\n      key: match[1],\n      value: match[2]\n    }\n  }\n}\n\n\nexport function parseRemoteEvent(input: string): RemoteEvent {\n  let [name, data] = breakNextSegment(input)\n  return {\n    name,\n    detail: JSON.parse(data)\n  }\n}\n\nexport function parseAction(input: string): [ViewId, string] {\n  let [viewId, action] = breakNextSegment(input)\n  return [viewId, action]\n}\n\nfunction breakNextSegment(input: string): [string, string] {\n  let ix = input.indexOf('|')\n  if (ix === -1) {\n    let err = new Error(\"Bad Encoding, Expected Segment\")\n    err.message = input\n    throw err\n  }\n  return [input.slice(0, ix), input.slice(ix + 1)]\n}\n\n", "\nimport { Meta, ViewId, RequestId, EncodedAction, ViewState } from \"./message\"\nimport * as message from \"./message\"\n\n\n\nexport type ActionMessage = {\n  viewId: ViewId\n  action: EncodedAction\n  requestId: RequestId\n  state?: ViewState\n  meta: Meta[]\n  form: URLSearchParams | undefined\n}\n\n\n\n\nexport function actionMessage(id: ViewId, action: EncodedAction, state: ViewState | undefined, reqId: RequestId, form?: FormData): ActionMessage {\n  let meta: Meta[] = [\n    { key: \"Cookie\", value: decodeURI(document.cookie) },\n    { key: \"Query\", value: window.location.search }\n  ]\n\n  return { viewId: id, action, state, requestId: reqId, meta, form: toSearch(form) }\n}\n\nexport function toSearch(form?: FormData): URLSearchParams | undefined {\n  if (!form) return undefined\n\n  const params = new URLSearchParams()\n\n  form.forEach((value, key) => {\n    params.append(key, value as string)\n  })\n\n  return params\n}\n\nexport function renderActionMessage(msg: ActionMessage): string {\n  let header = [\n    \"|ACTION|\",\n    \"ViewId: \" + msg.viewId,\n    \"Action: \" + msg.action,\n  ]\n\n\n  if (msg.state) {\n    header.push(\"State: \" + msg.state)\n  }\n\n  header.push(\"RequestId: \" + msg.requestId)\n\n  return [\n    header.join('\\n'),\n    message.renderMetas(msg.meta),\n  ].join('\\n') + renderForm(msg.form)\n}\n\n\nexport function renderForm(form: URLSearchParams | undefined): string {\n  if (!form) return \"\"\n  return \"\\n\\n\" + form\n}\n\nlet globalRequestId: RequestId = 0\n\nexport type Request = {\n  requestId: RequestId\n  isCancelled: boolean\n}\n\nexport function newRequest(): Request {\n  let requestId = ++globalRequestId\n  return { requestId, isCancelled: false }\n}\n\n\n\n// Sanitized Encoding ------------------------------------\n\nexport function encodedParam(action: string, param: string): string {\n  return action + ' ' + sanitizeParam(param)\n}\n\nfunction sanitizeParam(param: string): string {\n  if (param == \"\") {\n    return \"|\"\n  }\n\n  return param.replace(/_/g, \"\\\\_\").replace(/\\s+/g, \"_\")\n}\n", "import { ActionMessage, renderActionMessage } from './action'\nimport { ResponseBody } from \"./response\"\nimport * as message from \"./message\"\nimport { ViewId, RequestId, EncodedAction, metaValue, Metadata, RemoteEvent } from \"./message\"\n\nconst protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';\nconst defaultAddress = `${protocol}//${window.location.host}${window.location.pathname}`\n\ninterface SocketConnectionEventMap {\n  \"update\": CustomEvent<Update>;\n  \"response\": CustomEvent<Update>;\n  \"redirect\": CustomEvent<Redirect>;\n  \"trigger\": CustomEvent<Trigger>;\n  \"event\": CustomEvent<JSEvent>;\n}\n\nexport class SocketConnection {\n  socket: WebSocket\n\n  hasEverConnected: boolean = false\n  isConnected: boolean = false\n  reconnectDelay: number = 0\n  queue: ActionMessage[] = []\n  events: EventTarget\n\n  constructor(addr = defaultAddress) {\n    this.events = new EventTarget()\n    const sock = new WebSocket(addr)\n    this.socket = sock\n  }\n\n  connect(addr = defaultAddress, createSocket = false) {\n    const sock = createSocket ? new WebSocket(addr) : this.socket\n    this.socket = sock\n\n    function onConnectError(ev: Event) {\n      console.error(\"Connect Error\", ev)\n    }\n\n    function onSocketError(ev: Event) {\n      console.error(\"Socket Error\", ev)\n    }\n\n\n    // initial connection errors\n    sock.addEventListener('error', onConnectError)\n\n    sock.addEventListener('open', (_event) => {\n      console.log(\"Websocket Connected\")\n\n      if (this.hasEverConnected) {\n        document.dispatchEvent(new Event(\"hyp-socket-reconnect\"))\n      }\n\n      this.isConnected = true\n      this.hasEverConnected = true\n      this.reconnectDelay = 1000\n      sock.removeEventListener('error', onConnectError)\n      sock.addEventListener('error', onSocketError)\n\n      document.dispatchEvent(new Event(\"hyp-socket-connect\"))\n\n      this.runQueue()\n    })\n\n    sock.addEventListener('close', _ => {\n      console.log(\"CLOSE SOCKET\")\n      if (this.isConnected) {\n        document.dispatchEvent(new Event(\"hyp-socket-disconnect\"))\n      }\n\n      this.isConnected = false\n      sock.removeEventListener('error', onSocketError)\n\n      // attempt to reconnect in 1s\n      if (this.hasEverConnected) {\n        console.log(\"Reconnecting in \" + (this.reconnectDelay / 1000) + \"s\")\n        setTimeout(() => this.connect(addr, true), this.reconnectDelay)\n      }\n\n      sock.removeEventListener('error', onSocketError)\n    })\n\n    sock.addEventListener('message', ev => this.onMessage(ev))\n  }\n\n  async sendAction(action: ActionMessage) {\n    if (this.isConnected) {\n      let msg = renderActionMessage(action)\n      this.socket.send(msg)\n    }\n    else {\n      this.queue.push(action)\n    }\n  }\n\n  private runQueue() {\n    // send all messages queued while disconnected \n    let next: ActionMessage | undefined = this.queue.pop()\n    if (next) {\n      console.log(\"runQueue: \", next)\n      this.sendAction(next)\n      this.runQueue()\n    }\n  }\n\n\n  // full responses will never be sent over!\n  private onMessage(event: MessageEvent) {\n    let { command, metas, rest } = message.splitMessage(event.data)\n    // console.log(\"MESSAGE\", command, metas, rest)\n\n    let requestId = parseInt(requireMeta(\"RequestId\"), 0)\n\n    function requireMeta(key: string): string {\n      let val = metaValue(key, metas)\n      if (!val) throw new ProtocolError(\"Missing Required Metadata: \" + key, event.data)\n      return val\n    }\n\n    function parseResponse(rest: string[]): Update {\n      let viewId = requireMeta(\"ViewId\")\n      let action = requireMeta(\"Action\")\n      return {\n        requestId,\n        targetViewId: undefined,\n        viewId,\n        action,\n        meta: message.toMetadata(metas),\n        body: rest.join(\"\\n\"),\n      }\n    }\n\n    function parseUpdate(rest: string[]): Update {\n      let up = parseResponse(rest)\n      // add the TargetViewId\n      up.targetViewId = metaValue(\"TargetViewId\", metas)\n      return up\n    }\n\n    function parseRedirect(rest: string[]): Redirect {\n      let url = rest[0]\n      return {\n        requestId,\n        meta: message.toMetadata(metas),\n        url\n      }\n    }\n\n    function parseTrigger(rest: string[]): Trigger {\n      let { requestId, meta, viewId, action } = parseResponse(rest)\n      let [targetViewId, targetAction] = message.parseAction(requireMeta(\"Trigger\"))\n      return { requestId, meta, viewId, action, targetViewId, targetAction }\n    }\n\n    function parseEvent(rest: string[]): JSEvent {\n      let { requestId, meta, viewId, action } = parseResponse(rest)\n      let event = message.parseRemoteEvent(requireMeta(\"Event\"))\n      return { requestId, meta, viewId, action, event }\n    }\n\n\n    switch (command) {\n\n      case \"|UPDATE|\":\n        return this.dispatchEvent(new CustomEvent(\"update\", { detail: parseUpdate(rest) }))\n\n      case \"|RESPONSE|\":\n        return this.dispatchEvent(new CustomEvent(\"response\", { detail: parseResponse(rest) }))\n\n      case \"|REDIRECT|\":\n        return this.dispatchEvent(new CustomEvent(\"redirect\", { detail: parseRedirect(rest) }))\n\n      case \"|TRIGGER|\":\n        return this.dispatchEvent(new CustomEvent(\"trigger\", { detail: parseTrigger(rest) }))\n\n      case \"|EVENT|\":\n        return this.dispatchEvent(new CustomEvent(\"event\", { detail: parseEvent(rest) }))\n\n      default:\n        throw new ProtocolError(\"Unknown Server Command: \" + command, event.data)\n    }\n  }\n\n\n  // so what if they send remote events in the page? trigger, redirect, page title, etc...\n  // we aren't connected yet on a page thing\n\n  // private async waitMessage(reqId: RequestId, id: ViewId): Promise<ParsedResponse> {\n  //   return new Promise((resolve, reject) => {\n  //     const onMessage = (event: MessageEvent) => {\n  //       let data: string = event.data\n  //       let lines = data.split(\"\\n\").slice(1)  // drop the command line\n  //\n  //       let parsed = splitMetadata(lines)\n  //       let metadata: Metadata = parsed.metadata\n  //\n  //       if (!metadata.requestId) {\n  //         console.error(\"Missing RequestId!\", metadata, event.data)\n  //         return\n  //       }\n  //\n  //       if (metadata.requestId != reqId) {\n  //         // skip, it's not us!\n  //         return\n  //       }\n  //\n  //\n  //       // We have found our message. Remove the listener\n  //       this.socket.removeEventListener('message', onMessage)\n  //\n  //       // set the cookies. These happen automatically in http\n  //       metadata.cookies.forEach((cookie: string) => {\n  //         document.cookie = cookie\n  //       })\n  //\n  //       if (metadata.error) {\n  //         reject(new FetchError(id, metadata.error, parsed.rest.join('\\n')))\n  //         return\n  //       }\n  //\n  //       resolve(parsed)\n  //     }\n  //\n  //     this.socket.addEventListener('message', onMessage)\n  //     this.socket.addEventListener('error', reject)\n  //   })\n  // }\n\n  addEventListener<K extends keyof SocketConnectionEventMap>(e: K, cb: (ev: SocketConnectionEventMap[K]) => void) {\n    this.events.addEventListener(e,\n      // @ts-ignore: HACK\n      cb\n    )\n  }\n\n  dispatchEvent<K extends keyof SocketConnectionEventMap>(e: SocketConnectionEventMap[K]) {\n    this.events.dispatchEvent(e)\n  }\n\n  disconnect() {\n    this.isConnected = false\n    this.hasEverConnected = false\n    this.socket.close()\n  }\n}\n\n\nexport type Update = {\n  requestId: RequestId\n  meta: Metadata\n  viewId: ViewId\n  targetViewId?: ViewId\n  action: EncodedAction\n  body: ResponseBody\n}\n\nexport type Redirect = {\n  requestId: RequestId\n  meta: Metadata\n  url: string\n}\n\nexport type Trigger = {\n  requestId: RequestId\n  meta: Metadata\n  viewId: ViewId\n  action: EncodedAction\n  targetViewId: ViewId\n  targetAction: string\n}\n\nexport type JSEvent = {\n  requestId: RequestId\n  meta: Metadata\n  viewId: ViewId\n  action: EncodedAction\n  event: RemoteEvent\n}\n\nexport type MessageType = string\n\n\n// PARSING MESSAGE  ---------------------------------------\n\nexport class ProtocolError extends Error {\n  constructor(description: string, body: string) {\n    super(description + \"\\n\" + body)\n    this.name = \"ProtocolError\"\n  }\n}\n", "export default function debounce(function_, wait = 100, options = {}) {\n\tif (typeof function_ !== 'function') {\n\t\tthrow new TypeError(`Expected the first parameter to be a function, got \\`${typeof function_}\\`.`);\n\t}\n\n\tif (wait < 0) {\n\t\tthrow new RangeError('`wait` must not be negative.');\n\t}\n\n\tif (typeof options === 'boolean') {\n\t\tthrow new TypeError('The `options` parameter must be an object, not a boolean. Use `{immediate: true}` instead.');\n\t}\n\n\tconst {immediate} = options;\n\n\tlet storedContext;\n\tlet storedArguments;\n\tlet timeoutId;\n\tlet timestamp;\n\tlet result;\n\n\tfunction run() {\n\t\tconst callContext = storedContext;\n\t\tconst callArguments = storedArguments;\n\t\tstoredContext = undefined;\n\t\tstoredArguments = undefined;\n\t\tresult = function_.apply(callContext, callArguments);\n\t\treturn result;\n\t}\n\n\tfunction later() {\n\t\tconst last = Date.now() - timestamp;\n\n\t\tif (last < wait && last >= 0) {\n\t\t\ttimeoutId = setTimeout(later, wait - last);\n\t\t} else {\n\t\t\ttimeoutId = undefined;\n\n\t\t\tif (!immediate) {\n\t\t\t\tresult = run();\n\t\t\t}\n\t\t}\n\t}\n\n\tconst debounced = function (...arguments_) {\n\t\tif (\n\t\t\tstoredContext\n\t\t\t&& this !== storedContext\n\t\t\t&& Object.getPrototypeOf(this) === Object.getPrototypeOf(storedContext)\n\t\t) {\n\t\t\tthrow new Error('Debounced method called with different contexts of the same prototype.');\n\t\t}\n\n\t\tstoredContext = this; // eslint-disable-line unicorn/no-this-assignment\n\t\tstoredArguments = arguments_;\n\t\ttimestamp = Date.now();\n\n\t\tconst callNow = immediate && !timeoutId;\n\n\t\tif (!timeoutId) {\n\t\t\ttimeoutId = setTimeout(later, wait);\n\t\t}\n\n\t\tif (callNow) {\n\t\t\tresult = run();\n\t\t\treturn result;\n\t\t}\n\n\t\treturn undefined;\n\t};\n\n\tObject.defineProperty(debounced, 'isPending', {\n\t\tget() {\n\t\t\treturn timeoutId !== undefined;\n\t\t},\n\t});\n\n\tdebounced.clear = () => {\n\t\tif (!timeoutId) {\n\t\t\treturn;\n\t\t}\n\n\t\tclearTimeout(timeoutId);\n\t\ttimeoutId = undefined;\n\t\tstoredContext = undefined;\n\t\tstoredArguments = undefined;\n\t};\n\n\tdebounced.flush = () => {\n\t\tif (!timeoutId) {\n\t\t\treturn;\n\t\t}\n\n\t\tdebounced.trigger();\n\t};\n\n\tdebounced.trigger = () => {\n\t\tresult = run();\n\n\t\tdebounced.clear();\n\t};\n\n\treturn debounced;\n}\n", "import { type Request } from \"./action\";\n\nexport interface HyperView extends HTMLElement {\n  runAction(action: string): Promise<void>;\n  activeRequest?: Request;\n  cancelActiveRequest(): void;\n  concurrency: ConcurrencyMode;\n  _timeout?: number;\n}\n\nexport const isHyperView = (ele: any): ele is HyperView => {\n  return ele?.runAction !== undefined;\n};\n\nexport type ConcurrencyMode = string;\n\nexport function dispatchContent(node: HTMLElement): void {\n  let event = new Event(\"hyp-content\", { bubbles: true })\n  node.dispatchEvent(event)\n}\n\nexport function enrichHyperViews(node: HTMLElement, runAction: (target: HyperView, action: string, form?: FormData) => Promise<void>): void {\n  // enrich all the hyperviews\n  node.querySelectorAll<HyperView>(\"[id]\").forEach((element) => {\n    element.runAction = function(action: string) {\n      return runAction(element, action)\n    }\n\n    element.concurrency = element.dataset.concurrency || \"Drop\"\n\n    element.cancelActiveRequest = function() {\n      if (element.activeRequest && !element.activeRequest?.isCancelled) {\n        element.activeRequest.isCancelled = true\n      }\n    }\n\n    dispatchContent(node)\n  })\n}\n", "\nimport debounce from 'debounce'\nimport { encodedParam } from './action'\nimport { HyperView, isHyperView } from './hyperview'\n\nexport type UrlFragment = string\n\nexport function listenKeydown(cb: (target: HyperView, action: string) => void): void {\n  listenKeyEvent(\"keydown\", cb)\n}\n\nexport function listenKeyup(cb: (target: HyperView, action: string) => void): void {\n  listenKeyEvent(\"keyup\", cb)\n}\n\nexport function listenKeyEvent(event: \"keyup\" | \"keydown\", cb: (target: HyperView, action: string) => void): void {\n\n  document.addEventListener(event, function(e: KeyboardEvent) {\n    if (!(e.target instanceof HTMLElement)) {\n      console.warn(\"listenKeyEvent received event with non HTMLElment as EventTarget: %o\", e)\n      return\n    }\n    let source = e.target\n\n    let datasetKey = \"on\" + event + e.key\n    let action = source.dataset[datasetKey]\n    if (!action) return\n\n    e.preventDefault()\n    const target =  nearestHyperViewTarget(source)\n    if (!target) {\n      console.error(\"Missing target: \", source)\n      return\n    }\n    cb(target, action)\n  })\n}\n\nexport function listenBubblingEvent(event: string, cb: (_target: HyperView, action: string) => void): void {\n  document.addEventListener(event, function(e) {\n    if (!(e.target instanceof HTMLElement)) {\n      console.warn(\"listenBubblingEvent received an event with non HTMLElment as EventTarget: %o\", e)\n      return\n    }\n    let el = e.target\n\n    // clicks can fire on internal elements. Find the parent with a click handler\n    let source = el.closest<HTMLElement>(\"[data-on\" + event + \"]\")\n    if (!source) return\n\n    e.preventDefault()\n    let target = nearestHyperViewTarget(source)\n    if (!target) {\n      console.error(\"Missing target: \", source)\n      return\n    }\n    const action = source.dataset[\"on\" + event]\n    if (action === undefined) {\n      console.error(\"Missing action: \", source, event)\n      return\n    }\n    cb(target, action)\n  })\n}\n\nexport function listenClick(cb: (target: HyperView, action: string) => void): void {\n  listenBubblingEvent(\"click\", cb)\n}\n\nexport function listenDblClick(cb: (target: HyperView, action: string) => void): void {\n  listenBubblingEvent(\"dblclick\", cb)\n}\n\n\nexport function listenTopLevel(cb: (target: HyperView, action: string) => void): void {\n  document.addEventListener(\"hyp-load\", function(e: CustomEvent) {\n    let action = e.detail.onLoad\n    let target = e.detail.target\n    cb(target, action)\n  })\n\n  document.addEventListener(\"hyp-mouseenter\", function(e: CustomEvent) {\n    let action = e.detail.onMouseEnter\n    let target = e.detail.target\n    cb(target, action)\n  })\n\n  document.addEventListener(\"hyp-mouseleave\", function(e: CustomEvent) {\n    let action = e.detail.onMouseLeave\n    let target = e.detail.target\n    cb(target, action)\n  })\n}\n\n\nexport function listenLoad(node: HTMLElement): void {\n\n  // it doesn't really matter WHO runs this except that it should have target\n  node.querySelectorAll<HTMLElement>(\"[data-onload]\").forEach((load) => {\n    let delay = parseInt(load.dataset.delay || \"\") || 0\n    let onLoad = load.dataset.onload\n    // console.log(\"load start\", load.dataset.onLoad)\n\n    // load no longer exists!\n    // we should clear the timeout or back out if the dom is replaced in the interem\n    setTimeout(() => {\n      let target = nearestHyperViewTarget(load)\n      // console.log(\"load go\", load.dataset.onLoad)\n\n      if (load.dataset.onload != onLoad) {\n        // the onLoad no longer exists\n        return\n      }\n\n      const event = new CustomEvent(\"hyp-load\", { bubbles: true, detail: { target, onLoad } })\n      load.dispatchEvent(event)\n    }, delay)\n  })\n}\n\nexport function listenMouseEnter(node: HTMLElement): void {\n  node.querySelectorAll<HTMLElement>(\"[data-onmouseenter]\").forEach((node) => {\n    let onMouseEnter = node.dataset.onmouseenter\n\n    let target = nearestAnyTarget(node)\n\n    node.onmouseenter = () => {\n      const event = new CustomEvent(\"hyp-mouseenter\", { bubbles: true, detail: { target, onMouseEnter } })\n      node.dispatchEvent(event)\n    }\n  })\n}\n\nexport function listenMouseLeave(node: HTMLElement): void {\n  node.querySelectorAll<HTMLElement>(\"[data-onmouseleave]\").forEach((node) => {\n    let onMouseLeave = node.dataset.onmouseleave\n\n    let target = nearestAnyTarget(node)\n\n    node.onmouseleave = () => {\n      const event = new CustomEvent(\"hyp-mouseleave\", { bubbles: true, detail: { target, onMouseLeave } })\n      node.dispatchEvent(event)\n    }\n  })\n}\n\n\nexport function listenChange(cb: (target: HyperView, action: string) => void): void {\n  document.addEventListener(\"change\", function(e) {\n    if (!(e.target instanceof HTMLElement)) {\n      console.warn(\"listenChange received an event with non HTMLElment as EventTarget: %o\", e)\n      return\n    }\n    let el = e.target\n\n    let source = el.closest<HTMLInputElement>(\"[data-onchange]\")\n\n    if (!source) return\n    e.preventDefault()\n\n    if (source.value === null) {\n      console.error(\"Missing input value:\", source)\n      return\n    }\n\n    let target = nearestHyperViewTarget(source)\n    if (!target) {\n      console.error(\"Missing target: listenChange\")\n      return\n    }\n    if (!source.dataset.onchange) {\n      console.error(\"Missing onchange: \", source)\n      return\n    }\n    let action = encodedParam(source.dataset.onchange, source.value)\n    cb(target, action)\n  })\n}\n\ninterface LiveInputElement extends HTMLInputElement {\n  debouncedCallback?: Function;\n}\n\nexport function listenInput(startedTyping: (target: HyperView) => void, cb: (target: HyperView, action: string) => void): void {\n  document.addEventListener(\"input\", function(e) {\n    if (!(e.target instanceof HTMLElement)) {\n      console.warn(\"listenInput received an event with non HTMLElment as EventTarget: %o\", e)\n      return\n    }\n    let el = e.target\n    const source = el.closest<LiveInputElement>(\"[data-oninput]\")\n\n    if (!source) return\n\n    let delay = parseInt(source.dataset.delay || \"\") || 250\n    if (delay < 250) {\n      console.warn(\"Input delay < 250 can result in poor performance.\")\n    }\n\n    e.preventDefault()\n\n    const target = nearestHyperViewTarget(source)\n    if (!target) {\n      console.error(\"Missing target: \", source)\n      return\n    }\n\n    // I want to CANCEL the active request as soon as we start typing\n    startedTyping(target)\n\n    if (!source.debouncedCallback) {\n      source.debouncedCallback = debounce(() => {\n        if (!source.dataset.oninput) {\n          console.error(\"Missing onInput: \", source)\n          return\n        }\n        const action = encodedParam(source.dataset.oninput, source.value)\n        cb(target, action)\n      }, delay)\n    }\n\n    source.debouncedCallback()\n  })\n}\n\n\n\nexport function listenFormSubmit(cb: (target: HyperView, action: string, form: FormData) => void): void {\n  document.addEventListener(\"submit\", function(e) {\n    if (!(e.target instanceof HTMLFormElement)) {\n      console.warn(\"listenFormSubmit received an event with non HTMLElment as EventTarget: %o\", e)\n      return\n    }\n    let form = e.target\n\n\n    if (!form.dataset.onsubmit) {\n      console.error(\"Missing onSubmit: \", form)\n      return\n    }\n\n    e.preventDefault()\n\n    let target = nearestHyperViewTarget(form)\n    const formData = new FormData(form)\n    if (!target) {\n      console.error(\"Missing target: \", form)\n      return\n    }\n    cb(target, form.dataset.onsubmit, formData)\n  })\n}\n\nfunction nearestTargetId(node: HTMLElement): string | undefined {\n  let targetData = node.closest<HTMLElement>(\"[data-target]\")\n  return targetData?.dataset.target || node.closest(\"[id]\")?.id\n}\n\nfunction nearestHyperViewTarget(node: HTMLElement): HyperView | undefined {\n  const target = nearestAnyTarget(node)\n\n  if (!isHyperView(target)) {\n    console.error(\"Non HyperView target: \", target)\n    return\n  }\n\n  return target\n}\n\nfunction nearestAnyTarget(node: HTMLElement): HTMLElement | undefined {\n  let targetId = nearestTargetId(node)\n  let target = targetId && document.getElementById(targetId)\n\n  if (!target) {\n    console.error(\"Cannot find target: \", targetId, node)\n    return\n  }\n\n  return target\n}\n", "\nexport function setQuery(query: string) {\n  if (query != currentQuery()) {\n    if (query != \"\") query = \"?\" + query\n    let url = location.pathname + query\n    // console.log(\"history.replaceState(\", url, \")\")\n    window.history.replaceState({}, \"\", url)\n  }\n}\n\nfunction currentQuery(): string {\n  const query = window.location.search;\n  return query.startsWith('?') ? query.substring(1) : query;\n}\n", "\nimport { ViewId, Metadata } from './message'\n\n\n\nexport type Response = {\n  meta: Metadata\n  body: ResponseBody\n}\n\nexport type ResponseBody = string\n\nexport function parseResponse(res: ResponseBody): LiveUpdate {\n  const parser = new DOMParser()\n  const doc = parser.parseFromString(res, 'text/html')\n  const css = doc.querySelector<HTMLStyleElement>(\"style\")\n  const content = doc.querySelector<HTMLElement>(\"div\")\n\n  return {\n    content: content,\n    css: css\n  }\n}\n\nexport type LiveUpdate = {\n  content: HTMLElement | null\n  css: HTMLStyleElement | null\n}\n\n\nexport class FetchError extends Error {\n  viewId: ViewId\n  body: string\n  constructor(viewId: ViewId, msg: string, body: string) {\n    super(msg)\n    this.viewId = viewId\n    this.name = \"Fetch Error\"\n    this.body = body\n  }\n}\n", "{\n  \"name\": \"web-ui\",\n  \"version\": \"0.6.0\",\n  \"description\": \"Development -----------\",\n  \"main\": \"index.js\",\n  \"directories\": {\n    \"client\": \"client\"\n  },\n  \"scripts\": {\n    \"build\": \"esbuild src/index.ts --bundle --minify --sourcemap --outfile=dist/hyperbole.js\",\n    \"dev\": \"esbuild src/index.ts --bundle --minify --sourcemap --watch=forever --outfile=dist/hyperbole.js\",\n    \"check\": \"tsc --noEmit --preserveWatchOutput --watch\"\n  },\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"devDependencies\": {\n    \"esbuild\": \"^0.28.0\",\n    \"typescript\": \"^6.0.3\"\n  },\n  \"dependencies\": {\n    \"omdomdom\": \"^0.3.2\",\n    \"debounce\": \"^3.0.0\"\n  }\n}\n", "import { patch, create } from \"omdomdom/lib/omdomdom.es.js\"\nimport { SocketConnection, Update, Redirect, Trigger, JSEvent } from './sockets'\nimport { listenChange, listenClick, listenDblClick, listenFormSubmit, listenLoad, listenTopLevel, listenInput, listenKeydown, listenKeyup, listenMouseEnter, listenMouseLeave } from './events'\nimport { actionMessage, newRequest } from './action'\nimport { ViewId, Metadata, parseMetadata, RemoteEvent, EncodedAction } from './message'\nimport { setQuery } from \"./browser\"\nimport { parseResponse, LiveUpdate } from './response'\nimport { dispatchContent, enrichHyperViews, HyperView, isHyperView } from \"./hyperview\"\n\nimport PACKAGE from '../package.json';\n\n\n// console.log(\"VERSION 2\", INIT_PAGE, INIT_STATE)\nconsole.log(\"Hyperbole \" + PACKAGE.version + \"b\")\n\n\nlet rootStyles: HTMLStyleElement;\nlet addedRulesIndex = new Set();\n\n\n\n\n\n// Run an action in a given HyperView\nasync function runAction(target: HyperView, action: string, form?: FormData) {\n\n  if (target.activeRequest && !target.activeRequest?.isCancelled) {\n    // Active Request!\n    if (target.concurrency == \"Drop\") {\n      console.warn(\"Drop action overlapping with active request (\" + target.activeRequest + \")\", action)\n      return\n    }\n  }\n\n  target._timeout = window.setTimeout(() => {\n    // add loading after 100ms, not right away\n    // if it runs shorter than that we probably don't want to show the user any loading feedback\n    target.classList.add(\"hyp-loading\")\n  }, 100)\n\n  let state = target.dataset.state\n\n  let req = newRequest()\n  let msg = actionMessage(target.id, action, state, req.requestId, form)\n\n  // Set the requestId\n  target.activeRequest = req\n\n  sock.sendAction(msg)\n}\n\nfunction handleTrigger(trigger: Trigger) {\n  runTrigger(trigger.targetViewId, trigger.targetAction)\n}\n\nfunction handleEvent(ev: JSEvent) {\n  let target = document.getElementById(ev.viewId)\n  runRemoteEvent(ev.event, target)\n}\n\n// TODO: redirect concurrency\nfunction handleRedirect(red: Redirect) {\n  console.log(\"REDIRECT\", red)\n\n  // the other metdata doesn't apply, they are all specific to the page\n  applyCookies(red.meta.cookies ?? [])\n\n  window.location.href = red.url\n}\n\n// in-process update\nfunction handleResponse(res: Update) {\n  // console.log(\"Handle Response\", res)\n  let target = handleUpdate(res)\n  if (!target) return\n\n  // clean up the request\n  delete target.activeRequest\n  clearTimeout(target._timeout)\n  target.classList.remove(\"hyp-loading\")\n}\n\nfunction handleUpdate(res: Update): HyperView | undefined {\n  // console.log(\"|UPDATE|\", res)\n\n  let targetViewId = res.targetViewId || res.viewId\n  let target = document.getElementById(targetViewId)\n\n  if (!isHyperView(target)) {\n    console.error(\"Missing Update HyperView Target: \", targetViewId, res)\n    return\n  }\n\n  if (target.activeRequest?.requestId && res.requestId < target.activeRequest.requestId) {\n    // this should only happen on Replace, since other requests should be dropped\n    // but it's safe to assume we never want to apply an old requestId\n    console.warn(\"Ignore Stale Action (\" + res.requestId + \") vs (\" + target.activeRequest.requestId + \"): \" + res.action)\n    return target\n  }\n  else if (target.activeRequest?.isCancelled) {\n    console.warn(\"Cancelled request\", target.activeRequest?.requestId)\n    delete target.activeRequest\n    return target\n  }\n\n  let update: LiveUpdate = parseResponse(res.body)\n\n  if (!update.content) {\n    console.error(\"Empty Response!\", res.body)\n    return target\n  }\n\n  // First, update the stylesheet\n  addCSS(update.css)\n\n\n  // Patch the node\n  const old: VNode = create(target)\n  let next: VNode = create(update.content)\n  let atts = next.attributes\n\n  if (!res.meta.error && atts[\"id\"] != target.id) {\n    console.error(\"Mismatched ViewId in update - \", atts[\"id\"], \" target:\", target.id)\n    return\n  }\n\n  let state = atts[\"data-state\"]\n  next.attributes = old.attributes\n\n\n  patch(next, old)\n\n\n  // Emit relevant events\n  let newTarget = document.getElementById(target.id)\n\n  if (!newTarget) {\n    console.warn(\"Target Missing: \", target.id)\n    return target\n  }\n\n  dispatchContent(newTarget)\n\n  // re-add state attribute \n  if (state === undefined || state == \"()\")\n    delete newTarget.dataset.state\n  else\n    newTarget.dataset.state = state\n\n  // execute the metadata, anything that doesn't interrupt the dom update\n  runMetadata(res.meta, newTarget)\n  applyCookies(res.meta.cookies ?? [])\n\n  // now way for these to bubble)\n  listenLoad(newTarget)\n  listenMouseEnter(newTarget)\n  listenMouseLeave(newTarget)\n  fixInputs(newTarget)\n  enrichHyperViews(newTarget, runAction)\n\n  return target\n}\n// catch (err) {\n//   console.error(\"Caught Error in HyperView (\" + target.id + \"):\\n\", err)\n//\n//   // Hyperbole catches handler errors, and the server controls what to display to the user on an error\n//   //  but if you manage to crash your parent server process somehow, the response may be empty\n//   target.innerHTML = err.body || \"<div style='background:red;color:white;padding:10px'>Hyperbole Internal Error</div>\"\n// }\n\nfunction applyCookies(cookies: string[]) {\n  cookies.forEach((cookie: string) => {\n    console.log(\"SetCookie: \", cookie)\n    document.cookie = cookie\n  })\n}\n\nfunction runMetadata(meta: Metadata, target: HTMLElement | null) {\n  if (meta.query != null) {\n    setQuery(meta.query)\n  }\n\n  if (meta.pageTitle != null) {\n    document.title = meta.pageTitle\n  }\n\n  meta.events?.forEach((remoteEvent) => {\n    runRemoteEvent(remoteEvent, target)\n  })\n\n  meta.actions?.forEach(([viewId, action]) => {\n    runTrigger(viewId, action)\n  })\n}\n\nfunction runRemoteEvent(remoteEvent: RemoteEvent, target: HTMLElement | null) {\n  setTimeout(() => {\n    let event = new CustomEvent(remoteEvent.name, { bubbles: true, detail: remoteEvent.detail })\n    let eventTarget = target || document\n    eventTarget.dispatchEvent(event)\n  }, 10)\n}\n\nfunction runTrigger(viewId: ViewId, action: EncodedAction) {\n  setTimeout(() => {\n    let view = window.Hyperbole?.hyperView(viewId)\n    if (view) {\n      runAction(view, action)\n    }\n  }, 10)\n}\n\n\nfunction fixInputs(target: HTMLElement) {\n  let focused = target.querySelector<HTMLInputElement>(\"[autofocus]\")\n  if (focused?.focus) {\n    focused.focus()\n  }\n\n  target.querySelectorAll<HTMLInputElement>(\"input[value]\").forEach((input) => {\n    let val = input.getAttribute(\"value\")\n    if (val !== null) {\n      input.value = val\n    }\n  })\n\n  target.querySelectorAll<HTMLInputElement>(\"input[type=checkbox]\").forEach((checkbox) => {\n    let checked = checkbox.dataset.checked == \"True\"\n    checkbox.checked = checked\n  })\n}\n\nfunction addCSS(src: HTMLStyleElement | null) {\n  if (!src) return;\n  const rules = src.sheet?.cssRules\n  if (!rules) return;\n  for (let i = 0; i < rules.length; i++) {\n    const rule = rules.item(i)\n    if (rule && addedRulesIndex.has(rule.cssText) == false && rootStyles.sheet) {\n      rootStyles.sheet.insertRule(rule.cssText);\n      addedRulesIndex.add(rule.cssText);\n    }\n  }\n}\n\n\n\n\nfunction init() {\n  // metadata attached to initial page loads need to be executed\n  let meta = parseMetadata(document.getElementById(\"hyp.metadata\")?.innerText ?? \"\")\n  // runMetadataImmediate(meta)\n  runMetadata(meta, null)\n\n  const style = document.body.querySelector('style')\n\n  if (style !== null) {\n    rootStyles = style\n  } else {\n    console.warn(\"rootStyles missing from page, creating...\")\n    rootStyles = document.createElement(\"style\")\n    rootStyles.type = \"text/css\"\n    document.body.appendChild(rootStyles)\n  }\n\n  listenTopLevel(async function(target: HyperView, action: string) {\n    runAction(target, action)\n  })\n\n  listenLoad(document.body)\n  listenMouseEnter(document.body)\n  listenMouseLeave(document.body)\n  enrichHyperViews(document.body, runAction)\n\n\n  listenClick(async function(target: HyperView, action: string) {\n    // console.log(\"CLICK\", target.id, action)\n    runAction(target, action)\n  })\n\n  listenDblClick(async function(target: HyperView, action: string) {\n    // console.log(\"DBLCLICK\", target.id, action)\n    runAction(target, action)\n  })\n\n  listenKeydown(async function(target: HyperView, action: string) {\n    // console.log(\"KEYDOWN\", target.id, action)\n    runAction(target, action)\n  })\n\n  listenKeyup(async function(target: HyperView, action: string) {\n    // console.log(\"KEYUP\", target.id, action)\n    runAction(target, action)\n  })\n\n  listenFormSubmit(async function(target: HyperView, action: string, form: FormData) {\n    // console.log(\"FORM\", target.id, action, form)\n    runAction(target, action, form)\n  })\n\n  listenChange(async function(target: HyperView, action: string) {\n    runAction(target, action)\n  })\n\n  function onStartedTyping(target: HyperView) {\n    if (target.concurrency == \"Replace\") {\n      target.cancelActiveRequest()\n    }\n  }\n\n  listenInput(onStartedTyping, async function(target: HyperView, action: string) {\n    runAction(target, action)\n  })\n}\n\n\n\n\n\n\ndocument.addEventListener(\"DOMContentLoaded\", init)\n\n\n\n\nconst sock = new SocketConnection()\n// Should we connect to the socket or not?\nsock.connect()\nsock.addEventListener(\"update\", (ev: CustomEvent<Update>) => { handleUpdate(ev.detail) })\nsock.addEventListener(\"response\", (ev: CustomEvent<Update>) => handleResponse(ev.detail))\nsock.addEventListener(\"redirect\", (ev: CustomEvent<Redirect>) => handleRedirect(ev.detail))\nsock.addEventListener(\"trigger\", (ev: CustomEvent<Trigger>) => handleTrigger(ev.detail))\nsock.addEventListener(\"event\", (ev: CustomEvent<JSEvent>) => handleEvent(ev.detail))\n\n\n\n\n\ntype VNode = {\n  // One of three value types are used:\n  // - The tag name of the element\n  // - \"text\" if text node\n  // - \"comment\" if comment node\n  type: string\n\n  // An object whose key/value pairs are the attribute\n  // name and value, respectively\n  attributes: { [key: string]: string | undefined }\n\n  // Is set to `true` if a node is an `svg`, which tells\n  // Omdomdom to treat it, and its children, as such\n  isSVGContext: boolean\n\n  // The content of a \"text\" or \"comment\" node\n  content: string\n\n  // An array of virtual node children\n  children: Array<VNode>\n\n  // The real DOM node\n  node: Node\n}\n\n\n\n\n\ndeclare global {\n  interface Window {\n    Hyperbole?: HyperboleAPI;\n  }\n  interface DocumentEventMap {\n    \"hyp-load\": CustomEvent;\n    \"hyp-mouseenter\": CustomEvent;\n    \"hyp-mouseleave\": CustomEvent;\n  }\n}\n\nexport interface HyperboleAPI {\n  runAction(target: HTMLElement, action: string, form?: FormData): Promise<void>\n  action(con: string, ...params: any[]): string\n  hyperView(viewId: ViewId): HyperView | undefined\n  parseMetadata(input: string): Metadata\n  socket: SocketConnection\n}\n\nwindow.Hyperbole =\n{\n  runAction: runAction,\n  parseMetadata: parseMetadata,\n  action: function(con, ...params: any[]) {\n    return params.reduce((str, param) => str + \" \" + JSON.stringify(param), con);\n  },\n  hyperView: function(viewId) {\n    let element = document.getElementById(viewId)\n    if (!isHyperView(element)) {\n      console.error(\"Element id=\" + viewId + \" was not a HyperView\")\n      return\n    }\n    return element\n  },\n  socket: sock\n}\n"],
+  "mappings": "mBAAA,IAAMA,GAAqB,WAQdC,EAAc,SAACC,EAAKC,EAAI,CAAA,OACnCC,OAAOC,UAAUC,eAAeC,KAAKL,EAAKC,CAAI,CAAC,EAQ3CK,GAAa,SAACC,EAAKC,EAAQ,CAC/B,OAAKA,EAEDT,EAAYQ,EAAKC,CAAG,GAEtBC,QAAQC,KACN,6KAA6K,EAExK,IAGF,GAVU,EAWnB,EAQaC,EAAU,SAACC,EAAOC,EAAO,CACpC,IAAMC,EAASF,EAAME,OACjBC,EAAM,GAEV,GAAKD,EAEL,KAAO,EAAEC,EAAMD,GACTD,EAAGD,EAAMG,CAAG,EAAGA,CAAG,IAAM,IAA5B,CAEJ,EAOaC,GAAe,SAACC,EAAa,CACxC,IAAMV,EAAM,CAAA,EAEZI,EAAQM,EAAU,SAACC,EAAU,CAC3B,IAAMV,EAAMU,EAAMC,WAAWrB,EAAkB,EAC3CQ,GAAWC,EAAKC,CAAG,IACrBD,EAAIC,CAAG,EAAIU,EAEf,CAAC,EAID,QAAWE,KAAKb,EACd,OAAOA,CAEX,EAEac,EAAe,SAACC,EAAQJ,EAAOK,EAAY,CACtD,OAAOD,EAAOE,KAAKH,aAAaH,EAAMM,KAAMD,CAAO,CACrD,EAOaE,GAAc,SAACC,EAAUC,EAAU,CAC9C,QAASC,KAAYF,EACnBC,EAAMC,CAAQ,EAAIF,EAASE,CAAQ,CAEvC,EC/EaC,GAAS,SAACC,EAAe,CAOpC,IAAMC,EAAqBD,EACxBE,KAAI,EACJC,QAAQ,QAAS,GAAG,EACpBA,QAAQ,QAAS,GAAG,EAEjBC,EAAS,IAAIC,UACbC,EAAUF,EAAOG,gBAAgBN,EAAoB,WAAW,EAEtE,OAAOK,EAAQE,IACjB;qFClBA,IAAMC,EAAQ,CAAEC,OAAQ,SAAUC,IAAK,SAAUC,KAAM,SAAU,EAC3DC,EAAgB,CAAA,EAQhBC,EAAe,SAACC,EAAUC,EAAUC,EAAI,CAAA,MAAM,CAClDF,SAAAA,EACAC,SAAAA,EACAC,KAAAA,EACD,EAGKC,GAAc,CAIlB,CAAC,QAAS,SAAS,EACnB,CAAC,QAAS,WAAW,CAAC,EAExBrC,EAAQqC,GAAa,SAAAC,EAAsB,CAAA,IAAAC,EAAAC,EAAAF,EAAA,CAAA,EAApBG,EAAIF,EAAA,CAAA,EAAEtB,EAAQsB,EAAA,CAAA,EACnCP,EAAcS,CAAI,EAAIR,EAAaQ,EAAMxB,GAAYwB,EAAMb,EAAMC,MAAM,CACzE,CAAC,EAGD,IAAMa,GAAe,CACnB,YACA,YACA,SACA,UACA,WACA,QACA,UAAU,EAEZ1C,EAAQ0C,GAAc,SAACD,EAAS,CAC9BT,EAAcS,CAAI,EAAIR,EAAaQ,EAAMA,EAAMb,EAAMG,IAAI,CAC3D,CAAC,EAGD,IAAMY,GAAe,CAAC,CAAC,WAAY,UAAU,CAAC,EAC9C3C,EAAQ2C,GAAc,SAAAC,EAAsB,CAAA,IAAAC,EAAAL,EAAAI,EAAA,CAAA,EAApBH,EAAII,EAAA,CAAA,EAAE5B,EAAQ4B,EAAA,CAAA,EACpCb,EAAcS,CAAI,EAAIR,EAAaQ,EAAMxB,EAAUW,EAAME,GAAG,CAC9D,CAAC,EAMD,IAAMgB,EAAY,CAChBC,MAAO,CACLC,OAAQ,SACRC,SAAU,gCAEZC,IAAK,CACHF,OAAQ,OACRC,SAAU,sCACZ,CACF,ECrDaE,EAAc,SAACC,EAAShB,EAAM9C,EAAM+D,EAAU,CACzD,OAAQjB,EAAI,CACV,KAAKR,EAAMC,OAAQ,CACbvC,IAAS0C,EAAcsB,MAAMnB,SAC3BkB,IAAU,KACZD,EAAQE,MAAMhE,CAAI,EAAI,GAEtB8D,EAAQE,MAAMhE,CAAI,EAAI+D,EAEfA,IAAU,KACnBD,EAAQ9D,CAAI,EAAI,GAEhB8D,EAAQ9D,CAAI,EAAI+D,EAElB,KACF,CAEA,KAAKzB,EAAME,IAAK,CACd,GAAIuB,IAAU,KAAM,CAClB,IAAMZ,EAAOnD,EAAKiE,YAAW,EAG7BH,EAAQI,gBAAgBf,CAAI,CAC9B,SAAWY,IAAU,IACnBD,EAAQ9D,CAAI,EAAI,UACP+D,IAAU,KACnBD,EAAQ9D,CAAI,EAAI,OACX,CACL,IAAMmE,EAASC,SAASL,EAAO,EAAE,EAC5BM,MAAMF,CAAM,IACfL,EAAQ9D,CAAI,EAAImE,EAEpB,CACA,KACF,CAEA,KAAK7B,EAAMG,KAAM,CACX,CAAC,GAAI,MAAM,EAAE6B,QAAQP,CAAK,EAAI,EAChCD,EAAQ9D,CAAI,EAAI,GAEhB8D,EAAQ9D,CAAI,EAAI,GAElB,KACF,CAGO,CAEX,EChDMuE,GAAmB,SAAC7C,EAAOR,EAAe,CAC9CR,EAAQQ,EAAY,SAAC0B,EAAa,CAChC,GAAI9C,EAAY4C,EAAeE,CAAQ,EAAG,CACxC,IAAM4B,EAAiB9B,EAAcE,CAAQ,EAC7CiB,EACEnC,EAAMH,KACNiD,EAAe1B,KACf0B,EAAe3B,SACf,IAAI,CAER,MACMD,KAAYlB,EAAMH,MACpBsC,EAAYnC,EAAMH,KAAMe,EAAMC,OAAQK,EAAU,IAAI,EAEtDlB,EAAMH,KAAK2C,gBAAgBtB,CAAQ,EAGrC,OAAOlB,EAAMR,WAAW0B,CAAQ,CAClC,CAAC,CACH,EAOM6B,GAAgB,SAAC/C,EAAOR,EAAe,CAC3C,QAAS0B,KAAY1B,EAAY,CAC/B,IAAM6C,EAAQ7C,EAAW0B,CAAQ,EAGjC,GAFAlB,EAAMR,WAAW0B,CAAQ,EAAImB,EAEzBjE,EAAY4C,EAAeE,CAAQ,EAAG,CACxC,IAAM4B,EAAiB9B,EAAcE,CAAQ,EAC7CiB,EACEnC,EAAMH,KACNiD,EAAe1B,KACf0B,EAAe3B,SACfkB,CAAK,EAEP,QACF,CAGA,GAAInB,EAAS8B,WAAWlB,EAAUC,MAAMC,MAAM,EAAG,CAC/ChC,EAAMH,KAAKoD,eAAenB,EAAUC,MAAME,SAAUf,EAAUmB,CAAK,EACnE,QACF,CAEA,GAAInB,EAAS8B,WAAWlB,EAAUI,IAAIF,MAAM,EAAG,CAC7ChC,EAAMH,KAAKoD,eAAenB,EAAUI,IAAID,SAAUf,EAAUmB,CAAK,EACjE,QACF,CAEInB,KAAYlB,EAAMH,MACpBsC,EAAYnC,EAAMH,KAAMe,EAAMC,OAAQK,EAAUmB,CAAK,EAEvDrC,EAAMH,KAAKqD,aAAahC,EAAUmB,GAAS,EAAE,CAC/C,CACF,EAQMc,GAAoB,SAACf,EAAS5C,EAAe,CACjD,QAAS0B,KAAYF,EAAe,CAClC,IAAM8B,EAAiB9B,EAAcE,CAAQ,EACvCC,EAAW2B,EAAe3B,SAC1BiC,EAAYhB,EAAQiB,aAAanC,CAAQ,EAE3CA,IAAaF,EAAcsB,MAAMpB,SACnC1B,EAAW0B,CAAQ,EAAIkB,EAAQE,MAAMnB,CAAQ,EACpC,OAAOiC,GAAc,WAC9B5D,EAAW0B,CAAQ,EAAIkC,EAE3B,CACF,EAOME,GAAoB,SAAClB,EAAY,CACrC,OAAOmB,MAAM/E,UAAUgF,OAAO9E,KAC5B0D,EAAQ5C,WACR,SAACA,EAAY0B,EAAa,CACxB,OAAK9C,EAAY4C,EAAeE,EAASuC,IAAI,IAC3CjE,EAAW0B,EAASuC,IAAI,EAAIvC,EAASmB,OAEhC7C,GAET,CAAA,CAAE,CAEN,EAOakE,GAAgB,SAACtB,EAAY,CACxC,IAAM5C,EAAa8D,GAAkBlB,CAAO,EAC5Ce,OAAAA,GAAkBf,EAAS5C,CAAU,EAE9BA,CACT,EAOamE,GAAmB,SAAC5D,EAAUC,EAAU,CACnD,IAAI4D,EAAoB,CAAA,EACpBC,EAAoB,CAAA,EAGxB,QAAS3C,KAAYlB,EAAMR,WAAY,CACrC,IAAMsE,EAAW9D,EAAMR,WAAW0B,CAAQ,EACpC6C,EAAYhE,EAASP,WAAW0B,CAAQ,EAC1C4C,IAAaC,GAEb,OAAOA,EAAc,KACvBH,EAAkBI,KAAK9C,CAAQ,CAEnC,CAGA,QAASA,KAAYnB,EAASP,WAAY,CACxC,IAAMsE,EAAW9D,EAAMR,WAAW0B,CAAQ,EACpC6C,EAAYhE,EAASP,WAAW0B,CAAQ,EAC1C4C,IAAaC,GAEb,OAAOA,EAAc,MACvBF,EAAkB3C,CAAQ,EAAI6C,EAElC,CAGAlB,GAAiB7C,EAAO4D,CAAiB,EACzCb,GAAc/C,EAAO6D,CAAiB,CACxC,ECvJM1F,GAAqB,WAOpB,SAAS8F,GAAclE,EAAUC,EAAOkE,EAAO,CACpD,IAAMC,EAAyBpE,EAAST,SAASH,OAC3CiF,EAAsBpE,EAAMV,SAASH,OAE3C,GAAI,GAACgF,GAA0B,CAACC,GAEhC,KAAMC,EAAchF,GAAaW,EAAMV,QAAQ,EAC3CgF,EAAef,MAAMY,CAAsB,EAE3CE,IAAgBE,OAClBvF,EAAQe,EAAST,SAAU,SAACkF,EAAepF,EAAQ,CACjD,IAAMqF,EAAazE,EAAMH,KAAK4E,WACxB5F,EAAM2F,EAAchF,WAAWrB,EAAkB,EAEvD,GAAII,OAAOC,UAAUC,eAAeC,KAAK2F,EAAaxF,CAAG,EAAG,CAC1D,IAAM6F,EAAaL,EAAYxF,CAAG,EAE9B0E,MAAM/E,UAAUoE,QAAQlE,KAAK+F,EAAYC,EAAW7E,IAAI,IAAMT,GAChEM,EAAaM,EAAO0E,EAAYD,EAAWrF,CAAG,CAAC,EAGjDkF,EAAalF,CAAG,EAAIsF,EAGpB,OAAOL,EAAYxF,CAAG,EACtBqF,EAAMM,EAAeF,EAAalF,CAAG,CAAC,CACxC,MACEM,EAAaM,EAAOwE,EAAeC,EAAWrF,CAAG,CAAC,EAClDkF,EAAalF,CAAG,EAAIoF,CAExB,CAAC,EAEDxF,EAAQe,EAAST,SAAU,SAACkF,EAAepF,EAAQ,CACjD,IAAMuF,EAAa3E,EAAMV,SAASF,CAAG,EAEjC,OAAOuF,EAAe,KACxBT,EAAMM,EAAeG,CAAU,EAC/BL,EAAalF,CAAG,EAAIuF,IAEpB3E,EAAMH,KAAK+E,YAAYJ,EAAc3E,IAAI,EACzCyE,EAAalF,CAAG,EAAIoF,EAExB,CAAC,EAGHxE,EAAMV,SAAWgF,EAGjB,IAAIO,EAAmB7E,EAAMH,KAAK4E,WAAWtF,OACzC2F,EAAQD,EAAmBV,EAE/B,GAAIW,EAAQ,EACV,KAAOA,EAAQ,GACb9E,EAAMH,KAAKkF,YAAY/E,EAAMH,KAAK4E,WAAWI,EAAmB,CAAC,CAAC,EAClEA,IACAC,IAGN,CC5CO,IAAMZ,EAAQ,SAARA,EAASnE,EAAUC,EAAOgF,EAAa,CAGlD,GAAI,GAACjF,GAAY,CAACC,GAElBgF,CAAAA,EAAWA,GAAYhF,EAAMH,KAAKoF,WAClC,IAAMC,EAAiBnF,EAASoF,SAAWpF,EAASoF,UAAYnF,EAAMmF,QAGtE,GAAIpF,EAASqB,OAASpB,EAAMoB,MAAQ8D,EAClCF,OAAAA,EAASI,aAAarF,EAASF,KAAMG,EAAMH,IAAI,EACxCC,GAAYC,EAAUC,CAAK,EAIpC2D,GAAiB5D,EAAUC,CAAK,EAGhCiE,GAAclE,EAAUC,EAAOkE,CAAK,EACtC,MAmBamB,EAAS,SAATA,EAAUC,EAA+B,CAAA,IAAzBC,EAAYC,UAAAC,OAAA,GAAAD,UAAA,CAAA,IAAAE,OAAAF,UAAA,CAAA,EAAG,GACtC,OAAOF,GAAS,WAClBA,EAAOK,GAAOL,CAAI,GAGpB,IAAMM,EAASN,EAAKO,UAAY,OAC1BC,EAAaR,EAAKQ,WAClBC,EAAgBD,EAAaA,EAAWL,OAAS,EAGvD,GAAIG,EAAQ,CACV,GAAIG,EAAgB,EAClB,MAAM,IAAIC,MACR,mEAAmE,EAEhE,GAAID,IAAkB,EAC3B,MAAM,IAAIC,MACR,8DAA8D,EAGhE,OAAOX,EAAOS,EAAW,CAAC,CAAC,CAE/B,CAEA,IAAMG,EACJX,EAAKY,WAAa,EACd,OACAZ,EAAKY,WAAa,EAClB,UACAZ,EAAKO,QAAQM,YAAW,EACxBC,EAAQb,GAAgBU,IAAS,MACjCI,EAAaf,EAAKY,WAAa,EAAII,GAAchB,CAAI,EAAI,CAAA,EACzDiB,EAAUR,EAAgB,EAAI,KAAOT,EAAKkB,YAG1CC,EAAWC,MAAMX,CAAa,EACpCY,OAAAA,EAAQb,EAAY,SAACc,EAAOC,EAAQ,CAClCJ,EAASI,CAAG,EAAIxB,EAAOuB,EAAOR,CAAK,CACrC,CAAC,EAEM,CAAEH,KAAAA,EAAMI,WAAAA,EAAYI,SAAAA,EAAUF,QAAAA,EAASjB,KAAAA,EAAMC,aAAca,EACpE,ECpGO,SAASU,EAAmBC,EAAiCC,EAAiB,CACnF,IAAIC,EAAS,CAAC,EACd,QAASC,KAAQF,EAAO,CACtB,IAAIG,EAAIJ,EAAKG,CAAI,EACjB,GAAIC,EACFF,EAAO,KAAKE,CAAC,MAEb,MACJ,CAEA,OAAOF,CACT,CAEO,SAASG,EAAgBL,EAAiCC,EAAiB,CAChF,IAAIK,EAAQ,EACZ,KAAOA,EAAQL,EAAM,QAAUD,EAAKC,EAAMK,CAAK,CAAC,GAC9CA,IAEF,OAAOL,EAAM,MAAMK,CAAK,CAC1B,CCPO,SAASC,EAAYC,EAAsB,CAChD,OAAOA,EAAK,IAAIC,GAAKA,EAAE,IAAM,KAAOA,EAAE,KAAK,EAAE,KAAK;AAAA,CAAI,CACxD,CAaO,SAASC,EAAWF,EAAwB,CAEjD,MAAO,CACL,QAASA,EAAK,OAAOC,GAAKA,EAAE,KAAO,QAAQ,EAAE,IAAIA,GAAKA,EAAE,KAAK,EAE7D,MAAOE,EAAU,QAASH,CAAI,EAC9B,MAAOG,EAAU,QAASH,CAAI,EAC9B,UAAWG,EAAU,YAAaH,CAAI,EACtC,OAAQI,EAAc,QAASJ,CAAI,EAAE,IAAIK,CAAgB,EACzD,QAASD,EAAc,UAAWJ,CAAI,EAAE,IAAIM,CAAW,CACzD,CACF,CAIO,SAASC,EAAcC,EAAyB,CACrD,IAAIC,EAAQC,EAAaC,GAAWH,EAAM,KAAK,EAAE,MAAM;AAAA,CAAI,CAAC,EAC5D,OAAON,EAAWO,CAAK,CACzB,CAGO,SAASN,EAAUS,EAAaH,EAAmC,CACxE,OAAOA,EAAM,KAAKR,GAAKA,EAAE,KAAOW,CAAG,GAAG,KACxC,CAEO,SAASR,EAAcQ,EAAaH,EAAyB,CAClE,OAAOA,EAAM,OAAOR,GAAKA,EAAE,KAAOW,CAAG,EAAE,IAAIX,GAAKA,EAAE,KAAK,CACzD,CASO,SAASY,GAAaC,EAA+B,CAC1D,IAAIC,EAAQD,EAAQ,MAAM;AAAA,CAAI,EAC1BE,EAAkBD,EAAM,CAAC,EACzBN,EAAgBC,EAAaC,GAAWI,EAAM,MAAM,CAAC,CAAC,EAItDE,EAAOC,EAAUC,GAAKA,GAAK,GAAIJ,EAAM,MAAMN,EAAM,OAAS,CAAC,CAAC,EAEhE,MAAO,CAAE,QAAAO,EAAS,MAAAP,EAAO,KAAAQ,CAAK,CAChC,CAEO,SAASN,GAAUS,EAAgC,CACxD,IAAIC,EAAQD,EAAK,MAAM,gBAAgB,EACvC,GAAIC,EACF,MAAO,CACL,IAAKA,EAAM,CAAC,EACZ,MAAOA,EAAM,CAAC,CAChB,CAEJ,CAGO,SAAShB,EAAiBG,EAA4B,CAC3D,GAAI,CAACc,EAAMC,CAAI,EAAIC,GAAiBhB,CAAK,EACzC,MAAO,CACL,KAAAc,EACA,OAAQ,KAAK,MAAMC,CAAI,CACzB,CACF,CAEO,SAASjB,EAAYE,EAAiC,CAC3D,GAAI,CAACiB,EAAQC,CAAM,EAAIF,GAAiBhB,CAAK,EAC7C,MAAO,CAACiB,EAAQC,CAAM,CACxB,CAEA,SAASF,GAAiBhB,EAAiC,CACzD,IAAImB,EAAKnB,EAAM,QAAQ,GAAG,EAC1B,GAAImB,IAAO,GAAI,CACb,IAAIC,EAAM,IAAI,MAAM,gCAAgC,EACpD,MAAAA,EAAI,QAAUpB,EACRoB,CACR,CACA,MAAO,CAACpB,EAAM,MAAM,EAAGmB,CAAE,EAAGnB,EAAM,MAAMmB,EAAK,CAAC,CAAC,CACjD,CC3FO,SAASE,GAAcC,EAAYC,EAAuBC,EAA8BC,EAAkBC,EAAgC,CAC/I,IAAIC,EAAe,CACjB,CAAE,IAAK,SAAU,MAAO,UAAU,SAAS,MAAM,CAAE,EACnD,CAAE,IAAK,QAAS,MAAO,OAAO,SAAS,MAAO,CAChD,EAEA,MAAO,CAAE,OAAQL,EAAI,OAAAC,EAAQ,MAAAC,EAAO,UAAWC,EAAO,KAAAE,EAAM,KAAMC,GAASF,CAAI,CAAE,CACnF,CAEO,SAASE,GAASF,EAA8C,CACrE,GAAI,CAACA,EAAM,OAEX,IAAMG,EAAS,IAAI,gBAEnB,OAAAH,EAAK,QAAQ,CAACI,EAAOC,IAAQ,CAC3BF,EAAO,OAAOE,EAAKD,CAAe,CACpC,CAAC,EAEMD,CACT,CAEO,SAASG,GAAoBC,EAA4B,CAC9D,IAAIC,EAAS,CACX,WACA,WAAaD,EAAI,OACjB,WAAaA,EAAI,MACnB,EAGA,OAAIA,EAAI,OACNC,EAAO,KAAK,UAAYD,EAAI,KAAK,EAGnCC,EAAO,KAAK,cAAgBD,EAAI,SAAS,EAElC,CACLC,EAAO,KAAK;AAAA,CAAI,EACRC,EAAYF,EAAI,IAAI,CAC9B,EAAE,KAAK;AAAA,CAAI,EAAIG,GAAWH,EAAI,IAAI,CACpC,CAGO,SAASG,GAAWV,EAA2C,CACpE,OAAKA,EACE;AAAA;AAAA,EAASA,EADE,EAEpB,CAEA,IAAIW,GAA6B,EAO1B,SAASC,IAAsB,CAEpC,MAAO,CAAE,UADO,EAAED,GACE,YAAa,EAAM,CACzC,CAMO,SAASE,EAAahB,EAAgBiB,EAAuB,CAClE,OAAOjB,EAAS,IAAMkB,GAAcD,CAAK,CAC3C,CAEA,SAASC,GAAcD,EAAuB,CAC5C,OAAIA,GAAS,GACJ,IAGFA,EAAM,QAAQ,KAAM,KAAK,EAAE,QAAQ,OAAQ,GAAG,CACvD,CCtFA,IAAME,GAAW,OAAO,SAAS,WAAa,SAAW,OAAS,MAC5DC,GAAiB,GAAGD,EAAQ,KAAK,OAAO,SAAS,IAAI,GAAG,OAAO,SAAS,QAAQ,GAUzEE,EAAN,KAAuB,CAS5B,YAAYC,EAAOF,GAAgB,CANnC,sBAA4B,GAC5B,iBAAuB,GACvB,oBAAyB,EACzB,WAAyB,CAAC,EAIxB,KAAK,OAAS,IAAI,YAClB,IAAMG,EAAO,IAAI,UAAUD,CAAI,EAC/B,KAAK,OAASC,CAChB,CAEA,QAAQD,EAAOF,GAAgBI,EAAe,GAAO,CACnD,IAAMD,EAAOC,EAAe,IAAI,UAAUF,CAAI,EAAI,KAAK,OACvD,KAAK,OAASC,EAEd,SAASE,EAAeC,EAAW,CACjC,QAAQ,MAAM,gBAAiBA,CAAE,CACnC,CAEA,SAASC,EAAcD,EAAW,CAChC,QAAQ,MAAM,eAAgBA,CAAE,CAClC,CAIAH,EAAK,iBAAiB,QAASE,CAAc,EAE7CF,EAAK,iBAAiB,OAASK,GAAW,CACxC,QAAQ,IAAI,qBAAqB,EAE7B,KAAK,kBACP,SAAS,cAAc,IAAI,MAAM,sBAAsB,CAAC,EAG1D,KAAK,YAAc,GACnB,KAAK,iBAAmB,GACxB,KAAK,eAAiB,IACtBL,EAAK,oBAAoB,QAASE,CAAc,EAChDF,EAAK,iBAAiB,QAASI,CAAa,EAE5C,SAAS,cAAc,IAAI,MAAM,oBAAoB,CAAC,EAEtD,KAAK,SAAS,CAChB,CAAC,EAEDJ,EAAK,iBAAiB,QAASM,GAAK,CAClC,QAAQ,IAAI,cAAc,EACtB,KAAK,aACP,SAAS,cAAc,IAAI,MAAM,uBAAuB,CAAC,EAG3D,KAAK,YAAc,GACnBN,EAAK,oBAAoB,QAASI,CAAa,EAG3C,KAAK,mBACP,QAAQ,IAAI,mBAAsB,KAAK,eAAiB,IAAQ,GAAG,EACnE,WAAW,IAAM,KAAK,QAAQL,EAAM,EAAI,EAAG,KAAK,cAAc,GAGhEC,EAAK,oBAAoB,QAASI,CAAa,CACjD,CAAC,EAEDJ,EAAK,iBAAiB,UAAWG,GAAM,KAAK,UAAUA,CAAE,CAAC,CAC3D,CAEA,MAAM,WAAWI,EAAuB,CACtC,GAAI,KAAK,YAAa,CACpB,IAAIC,EAAMC,GAAoBF,CAAM,EACpC,KAAK,OAAO,KAAKC,CAAG,CACtB,MAEE,KAAK,MAAM,KAAKD,CAAM,CAE1B,CAEQ,UAAW,CAEjB,IAAIG,EAAkC,KAAK,MAAM,IAAI,EACjDA,IACF,QAAQ,IAAI,aAAcA,CAAI,EAC9B,KAAK,WAAWA,CAAI,EACpB,KAAK,SAAS,EAElB,CAIQ,UAAUC,EAAqB,CACrC,GAAI,CAAE,QAAAC,EAAS,MAAAC,EAAO,KAAAC,CAAK,EAAYC,GAAaJ,EAAM,IAAI,EAG1DK,EAAY,SAASC,EAAY,WAAW,EAAG,CAAC,EAEpD,SAASA,EAAYC,EAAqB,CACxC,IAAIC,EAAMC,EAAUF,EAAKL,CAAK,EAC9B,GAAI,CAACM,EAAK,MAAM,IAAIE,EAAc,8BAAgCH,EAAKP,EAAM,IAAI,EACjF,OAAOQ,CACT,CAEA,SAASG,EAAcR,EAAwB,CAC7C,IAAIS,EAASN,EAAY,QAAQ,EAC7BV,EAASU,EAAY,QAAQ,EACjC,MAAO,CACL,UAAAD,EACA,aAAc,OACd,OAAAO,EACA,OAAAhB,EACA,KAAciB,EAAWX,CAAK,EAC9B,KAAMC,EAAK,KAAK;AAAA,CAAI,CACtB,CACF,CAEA,SAASW,EAAYX,EAAwB,CAC3C,IAAIY,EAAKJ,EAAcR,CAAI,EAE3B,OAAAY,EAAG,aAAeN,EAAU,eAAgBP,CAAK,EAC1Ca,CACT,CAEA,SAASC,EAAcb,EAA0B,CAC/C,IAAIc,EAAMd,EAAK,CAAC,EAChB,MAAO,CACL,UAAAE,EACA,KAAcQ,EAAWX,CAAK,EAC9B,IAAAe,CACF,CACF,CAEA,SAASC,EAAaf,EAAyB,CAC7C,GAAI,CAAE,UAAAE,EAAW,KAAAc,EAAM,OAAAP,EAAQ,OAAAhB,CAAO,EAAIe,EAAcR,CAAI,EACxD,CAACiB,EAAcC,EAAY,EAAYC,EAAYhB,EAAY,SAAS,CAAC,EAC7E,MAAO,CAAE,UAAAD,EAAW,KAAAc,EAAM,OAAAP,EAAQ,OAAAhB,EAAQ,aAAAwB,EAAc,aAAAC,EAAa,CACvE,CAEA,SAASE,EAAWpB,EAAyB,CAC3C,GAAI,CAAE,UAAAE,EAAW,KAAAc,EAAM,OAAAP,EAAQ,OAAAhB,CAAO,EAAIe,EAAcR,CAAI,EACxDH,EAAgBwB,EAAiBlB,EAAY,OAAO,CAAC,EACzD,MAAO,CAAE,UAAAD,EAAW,KAAAc,EAAM,OAAAP,EAAQ,OAAAhB,EAAQ,MAAAI,CAAM,CAClD,CAGA,OAAQC,EAAS,CAEf,IAAK,WACH,OAAO,KAAK,cAAc,IAAI,YAAY,SAAU,CAAE,OAAQa,EAAYX,CAAI,CAAE,CAAC,CAAC,EAEpF,IAAK,aACH,OAAO,KAAK,cAAc,IAAI,YAAY,WAAY,CAAE,OAAQQ,EAAcR,CAAI,CAAE,CAAC,CAAC,EAExF,IAAK,aACH,OAAO,KAAK,cAAc,IAAI,YAAY,WAAY,CAAE,OAAQa,EAAcb,CAAI,CAAE,CAAC,CAAC,EAExF,IAAK,YACH,OAAO,KAAK,cAAc,IAAI,YAAY,UAAW,CAAE,OAAQe,EAAaf,CAAI,CAAE,CAAC,CAAC,EAEtF,IAAK,UACH,OAAO,KAAK,cAAc,IAAI,YAAY,QAAS,CAAE,OAAQoB,EAAWpB,CAAI,CAAE,CAAC,CAAC,EAElF,QACE,MAAM,IAAIO,EAAc,2BAA6BT,EAASD,EAAM,IAAI,CAC5E,CACF,CA+CA,iBAA2D,EAAMyB,EAA+C,CAC9G,KAAK,OAAO,iBAAiB,EAE3BA,CACF,CACF,CAEA,cAAwD,EAAgC,CACtF,KAAK,OAAO,cAAc,CAAC,CAC7B,CAEA,YAAa,CACX,KAAK,YAAc,GACnB,KAAK,iBAAmB,GACxB,KAAK,OAAO,MAAM,CACpB,CACF,EAwCaf,EAAN,cAA4B,KAAM,CACvC,YAAYgB,EAAqBC,EAAc,CAC7C,MAAMD,EAAc;AAAA,EAAOC,CAAI,EAC/B,KAAK,KAAO,eACd,CACF,EClSe,SAARC,EAA0BC,EAAWC,EAAO,IAAKC,EAAU,CAAC,EAAG,CACrE,GAAI,OAAOF,GAAc,WACxB,MAAM,IAAI,UAAU,wDAAwD,OAAOA,CAAS,KAAK,EAGlG,GAAIC,EAAO,EACV,MAAM,IAAI,WAAW,8BAA8B,EAGpD,GAAI,OAAOC,GAAY,UACtB,MAAM,IAAI,UAAU,4FAA4F,EAGjH,GAAM,CAAC,UAAAC,CAAS,EAAID,EAEhBE,EACAC,EACAC,EACAC,EACAC,EAEJ,SAASC,GAAM,CACd,IAAMC,EAAcN,EACdO,EAAgBN,EACtB,OAAAD,EAAgB,OAChBC,EAAkB,OAClBG,EAASR,EAAU,MAAMU,EAAaC,CAAa,EAC5CH,CACR,CAEA,SAASI,GAAQ,CAChB,IAAMC,EAAO,KAAK,IAAI,EAAIN,EAEtBM,EAAOZ,GAAQY,GAAQ,EAC1BP,EAAY,WAAWM,EAAOX,EAAOY,CAAI,GAEzCP,EAAY,OAEPH,IACJK,EAASC,EAAI,GAGhB,CAEA,IAAMK,EAAY,YAAaC,EAAY,CAC1C,GACCX,GACG,OAASA,GACT,OAAO,eAAe,IAAI,IAAM,OAAO,eAAeA,CAAa,EAEtE,MAAM,IAAI,MAAM,wEAAwE,EAGzFA,EAAgB,KAChBC,EAAkBU,EAClBR,EAAY,KAAK,IAAI,EAErB,IAAMS,EAAUb,GAAa,CAACG,EAM9B,GAJKA,IACJA,EAAY,WAAWM,EAAOX,CAAI,GAG/Be,EACH,OAAAR,EAASC,EAAI,EACND,CAIT,EAEA,cAAO,eAAeM,EAAW,YAAa,CAC7C,KAAM,CACL,OAAOR,IAAc,MACtB,CACD,CAAC,EAEDQ,EAAU,MAAQ,IAAM,CAClBR,IAIL,aAAaA,CAAS,EACtBA,EAAY,OACZF,EAAgB,OAChBC,EAAkB,OACnB,EAEAS,EAAU,MAAQ,IAAM,CAClBR,GAILQ,EAAU,QAAQ,CACnB,EAEAA,EAAU,QAAU,IAAM,CACzBN,EAASC,EAAI,EAEbK,EAAU,MAAM,CACjB,EAEOA,CACR,CC7FO,IAAMG,EAAeC,GACnBA,GAAK,YAAc,OAKrB,SAASC,EAAgBC,EAAyB,CACvD,IAAIC,EAAQ,IAAI,MAAM,cAAe,CAAE,QAAS,EAAK,CAAC,EACtDD,EAAK,cAAcC,CAAK,CAC1B,CAEO,SAASC,EAAiBF,EAAmBG,EAAwF,CAE1IH,EAAK,iBAA4B,MAAM,EAAE,QAASI,GAAY,CAC5DA,EAAQ,UAAY,SAASC,EAAgB,CAC3C,OAAOF,EAAUC,EAASC,CAAM,CAClC,EAEAD,EAAQ,YAAcA,EAAQ,QAAQ,aAAe,OAErDA,EAAQ,oBAAsB,UAAW,CACnCA,EAAQ,eAAiB,CAACA,EAAQ,eAAe,cACnDA,EAAQ,cAAc,YAAc,GAExC,EAEAL,EAAgBC,CAAI,CACtB,CAAC,CACH,CC/BO,SAASM,GAAcC,EAAuD,CACnFC,GAAe,UAAWD,CAAE,CAC9B,CAEO,SAASE,GAAYF,EAAuD,CACjFC,GAAe,QAASD,CAAE,CAC5B,CAEO,SAASC,GAAeE,EAA4BH,EAAuD,CAEhH,SAAS,iBAAiBG,EAAO,SAASC,EAAkB,CAC1D,GAAI,EAAEA,EAAE,kBAAkB,aAAc,CACtC,QAAQ,KAAK,uEAAwEA,CAAC,EACtF,MACF,CACA,IAAIC,EAASD,EAAE,OAEXE,EAAa,KAAOH,EAAQC,EAAE,IAC9BG,EAASF,EAAO,QAAQC,CAAU,EACtC,GAAI,CAACC,EAAQ,OAEbH,EAAE,eAAe,EACjB,IAAMI,EAAUC,EAAuBJ,CAAM,EAC7C,GAAI,CAACG,EAAQ,CACX,QAAQ,MAAM,mBAAoBH,CAAM,EACxC,MACF,CACAL,EAAGQ,EAAQD,CAAM,CACnB,CAAC,CACH,CAEO,SAASG,GAAoBP,EAAeH,EAAwD,CACzG,SAAS,iBAAiBG,EAAO,SAASC,EAAG,CAC3C,GAAI,EAAEA,EAAE,kBAAkB,aAAc,CACtC,QAAQ,KAAK,+EAAgFA,CAAC,EAC9F,MACF,CAIA,IAAIC,EAHKD,EAAE,OAGK,QAAqB,WAAaD,EAAQ,GAAG,EAC7D,GAAI,CAACE,EAAQ,OAEbD,EAAE,eAAe,EACjB,IAAII,EAASC,EAAuBJ,CAAM,EAC1C,GAAI,CAACG,EAAQ,CACX,QAAQ,MAAM,mBAAoBH,CAAM,EACxC,MACF,CACA,IAAME,EAASF,EAAO,QAAQ,KAAOF,CAAK,EAC1C,GAAII,IAAW,OAAW,CACxB,QAAQ,MAAM,mBAAoBF,EAAQF,CAAK,EAC/C,MACF,CACAH,EAAGQ,EAAQD,CAAM,CACnB,CAAC,CACH,CAEO,SAASI,GAAYX,EAAuD,CACjFU,GAAoB,QAASV,CAAE,CACjC,CAEO,SAASY,GAAeZ,EAAuD,CACpFU,GAAoB,WAAYV,CAAE,CACpC,CAGO,SAASa,GAAeb,EAAuD,CACpF,SAAS,iBAAiB,WAAY,SAAS,EAAgB,CAC7D,IAAIO,EAAS,EAAE,OAAO,OAClBC,EAAS,EAAE,OAAO,OACtBR,EAAGQ,EAAQD,CAAM,CACnB,CAAC,EAED,SAAS,iBAAiB,iBAAkB,SAAS,EAAgB,CACnE,IAAIA,EAAS,EAAE,OAAO,aAClBC,EAAS,EAAE,OAAO,OACtBR,EAAGQ,EAAQD,CAAM,CACnB,CAAC,EAED,SAAS,iBAAiB,iBAAkB,SAAS,EAAgB,CACnE,IAAIA,EAAS,EAAE,OAAO,aAClBC,EAAS,EAAE,OAAO,OACtBR,EAAGQ,EAAQD,CAAM,CACnB,CAAC,CACH,CAGO,SAASO,EAAWC,EAAyB,CAGlDA,EAAK,iBAA8B,eAAe,EAAE,QAASC,GAAS,CACpE,IAAIC,EAAQ,SAASD,EAAK,QAAQ,OAAS,EAAE,GAAK,EAC9CE,EAASF,EAAK,QAAQ,OAK1B,WAAW,IAAM,CACf,IAAIR,EAASC,EAAuBO,CAAI,EAGxC,GAAIA,EAAK,QAAQ,QAAUE,EAEzB,OAGF,IAAMf,EAAQ,IAAI,YAAY,WAAY,CAAE,QAAS,GAAM,OAAQ,CAAE,OAAAK,EAAQ,OAAAU,CAAO,CAAE,CAAC,EACvFF,EAAK,cAAcb,CAAK,CAC1B,EAAGc,CAAK,CACV,CAAC,CACH,CAEO,SAASE,EAAiBJ,EAAyB,CACxDA,EAAK,iBAA8B,qBAAqB,EAAE,QAASA,GAAS,CAC1E,IAAIK,EAAeL,EAAK,QAAQ,aAE5BP,EAASa,EAAiBN,CAAI,EAElCA,EAAK,aAAe,IAAM,CACxB,IAAMZ,EAAQ,IAAI,YAAY,iBAAkB,CAAE,QAAS,GAAM,OAAQ,CAAE,OAAAK,EAAQ,aAAAY,CAAa,CAAE,CAAC,EACnGL,EAAK,cAAcZ,CAAK,CAC1B,CACF,CAAC,CACH,CAEO,SAASmB,EAAiBP,EAAyB,CACxDA,EAAK,iBAA8B,qBAAqB,EAAE,QAASA,GAAS,CAC1E,IAAIQ,EAAeR,EAAK,QAAQ,aAE5BP,EAASa,EAAiBN,CAAI,EAElCA,EAAK,aAAe,IAAM,CACxB,IAAMZ,EAAQ,IAAI,YAAY,iBAAkB,CAAE,QAAS,GAAM,OAAQ,CAAE,OAAAK,EAAQ,aAAAe,CAAa,CAAE,CAAC,EACnGR,EAAK,cAAcZ,CAAK,CAC1B,CACF,CAAC,CACH,CAGO,SAASqB,GAAaxB,EAAuD,CAClF,SAAS,iBAAiB,SAAU,SAAS,EAAG,CAC9C,GAAI,EAAE,EAAE,kBAAkB,aAAc,CACtC,QAAQ,KAAK,wEAAyE,CAAC,EACvF,MACF,CAGA,IAAIK,EAFK,EAAE,OAEK,QAA0B,iBAAiB,EAE3D,GAAI,CAACA,EAAQ,OAGb,GAFA,EAAE,eAAe,EAEbA,EAAO,QAAU,KAAM,CACzB,QAAQ,MAAM,uBAAwBA,CAAM,EAC5C,MACF,CAEA,IAAIG,EAASC,EAAuBJ,CAAM,EAC1C,GAAI,CAACG,EAAQ,CACX,QAAQ,MAAM,8BAA8B,EAC5C,MACF,CACA,GAAI,CAACH,EAAO,QAAQ,SAAU,CAC5B,QAAQ,MAAM,qBAAsBA,CAAM,EAC1C,MACF,CACA,IAAIE,EAASkB,EAAapB,EAAO,QAAQ,SAAUA,EAAO,KAAK,EAC/DL,EAAGQ,EAAQD,CAAM,CACnB,CAAC,CACH,CAMO,SAASmB,GAAYC,EAA4C3B,EAAuD,CAC7H,SAAS,iBAAiB,QAAS,SAASI,EAAG,CAC7C,GAAI,EAAEA,EAAE,kBAAkB,aAAc,CACtC,QAAQ,KAAK,uEAAwEA,CAAC,EACtF,MACF,CAEA,IAAMC,EADGD,EAAE,OACO,QAA0B,gBAAgB,EAE5D,GAAI,CAACC,EAAQ,OAEb,IAAIY,EAAQ,SAASZ,EAAO,QAAQ,OAAS,EAAE,GAAK,IAChDY,EAAQ,KACV,QAAQ,KAAK,mDAAmD,EAGlEb,EAAE,eAAe,EAEjB,IAAMI,EAASC,EAAuBJ,CAAM,EAC5C,GAAI,CAACG,EAAQ,CACX,QAAQ,MAAM,mBAAoBH,CAAM,EACxC,MACF,CAGAsB,EAAcnB,CAAM,EAEfH,EAAO,oBACVA,EAAO,kBAAoBuB,EAAS,IAAM,CACxC,GAAI,CAACvB,EAAO,QAAQ,QAAS,CAC3B,QAAQ,MAAM,oBAAqBA,CAAM,EACzC,MACF,CACA,IAAME,EAASkB,EAAapB,EAAO,QAAQ,QAASA,EAAO,KAAK,EAChEL,EAAGQ,EAAQD,CAAM,CACnB,EAAGU,CAAK,GAGVZ,EAAO,kBAAkB,CAC3B,CAAC,CACH,CAIO,SAASwB,GAAiB7B,EAAuE,CACtG,SAAS,iBAAiB,SAAU,SAAS,EAAG,CAC9C,GAAI,EAAE,EAAE,kBAAkB,iBAAkB,CAC1C,QAAQ,KAAK,4EAA6E,CAAC,EAC3F,MACF,CACA,IAAI8B,EAAO,EAAE,OAGb,GAAI,CAACA,EAAK,QAAQ,SAAU,CAC1B,QAAQ,MAAM,qBAAsBA,CAAI,EACxC,MACF,CAEA,EAAE,eAAe,EAEjB,IAAItB,EAASC,EAAuBqB,CAAI,EAClCC,EAAW,IAAI,SAASD,CAAI,EAClC,GAAI,CAACtB,EAAQ,CACX,QAAQ,MAAM,mBAAoBsB,CAAI,EACtC,MACF,CACA9B,EAAGQ,EAAQsB,EAAK,QAAQ,SAAUC,CAAQ,CAC5C,CAAC,CACH,CAEA,SAASC,GAAgBjB,EAAuC,CAE9D,OADiBA,EAAK,QAAqB,eAAe,GACvC,QAAQ,QAAUA,EAAK,QAAQ,MAAM,GAAG,EAC7D,CAEA,SAASN,EAAuBM,EAA0C,CACxE,IAAMP,EAASa,EAAiBN,CAAI,EAEpC,GAAI,CAACkB,EAAYzB,CAAM,EAAG,CACxB,QAAQ,MAAM,yBAA0BA,CAAM,EAC9C,MACF,CAEA,OAAOA,CACT,CAEA,SAASa,EAAiBN,EAA4C,CACpE,IAAImB,EAAWF,GAAgBjB,CAAI,EAC/BP,EAAS0B,GAAY,SAAS,eAAeA,CAAQ,EAEzD,GAAI,CAAC1B,EAAQ,CACX,QAAQ,MAAM,uBAAwB0B,EAAUnB,CAAI,EACpD,MACF,CAEA,OAAOP,CACT,CCtRO,SAAS2B,GAASC,EAAe,CACtC,GAAIA,GAASC,GAAa,EAAG,CACvBD,GAAS,KAAIA,EAAQ,IAAMA,GAC/B,IAAIE,EAAM,SAAS,SAAWF,EAE9B,OAAO,QAAQ,aAAa,CAAC,EAAG,GAAIE,CAAG,CACzC,CACF,CAEA,SAASD,IAAuB,CAC9B,IAAMD,EAAQ,OAAO,SAAS,OAC9B,OAAOA,EAAM,WAAW,GAAG,EAAIA,EAAM,UAAU,CAAC,EAAIA,CACtD,CCDO,SAASG,GAAcC,EAA+B,CAE3D,IAAMC,EADS,IAAI,UAAU,EACV,gBAAgBD,EAAK,WAAW,EAC7CE,EAAMD,EAAI,cAAgC,OAAO,EAGvD,MAAO,CACL,QAHcA,EAAI,cAA2B,KAAK,EAIlD,IAAKC,CACP,CACF,CCtBA,IAAAC,GAAA,CACE,KAAQ,SACR,QAAW,QACX,YAAe,0BACf,KAAQ,WACR,YAAe,CACb,OAAU,QACZ,EACA,QAAW,CACT,MAAS,iFACT,IAAO,iGACP,MAAS,4CACX,EACA,OAAU,GACV,QAAW,MACX,gBAAmB,CACjB,QAAW,UACX,WAAc,QAChB,EACA,aAAgB,CACd,SAAY,SACZ,SAAY,QACd,CACF,ECVA,QAAQ,IAAI,aAAeC,GAAQ,QAAU,GAAG,EAGhD,IAAIC,EACAC,GAAkB,IAAI,IAO1B,eAAeC,EAAUC,EAAmBC,EAAgBC,EAAiB,CAE3E,GAAIF,EAAO,eAAiB,CAACA,EAAO,eAAe,aAE7CA,EAAO,aAAe,OAAQ,CAChC,QAAQ,KAAK,gDAAkDA,EAAO,cAAgB,IAAKC,CAAM,EACjG,MACF,CAGFD,EAAO,SAAW,OAAO,WAAW,IAAM,CAGxCA,EAAO,UAAU,IAAI,aAAa,CACpC,EAAG,GAAG,EAEN,IAAIG,EAAQH,EAAO,QAAQ,MAEvBI,EAAMC,GAAW,EACjBC,EAAMC,GAAcP,EAAO,GAAIC,EAAQE,EAAOC,EAAI,UAAWF,CAAI,EAGrEF,EAAO,cAAgBI,EAEvBI,EAAK,WAAWF,CAAG,CACrB,CAEA,SAASG,GAAcC,EAAkB,CACvCC,GAAWD,EAAQ,aAAcA,EAAQ,YAAY,CACvD,CAEA,SAASE,GAAYC,EAAa,CAChC,IAAIb,EAAS,SAAS,eAAea,EAAG,MAAM,EAC9CC,GAAeD,EAAG,MAAOb,CAAM,CACjC,CAGA,SAASe,GAAeC,EAAe,CACrC,QAAQ,IAAI,WAAYA,CAAG,EAG3BC,GAAaD,EAAI,KAAK,SAAW,CAAC,CAAC,EAEnC,OAAO,SAAS,KAAOA,EAAI,GAC7B,CAGA,SAASE,GAAeC,EAAa,CAEnC,IAAInB,EAASoB,GAAaD,CAAG,EACxBnB,IAGL,OAAOA,EAAO,cACd,aAAaA,EAAO,QAAQ,EAC5BA,EAAO,UAAU,OAAO,aAAa,EACvC,CAEA,SAASoB,GAAaD,EAAoC,CAGxD,IAAIE,EAAeF,EAAI,cAAgBA,EAAI,OACvCnB,EAAS,SAAS,eAAeqB,CAAY,EAEjD,GAAI,CAACC,EAAYtB,CAAM,EAAG,CACxB,QAAQ,MAAM,oCAAqCqB,EAAcF,CAAG,EACpE,MACF,CAEA,GAAInB,EAAO,eAAe,WAAamB,EAAI,UAAYnB,EAAO,cAAc,UAG1E,eAAQ,KAAK,wBAA0BmB,EAAI,UAAY,SAAWnB,EAAO,cAAc,UAAY,MAAQmB,EAAI,MAAM,EAC9GnB,EAEJ,GAAIA,EAAO,eAAe,YAC7B,eAAQ,KAAK,oBAAqBA,EAAO,eAAe,SAAS,EACjE,OAAOA,EAAO,cACPA,EAGT,IAAIuB,EAAqBC,GAAcL,EAAI,IAAI,EAE/C,GAAI,CAACI,EAAO,QACV,eAAQ,MAAM,kBAAmBJ,EAAI,IAAI,EAClCnB,EAITyB,GAAOF,EAAO,GAAG,EAIjB,IAAMG,EAAaC,EAAO3B,CAAM,EAC5B4B,EAAcD,EAAOJ,EAAO,OAAO,EACnCM,EAAOD,EAAK,WAEhB,GAAI,CAACT,EAAI,KAAK,OAASU,EAAK,IAAS7B,EAAO,GAAI,CAC9C,QAAQ,MAAM,iCAAkC6B,EAAK,GAAO,WAAY7B,EAAO,EAAE,EACjF,MACF,CAEA,IAAIG,EAAQ0B,EAAK,YAAY,EAC7BD,EAAK,WAAaF,EAAI,WAGtBI,EAAMF,EAAMF,CAAG,EAIf,IAAIK,EAAY,SAAS,eAAe/B,EAAO,EAAE,EAEjD,OAAK+B,GAKLC,EAAgBD,CAAS,EAGrB5B,IAAU,QAAaA,GAAS,KAClC,OAAO4B,EAAU,QAAQ,MAEzBA,EAAU,QAAQ,MAAQ5B,EAG5B8B,GAAYd,EAAI,KAAMY,CAAS,EAC/Bd,GAAaE,EAAI,KAAK,SAAW,CAAC,CAAC,EAGnCe,EAAWH,CAAS,EACpBI,EAAiBJ,CAAS,EAC1BK,EAAiBL,CAAS,EAC1BM,GAAUN,CAAS,EACnBO,EAAiBP,EAAWhC,CAAS,EAE9BC,IAvBL,QAAQ,KAAK,mBAAoBA,EAAO,EAAE,EACnCA,EAuBX,CASA,SAASiB,GAAasB,EAAmB,CACvCA,EAAQ,QAASC,GAAmB,CAClC,QAAQ,IAAI,cAAeA,CAAM,EACjC,SAAS,OAASA,CACpB,CAAC,CACH,CAEA,SAASP,GAAYQ,EAAgBzC,EAA4B,CAC3DyC,EAAK,OAAS,MAChBC,GAASD,EAAK,KAAK,EAGjBA,EAAK,WAAa,OACpB,SAAS,MAAQA,EAAK,WAGxBA,EAAK,QAAQ,QAASE,GAAgB,CACpC7B,GAAe6B,EAAa3C,CAAM,CACpC,CAAC,EAEDyC,EAAK,SAAS,QAAQ,CAAC,CAACG,EAAQ3C,CAAM,IAAM,CAC1CU,GAAWiC,EAAQ3C,CAAM,CAC3B,CAAC,CACH,CAEA,SAASa,GAAe6B,EAA0B3C,EAA4B,CAC5E,WAAW,IAAM,CACf,IAAI6C,EAAQ,IAAI,YAAYF,EAAY,KAAM,CAAE,QAAS,GAAM,OAAQA,EAAY,MAAO,CAAC,GACzE3C,GAAU,UAChB,cAAc6C,CAAK,CACjC,EAAG,EAAE,CACP,CAEA,SAASlC,GAAWiC,EAAgB3C,EAAuB,CACzD,WAAW,IAAM,CACf,IAAI6C,EAAO,OAAO,WAAW,UAAUF,CAAM,EACzCE,GACF/C,EAAU+C,EAAM7C,CAAM,CAE1B,EAAG,EAAE,CACP,CAGA,SAASoC,GAAUrC,EAAqB,CACtC,IAAI+C,EAAU/C,EAAO,cAAgC,aAAa,EAC9D+C,GAAS,OACXA,EAAQ,MAAM,EAGhB/C,EAAO,iBAAmC,cAAc,EAAE,QAASgD,GAAU,CAC3E,IAAIC,EAAMD,EAAM,aAAa,OAAO,EAChCC,IAAQ,OACVD,EAAM,MAAQC,EAElB,CAAC,EAEDjD,EAAO,iBAAmC,sBAAsB,EAAE,QAASkD,GAAa,CACtF,IAAIC,EAAUD,EAAS,QAAQ,SAAW,OAC1CA,EAAS,QAAUC,CACrB,CAAC,CACH,CAEA,SAAS1B,GAAO2B,EAA8B,CAC5C,GAAI,CAACA,EAAK,OACV,IAAMC,EAAQD,EAAI,OAAO,SACzB,GAAKC,EACL,QAASC,EAAI,EAAGA,EAAID,EAAM,OAAQC,IAAK,CACrC,IAAMC,EAAOF,EAAM,KAAKC,CAAC,EACrBC,GAAQzD,GAAgB,IAAIyD,EAAK,OAAO,GAAK,IAAS1D,EAAW,QACnEA,EAAW,MAAM,WAAW0D,EAAK,OAAO,EACxCzD,GAAgB,IAAIyD,EAAK,OAAO,EAEpC,CACF,CAKA,SAASC,IAAO,CAEd,IAAIf,EAAOgB,EAAc,SAAS,eAAe,cAAc,GAAG,WAAa,EAAE,EAEjFxB,GAAYQ,EAAM,IAAI,EAEtB,IAAMiB,EAAQ,SAAS,KAAK,cAAc,OAAO,EAE7CA,IAAU,KACZ7D,EAAa6D,GAEb,QAAQ,KAAK,2CAA2C,EACxD7D,EAAa,SAAS,cAAc,OAAO,EAC3CA,EAAW,KAAO,WAClB,SAAS,KAAK,YAAYA,CAAU,GAGtC8D,GAAe,eAAe3D,EAAmBC,EAAgB,CAC/DF,EAAUC,EAAQC,CAAM,CAC1B,CAAC,EAEDiC,EAAW,SAAS,IAAI,EACxBC,EAAiB,SAAS,IAAI,EAC9BC,EAAiB,SAAS,IAAI,EAC9BE,EAAiB,SAAS,KAAMvC,CAAS,EAGzC6D,GAAY,eAAe5D,EAAmBC,EAAgB,CAE5DF,EAAUC,EAAQC,CAAM,CAC1B,CAAC,EAED4D,GAAe,eAAe7D,EAAmBC,EAAgB,CAE/DF,EAAUC,EAAQC,CAAM,CAC1B,CAAC,EAED6D,GAAc,eAAe9D,EAAmBC,EAAgB,CAE9DF,EAAUC,EAAQC,CAAM,CAC1B,CAAC,EAED8D,GAAY,eAAe/D,EAAmBC,EAAgB,CAE5DF,EAAUC,EAAQC,CAAM,CAC1B,CAAC,EAED+D,GAAiB,eAAehE,EAAmBC,EAAgBC,EAAgB,CAEjFH,EAAUC,EAAQC,EAAQC,CAAI,CAChC,CAAC,EAED+D,GAAa,eAAejE,EAAmBC,EAAgB,CAC7DF,EAAUC,EAAQC,CAAM,CAC1B,CAAC,EAED,SAASiE,EAAgBlE,EAAmB,CACtCA,EAAO,aAAe,WACxBA,EAAO,oBAAoB,CAE/B,CAEAmE,GAAYD,EAAiB,eAAelE,EAAmBC,EAAgB,CAC7EF,EAAUC,EAAQC,CAAM,CAC1B,CAAC,CACH,CAOA,SAAS,iBAAiB,mBAAoBuD,EAAI,EAKlD,IAAMhD,EAAO,IAAI4D,EAEjB5D,EAAK,QAAQ,EACbA,EAAK,iBAAiB,SAAWK,GAA4B,CAAEO,GAAaP,EAAG,MAAM,CAAE,CAAC,EACxFL,EAAK,iBAAiB,WAAaK,GAA4BK,GAAeL,EAAG,MAAM,CAAC,EACxFL,EAAK,iBAAiB,WAAaK,GAA8BE,GAAeF,EAAG,MAAM,CAAC,EAC1FL,EAAK,iBAAiB,UAAYK,GAA6BJ,GAAcI,EAAG,MAAM,CAAC,EACvFL,EAAK,iBAAiB,QAAUK,GAA6BD,GAAYC,EAAG,MAAM,CAAC,EAsDnF,OAAO,UACP,CACE,UAAWd,EACX,cAAe0D,EACf,OAAQ,SAASY,KAAQC,EAAe,CACtC,OAAOA,EAAO,OAAO,CAACC,EAAKC,IAAUD,EAAM,IAAM,KAAK,UAAUC,CAAK,EAAGH,CAAG,CAC7E,EACA,UAAW,SAASzB,EAAQ,CAC1B,IAAI6B,EAAU,SAAS,eAAe7B,CAAM,EAC5C,GAAI,CAACtB,EAAYmD,CAAO,EAAG,CACzB,QAAQ,MAAM,cAAgB7B,EAAS,sBAAsB,EAC7D,MACF,CACA,OAAO6B,CACT,EACA,OAAQjE,CACV",
+  "names": ["DATA_KEY_ATTRIBUTE", "hasProperty", "obj", "prop", "Object", "prototype", "hasOwnProperty", "call", "keyIsValid", "map", "key", "console", "warn", "forEach", "items", "fn", "length", "idx", "createKeyMap", "children", "child", "attributes", "_", "insertBefore", "parent", "refNode", "node", "assignVNode", "template", "vNode", "property", "toHTML", "htmlString", "processedDOMString", "trim", "replace", "parser", "DOMParser", "context", "parseFromString", "body", "Types", "STRING", "INT", "BOOL", "DomProperties", "createRecord", "attrName", "propName", "type", "stringProps", "_ref", "_ref2", "_slicedToArray", "attr", "booleanProps", "integerProps", "_ref3", "_ref4", "Namespace", "xlink", "prefix", "resource", "xml", "setProperty", "element", "value", "style", "toLowerCase", "removeAttribute", "parsed", "parseInt", "isNaN", "indexOf", "removeAttributes", "propertyRecord", "setAttributes", "startsWith", "setAttributeNS", "setAttribute", "getPropertyValues", "attrValue", "getAttribute", "getBaseAttributes", "Array", "reduce", "name", "getAttributes", "updateAttributes", "removedAttributes", "changedAttributes", "oldValue", "nextValue", "push", "patchChildren", "patch", "templateChildrenLength", "vNodeChildrenLength", "vNodeKeyMap", "nextChildren", "undefined", "templateChild", "childNodes", "keyedChild", "vNodeChild", "appendChild", "childNodesLength", "delta", "removeChild", "rootNode", "parentNode", "contentChanged", "content", "replaceChild", "create", "node", "isSVGContext", "arguments", "length", "undefined", "toHTML", "isRoot", "tagName", "childNodes", "numChildNodes", "Error", "type", "nodeType", "toLowerCase", "isSVG", "attributes", "getAttributes", "content", "textContent", "children", "Array", "forEach", "child", "idx", "takeWhileMap", "pred", "lines", "output", "line", "a", "dropWhile", "index", "renderMetas", "meta", "m", "toMetadata", "metaValue", "metaValuesAll", "parseRemoteEvent", "parseAction", "parseMetadata", "input", "metas", "takeWhileMap", "parseMeta", "key", "splitMessage", "message", "lines", "command", "rest", "dropWhile", "l", "line", "match", "name", "data", "breakNextSegment", "viewId", "action", "ix", "err", "actionMessage", "id", "action", "state", "reqId", "form", "meta", "toSearch", "params", "value", "key", "renderActionMessage", "msg", "header", "renderMetas", "renderForm", "globalRequestId", "newRequest", "encodedParam", "param", "sanitizeParam", "protocol", "defaultAddress", "SocketConnection", "addr", "sock", "createSocket", "onConnectError", "ev", "onSocketError", "_event", "_", "action", "msg", "renderActionMessage", "next", "event", "command", "metas", "rest", "splitMessage", "requestId", "requireMeta", "key", "val", "metaValue", "ProtocolError", "parseResponse", "viewId", "toMetadata", "parseUpdate", "up", "parseRedirect", "url", "parseTrigger", "meta", "targetViewId", "targetAction", "parseAction", "parseEvent", "parseRemoteEvent", "cb", "description", "body", "debounce", "function_", "wait", "options", "immediate", "storedContext", "storedArguments", "timeoutId", "timestamp", "result", "run", "callContext", "callArguments", "later", "last", "debounced", "arguments_", "callNow", "isHyperView", "ele", "dispatchContent", "node", "event", "enrichHyperViews", "runAction", "element", "action", "listenKeydown", "cb", "listenKeyEvent", "listenKeyup", "event", "e", "source", "datasetKey", "action", "target", "nearestHyperViewTarget", "listenBubblingEvent", "listenClick", "listenDblClick", "listenTopLevel", "listenLoad", "node", "load", "delay", "onLoad", "listenMouseEnter", "onMouseEnter", "nearestAnyTarget", "listenMouseLeave", "onMouseLeave", "listenChange", "encodedParam", "listenInput", "startedTyping", "debounce", "listenFormSubmit", "form", "formData", "nearestTargetId", "isHyperView", "targetId", "setQuery", "query", "currentQuery", "url", "parseResponse", "res", "doc", "css", "package_default", "package_default", "rootStyles", "addedRulesIndex", "runAction", "target", "action", "form", "state", "req", "newRequest", "msg", "actionMessage", "sock", "handleTrigger", "trigger", "runTrigger", "handleEvent", "ev", "runRemoteEvent", "handleRedirect", "red", "applyCookies", "handleResponse", "res", "handleUpdate", "targetViewId", "isHyperView", "update", "parseResponse", "addCSS", "old", "create", "next", "atts", "patch", "newTarget", "dispatchContent", "runMetadata", "listenLoad", "listenMouseEnter", "listenMouseLeave", "fixInputs", "enrichHyperViews", "cookies", "cookie", "meta", "setQuery", "remoteEvent", "viewId", "event", "view", "focused", "input", "val", "checkbox", "checked", "src", "rules", "i", "rule", "init", "parseMetadata", "style", "listenTopLevel", "listenClick", "listenDblClick", "listenKeydown", "listenKeyup", "listenFormSubmit", "listenChange", "onStartedTyping", "listenInput", "SocketConnection", "con", "params", "str", "param", "element"]
+}
diff --git a/hyperbole.cabal b/hyperbole.cabal
--- a/hyperbole.cabal
+++ b/hyperbole.cabal
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           hyperbole
-version:        0.6.0
+version:        0.6.1
 synopsis:       Interactive HTML apps using type-safe serverside Haskell
 description:    Interactive HTML applications with type-safe serverside Haskell. Inspired by HTMX, Elm, and Phoenix LiveView.
 category:       Web, Network
@@ -107,7 +107,7 @@
     , effectful >=2.4 && <3
     , file-embed >=0.0.10 && <0.1
     , filepath >=1.4 && <2
-    , http-api-data ==0.6.*
+    , http-api-data >=0.6 && <0.8
     , http-client ==0.7.*
     , http-client-tls ==0.3.*
     , http-types ==0.12.*
@@ -137,6 +137,7 @@
       Test.URISpec
       Test.ViewActionSpec
       Test.ViewIdSpec
+      Test.ViewSpec
       Paths_hyperbole
   autogen-modules:
       Paths_hyperbole
@@ -168,7 +169,7 @@
     , effectful >=2.4 && <3
     , file-embed >=0.0.10 && <0.1
     , filepath >=1.4 && <2
-    , http-api-data ==0.6.*
+    , http-api-data >=0.6 && <0.8
     , http-client ==0.7.*
     , http-client-tls ==0.3.*
     , http-types ==0.12.*
diff --git a/src/Web/Hyperbole/Data/Cookie.hs b/src/Web/Hyperbole/Data/Cookie.hs
--- a/src/Web/Hyperbole/Data/Cookie.hs
+++ b/src/Web/Hyperbole/Data/Cookie.hs
@@ -19,6 +19,7 @@
   { key :: Key
   , path :: Maybe Path
   , value :: Maybe CookieValue
+  , secure :: Bool
   }
   deriving (Show, Eq)
 
@@ -60,7 +61,9 @@
 render :: Path -> Cookie -> ByteString
 render requestPath cookie =
   let p = fromMaybe requestPath cookie.path
-   in cs cookie.key <> "=" <> value cookie.value <> "; SameSite=None; secure; path=" <> cs (uriToText (pathUri p))
+      secureFlag = if cookie.secure then "; secure" else ""
+      sameSite = if cookie.secure then "; SameSite=None" else "; SameSite=Lax"
+   in cs cookie.key <> "=" <> value cookie.value <> sameSite <> secureFlag <> "; path=" <> cs (uriToText (pathUri p))
  where
   value Nothing = "; expires=Thu, 01 Jan 1970 00:00:00 GMT"
   value (Just (CookieValue val)) = urlEncode True $ cs val
@@ -75,4 +78,4 @@
 parseValue :: ByteString -> ByteString -> Either String Cookie
 parseValue k val = do
   let cval = CookieValue $ cs $ urlDecode True val
-  pure $ Cookie (cs k) Nothing (Just $ cval)
+  pure $ Cookie (cs k) Nothing (Just $ cval) True
diff --git a/src/Web/Hyperbole/Data/Encoded.hs b/src/Web/Hyperbole/Data/Encoded.hs
--- a/src/Web/Hyperbole/Data/Encoded.hs
+++ b/src/Web/Hyperbole/Data/Encoded.hs
@@ -164,11 +164,33 @@
   t -> ParamValue $ desanitizeParamText t
 
 
--- replace all underscores that are NOT "\\_" with spaces
+-- Param encoding scheme:
+--   Wire format must not contain bare spaces (field separator) or real newlines.
+--   We use backslash as the escape character:
+--     '\'  → "\\"    (escape backslash itself, so it cannot be confused with an escape prefix)
+--     '\n' → "\n"    (literal backslash + 'n', for real newline characters)
+--     '_'  → "\_"    (escape underscore, since bare underscore encodes space)
+--     ' '  → "_"     (encode space as underscore)
+--   Decoding is the single-pass reverse of the above.
+--
+-- The critical invariant: backslash is escaped FIRST on encode and unescaped
+-- LAST on decode.  This ensures that JSON escape sequences (e.g. the two chars
+-- '\' 'n' inside "[\"\n\"]") are treated as an escaped backslash followed by
+-- a plain 'n', not as the param newline escape.
+-- See: https://github.com/seanhess/hyperbole/issues/187
 
 desanitizeParamText :: Text -> Text
-desanitizeParamText =
-  T.replace "\\ " "_" . T.replace "_" " " . T.replace "\\n" "\n"
+desanitizeParamText = go
+ where
+  go t = case T.uncons t of
+    Nothing -> ""
+    Just ('\\', rest) -> case T.uncons rest of
+      Just ('\\', rest') -> T.cons '\\' (go rest')   -- \\ → \
+      Just ('n', rest')  -> T.cons '\n' (go rest')   -- \n → newline
+      Just ('_', rest')  -> T.cons '_' (go rest')    -- \_ → _
+      _                  -> T.cons '\\' (go rest)    -- bare backslash (shouldn't occur)
+    Just ('_', rest) -> T.cons ' ' (go rest)         -- _ → space
+    Just (c, rest)   -> T.cons c (go rest)            -- other chars verbatim
 
 
 --   | T.isSuffixOf "\\" seg = T.dropEnd 1 seg <> "_" <> txt
@@ -190,10 +212,14 @@
     "" -> "|"
     _ -> sanitizeParamText t
  where
-  -- Q: Should we also sanitize \r\n?
+  -- Encode a param value for the wire format.
+  -- Backslash MUST be escaped first (before newline), otherwise a literal
+  -- backslash followed by 'n' in the input (e.g. from JSON encoding) would
+  -- be indistinguishable from the newline escape on the wire.
+  -- See: https://github.com/seanhess/hyperbole/issues/187
   sanitizeParamText :: Text -> Text
   sanitizeParamText =
-    T.replace " " "_" . T.replace "_" "\\_" . T.replace "\n" "\\n"
+    T.replace " " "_" . T.replace "_" "\\_" . T.replace "\n" "\\n" . T.replace "\\" "\\\\"
 
 
 -- decodeParamValue :: (FromParam a) => Text -> Either String a
diff --git a/src/Web/Hyperbole/Effect/Client.hs b/src/Web/Hyperbole/Effect/Client.hs
--- a/src/Web/Hyperbole/Effect/Client.hs
+++ b/src/Web/Hyperbole/Effect/Client.hs
@@ -20,7 +20,7 @@
 -}
 trigger :: (HyperView id es, HyperViewHandled id view, Hyperbole :> es) => id -> Action id -> Eff (Reader view : es) ()
 trigger vid act = do
-  send $ TriggerAction (TargetViewId $ toViewId vid) (toAction act)
+  send $ PushTrigger (TargetViewId $ toViewId vid) (toAction act)
 
 
 {- | Dispatch a custom javascript event. This is emitted on the current hyper view and bubbles up to the document
@@ -40,7 +40,7 @@
 -}
 pushEvent :: (ToJSON a, Hyperbole :> es) => Text -> a -> Eff es ()
 pushEvent nm a = do
-  send $ TriggerEvent nm (toJSON a)
+  send $ PushEvent nm (toJSON a)
 
 
 {- | Set the document title
diff --git a/src/Web/Hyperbole/Effect/Hyperbole.hs b/src/Web/Hyperbole/Effect/Hyperbole.hs
--- a/src/Web/Hyperbole/Effect/Hyperbole.hs
+++ b/src/Web/Hyperbole/Effect/Hyperbole.hs
@@ -22,9 +22,8 @@
   PushUpdate :: ViewUpdate -> Hyperbole m ()
   ModClient :: (Client -> Client) -> Hyperbole m ()
   GetClient :: Hyperbole m Client
-  -- TODO: this should actually execute the other view, and send the response to the client
-  TriggerAction :: TargetViewId -> Encoded -> Hyperbole m ()
-  TriggerEvent :: Text -> Value -> Hyperbole m ()
+  PushTrigger :: TargetViewId -> Encoded -> Hyperbole m ()
+  PushEvent :: Text -> Value -> Hyperbole m ()
 
 
 type instance DispatchOf Hyperbole = 'Dynamic
diff --git a/src/Web/Hyperbole/Effect/Session.hs b/src/Web/Hyperbole/Effect/Session.hs
--- a/src/Web/Hyperbole/Effect/Session.hs
+++ b/src/Web/Hyperbole/Effect/Session.hs
@@ -42,6 +42,12 @@
   cookiePath = Nothing
 
 
+  -- | By default cookies are secure (HTTPS only). Set to False for local development or LAN usage
+  cookieSecure :: Bool
+  default cookieSecure :: Bool
+  cookieSecure = True
+
+
   -- | Encode type to a a cookie value
   toCookie :: a -> CookieValue
   default toCookie :: (ToEncoded a) => a -> CookieValue
@@ -113,7 +119,7 @@
 -- | Remove a single 'Session' from the browser cookies
 deleteSession :: forall a es. (Session a, Hyperbole :> es) => Eff es ()
 deleteSession = do
-  let cookie = Cookie (sessionKey @a) (cookiePath @a) Nothing
+  let cookie = Cookie (sessionKey @a) (cookiePath @a) Nothing (cookieSecure @a)
   modifyCookies $ Cookie.insert cookie
 
 
@@ -158,7 +164,7 @@
 
 sessionCookie :: forall a. (Session a) => a -> Cookie
 sessionCookie a =
-  Cookie (sessionKey @a) (cookiePath @a) (Just $ toCookie a)
+  Cookie (sessionKey @a) (cookiePath @a) (Just $ toCookie a) (cookieSecure @a)
 
 
 -- | generic datatype name
diff --git a/src/Web/Hyperbole/HyperView/Forms.hs b/src/Web/Hyperbole/HyperView/Forms.hs
--- a/src/Web/Hyperbole/HyperView/Forms.hs
+++ b/src/Web/Hyperbole/HyperView/Forms.hs
@@ -126,8 +126,6 @@
 
 {- | Generate FieldNames for a form
 
-#EXAMPLE /forms
-
 > #EMBED Example.Todos.Todo data TodoForm
 >
 > #EMBED Example.Todos.Todo todoForm
@@ -252,7 +250,7 @@
 checkbox :: forall id a. Bool -> View (Input id a) ()
 checkbox isChecked = do
   inp :: Input id a <- viewId
-  tag "input" @ att "type" "checkbox" . name inp.inputName.value $ none @ checked isChecked
+  tag "input" @ att "type" "checkbox" . checked isChecked . name inp.inputName.value $ none
 
 
 -- NOTE: Radio is a special type of selection different from list type or
diff --git a/src/Web/Hyperbole/HyperView/Input.hs b/src/Web/Hyperbole/HyperView/Input.hs
--- a/src/Web/Hyperbole/HyperView/Input.hs
+++ b/src/Web/Hyperbole/HyperView/Input.hs
@@ -24,8 +24,6 @@
 
 {- | Type-safe dropdown. Sends (opt -> Action id) when selected. The default will be selected.
 
-#EXAMPLE /data/filter
-
 @
 #EMBED Example.DataLists.Filter familyDropdown
 @
diff --git a/src/Web/Hyperbole/Server/Message.hs b/src/Web/Hyperbole/Server/Message.hs
--- a/src/Web/Hyperbole/Server/Message.hs
+++ b/src/Web/Hyperbole/Server/Message.hs
@@ -232,15 +232,17 @@
 
 
 metaRemotes :: [Remote] -> Metadata
-metaRemotes rs = mconcat $ fmap meta rs
- where
-  meta = \case
-    RemoteAction (TargetViewId vid) act ->
-      metadata "Trigger" $ encodedToText vid <> "|" <> encodedToText act
-    RemoteEvent ev dat ->
-      metadata "Event" $ T.intercalate "|" [ev, cs $ Aeson.encode dat]
+metaRemotes = mconcat . fmap metaRemote
 
 
+metaRemote :: Remote -> Metadata
+metaRemote = \case
+  RemoteAction (TargetViewId vid) act ->
+    metadata "Trigger" $ encodedToText vid <> "|" <> encodedToText act
+  RemoteEvent ev dat ->
+    metadata "Event" $ T.intercalate "|" [ev, cs $ Aeson.encode dat]
+
+
 metaError :: Text -> Metadata
 metaError = metadata "Error"
 
@@ -256,3 +258,4 @@
 data RenderedMessage
   = MessageHtml BL.ByteString
   | MessageText Text
+  | MessageNone
diff --git a/src/Web/Hyperbole/Server/Socket.hs b/src/Web/Hyperbole/Server/Socket.hs
--- a/src/Web/Hyperbole/Server/Socket.hs
+++ b/src/Web/Hyperbole/Server/Socket.hs
@@ -3,6 +3,7 @@
 module Web.Hyperbole.Server.Socket where
 
 import Control.Monad (void)
+import Data.Aeson (Value)
 import Data.Bifunctor (first)
 import Data.List qualified as L
 import Data.Map (Map)
@@ -18,7 +19,6 @@
 import Effectful.Error.Static (throwError_)
 import Effectful.Exception
 import Effectful.State.Static.Local as Local (get, modify)
-import Effectful.Writer.Static.Local (tell)
 import Network.HTTP.Types as HTTP (parseQuery)
 import Network.Wai qualified as Wai
 import Network.WebSockets (Connection)
@@ -56,16 +56,16 @@
     pure req
   RespondNow r -> do
     throwError_ r
-  PushUpdate (ViewUpdate vid vw) -> do
-    sendUpdate conn (targetViewMetadata vid <> requestMetadata req) vw
   GetClient -> do
     Local.get @Client
   ModClient f -> do
     Local.modify @Client f
-  TriggerAction vid act -> do
-    tell [RemoteAction vid act]
-  TriggerEvent name dat -> do
-    tell [RemoteEvent name dat]
+  PushUpdate (ViewUpdate vid vw) -> do
+    sendUpdate conn req vid vw
+  PushTrigger vid act -> do
+    sendTrigger conn req vid act
+  PushEvent name dat -> do
+    sendEvent conn req name dat
 
 
 handleRequestSocket
@@ -190,11 +190,21 @@
   sendMessage "RESPONSE" conn meta (MessageHtml b)
 
 
-sendUpdate :: (IOE :> es) => Connection -> Metadata -> Body -> Eff es ()
-sendUpdate conn meta (Body b) = do
-  sendMessage "UPDATE" conn meta (MessageHtml b)
+sendUpdate :: (IOE :> es) => Connection -> Request -> TargetViewId -> Body -> Eff es ()
+sendUpdate conn req vid (Body b) = do
+  sendMessage "UPDATE" conn (requestMetadata req <> targetViewMetadata vid) (MessageHtml b)
 
 
+sendTrigger :: (IOE :> es) => Connection -> Request -> TargetViewId -> Encoded -> Eff es ()
+sendTrigger conn req vid act = do
+  sendRemote "TRIGGER" conn req $ RemoteAction vid act
+
+
+sendEvent :: (IOE :> es) => Connection -> Request -> Text -> Value -> Eff es ()
+sendEvent conn req nm val = do
+  sendRemote "EVENT" conn req $ RemoteEvent nm val
+
+
 sendRedirect :: (IOE :> es) => Connection -> Metadata -> URI -> Eff es ()
 sendRedirect conn meta u = do
   sendMessage "REDIRECT" conn meta (MessageText $ uriToText u)
@@ -209,13 +219,19 @@
   deriving newtype (IsString)
 
 
+sendRemote :: (IOE :> es) => Command -> Connection -> Request -> Remote -> Eff es ()
+sendRemote cmd conn req remote = do
+  sendMessage cmd conn (requestMetadata req <> metaRemote remote) MessageNone
+
+
 -- low level message. Use sendResponse
 sendMessage :: (MonadIO m) => Command -> Connection -> Metadata -> RenderedMessage -> m ()
 sendMessage (Command cmd) conn meta' msg = do
   let header = "|" <> cs cmd <> "|\n" <> cs (renderMetadata meta')
 
   let body = case msg of
-        MessageHtml html -> html
-        MessageText t -> cs t
+        MessageHtml html -> "\n\n" <> html
+        MessageText t -> "\n\n" <> cs t
+        MessageNone -> ""
 
-  liftIO $ WS.sendTextData conn (header <> "\n\n" <> body)
+  liftIO $ WS.sendTextData conn (header <> body)
diff --git a/src/Web/Hyperbole/Server/Wai.hs b/src/Web/Hyperbole/Server/Wai.hs
--- a/src/Web/Hyperbole/Server/Wai.hs
+++ b/src/Web/Hyperbole/Server/Wai.hs
@@ -61,16 +61,19 @@
     pure req
   RespondNow r -> do
     throwError_ r
-  PushUpdate _ -> do
-    -- ignore! you can't push updates using WAI
-    pure ()
   GetClient -> do
     get @Client
   ModClient f -> do
     modify @Client f
-  TriggerAction vid act -> do
+  PushUpdate _ -> do
+    -- ignore! you can't push updates using WAI
+    -- whatever you end up returning after all pushes will be what the user sees
+    pure ()
+  PushTrigger vid act -> do
+    -- deferred until the response
     tell [RemoteAction vid act]
-  TriggerEvent name dat -> do
+  PushEvent name dat -> do
+    -- deferred until the response
     tell [RemoteEvent name dat]
 
 
diff --git a/src/Web/Hyperbole/View/Types.hs b/src/Web/Hyperbole/View/Types.hs
--- a/src/Web/Hyperbole/View/Types.hs
+++ b/src/Web/Hyperbole/View/Types.hs
@@ -56,9 +56,9 @@
   (>>=) :: forall a b. View ctx a -> (a -> View ctx b) -> View ctx b
   -- TEST: appending Empty
   View ea >>= famb = View $ do
-    a :: a <- (.value) <$> ea
-    let View eb :: View ctx b = famb a
-    eb
+    ha <- ea
+    let View eb = famb ha.value
+    (ha >>) <$> eb
 
 
 -- Context -----------------------------------------
diff --git a/test/Test/EncodedSpec.hs b/test/Test/EncodedSpec.hs
--- a/test/Test/EncodedSpec.hs
+++ b/test/Test/EncodedSpec.hs
@@ -232,6 +232,17 @@
       print $ encode l
       decode @Sum (encode l) `shouldBe` Just l
 
+    -- Regression tests for https://github.com/seanhess/hyperbole/issues/187
+    -- A ViewId (or state) containing a list with newline characters must
+    -- encode/decode correctly.  Previously, desanitizeParamText blindly
+    -- replaced the JSON escape sequence "\\n" with a real newline, corrupting
+    -- the JSON and causing "No Handler for Event viewId".
+    it "list with newline character round-trips correctly (issue #187)" $ do
+      decode @Sum (encode (List ["\n"])) `shouldBe` Just (List ["\n"])
+
+    it "list with newline in multiple elements" $ do
+      decode @Sum (encode (List ["\n", "hello\nworld", "plain"])) `shouldBe` Just (List ["\n", "hello\nworld", "plain"])
+
     it "strings" $ do
       decode @Sum (encode (Str "")) `shouldBe` pure (Str "")
       decode @Sum (encode (Str " ")) `shouldBe` pure (Str " ")
diff --git a/test/Test/SessionSpec.hs b/test/Test/SessionSpec.hs
--- a/test/Test/SessionSpec.hs
+++ b/test/Test/SessionSpec.hs
@@ -21,6 +21,12 @@
   cookiePath = Just $ Path ["somepage"]
 
 
+data InsecureSession = InsecureSession Text
+  deriving (Generic, Show, ToEncoded, FromEncoded)
+instance Session InsecureSession where
+  cookieSecure = False
+
+
 spec :: Spec
 spec = do
   describe "Session" $ do
@@ -31,16 +37,20 @@
   describe "sessionCookie" $ do
     it "should create cookie" $ do
       let woot = Woot "hello"
-      sessionCookie woot `shouldBe` Cookie (sessionKey @Woot) (cookiePath @Woot) (Just (toCookie woot))
+      sessionCookie woot `shouldBe` Cookie (sessionKey @Woot) (cookiePath @Woot) (Just (toCookie woot)) (cookieSecure @Woot)
 
   describe "render" $ do
     it "should parse cookies" $ do
-      Cookie.parse [("Woot", "Woot")] `shouldBe` Right (Cookie.fromList [Cookie "Woot" Nothing (Just (CookieValue "Woot"))])
+      Cookie.parse [("Woot", "Woot")] `shouldBe` Right (Cookie.fromList [Cookie "Woot" Nothing (Just (CookieValue "Woot")) True])
 
     it "should render cookie with root path" $ do
-      let cookie = Cookie "Woot" Nothing (Just (CookieValue "Woot"))
+      let cookie = Cookie "Woot" Nothing (Just (CookieValue "Woot")) True
       Cookie.render [] cookie `shouldBe` "Woot=Woot; SameSite=None; secure; path=/"
 
+    it "should render non-secure cookie" $ do
+      let cookie = Cookie "Woot" Nothing (Just (CookieValue "Woot")) False
+      Cookie.render [] cookie `shouldBe` "Woot=Woot; SameSite=Lax; path=/"
+
     it "should render complex cookie with included path" $ do
       let woot = Woot "hello world"
       let cookie = sessionCookie woot
@@ -57,6 +67,11 @@
       let cooks = Cookie.insert (sessionCookie prefs) mempty
       Just val <- pure $ Cookie.lookup (sessionKey @Preferences) cooks
       parseCookie val `shouldBe` Right prefs
+
+    it "should create non-secure cookie when cookieSecure is False" $ do
+      let insecure = InsecureSession "test"
+      let cookie = sessionCookie insecure
+      cookie.secure `shouldBe` False
 
 
 data Preferences = Preferences
diff --git a/test/Test/ViewIdSpec.hs b/test/Test/ViewIdSpec.hs
--- a/test/Test/ViewIdSpec.hs
+++ b/test/Test/ViewIdSpec.hs
@@ -34,6 +34,11 @@
   deriving (Generic, Show, Eq, Read, ViewId)
 
 
+-- Regression test for https://github.com/seanhess/hyperbole/issues/187
+data MessageView = MessageView [Text]
+  deriving (Generic, Show, Eq, ViewId)
+
+
 newtype Id a = Id {fromId :: Text}
   deriving newtype (Eq, ToJSON, FromJSON, Ord, Show, ToParam, FromParam)
   deriving (Generic)
@@ -79,6 +84,18 @@
       it "should roundtrip" $ do
         let vid = encodeViewId p
         decodeViewId vid `shouldBe` pure p
+
+    -- Regression tests for https://github.com/seanhess/hyperbole/issues/187
+    -- When a ViewId contains a list of Text with newline characters, the
+    -- encoded/decoded form must round-trip correctly.
+    describe "list with newline (issue #187)" $ do
+      it "roundtrips MessageView with single newline" $ do
+        let v = MessageView ["\n"]
+        decodeViewId (encodeViewId v) `shouldBe` pure v
+
+      it "roundtrips MessageView with newlines in multiple elements" $ do
+        let v = MessageView ["\n", "hello\nworld", "plain"]
+        decodeViewId (encodeViewId v) `shouldBe` pure v
 
 
 -- describe "Param Attributes" $ do
diff --git a/test/Test/ViewSpec.hs b/test/Test/ViewSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/Test/ViewSpec.hs
@@ -0,0 +1,23 @@
+module Test.ViewSpec where
+
+import Skeletest
+import Web.Hyperbole
+
+
+spec :: Spec
+spec = do
+  describe "View" $ do
+    describe "monad" $ do
+      it "renders all nodes with do" $ do
+        let v = do
+              el "one"
+              el "two"
+        renderText v `shouldBe` "<div>one</div>\n<div>two</div>"
+
+      it "renders all nodes with >>" $ do
+        let v = el "one" >> el "two"
+        renderText v `shouldBe` "<div>one</div>\n<div>two</div>"
+
+      it "renders all nodes with >>=" $ do
+        let v = el "one" >>= \_ -> el "two"
+        renderText v `shouldBe` "<div>one</div>\n<div>two</div>"
