Help
RSS
API
Feed
Maltego
Contact
Domain > www.memegenerator.net
×
More information on this domain is in
AlienVault OTX
Is this malicious?
Yes
No
Whois
Property
Value
NameServer
NS46.DOMAINCONTROL.COM
Created
2009-03-18 00:00:00
Changed
2016-04-09 00:00:00
Expires
2018-03-18 00:00:00
Registrar
GODADDY.COM, LLC
DNS Resolutions
Date
IP Address
2020-12-04
172.64.135.12
(
ClassC
)
2024-08-08
172.67.198.95
(
ClassC
)
Port 80
HTTP/1.1 301 Moved PermanentlyDate: Thu, 08 Aug 2024 12:07:22 GMTContent-Type: text/htmlContent-Length: 167Connection: keep-aliveCache-Control: max-age3600Expires: Thu, 08 Aug 2024 13:07:22 GMTLocation: https://www.memegenerator.net/Report-To: {endpoints:{url:https:\/\/a.nel.cloudflare.com\/report\/v4?sN1%2Bztd27tlS1DVst%2BE9763E6VEA0Qb9bHQmkd1SdGbg5kkm4PPxEk9dcEMxaijJFJFiT730NDCGsWenJY1YJo3VzlbjtXifA9WI7cF2CsIxz5HwbZ1WzeJ8zqGzhRbr8Srzby1poJ2s%3D},group:cf-nel,max_age:604800}NEL: {success_fraction:0,report_to:cf-nel,max_age:604800}Server: cloudflareCF-RAY: 8aff62bfda852805-SEAalt-svc: h3:443; ma86400 html>head>title>301 Moved Permanently/title>/head>body>center>h1>301 Moved Permanently/h1>/center>hr>center>cloudflare/center>/body>/html>
Port 443
HTTP/1.1 200 OKDate: Thu, 08 Aug 2024 12:07:23 GMTContent-Type: text/html; charsetutf-8Transfer-Encoding: chunkedConnection: keep-aliveX-Powered-By: ExpressAccess-Control-Allow-Origin: www.memegenerator.netAccess-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONSAccess-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorizationx-debug-proxy-source: forwarded (0 attempt)CF-Cache-Status: DYNAMICReport-To: {endpoints:{url:https:\/\/a.nel.cloudflare.com\/report\/v4?s9pIknhF%2FyIyeVbCH7HW08tXjIGS2KP1kkhPXwsC7q6PA316etWdeamRB5SOWeZOluNOr4IGR4DGRgnBuWkh8LvUcIZczkRCLVZTE4OgwUGhpGYg%2F5crGhcvjsdUsfy2uijjW5YA8Df8%3D},group:cf-nel,max_age:604800}NEL: {success_fraction:0,report_to:cf-nel,max_age:604800}Server: cloudflareCF-RAY: 8aff62c03e60283d-SEAalt-svc: h3:443; ma86400 !DOCTYPE html>html>head>meta contentwidthdevice-width, initial-scale1 data-n-headssr nameviewport/>meta propertyog:title contentMeme Generator/>meta propertyog:type contentarticle/>meta propertyog:url contenthttps://memegenerator.net//>meta propertyog:image/>meta propertyog:description/>title>Meme Generator/title>script asyncasync defertrue src//accounts.google.com/gsi/client>/script>script asyncasync srchttps://static.addtoany.com/menu/page.js>/script>script asyncasync srchttps://www.googletagmanager.com/gtag/js?idG-P952PRPTTR>/script>script>window.dataLayer window.dataLayer || ; function gtag(){dataLayer.push(arguments);} gtag(js, new Date()); gtag(config, G-P952PRPTTR);/script>link relstylesheet hrefhttps://fonts.googleapis.com/css?familyPoppins|Roboto|Playfair|Orbitron|Audiowide|Russo One|Electrolize|Allura|Old Standard TT|Oswald|Special Elite&displayswap/>link relstylesheet hrefhttps://cdnjs.cloudflare.com/ajax/libs/AlertifyJS/1.13.1/css/alertify.css/>link relstylesheet hrefhttps://cdn.jsdelivr.net/npm/shorthandcss@1.1.1/dist/shorthand.min.css/>link relstylesheet href/css/defaults.css/>link relstylesheet href/css/layout.css/>link relstylesheet href/css/transitions.css/>link relstylesheet href/js/lib/prism/prism.css/>script srchttps://pugjs.org/js/pug.js>/script>script srchttps://cdn.jsdelivr.net/npm/deep-diff@1.0.2/dist/deep-diff.min.js>/script>script src//cdnjs.cloudflare.com/ajax/libs/AlertifyJS/1.13.1/alertify.js>/script>script srchttps://cdnjs.cloudflare.com/ajax/libs/dexie/3.2.3/dexie.js>/script>script srchttps://cdnjs.cloudflare.com/ajax/libs/js-yaml/4.1.0/js-yaml.js>/script>script srchttps://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.7/handlebars.js>/script>script srchttps://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js>/script>script srchttps://unpkg.com/vue-async-computed>/script>script src/js/lib/leader-line/leader-line.min.js>/script>script src/js/tooltip.js>/script>script>window.components {name:ide.component.activity,path:\\ide\\component\\activity.ws.yaml,source:{dom:{div#1:{.flex.gap-3.justify-between:{h3:{ui.title:{text:β¨ Activity,:number:changes.length}}},.flex1:{.slider-closed:{div#2:{class:show-on-hover-container,div#3:{ui.checkbox#1:{v-for:type in changes.map(c > c.type).distinct(),:text:$root.getIcon(type) + + getTypeName(type),:value-array:showTypes,:value-key:type}},div#4:{class:mt-l1,ui.checkbox#2:{text:π Child components,v-model:includeChildComps},transition#1:{name:slide,div#5:{v-if:includeChildComps,class:show-on-hover mt-1 ml-l1,div#6:{ui.select:{type:toggle,:options:childCompsDepthOptions,:can-select-none:false,v-model:childCompsDepthIndex,:get-item-text:(i) > (childCompsDepthOptionsi + levels deep)}},ui.checkbox#3:{v-for:vueCompName in vueCompNames,icon:π¦,:text:vueCompName,:value-array:excludedVueCompNames,:value-array-exclude:true,:value-key:vueCompName,on_mouseenter:hoveredVueCompName vueCompName,on_mouseleave:hoveredVueCompName null}}}}}},div#7:{transition.group:{tag:table,name:list2,:class:activityListClass,:key:key1,ide.state.tracker.item#1:{v-for:change in visibleChanges,:icon:β¨,:item:change,:class:{ hoverable: true, highlight: (change.vueCompName hoveredVueCompName), selected: (selectedChange change) },:show-comp-name:includeChildComps,:key:change.id,on_mouseenter:() > onMouseEnter(change),on_mouseleave:() > onMouseLeave(change),on_click:() > onClick(change)}}},div#8:{table:{transition#2:{name:slide-hor,ide.state.tracker.item#2:{v-if:selectedChange,:preview:true,:icon:β¨,:item:selectedChange,:key:selectedChange.id}}}}}}},props:{uid:null},data:{changes:,vueCompNames:,hoveredVueCompName:null,excludedVueCompNames:,includeChildComps:false,childCompsDepthOptions:all,1,2,3,4,5,childCompsDepthIndex:0,showTypes:p,d,e,m,c,selectedChange:null,key1:1},mounted:async function() {\n this.$root.$on(\state-changed\, this.onStateChanged.bind(this));\n}\n,methods:{getTypeName:function(type) {\n return {\n p: prop,\n d: data,\n e: event,\n m: method,\n c: computed,\n }type;\n}\n,getChangeDepth:function(change) {\n const mainVue this.$root.vm.getVue(this.uid);\n const changeVue this.$root.vm.getDescendant(mainVue, change.uid);\n return this.getVueDistance(mainVue, changeVue);\n}\n,getVueDistance:function(parentVue, childVue) {\n if (!childVue) return null;\n if (parentVue childVue) return 0;\n let distance 1;\n let vue childVue;\n while (vue.$parent) {\n vue vue.$parent;\n if (vue parentVue) return distance;\n distance++;\n }\n return null;\n}\n,onStateChanged:function(change) {\n if (!change) return;\n if (this.uid change.uid) this.reload();\n}\n,onMouseEnter:function(item) {\n this.$root.state.apply(this.uid, item);\n}\n,onMouseLeave:function(item) {\n}\n,onClick:function(change) {\n this.selectedChange (this.selectedChange change) ? null : change;\n}\n,getChanges:function(uid, depth 0) {\n let changes ...(this.$root.state.changes.get(uid) || );\n const vue this.$root.vm.getVue(uid);\n if (vue && this.includeChildComps && this.includeChildCompsDepth(depth)) {\n for (const childVue of vue.$children) {\n changes.push(...this.getChanges(childVue._uid, (depth + 1)));\n }\n }\n if (!depth) {\n changes changes.sortBy(c > c.id);\n changes ...changes.reverse();\n }\n return changes;\n}\n,includeChildCompsDepth:function(depth) {\n if (this.childCompsDepth all) return true;\n return (depth parseInt(this.childCompsDepth));\n}\n,reload:function() {\n this.changes this.getChanges(this.uid);\n this.vueCompNames this.changes\n .map(c > c.vueCompName)\n .distinct()\n .sort();\n}\n,refresh:function() {\n this.key1++;\n}\n},computed:{childCompsDepth:function() {\n return this.childCompsDepthOptionsthis.childCompsDepthIndex;\n}\n,activityListClass:function() {\n return {\n // slider-opened: !this.selectedChange,\n // slider-closed: !!this.selectedChange,\n };\n}\n,visibleChanges:function() {\n let changes ...this.changes;\n changes changes.filter(c > this.showTypes.includes(c.type));\n changes changes.filter(c > !this.excludedVueCompNames.includes(c.vueCompName));\n changes changes.take(50);\n return changes;\n}\n},watch:{uid:{handler:function() {\n this.reload();\n}\n,immediate:true},includeChildComps:{handler:function() {\n this.reload();\n}\n,immediate:true},excludedVueCompNames:{handler:function() {\n this.reload();\n}\n,immediate:true,deep:true}},style:{.highlight:{background-color:#ffffff20},.flex1:{display:flex,flex-direction:row,gap:1em,margin-top:1em,max-height:50vh,overflow-x:hidden,overflow-y:auto},.checkboxes:{display:flex},.disabled:{opacity:0.5}},name:ide-component-activity,_:{examples:{count:0}},template:div class\comp-ide-component-activity\ path\720218788.\>div class\flex gap-3 justify-between\ path\720218788.0\>h3 path\720218788.0.0\>ui-title text\β¨ Activity\ :number\changes.length\ path\720218788.0.0.0\>/ui-title>/h3>/div>div class\flex1\ path\720218788.1\>div class\slider-closed\ path\720218788.1.0\>div class\show-on-hover-container\ path\720218788.1.0.0\>div path\720218788.1.0.0.0\>ui-checkbox v-for\type in changes.map(c > c.type).distinct()\ :text\$root.getIcon(type) + + getTypeName(type)\ :value-array\showTypes\ :value-key\type\ path\720218788.1.0.0.0.0\>/ui-checkbox>/div>div class\mt-l1\ path\720218788.1.0.0.1\>ui-checkbox text\π Child components\ v-model\includeChildComps\ path\720218788.1.0.0.1.0\>/ui-checkbox>transition name\slide\ path\720218788.1.0.0.1.1\>div class\show-on-hover mt-1 ml-l1\ v-if\includeChildComps\ path\720218788.1.0.0.1.1.0\>div path\720218788.1.0.0.1.1.0.0\>ui-select type\toggle\ :options\childCompsDepthOptions\ v-model\childCompsDepthIndex\ :get-item-text\(i) > (childCompsDepthOptionsi + levels deep)\ path\720218788.1.0.0.1.1.0.0.0\>/ui-select>/div>ui-checkbox v-for\vueCompName in vueCompNames\ icon\π¦\ :text\vueCompName\ :value-array\excludedVueCompNames\ :value-array-exclude\true\ :value-key\vueCompName\ on_mouseenter\hoveredVueCompName vueCompName\ on_mouseleave\hoveredVueCompName null\ path\720218788.1.0.0.1.1.0.1\>/ui-checkbox>/div>/transition>/div>/div>/div>div path\720218788.1.1\>transition-group tag\table\ name\list2\ :class\activityListClass\ :key\key1\ path\720218788.1.1.0\>ide-state-tracker-item v-for\change in visibleChanges\ :icon\β¨\ :item\change\ :class\{ hoverable: true, highlight: (change.vueCompName hoveredVueCompName), selected: (selectedChange change) }\ :show-comp-name\includeChildComps\ :key\change.id\ on_mouseenter\() > onMouseEnter(change)\ on_mouseleave\() > onMouseLeave(change)\ on_click\() > onClick(change)\ path\720218788.1.1.0.0\>/ide-state-tracker-item>/transition-group>/div>div path\720218788.1.2\>table path\720218788.1.2.0\>transition name\slide-hor\ path\720218788.1.2.0.0\>ide-state-tracker-item v-if\selectedChange\ :preview\true\ :icon\β¨\ :item\selectedChange\ :key\selectedChange.id\ path\720218788.1.2.0.0.0\>/ide-state-tracker-item>/transition>/table>/div>/div>/div>}},{name:ide.component.editor,path:\\ide\\component\\editor.ws.yaml,source:{dom:{div#1:{div#2:{:key:vue()._uid,h2:{ui.title:{icon:π¦,:text:vue().$options.name}},ui.tabs:{:options:π§ state, β¨ activity, π view, π΄ methods,v-model:selectedTabIndex,direction:horizontal,template#1:{v-slot:header,div#3:{class:mt-l1}},template#2:{v-slot:tab0,ide.state.tracker:{:vue:vue}},template#3:{v-slot:tab1,ide.component.activity:{v-if:false,:vue:vue}},template#4:{v-slot:tab2,ide.component.view.editor:{v-if:false,:component:component,on_selected-node:(node) > $emit(selected-view-node, node)}},template#5:{v-slot:tab3,ide.component.methods:{v-if:false,:component:component}}}}}},props:{vue:null},data:{component:null,selectedViewNode:null,selectedTabIndex:0},methods:null,watch:{vue:function(vue) {\n this.component !vue ? null : this.$root.getComponent(vue._uid);\n}\n,selectedTabIndex:function(selectedTabIndex) {\n this.$emit(\selected-tab-index\, selectedTabIndex);\n}\n},style:{.list1:{margin-top:1em,max-height:40vh,overflow-x:hidden,overflow-y:auto}},name:ide-component-editor,_:{examples:{count:0}},template:div class\comp-ide-component-editor\ path\-965690814.\>div :key\vue()._uid\ path\-965690814.0\>h2 path\-965690814.0.0\>ui-title icon\π¦\ :text\vue().$options.name\ path\-965690814.0.0.0\>/ui-title>/h2>ui-tabs :options\π§ state, β¨ activity, π view, π΄ methods\ v-model\selectedTabIndex\ direction\horizontal\ path\-965690814.0.1\>template v-slot\header\ path\-965690814.0.1.0\>div class\mt-l1\ path\-965690814.0.1.0.0\>/div>/template>template v-slot\tab0\ path\-965690814.0.1.1\>ide-state-tracker :vue\vue\ path\-965690814.0.1.1.0\>/ide-state-tracker>/template>template v-slot\tab1\ path\-965690814.0.1.2\>ide-component-activity v-if\false\ :vue\vue\ path\-965690814.0.1.2.0\>/ide-component-activity>/template>template v-slot\tab2\ path\-965690814.0.1.3\>ide-component-view-editor v-if\false\ :component\component\ on_selected-node\(node) > $emit(selected-view-node, node)\ path\-965690814.0.1.3.0\>/ide-component-view-editor>/template>template v-slot\tab3\ path\-965690814.0.1.4\>ide-component-methods v-if\false\ :component\component\ path\-965690814.0.1.4.0\>/ide-component-methods>/template>/ui-tabs>/div>/div>}},{name:ide.component.flow,path:\\ide\\component\\flow.ws.yaml,source:{dom:{div:{h3:{v-text:Data flow},ui.tree:{:root:dataFlow,item-type:ide.component.grid.tree.node,:initial-expanded:2}}},props:{uid:null},data:{vue:null,maxDataFlowDepth:5},methods:{getDataFlow:function(vue) {\n const dataFlow { children: };\n datagrid.children.push(...this.getDfProps(vue));\n return dataFlow;\n}\n,getDfProps:function(vue, depth 0) {\n const props ;\n if (depth > this.maxDataFlowDepth) return props;\n for (const propKey of this.getDfPropKeys(vue)) {\n props.push({\n item: {\n id: this.$root.getUniqueClientID(),\n type: \propKey\,\n name: {\n icon: \π\,\n text: propKey\n },\n },\n children: this.getDfComps(vue, propKey, (depth + 1)),\n });\n }\n return props;\n}\n,getDfComps:function(vue, propKey, depth 0) {\n const comps ;\n if (depth > this.maxDataFlowDepth) return comps;\n for (const childVue of this.getChildVuesByPropKey(vue, propKey)) {\n comps.push({\n item: {\n id: this.$root.getUniqueClientID(),\n type: \vue\,\n name: {\n icon: \π¦\,\n text: childVue.$options._componentTag\n },\n },\n children: this.getDfProps(childVue, depth + 1)\n });\n }\n return comps;\n}\n,getChildVuesByPropKey:function(vue, propKey) {\n const childVues ;\n for (const childComp of vue.$children) {\n if (childComp.$options._propKeys.includes(propKey)) {\n childVues.push(childComp);\n }\n }\n return childVues;\n}\n,getDfPropKeys:function(vue) {\n let propKeys ;\n for (const childComp of vue.$children) {\n propKeys.push(...childComp.$options._propKeys);\n }\n propKeys propKeys.distinct();\n propKeys propKeys.sort();\n return propKeys;\n}\n},computed:{dataFlow:function() {\n if (!this.vue) return null;\n return this.getDataFlow(this.vue());\n}\n},watch:{uid:{handler:function(uid) {\n this.vue !uid ? null : this.$root.vm.vuesuid;\n}\n,immediate:true}},name:ide-component-flow,_:{examples:{count:0}},template:div class\comp-ide-component-flow\ path\-1793143997.\>h3 v-text\Data flow\ path\-1793143997.0\>/h3>ui-tree :root\dataFlow\ item-type\ide.component.grid.tree.node\ :initial-expanded\2\ path\-1793143997.1\>/ui-tree>/div>}},{name:ide.component.info,path:\\ide\\component\\info.ws.yaml,source:{dom:{div#1:{div#2:{ui.button:{:text:refresh,:click:updateChanges}},table:{tr:{class:hoverable,v-for:change in changes,on_mouseenter:onItemHover(change),on_mouseleave:onItemUnhover(change),on_click:onItemClick(change),td#1:{class:opacity-50,v-text:change.id},td#2:{v-text:π¦},td#3:{class:opacity-50,v-text:getItemCompName(change)},td#4:{class:clickable,v-text:π,on_click:onClickHideField(change)},td#5:{v-text:π§},td#6:{class:opacity-30,v-text:change.key},td#7:{div#3:{:class:getValueType(change.newValue),v-text:previewValue(change.newValue)}},td#8:{class:opacity-30,div#4:{:class:getValueType(change.newValue),v-text:previewValue(change.oldValue)}}}}}},props:{item:null},data:{changes:,hoveredItem:null,hiddenFields:},methods:{onClickHideField:function(change) {\n const compName this.getItemCompName(change);\n const key change.key;\n this.hiddenFields.push({ compName, key });\n this.updateChanges();\n}\n,onItemHover:function(change) {\n this.hoveredItem change;\n}\n,onItemUnhover:function(change) {\n this.hoveredItem null;\n}\n,isHiddenField:function(change) {\n const compName this.getItemCompName(change);\n return this.hiddenFields.some(item > item.compName compName && item.key change.key);\n}\n,getItemCompName:function(change) {\n return this.$root.vueschange.uid()?.$options?._componentTag;\n}\n,updateChanges:function() {\n this.changes this.getChanges();\n}\n,getChanges:function() {\n if (!this.item) return ;\n let items this.getStateChanges(this.item());\n items items.sortBy(item > item.id);\n items ...items.reverse();\n return items;\n}\n,getStateChanges:function(vue) {\n if (!vue) return ;\n let items ;\n items.push(...(vue.$data._?.state.items||));\n items items.filter(item > !this.isHiddenField(item));\n items.push(...((vue.$children||).flatMap(c > this.getStateChanges(c))));\n return items;\n}\n,onItemClick:function(change) {\n console.log(change);\n}\n,getItemProperties:function() {\n const props ;\n if (!this.item) return props;\n props.push(...this.getItemProps(this.item().$data));\n props.push(...this.getItemProps(this.item().$props));\n props.push(...this.getItemProps(this.item().$options.computed));\n return props;\n}\n,getItemProps:function(collection) {\n if (!collection) return ;\n const props ;\n for (const name of Object.keys(collection)) {\n if (\$\, \_\.some(s > name.startsWith(s))) continue;\n props.push({\n name,\n value: (name in collection) ? collectionname : this.item()name,\n });\n }\n return props;\n}\n,previewValue:function(value) {\n if (typeof value \function\) return value.toString();\n try\n {\n return jsyaml.dump(value);\n }\n catch (ex)\n {\n return ex.message;\n }\n}\n,getValueType:function(value) {\n return typeof value;\n}\n},watch:{hoveredItem:function(newItem, oldItem) {\n const newVue (!newItem) ? null : this.$root.vuesnewItem.uid();\n const oldVue (!oldItem) ? null : this.$root.vuesoldItem.uid();\n newVue?.$el.classList.add(\highlighted2\);\n oldVue?.$el.classList.remove(\highlighted2\);\n}\n},style:{.comp-ide-component-info:{max-width:40em,max-height:30em,overflow:auto},td:{font-size:1rem,white-space:pre,padding:0 0.3rem},.object:{max-width:20rem,max-height:5rem,overflow:auto,opacity:0.5,padding:0.5em,border:1px solid gray},.clickable:{filter:grayscale(1)},.clickable:hover:{filter:none}},name:ide-component-info,_:{examples:{count:0}},template:div class\comp-ide-component-info\ path\-1793052989.\>div path\-1793052989.0\>ui-button :text\refresh\ :click\updateChanges\ path\-1793052989.0.0\>/ui-button>/div>table path\-1793052989.1\>tr class\hoverable\ v-for\change in changes\ on_mouseenter\onItemHover(change)\ on_mouseleave\onItemUnhover(change)\ on_click\onItemClick(change)\ path\-1793052989.1.0\>td class\opacity-50\ v-text\change.id\ path\-1793052989.1.0.0\>/td>td v-text\π¦\ path\-1793052989.1.0.1\>/td>td class\opacity-50\ v-text\getItemCompName(change)\ path\-1793052989.1.0.2\>/td>td class\clickable\ v-text\π\ on_click\onClickHideField(change)\ path\-1793052989.1.0.3\>/td>td v-text\π§\ path\-1793052989.1.0.4\>/td>td class\opacity-30\ v-text\change.key\ path\-1793052989.1.0.5\>/td>td path\-1793052989.1.0.6\>div :class\getValueType(change.newValue)\ v-text\previewValue(change.newValue)\ path\-1793052989.1.0.6.0\>/div>/td>td class\opacity-30\ path\-1793052989.1.0.7\>div :class\getValueType(change.newValue)\ v-text\previewValue(change.oldValue)\ path\-1793052989.1.0.7.0\>/div>/td>/tr>/table>/div>}},{name:ide.component.method,path:\\ide\\component\\method.ws.yaml,source:{dom:{div#1:{div#2:{ui.value.code:{:value:method.code.toString()}},div#3:{v-for:(arg, i) in args,ui.value.any:{:title:argNamesi,:value:arg}}}},props:{method:null,args:null},computed:{argNames:function() {\n return (this.method?.args || );\n}\n},name:ide-component-method,_:{examples:{count:0}},template:div class\comp-ide-component-method\ path\-735417930.\>div path\-735417930.0\>ui-value-code :value\method.code.toString()\ path\-735417930.0.0\>/ui-value-code>/div>div v-for\(arg, i) in args\ path\-735417930.1\>ui-value-any :title\argNamesi\ :value\arg\ path\-735417930.1.0\>/ui-value-any>/div>/div>}},{name:ide.component.methods,path:\\ide\\component\\methods.ws.yaml,source:{dom:{div:{table:{thead:{tr#1:{th:{v-text:pause}}},tbody:{tr#2:{v-for:method in component.source.methods,td:{ui.checkbox:{:text:π΄ + method.name,on_input:(value) > onDebugMethodInput(method, value)}}}}},ui.value.any:{:value:isDebugMethod}}},props:{component:null},data:{isDebugMethod:{}},methods:{onDebugMethodInput:function(method, value) {\n const compName this.component.name.replace(/-/g, .);\n const comp vueIdeApp.comps.find(c > (c.name compName));\n comp.debug (comp.debug || {});\n comp.debug.methods (comp.debug.methods || {});\n comp.debug.methodsmethod.name (comp.debug.methodsmethod.name || {});\n comp.debug.methodsmethod.name.pause value;\n}\n},style:{th:first-child:{width:2em}},_:{examples:{count:0}},name:ide-component-methods,template:div class\comp-ide-component-methods\ path\-1323119235.\>table path\-1323119235.0\>thead path\-1323119235.0.0\>tr path\-1323119235.0.0.0\>th v-text\pause\ path\-1323119235.0.0.0.0\>/th>/tr>/thead>tbody path\-1323119235.0.1\>tr v-for\method in component.source.methods\ path\-1323119235.0.1.0\>td path\-1323119235.0.1.0.0\>ui-checkbox :text\π΄ + method.name\ on_input\(value) > onDebugMethodInput(method, value)\ path\-1323119235.0.1.0.0.0\>/ui-checkbox>/td>/tr>/tbody>/table>ui-value-any :value\isDebugMethod\ path\-1323119235.1\>/ui-value-any>/div>}},{name:ide.component.picker.vue.list,path:\\ide\\component\\picker\\vue\\list.ws.yaml,source:{dom:{div#1:{transition.group:{name:slide,:class:((className||) + + (tree ? tree1 : )),div#2:{v-for:vue in vues.filter(showVueComponent).take(maxVisibleVues),:key:vue()._uid,ide.component.title:{:item:vue,:class:{ selected: (vue()._uid (selectedVue?.())?._uid) },on_mouseenter:$emit(hover, vue()),on_mouseleave:$emit(hover, null),on_click:$emit(select, vue())}}},div#3:{v-if:(vues.length > maxVisibleVues),v-text:β¬ + (vues.length - maxVisibleVues) + more...}}},props:{vues:null,selectedVue:null,className:null,tree:false,showIdeComponents:false},data:{maxVisibleVues:20},methods:{showVueComponent:function(vue) {\n if (typeof vue \function\) vue vue();\n if (!this.showIdeComponents) {\n if (vue.$options.name?.startsWith(ide-)) return false;\n }\n return true;\n}\n,getVue:function(uid) {\n const vue vueApp.vm.vuesuid;\n return vue;\n}\n},style:{.tree1 > :nth-child(1):{margin-left:0.5em},.tree1 > :nth-child(2):{margin-left:1em},.tree1 > :nth-child(3):{margin-left:1.5em},.tree1 > :nth-child(4):{margin-left:2em},.tree1 > :nth-child(5):{margin-left:2.5em},.tree1 > :nth-child(6):{margin-left:3em},.tree1 > :nth-child(7):{margin-left:3.5em},.tree1 > :nth-child(8):{margin-left:4em}},name:ide-component-picker-vue-list,_:{examples:{count:0}},template:div class\comp-ide-component-picker-vue-list\ :class\((className||) + + (tree ? tree1 : ))\ path\-912894927.\>div v-for\vue in vues.take(maxVisibleVues)\ :key\vue()._uid\ path\-912894927.0\>ide-component-title :item\vue\ :class\{ selected: (vue()._uid (selectedVue?.())?._uid) }\ on_mouseenter\$emit(hover, vue())\ on_mouseleave\$emit(hover, null)\ on_click\$emit(select, vue())\ path\-912894927.0.0\>/ide-component-title>/div>div v-if\(vues.length > maxVisibleVues)\ v-text\β¬ + (vues.length - maxVisibleVues) + more...\ path\-912894927.1\>/div>/div>}},{name:ide.component.picker,path:\\ide\\component\\picker\\_.ws.yaml,source:{dom:{div#1:{class:highlighted,ui.keyboard:{on_ctrl:isCtrl$event},ui.mouse:{on_hovered-element:onHoveredElement,:global:true},ui.context.window:{ref:context1,v-show:showPicker,:global:true,on_pinned:onPinned,.flex.flex-row.gap-1:{.flex.flex-column.gap-1:{div#2:{:class:componentTreeClass,ide.component.picker.vue.list#1:{:vues:parentChainVues,:show-ide-components:showIdeComponents,:tree:true,:selectedVue:selectedVue,on_hover:onHoverVue,on_select:onSelectVue},ide.component.picker.vue.list#2:{:vues:childChainVues,:show-ide-components:showIdeComponents,:selectedVue:selectedVue,:style:childChainStyle,on_hover:onHoverVue,on_select:onSelectVue},.opacity-hover.mt-l2:{ui.checkbox:{text:ide components,v-model:showIdeComponents}}},ide.element.inspector:{class:hidden,:element:hoveredElement}},div#3:{ide.vue.inspector:{:vue:selectedVue}}}}}},props:null,data:{hoveredElement:null,hoveredVue:null,selectedVue:null,parentChainVues:null,childChainVues:null,showPicker:false,isCtrl:false,selectedViewNode:null,selectedEditorTabIndex:0,isPinned:false,showIdeComponents:false},methods:{onPinned:function(pinned) {\n this.isPinned pinned;\n if (pinned) return;\n this.selectedVue null;\n}\n,onHoverVue:function(vue) {\n this.hoveredVue (!vue ? null : (() > vue));\n}\n,onSelectVue:function(vue) {\n if ((vue && this.selectedVue) && (vue._uid this.selectedVue()._uid)) vue null;\n this.selectedVue (!vue ? null : (() > vue));\n}\n,onHoveredElement:function(el) {\n if (this.$refs.context1?.isPinned) return;\n this.hoveredElement el;\n}\n,getParentChainVues:function(vue) {\n if (!vue) return ;\n const maxChainLength 6;\n let chain ;\n let parent vue;\n while (parent && (chain.length maxChainLength)) {\n const parentVue parent;\n chain.push(() > parentVue);\n parent this.getParentVue(parent);\n }\n chain chain.reverse();\n return chain;\n}\n,getChildChainVues:function(vue) {\n if (!vue) return ;\n const children ;\n const addChildren (vue) > {\n if (!vue) return;\n for (const child of vue.$children) {\n if (\transition\, \transition-group\.includes(child.$options._componentTag)) {\n addChildren(child);\n continue;\n }\n const childVue child;\n children.push(() > childVue);\n }\n };\n addChildren(vue);\n return children;\n}\n,getParentVue:function(vue) {\n return this.getVueFromVnode(vue.$parent);\n}\n,getVueFromElement:function(el) {\n const vue this.getVueFromVnode(this.getVnodeFromElement(el));\n return vue;\n}\n,getVnodeFromElement:function(el) {\n if (!el) return null;\n if (el.__vue__) return el.__vue__;\n return this.getVnodeFromElement(el.parentElement);\n}\n,getVueFromVnode:// Skip vnodes like keep-alive>, transition>, etc.\nfunction(vnode) {\n if (!vnode) return null;\n if (this.vNodeIsVue(vnode)) return vnode;\n return this.getVueFromVnode(vnode.$parent);\n}\n,vNodeIsVue:function(vnode) {\n if (`transition`, `transition-group`, `keep-alive`.includes(vnode.$options._componentTag)) return false;\n return true;\n}\n,updateChains:function(vue) {\n this.parentChainVues this.getParentChainVues(vue);\n this.childChainVues this.getChildChainVues(vue);\n}\n},computed:{childChainStyle:function() {\n return {\n margin-left: `${(this.parentChainVues?.length||0) * 0.8}em`\n };\n}\n,showComponentTree:function() {\n return true;\n}\n,componentTreeClass:function() {\n return {\n component-tree: true,\n slider-closed: (!!this.selectedVue),\n slider-opened: (!!!this.selectedVue)\n };\n}\n,activeVue:function() {\n return this.hoveredVue || this.selectedVue;\n}\n},watch:{isCtrl:{handler:function(isCtrl) {\n this.showPicker (isCtrl || this.$refs.context1?.isPinned);\n}\n},hoveredElement:function(newEl, oldEl) {\n const vue this.getVueFromElement(newEl);\n this.hoveredVue (!vue ? null : () > vue);\n}\n,hoveredVue:{handler:function(newVue, oldVue) {\n (oldVue?.())?.$el.classList?.remove(`highlighted`);\n if (this.showPicker)\n {\n (newVue?.())?.$el.classList?.add(`highlighted`);\n }\n if (!this.$refs.context1?.isPinned) this.updateChains((newVue?.()));\n}\n,immediate:true},selectedVue:{handler:function(newVue, oldVue) {\n (oldVue?.())?.$el.classList?.remove(`highlighted2`)\n if (!newVue) return;\n (newVue?.())?.$el.classList?.add(`highlighted2`);\n this.updateChains((newVue?.()));\n}\n,immediate:true},showPicker:{handler:function(showPicker) {\n if (!showPicker && !this.$refs.context1?.isPinned) this.selectedVue null;\n}\n,immediate:true}},style:{.component-tree:{max-height:50vh,margin-top:1em,margin-right:2em,overflow-x:hidden,overflow-y:auto},div:{font-family:monospace}},name:ide-component-picker,_:{examples:{count:0}},template:div class\comp-ide-component-picker highlighted\ path\-646340253.\>ui-keyboard on_ctrl\isCtrl$event\ path\-646340253.0\>/ui-keyboard>ui-mouse on_hovered-element\onHoveredElement\ :global\true\ path\-646340253.1\>/ui-mouse>ui-context-window ref\context1\ v-if\showPicker\ :global\true\ on_pinned\onPinned\ path\-646340253.2\>div class\flex flex-row gap-1\ path\-646340253.2.0\>div class\flex flex-column gap-1\ path\-646340253.2.0.0\>div :class\componentTreeClass\ path\-646340253.2.0.0.0\>ide-component-picker-vue-list :vues\parentChainVues\ :tree\true\ :selectedVue\selectedVue\ on_hover\onHoverVue\ on_select\onSelectVue\ path\-646340253.2.0.0.0.0\>/ide-component-picker-vue-list>ide-component-picker-vue-list :vues\childChainVues\ :selectedVue\selectedVue\ :style\childChainStyle\ on_hover\onHoverVue\ on_select\onSelectVue\ path\-646340253.2.0.0.0.1\>/ide-component-picker-vue-list>/div>ide-element-inspector class\hidden\ :element\hoveredElement\ path\-646340253.2.0.0.1\>/ide-element-inspector>/div>div path\-646340253.2.0.1\>ide-vue-inspector :vue\selectedVue\ path\-646340253.2.0.1.0\>/ide-vue-inspector>/div>/div>/ui-context-window>/div>}},{name:ide.component.state.watches,path:\\ide\\component\\state\\watches.ws.yaml,source:{dom:{div#1:{h3:{v-text:State Watches},div#2:{v-text:stateItems},div#3:{div#4:{v-if:previewedStateItem,ide.title#1:{:item:previewedStateItem},ui.value.any#1:{:value:previewedStateItem.newValue}}},div#5:{div#6:{v-for:stateItem in stateItems,ide.title#2:{:item:stateItem},ui.value.any#2:{:value:stateItem.newValue}}}}},data:{previewedStateItem:null,stateItems:},mounted:function() {\n this.$root.$on(\preview-state-item\, (stateItem) > {\n this.previewedStateItem stateItem;\n });\n this.$root.$on(\watch-state-item\, (stateItem) > {\n this.stateItems.push(stateItem);\n console.log(stateItem);\n });\n}\n,name:ide-component-state-watches,_:{examples:{count:0}},template:div class\comp-ide-component-state-watches\ path\1039616747.\>h3 v-text\State Watches\ path\1039616747.0\>/h3>div v-text\stateItems\ path\1039616747.1\>/div>div path\1039616747.2\>div v-if\previewedStateItem\ path\1039616747.2.0\>ide-title :item\previewedStateItem\ path\1039616747.2.0.0\>/ide-title>ui-value-any :value\previewedStateItem.newValue\ path\1039616747.2.0.1\>/ui-value-any>/div>/div>div path\1039616747.3\>div v-for\stateItem in stateItems\ path\1039616747.3.0\>ide-title :item\stateItem\ path\1039616747.3.0.0\>/ide-title>ui-value-any :value\stateItem.newValue\ path\1039616747.3.0.1\>/ui-value-any>/div>/div>/div>}},{name:ide.component.title,path:\\ide\\component\\title.ws.yaml,source:{dom:{div#1:{v-if:vue,on_mouseenter:$emit(mouseenter),on_mouseleave:$emit(mouseleave),on_click:$emit(click),ui.highlighter:{:get-elements:() > vue.$el,div#2:{:class:{ opacity-40: (getTitle(vue)?.startsWith(ide-)) },on_click:onClick,ui.title:{icon:π¦,:value:getTitle(vue)}}}}},props:{item:null},data:{vue:null},methods:{getTitle:function(vue) {\n return vue.$options._componentTag;\n}\n,onClick:function() {\n console.log(this.vue);\n}\n},watch:{item:{handler:function(item) {\n this.vue (!item ? null : item());\n}\n,immediate:true}},name:ide-component-title,_:{examples:{count:0}},template:div class\comp-ide-component-title\ on_mouseenter\$emit(mouseenter)\ on_mouseleave\$emit(mouseleave)\ on_click\$emit(click)\ v-if\vue\ path\259955427.\>ui-highlighter :get-elements\() > vue.$el\ path\259955427.0\>div on_click\onClick\ path\259955427.0.0\>ui-title icon\π¦\ :value\vue.$options._componentTag\ path\259955427.0.0.0\>/ui-title>/div>/ui-highlighter>/div>}},{name:ide.component.view.editor,path:\\ide\\component\\view\\editor.ws.yaml,source:{dom:{div#1:{:style:{ min-width: 30em },v-if:component,.flex.gap-2:{div#2:{transition#1:{name:slide-hor,div#3:{v-show:(selectedTabIndex 0),ui.tree:{:root:dom,:expandable:false,:initial-expanded:true,item-type:ide.component.view.node,:get-item:(node) > node,:get-children:(node) > node.children,on_node-hover:onNodeHover,on_node-select:onNodeSelect}}}},.w-100pc:{transition#2:{name:slide-hor-key,div#4:{:key:selectedNode?.cid,transition#3:{name:slide,h2:{v-if:(selectedNode),ui.title:{icon:π,:text:selectedNode.tag}}},transition#4:{name:slide-hor,div#5:{v-show:selectedNode,ui.tabs:{:options:βοΈ edit,v-model:selectedTabIndex,direction:horizontal,template#1:{v-slot:header},template#2:{v-slot:tab0,ide.component.view.node.editor:{:node:selectedNode}}}}}}}}}}},props:{component:null},data:{dom:null,domYaml:null,hoveredNode:null,selectedNode:null,contextElement:null,selectedTabIndex:0},computed:{activeNode:function() {\n return (this.hoveredNode || this.selectedNode);\n}\n,selectedNodeSelector:function() {\n if (!this.selectedNode) return null;\n return null;\n //return `.comp-${this.component.name.replace(/\\./g, -)} path\${this.selectedNode1.path}\`;\n}\n},watch:{component:{handler:function(component) {\n const dom component.source.dom;\n this.dom JSON.parse(JSON.stringify(dom));\n this.domYaml !dom ? null : jsyaml.dump(dom);\n this.selectedNode null;\n}\n,immediate:true},selectedNodeSelector:{handler:function(selector, oldSelector) {\n let els ...document.querySelectorAll(oldSelector);\n els.forEach(el > el.classList.remove(\highlighted2\));\n this.contextElement null;\n if (!selector) return;\n els ...document.querySelectorAll(selector);\n this.contextElement els0;\n if (!this.contextElement) return;\n els.forEach(el > el.classList.add(\highlighted2\));\n}\n,immediate:true},contextElement:{handler:function(contextElement) {\n this.selectedNode null;\n}\n},activeNode:{handler:function(newNode, oldNode) {\n}\n},hoveredNode:{handler:function(node) {\n if (this.selectedNode) return;\n //this.selectedNode node;\n}\n},selectedNode:{handler:function(node) {\n this.$emit(\selected-node\, node);\n}\n},selectedTabIndex:{handler:function(newIndex, oldIndex) {\n}\n}},methods:{onNodeHover:function(node) {\n this.hoveredNode node;\n}\n,onNodeSelect:function(node) {\n this.selectedNode node;\n}\n},style:{textarea:{width:30em,height:20em}},name:ide-component-view-editor,_:{examples:{count:0}},template:div class\comp-ide-component-view-editor\ :style\{ min-width: 30em }\ v-if\component\ path\-1512907487.\>div class\flex gap-2\ path\-1512907487.0\>div path\-1512907487.0.0\>transition name\slide-hor\ path\-1512907487.0.0.0\>div v-show\(selectedTabIndex 0)\ path\-1512907487.0.0.0.0\>ui-tree :root\dom\ :expandable\false\ :initial-expanded\true\ item-type\ide.component.view.node\ :get-item\(node) > node\ :get-children\(node) > node.children\ on_node-hover\onNodeHover\ on_node-select\onNodeSelect\ path\-1512907487.0.0.0.0.0\>/ui-tree>/div>/transition>/div>div class\w-100pc\ path\-1512907487.0.1\>transition name\slide-hor-key\ path\-1512907487.0.1.0\>div :key\selectedNode?.cid\ path\-1512907487.0.1.0.0\>transition name\slide\ path\-1512907487.0.1.0.0.0\>h2 v-if\(selectedNode)\ path\-1512907487.0.1.0.0.0.0\>ui-title icon\π\ :text\selectedNode.tag\ path\-1512907487.0.1.0.0.0.0.0\>/ui-title>/h2>/transition>transition name\slide-hor\ path\-1512907487.0.1.0.0.1\>div v-show\selectedNode\ path\-1512907487.0.1.0.0.1.0\>ui-tabs :options\βοΈ edit\ v-model\selectedTabIndex\ direction\horizontal\ path\-1512907487.0.1.0.0.1.0.0\>template v-slot\header\ path\-1512907487.0.1.0.0.1.0.0.0\>/template>template v-slot\tab0\ path\-1512907487.0.1.0.0.1.0.0.1\>ide-component-view-node-editor :node\selectedNode\ path\-1512907487.0.1.0.0.1.0.0.1.0\>/ide-component-view-node-editor>/template>/ui-tabs>/div>/transition>/div>/transition>/div>/div>/div>}},{name:ide.component.view.node.editor,path:\\ide\\component\\view\\node\\editor.ws.yaml,source:{dom:{div#1:{v-if:node,div#2:{ui.input.text.box#1:{class:fs-m3,v-model:node.tag,:enabled:false}},div#3:{table:{tr:{v-for:(key) in getVisibleKeys(node.attributes),th:{div#4:{v-text:key}},td:{ui.input.text.box#2:{v-model:node.attributeskey,:enabled:false}}}}}}},props:{node:null},methods:{getVisibleKeys:function(obj) {\n if (!obj) return ;\n return Object.keys(obj)\n .filter(k > (typeof objk ! object))\n .filter(k > (k ! path));\n}\n},style:{input:{font-size:100%},th:{padding-right:1em}},name:ide-component-view-node-editor,_:{examples:{count:0}},template:div class\comp-ide-component-view-node-editor\ v-if\node\ path\-981981275.\>div path\-981981275.0\>ui-input-text-box class\fs-m3\ v-model\node.tag\ :enabled\false\ path\-981981275.0.0\>/ui-input-text-box>/div>div path\-981981275.1\>table path\-981981275.1.0\>tr v-for\(key) in getVisibleKeys(node.attributes)\ path\-981981275.1.0.0\>th path\-981981275.1.0.0.0\>div v-text\key\ path\-981981275.1.0.0.0.0\>/div>/th>td path\-981981275.1.0.0.1\>ui-input-text-box v-model\node.attributeskey\ :enabled\false\ path\-981981275.1.0.0.1.0\>/ui-input-text-box>/td>/tr>/table>/div>/div>}},{name:ide.component.view.node,path:\\ide\\component\\view\\node.ws.yaml,source:{dom:{.w-100pc:{v-if:item,ui.highlighter:{:get-elements:() > $root.html.getElementsFromViewNode(item),ui.title:{:icon:icon,:text:item.tag||root}}}},props:{item:null},data:{icon:null},methods:{getAttributes:function(item) {\n if (!item) return ;\n return Object.entries(item1)\n .filter(e > (e0 ! \path\))\n .filter(e > (typeof e1 ! object));\n}\n,getIcon:function(item) {\n if (this.$root.html.isTagName(item.tag)) return π;\n return π¦;\n}\n},watch:{item:{handler:function(item) {\n this.icon this.getIcon(item);\n}\n,immediate:true}},name:ide-component-view-node,_:{examples:{count:0}},template:div class\comp-ide-component-view-node w-100pc\ v-if\item\ path\-971127114.\>ui-highlighter :get-elements\() > $root.html.getElementsFromViewNode(item)\ path\-971127114.0\>ui-title :icon\icon\ :text\item.tag||root\ path\-971127114.0.0\>/ui-title>/ui-highlighter>/div>}},{name:ide.component,path:\\ide\\component.ws.yaml,source:{dom:{div:{ui.title:{icon:π¦,:value:name}}},props:{name:null,source:null},name:ide-component,_:{examples:{count:0}},template:div class\comp-ide-component\ path\622738105.\>ui-title icon\π¦\ :value\name\ path\622738105.0\>/ui-title>/div>}},{name:ide.css.editor.example.flex,path:\\ide\\css\\editor\\example\\flex.ws.yaml,source:{dom:{div:{.example-flex:{:style:exampleStyle,.example-flex-item:{:style:getExampleItemStyle(i),v-for:i in itemsCount,v-text:i}}}},props:{exampleStyle:null},data:null,methods:{getExampleItemStyle:function(i) {\n const style {};\n let heights Array.from({ length: this.itemsCount }).map((a, i) > (1.5 + (i * 0.5)) * 2 );\n heights heights.take(3);\n style.height (`${heights.rotate(i)0}rem`);\n style.fontSize ((`${(2 + (i/6))}rem`));\n return style;\n}\n},computed:{itemsCount:function() {\n if (wrap, wrap-reverse.includes(this.exampleStyleflex-wrap)) return 5;\n return 3;\n}\n},style:{.example-flex:{display:flex,width:25em,height:14em,margin:1em auto,border:1px solid gray,overflow:auto},.example-flex-item:{display:flex,width:7rem,color:#ffffff60,background:#ffffff30,border:1px solid gray,border-radius:0.5rem,text-align:center,align-items:center,justify-content:center,font-size:3rem,transition:0s}},name:ide-css-editor-example-flex,template:div class\comp-ide-css-editor-example-flex\ path\-1461106385.\>div class\example-flex\ :style\exampleStyle\ path\-1461106385.0\>div class\example-flex-item\ :style\getExampleItemStyle(i)\ v-for\i in itemsCount\ v-text\i\ path\-1461106385.0.0\>/div>/div>/div>,_:{examples:{count:0}}}},{name:ide.css.editor.field.options,path:\\ide\\css\\editor\\field\\options.ws.yaml,source:{dom:{div#1:{div#2:{v-text:name},ide.css.editor.example.flex:{v-for:option in options,:example-style:getExampleStyle(option)}}},props:{name:null},data:null,methods:{getExampleStyle:function(option) {\n const style {};\n stylethis.name option;\n return style;\n}\n},computed:{options:function() {\n if (!this.name) return ;\n let values this.$root.html.cssPropertiesthis.name.values;\n return values;\n}\n},name:ide-css-editor-field-options,_:{examples:{count:0}},template:div class\comp-ide-css-editor-field-options\ path\-1253591880.\>div v-text\name\ path\-1253591880.0\>/div>ide-css-editor-example-flex v-for\option in options\ :example-style\getExampleStyle(option)\ path\-1253591880.1\>/ide-css-editor-example-flex>/div>}},{name:ide.css.editor.field,path:\\ide\\css\\editor\\field.ws.yaml,source:{dom:{.flex:{:tooltip:tooltip,div#1:{:style:{ width: 12em },v-text:βοΈ + name},div#2:{class:flex-grow-1,ui.select:{:options:cOptions,:value:value,:input-type:value,:type:toggle,on_input:onInput($event)}}}},props:{name:null,tooltip:null,value:null},methods:{onInput:function(value) {\n this.$emit(\input\, value);\n}\n},computed:{cOptions:function() {\n return this.$root.html.getPossibleCssValues(this.name);\n}\n},name:ide-css-editor-field,_:{examples:{count:0}},template:div class\comp-ide-css-editor-field flex\ :tooltip\tooltip\ path\-802314744.\>div :style\{ width: 12em }\ v-text\βοΈ + name\ path\-802314744.0\>/div>div class\flex-grow-1\ path\-802314744.1\>ui-select :options\cOptions\ :value\value\ :input-type\value\ :type\toggle\ on_input\onInput($event)\ path\-802314744.1.0\>/ui-select>/div>/div>}},{name:ide.css.editor.flex,path:\\ide\\css\\editor\\flex.ws.yaml,source:{dom:{div:{ide.css.editor.example.flex:{:example-style:flexStyle},ide.css.editor.field:{v-for:(name, index) in fieldNames,:name:name,:tooltip:fieldTooltipsindex,v-model:flexStylename}}},props:null,data:{flexStyle:{},fieldNames:flex-direction,flex-wrap,justify-content,align-items,align-content},computed:{fieldTooltips:function() {\n const tips null, null, null, null, null;\n if (!\wrap\, \wrap-reverse\.includes(this.flexStyle\flex-wrap\)) {\n tips4 \align-content only works with wrap or wrap-reverse\;\n }\n return tips;\n}\n},style:null,name:ide-css-editor-flex,_:{examples:{count:0}},template:div class\comp-ide-css-editor-flex\ path\-25878229.\>ide-css-editor-example-flex :example-style\flexStyle\ path\-25878229.0\>/ide-css-editor-example-flex>ide-css-editor-field v-for\(name, index) in fieldNames\ :name\name\ :tooltip\fieldTooltipsindex\ v-model\flexStylename\ path\-25878229.1\>/ide-css-editor-field>/div>}},{name:ide.css.editor.margin,path:\\ide\\css\\editor\\margin.ws.yaml,source:{dom:{div#1:{h3:{v-text:Margin},div#2:{ui.select:{:options:options,:getItemKey:a > a,v-model:selectedOption,on_item-hover:onOptionHover($event)}}}},props:{el:null},data:{options:,selectedOption:null,hoveredOption:null,appliedStyles:null},mounted:function() {\n for (let i 0; i 10; i++) {\n this.options.push(i * 3);\n }\n}\n,methods:{onOptionHover:function(option) {\n this.hoveredOption option.item;\n}\n},computed:{hoveredOrSelectedOption:function() {\n return this.hoveredOption || this.selectedOption;\n}\n},watch:{hoveredOrSelectedOption:function(hoso) {\n const el this.el;\n if (!hoso) \n {\n el.style.margin \\;\n return;\n }\n el.style.margin hoso + \px\;\n}\n},style:null,name:ide-css-editor-margin,_:{examples:{count:0}},template:div class\comp-ide-css-editor-margin\ path\1091445344.\>h3 v-text\Margin\ path\1091445344.0\>/h3>div path\1091445344.1\>ui-select :options\options\ :getItemKey\a > a\ v-model\selectedOption\ on_item-hover\onOptionHover($event)\ path\1091445344.1.0\>/ui-select>/div>/div>}},{name:ide.css.editor,path:\\ide\\css\\editor.ws.yaml,source:{dom:{div#1:{.flex.gap-2:{div#2:{transition#1:{name:slide-hor,.opacity-50:{v-show:!selectedRule,ui.select#1:{:options:classList,item-icon:π’,input-type:value,v-model:selectedClass},ui.select#2:{:options:cssFieldNames,:get-item-icon:() > βοΈ,input-type:value,search-hint:propertiesβ¦,v-model:selectedFieldName}}}},.css-rule-select:{ui.select:{:options:cssRules,item-icon:π,:get-item-text:(rule) > rule.selectorText,:get-item-key:(rule) > rule.selectorText,:is-option-visible:isRuleVisible,search-hint:rulesβ¦,:show-search:true,v-model:selectedRuleIndex,on_input:query:ruleQuery$event},div#3:{v-if:ruleQuery?.length,h3:{ui.title#1:{icon:π,:text:ruleQuery}},ui.button#1:{text:β add new rule,:click:addNewRule}}},.flex.ver.gap-1:{transition#2:{name:slide-hor,div#4:{v-if:selectedRule,div#5:{.opacity-30:{v-text:getShortPath(selectedRule.parentStyleSheet?.href)},.title1:{.flex#1:{span:{v-text:π},ul:{li:{v-for:selector in getSelectors(selectedRule),div#6:{v-text:selector}}}}}},div#7:{ui.tabs:{:options:π Properties, π³ Flex,direction:horizontal,template#1:{v-slot:tab0,table#1:{tr#1:{:class:{ highlighted: (selectedFieldName field.name) },v-for:field in selectedRuleFields,:key:field.id,th#1:{.flex#2:{.w-l2:{v-text:βοΈ},div#8:{div#9:{v-if:field.value,v-text:field.name},ui.input.text.box:{:style:{ width: 5em },v-if:!field.value,v-model:field.name}}}},td#1:{ide.css.field.editor:{:field:field,on_input:(value) > setNewCssRule(field.name, value)}}}},.mt-l1:{ui.button#2:{text:β,:click:addNewField}}},template#2:{v-slot:tab1,ide.css.editor.flex:null}}}}},div#10:{table#2:{v-if:false,tr#2:{v-for:field in appliedStyles,th#2:{ui.title#2:{icon:βοΈ,:text:field.name}},td#2:{.css-field-value:{v-text:field.value}}}}}}}}},props:{contextElement:null},data:{classList:,cssRules:,cssFields:,cssFieldNames:,selectedFieldName:null,selectedClass:null,selectedClassRules:,selectedClassFields:,selectedRuleIndex:null,selectedRuleFields:,selectedItemFields:,appliedStyles:{},allCssRules:,newCssRules:{},ruleQuery:null},mounted:function() {\n this.init();\n}\n,methods:{init:function() {\n this.allCssRules this.getAllCssRules();\n}\n,update:function() {\n this.selectedClassRules ;\n this.selectedClassFields ;\n this.selectedRuleFields ;\n this.selectedClassRules this.cssRules.filter(rule > {\n return rule.selectorText?.includes(`.${this.selectedClass}`);\n });\n this.selectedClassFields this.selectedClassRules.flatMap(r > this.getCssFields(r));\n this.selectedRuleFields this.getCssFields(this.selectedRule);\n this.selectedItemFields this.selectedClass ? this.selectedClassFields :\n this.selectedRule ? this.selectedRuleFields : ;\n}\n,addNewRule:function() {\n const selector this.ruleQuery;\n this.setNewCssRule(\display\, \flex\, selector);\n this.allCssRules this.getAllCssRules();\n}\n,addNewField:function() {\n this.selectedRuleFields.push({ id: this.$root.getUniqueClientID(), name: \\, value: \\ });\n}\n,setNewCssRule:function(name, value, selector) {\n selector selector || (this.selectedRule ? this.selectedRule.selectorText : this.selectedClass ? `.${this.selectedClass}` : null);\n if (!selector) throw new Error(\Selector is needed to set a new css rule\);\n const newCssRule (this.newCssRulesselector (this.newCssRulesselector || {}));\n newCssRulename value;\n this.$root.newCssRules JSON.parse(JSON.stringify(this.newCssRules));\n}\n,getCssFields:function(rule) {\n if (!rule) return ;\n // Take everything between the first { and the last }\n const cssText rule.cssText;\n const start cssText.indexOf(\{\);\n const end cssText.lastIndexOf(\}\);\n const fields cssText.substring(start + 1, end)\n .split(\;\)\n .map(s > s.trim())\n .map(s > s.split(\:\))\n .map(s > { return {\n id: this.$root.getUniqueClientID(),\n name: s0?.trim(),\n value: this.removeImportant(s1?.trim())\n } })\n .filter(f > f.name)\n return fields;\n}\n,stringifyCssFields:function(fields, block false) {\n if (!fields) return \\;\n const s fields.map(f > `${f.name}: ${f.value}`).join(\;\\n\);\n return block ? `{${s}}` : s;\n}\n,getCssFieldStyle:function(field) {\n const canVisualize (!\position\.includes(field.name));\n if (!canVisualize) return {};\n const style {};\n stylefield.name field.value;\n return style;\n}\n,removeImportant:function(s) {\n if (!s) return s;\n return s.replace(\ !important\, \\).trim();\n}\n,getSelectors:function(rule) {\n if (!rule) return ;\n return rule.selectorText.split(\,\).map(s > s.trim());\n}\n,isRuleVisible:function(rule) {\n let isVisible true;\n if (this.selectedFieldName) isVisible isVisible && rule.cssText?.includes(this.selectedFieldName);\n if (this.selectedClass) isVisible isVisible && rule.selectorText?.includes(`.${this.selectedClass}`);\n return isVisible;\n}\n,getClassList:function(el) {\n if (!el) return ;\n return ...el.classList;\n}\n,getAllCssRules:function() {\n let rules ...document.styleSheets.map(st > {\n try { return st.rules; }\n catch (ex) { return null; }\n })\n .filter(a > a)\n .flatMap(a > ...a);\n\n // Multiple rules may have the same selectors\n const selectors rules.map(r > r.selectorText).distinct();\n\n rules selectors.map(s > {\n const sameSelectorRules rules.filter(r > r.selectorText s);\n let fields sameSelectorRules.flatMap(r > this.getCssFields(r));\n fields fields.map(f > f.name).distinct().map(f > {\n return {\n name: f,\n value: fields.filter(f2 > f2.name f).last().value\n };\n });\n return {\n selectorText: s,\n cssText: this.stringifyCssFields(fields, true)\n }\n });\n\n return rules;\n}\n,getCssRulesForElement:function(el) {\n if (!el) return ;\n\n const elCssRules this.allCssRules.filter(rule > {\n return el.matches(rule.selectorText);\n });\n\n return elCssRules;\n}\n,getShortPath:function(path) {\n if (!path) return null;\n return `/` + path.split(\/\).reverse().take(2).reverse().join(\/\);\n}\n},computed:{selectedRule:function() {\n if (!this.cssRules) return null;\n return this.cssRulesthis.selectedRuleIndex;\n}\n,visibleCssRules:function() {\n if (!this.cssRules) return ;\n return this.cssRules.filter(r > this.isRuleVisible(r));\n}\n,visibleCssRulesKey:function() {\n return this.visibleCssRules.map(r > r.selectorText).join(\,\);\n}\n},watch:{selectedRule:function(selectedRule) {\n //if (selectedRule) this.selectedClass null;\n this.update();\n}\n,selectedClass:function(selectedClass) {\n //if (selectedClass) this.selectedRuleIndex null;\n this.update();\n}\n,visibleCssRulesKey:function(visibleCssRulesKey) {\n}\n,contextElement:{handler:function(contextElement) {\n this.selectedFieldName null;\n this.classList this.getClassList(contextElement);\n this.cssRules this.getCssRulesForElement(contextElement).sortBy(r > r.selectorText);\n this.cssFields this.cssRules.flatMap(r > this.getCssFields(r)).sortBy(f > f.name);\n this.cssFieldNames this.cssFields.map(f > f.name).distinct();\n this.appliedStyles this.$root.html.getAppliedStyles(contextElement);\n this.update();\n}\n,immediate:true}},style:{table:{display:block,max-height:30em,overflow:auto},.title1:{font-size:120%,border-bottom:1px solid #ffffff30,border-radius:0,margin-bottom:1em},tr:hover th, tr:hover td:{background-color:#ffffff20,transition:0s},th:{padding-right:2em},.css-field-value:{min-width:10em,text-align:left,cursor:pointer,user-select:none,transition:0s},.css-field-value:hover:{background-color:#ffffff20},div:{font-family:monospace},.css-rule-select:{max-width:15em,overflow:hidden},input:{font-size:100%}},name:ide-css-editor,_:{examples:{count:0}},template:div class\comp-ide-css-editor\ path\-1978980996.\>div class\flex gap-2\ path\-1978980996.0\>div path\-1978980996.0.0\>transition name\slide-hor\ path\-1978980996.0.0.0\>div class\opacity-50\ v-show\!selectedRule\ path\-1978980996.0.0.0.0\>ui-select :options\classList\ item-icon\π’\ input-type\value\ v-model\selectedClass\ path\-1978980996.0.0.0.0.0\>/ui-select>ui-select :options\cssFieldNames\ :get-item-icon\() > βοΈ\ input-type\value\ search-hint\propertiesβ¦\ v-model\selectedFieldName\ path\-1978980996.0.0.0.0.1\>/ui-select>/div>/transition>/div>div class\css-rule-select\ path\-1978980996.0.1\>ui-select :options\cssRules\ item-icon\π\ :get-item-text\(rule) > rule.selectorText\ :get-item-key\(rule) > rule.selectorText\ :is-option-visible\isRuleVisible\ search-hint\rulesβ¦\ :show-search\true\ v-model\selectedRuleIndex\ on_input:query\ruleQuery$event\ path\-1978980996.0.1.0\>/ui-select>div v-if\ruleQuery?.length\ path\-1978980996.0.1.1\>h3 path\-1978980996.0.1.1.0\>ui-title icon\π\ :text\ruleQuery\ path\-1978980996.0.1.1.0.0\>/ui-title>/h3>ui-button text\β add new rule\ :click\addNewRule\ path\-1978980996.0.1.1.1\>/ui-button>/div>/div>div class\flex ver gap-1\ path\-1978980996.0.2\>transition name\slide-hor\ path\-1978980996.0.2.0\>div v-if\selectedRule\ path\-1978980996.0.2.0.0\>div path\-1978980996.0.2.0.0.0\>div class\opacity-30\ v-text\getShortPath(selectedRule.parentStyleSheet?.href)\ path\-1978980996.0.2.0.0.0.0\>/div>div class\title1\ path\-1978980996.0.2.0.0.0.1\>div class\flex\ path\-1978980996.0.2.0.0.0.1.0\>span v-text\π\ path\-1978980996.0.2.0.0.0.1.0.0\>/span>ul path\-1978980996.0.2.0.0.0.1.0.1\>li v-for\selector in getSelectors(selectedRule)\ path\-1978980996.0.2.0.0.0.1.0.1.0\>div v-text\selector\ path\-1978980996.0.2.0.0.0.1.0.1.0.0\>/div>/li>/ul>/div>/div>/div>div path\-1978980996.0.2.0.0.1\>ui-tabs :options\π Properties, π³ Flex\ direction\horizontal\ path\-1978980996.0.2.0.0.1.0\>template v-slot\tab0\ path\-1978980996.0.2.0.0.1.0.0\>table path\-1978980996.0.2.0.0.1.0.0.0\>tr :class\{ highlighted: (selectedFieldName field.name) }\ v-for\field in selectedRuleFields\ :key\field.id\ path\-1978980996.0.2.0.0.1.0.0.0.0\>th path\-1978980996.0.2.0.0.1.0.0.0.0.0\>div class\flex\ path\-1978980996.0.2.0.0.1.0.0.0.0.0.0\>div class\w-l2\ v-text\βοΈ\ path\-1978980996.0.2.0.0.1.0.0.0.0.0.0.0\>/div>div path\-1978980996.0.2.0.0.1.0.0.0.0.0.0.1\>div v-if\field.value\ v-text\field.name\ path\-1978980996.0.2.0.0.1.0.0.0.0.0.0.1.0\>/div>ui-input-text-box :style\{ width: 5em }\ v-if\!field.value\ v-model\field.name\ path\-1978980996.0.2.0.0.1.0.0.0.0.0.0.1.1\>/ui-input-text-box>/div>/div>/th>td path\-1978980996.0.2.0.0.1.0.0.0.0.1\>ide-css-field-editor :field\field\ on_input\(value) > setNewCssRule(field.name, value)\ path\-1978980996.0.2.0.0.1.0.0.0.0.1.0\>/ide-css-field-editor>/td>/tr>/table>div class\mt-l1\ path\-1978980996.0.2.0.0.1.0.0.1\>ui-button text\β\ :click\addNewField\ path\-1978980996.0.2.0.0.1.0.0.1.0\>/ui-button>/div>/template>template v-slot\tab1\ path\-1978980996.0.2.0.0.1.0.1\>ide-css-editor-flex>/ide-css-editor-flex>/template>/ui-tabs>/div>/div>/transition>div path\-1978980996.0.2.1\>table v-if\false\ path\-1978980996.0.2.1.0\>tr v-for\field in appliedStyles\ path\-1978980996.0.2.1.0.0\>th path\-1978980996.0.2.1.0.0.0\>ui-title icon\βοΈ\ :text\field.name\ path\-1978980996.0.2.1.0.0.0.0\>/ui-title>/th>td path\-1978980996.0.2.1.0.0.1\>div class\css-field-value\ v-text\field.value\ path\-1978980996.0.2.1.0.0.1.0\>/div>/td>/tr>/table>/div>/div>/div>/div>}},{name:ide.css.field.editor,path:\\ide\\css\\field\\editor.ws.yaml,source:{dom:{div#1:{div#2:{v-if:isToggleable,ui.select:{type:toggle,input-type:value,:options:options,v-model:field.value}},div#3:{v-if:!isToggleable,ui.input.text.box:{v-model:field.value,on_input:$emit(input, $event)}}}},props:{field:null},data:null,computed:{options:function() {\n if (!this.field.name) return ;\n let values this.$root.html.getPossibleCssValues(this.field.name);\n return values;\n}\n,isToggleable:function() {\n const values this.$root.html.cssPropertiesthis.field.name?.values||;\n if (!values.length) return false;\n if (values.some(v > v?.startsWith())) return false;\n return true;\n}\n},name:ide-css-field-editor,_:{examples:{count:0}},template:div class\comp-ide-css-field-editor\ path\653751728.\>div v-if\isToggleable\ path\653751728.0\>ui-select type\toggle\ input-type\value\ :options\options\ v-model\field.value\ path\653751728.0.0\>/ui-select>/div>div v-if\!isToggleable\ path\653751728.1\>ui-input-text-box v-model\field.value\ on_input\$emit(input, $event)\ path\653751728.1.0\>/ui-input-text-box>/div>/div>}},{name:ide.debug,path:\\ide\\debug.ws.yaml,source:{dom:{div:null},props:null,data:{contextMenus:},mounted:function() {\n this.$root.$on(\context-menu-mounted\, (contextMenu) > {\n });\n this.$root.$on(\context-menu-unmounted\, () > {\n });\n}\n,computed:{contextMenuOptions:function() {\n}\n},name:ide-debug,_:{examples:{count:0}},template:div class\comp-ide-debug\>/div>}},{name:ide.element.inspector,path:\\ide\\element\\inspector.ws.yaml,source:{dom:{div:{table:{tr:{v-for:prop in appliedStyles,th:{v-text:prop.name},td:{v-text:prop.value}}}}},props:{element:null},data:{appliedStyles:null},watch:{element:{immediate:true,handler:function() {\n this.appliedStyles this.$root.html.getAppliedStyles(this.element);\n}\n}},style:{.comp-ide-element-inspector:{background:#ffffff10,padding:1em,max-height:20em,overflow:auto}},name:ide-element-inspector,_:{examples:{count:0}},template:div class\comp-ide-element-inspector\ path\2011677761.\>table path\2011677761.0\>tr v-for\prop in appliedStyles\ path\2011677761.0.0\>th v-text\prop.name\ path\2011677761.0.0.0\>/th>td v-text\prop.value\ path\2011677761.0.0.1\>/td>/tr>/table>/div>}},{name:ide.element.picker,path:\\ide\\element\\picker.ws.yaml,source:{dom:{div#1:{ui.keyboard:{on_ctrl:onTriggerKey},ui.mouse:{on_hovered-element:onHoveredElement,:global:true},ui.context.window:{ref:context1,:global:true,:visible:isTriggerPressed,:icon:icon,:title:contextElement?.tagName.toLowerCase(),on_pinned:onPinned,.flex.gap-2:{div#2:{ui.tree:{:root:contextTree,:initial-expanded:10,:expandable:false,item-type:ide.element.tree.node,:get-item:(node) > (!node?.el ? null : node.el()),:get-children:(node) > node.children,on_node-hover:onNodeHover,on_node-unhover:onNodeUnhover,on_node-select:onNodeSelect}},div#3:{ide.css.editor:{:context-element:contextElement}}}}}},props:{icon:β,title:null},data:{selectedElement:null,hoveredElement:null,contextTree:null,isTriggerPressed:false},methods:{onTriggerKey:function(trigger) {\n this.isTriggerPressed trigger;\n const action trigger ? \add\ : \remove\;\n this.hoveredElement?.classListaction(\highlighted\);\n}\n,onHoveredElement:function(el) {\n if (this.$refs.context1.isPinned) return;\n this.hoveredElement el;\n}\n,onNodeHover:function(node) {\n this.hoveredElement (!node?.el ? null : node.el());\n}\n,onNodeUnhover:function(node) {\n this.hoveredElement null;\n}\n,onNodeSelect:function(node) {\n this.selectedElement (!node?.el ? null : node.el());\n}\n,onPinned:function(isPinned) {\n const treeNodeComps this.$root.vm.getDescendants(this, (c) > c.$data._?.comp.name \ui.tree.node\);\n const treeNodeComp treeNodeComps.find(c > ((!c.node.el ? null : c.node.el()) this.hoveredElement));\n treeNodeComp?.onNodeClick();\n}\n,getParentChain:function(el) {\n let chain ;\n while (el && chain.length 5) {\n chain.push(el);\n el el.parentElement;\n }\n chain chain;\n return chain;\n}\n,getContextTree:function(el) {\n const root {};\n let node root;\n let parentChain this.getParentChain(el);\n parentChain ...parentChain.reverse();\n while (parentChain.length) {\n const el parentChain.shift();\n node.el () > el;\n node.children ;\n node.children.push({});\n node node.children0;\n }\n return root;\n}\n},computed:{contextElement:function() {\n if (this.$refs.context1?.isPinned) return this.selectedElement;\n return this.hoveredElement || this.selectedElement;\n}\n,isContextWindowVisible:function() {\n return this.isTriggerPressed || this.$refs.context1?.isPinned;\n}\n},watch:{contextElement:{handler:function(el) {\n if (!this.$refs.context1?.isPinned) this.contextTree this.getContextTree(el);\n this.$emit(\context-element\, el);\n}\n,immediate:true},selectedElement:{handler:function(el, oldEl) {\n oldEl?.classList.remove(\highlighted2\);\n el?.classList.add(\highlighted2\);\n}\n,immediate:true},hoveredElement:function(el, oldEl) {\n oldEl?.classList.remove(\highlighted\);\n if (!this.isContextWindowVisible) return;\n el?.classList.add(\highlighted\);\n}\n},style:null,name:ide-element-picker,_:{examples:{count:0}},template:div class\comp-ide-element-picker\ path\-549121148.\>ui-keyboard on_ctrl\onTriggerKey\ path\-549121148.0\>/ui-keyboard>ui-mouse on_hovered-element\onHoveredElement\ :global\true\ path\-549121148.1\>/ui-mouse>ui-context-window ref\context1\ :global\true\ :visible\isTriggerPressed\ :icon\icon\ :title\contextElement?.tagName.toLowerCase()\ on_pinned\onPinned\ path\-549121148.2\>div class\flex gap-2\ path\-549121148.2.0\>div path\-549121148.2.0.0\>ui-tree :root\contextTree\ :initial-expanded\10\ :expandable\false\ item-type\ide.element.tree.node\ :get-item\(node) > (!node?.el ? null : node.el())\ :get-children\(node) > node.children\ on_node-hover\onNodeHover\ on_node-unhover\onNodeUnhover\ on_node-select\onNodeSelect\ path\-549121148.2.0.0.0\>/ui-tree>/div>div path\-549121148.2.0.1\>ide-css-editor :context-element\contextElement\ path\-549121148.2.0.1.0\>/ide-css-editor>/div>/div>/ui-context-window>/div>}},{name:ide.element.tree.node,path:\\ide\\element\\tree\\node.ws.yaml,source:{dom:{div#1:{v-if:item,div#2:{v-text:π + item.tagName.toLowerCase()}}},props:{item:null},style:{div:{white-space:nowrap}},name:ide-element-tree-node,_:{examples:{count:0}},template:div class\comp-ide-element-tree-node\ v-if\item\ path\2080280476.\>div v-text\π + item.tagName.toLowerCase()\ path\2080280476.0\>/div>/div>}},{name:ide.module.action,path:\\ide\\module\\action.ws.yaml,source:{dom:{.flex:{v-if:action,ui.context.window:{h2:{ui.title#1:{icon:π΄,:text:action.redo.method}},ui.value.any:{:value:action}},div#1:{class:opacity-30 px-3,v-text:action._id},ui.title#2:{:style:{ width: 10em },:icon:getIcon(action),:text:getText(action),:number:action?.redo?.args?.length},div#2:{class:pl-l2,ui.data.changes:{:data-changes:action._info?.dataChanges}}}},props:{action:null},methods:{getIcon:function(action) {\n const redo action.redo;\n if (redo.noop) return βͺ;\n if (redo.method) return π΄;\n return ;\n}\n,getText:function(action) {\n const redo action.redo;\n if (redo.noop) return no.op;\n if (redo.method) return redo.method;\n return ;\n}\n},computed:{redo:function() {\n return this.action.redo;\n}\n},style:null,_:{examples:{count:0}},name:ide-module-action,template:div class\comp-ide-module-action flex\ v-if\action\ path\-1542681676.\>ui-context-window path\-1542681676.0\>h2 path\-1542681676.0.0\>ui-title icon\π΄\ :text\action.redo.method\ path\-1542681676.0.0.0\>/ui-title>/h2>ui-value-any :value\action\ path\-1542681676.0.1\>/ui-value-any>/ui-context-window>div class\opacity-30 px-3\ v-text\action._id\ path\-1542681676.1\>/div>ui-title :style\{ width: 10em }\ :icon\getIcon(action)\ :text\getText(action)\ :number\action?.redo?.args?.length\ path\-1542681676.2\>/ui-title>div class\pl-l2\ path\-1542681676.3\>ui-data-changes :data-changes\action._info?.dataChanges\ path\-1542681676.3.0\>/ui-data-changes>/div>/div>}},{name:ide.module.data,path:\\ide\\module\\data.ws.yaml,source:{dom:{div:{ui.value.any:{:value:getModuleData(moduleInstance)}}},props:{moduleInstance:null},methods:{getModuleData:function(moduleInstance) {\n const data {};\n for (const key in moduleInstance) {\n const value moduleInstancekey;\n if (!this.includeData(key, value)) continue;\n datakey value;\n }\n return data;\n}\n,includeData:function(key, value) {\n if (key.startsWith(_)) return false;\n if (typeof value function) return false;\n return true;\n}\n},_:{examples:{count:0}},name:ide-module-data,template:div class\comp-ide-module-data\ path\1196246184.\>ui-value-any :value\getModuleData(moduleInstance)\ path\1196246184.0\>/ui-value-any>/div>}},{name:ide.module.list,path:\\ide\\module\\list.ws.yaml,source:{dom:{.flex:{ui.select:{:options:modules,item-icon:π¦,:get-item-text:(m) > m.name,input-type:value,v-model:selectedModule},div:{ide.module:{:module:selectedModule}}}},data:{selectedModule:null},computed:{modules:function() {\n const modules vueApp.client.moduleManager.modules;\n return modules;\n}\n},_:{examples:{count:0}},name:ide-module-list,template:div class\comp-ide-module-list flex\ path\1196492188.\>ui-select :options\modules\ item-icon\π¦\ :get-item-text\(m) > m.name\ input-type\value\ v-model\selectedModule\ path\1196492188.0\>/ui-select>div path\1196492188.1\>ide-module :module\selectedModule\ path\1196492188.1.0\>/ide-module>/div>/div>}},{name:ide.module.method.args,path:\\ide\\module\\method\\args.ws.yaml,source:{dom:{div:{table:{tr:{v-for:argName in method.args,td#1:{ui.title:{icon:π§,:text:argName}},td#2:{ui.input.text.box:{v-model:argJsonsargName}},td#3:{ui.value.any:{:value:argsargName}}}}}},props:{method:null},data:{argJsons:{}},computed:{args:function() {\n return Object.fromEntries(\n Object.entries(this.argJsons)\n .map((k, v) > {\n try\n {\n return k, JSON.parse(v)\n }\n catch (ex)\n {\n return k, null\n }\n })\n );\n}\n},watch:{args:{handler:function() {\n this.$emit(input, this.args);\n}\n,deep:true}},_:{examples:{count:0}},name:ide-module-method-args,template:div class\comp-ide-module-method-args\ path\-716550388.\>table path\-716550388.0\>tr v-for\argName in method.args\ path\-716550388.0.0\>td path\-716550388.0.0.0\>ui-title icon\π§\ :text\argName\ path\-716550388.0.0.0.0\>/ui-title>/td>td path\-716550388.0.0.1\>ui-input-text-box v-model\argJsonsargName\ path\-716550388.0.0.1.0\>/ui-input-text-box>/td>td path\-716550388.0.0.2\>ui-value-any :value\argsargName\ path\-716550388.0.0.2.0\>/ui-value-any>/td>/tr>/table>/div>}},{name:ide.module.method,path:\\ide\\module\\method\\_.ws.yaml,source:{dom:{div:{v-if:method,h3:{ui.title:{icon:π΄,:text:method.name},pre:{v-html:method.code}}}},props:{method:null},_:{examples:{count:0}},name:ide-module-method,template:div class\comp-ide-module-method\ v-if\method\ path\-1197285793.\>h3 path\-1197285793.0\>ui-title icon\π΄\ :text\method.name\ path\-1197285793.0.0\>/ui-title>pre v-html\method.code\ path\-1197285793.0.1\>/pre>/h3>/div>}},{name:ide.module,path:\\ide\\module\\_.ws.yaml,source:{dom:{div#1:{transition#1:{name:slide-hor,div#2:{v-if:module,:key:module.name,h2:{:key:module.name,ui.title#1:{icon:π¦,:text:module.name}},.flex.gap-2:{ui.select:{:options:module.source.methods,item-icon:π΄,:get-item-text:(m) > m.name,input-type:value,v-model:selectedMethod},transition#2:{name:slide-hor,div#3:{v-if:selectedMethod,:key:selectedMethod.name,ide.module.method.args:{:method:selectedMethod,v-model:methodArgs},ui.button:{icon:βΆ,:text:selectedMethod.name,:click:() > invokeMethod(selectedMethod)},ide.module.method:{:method:selectedMethod}}},div#4:{v-if:moduleInstance,:key:key1,ide.module.data:{:module-instance:moduleInstance},ui.action.stack:{:action-stack:moduleInstance._actionStack,v-slot:slotProps,template:{ide.module.action:{:action:slotProps.action}}}},div#5:{h3:{ui.title#2:{icon:π,text:Log}},ui.value.array:{:value:logItems,:reverse:true}}}}}}},props:{module:null},data:{selectedMethod:null,methodArgs:,moduleInstance:null,logItems:,key1:1},methods:{invokeMethod:async function(method) {\n const moduleInstance this.moduleInstance;\n if (!moduleInstance) return;\n const args this.getMethodArgs(method);\n const result await moduleInstancemethod.name(...args);\n this.logItems.add({ method: method.name, args, result });\n this.refresh();\n}\n,getNewModuleInstance:async function(module) {\n const moduleClass eval(module.name);\n const instance await moduleClass._new();\n return instance;\n}\n,getMethodArgs:function(method) {\n const args method.args\n .map(argName > this.methodArgsargName);\n return Objects.clone(args);\n}\n,refresh:async function() {\n await this.$nextTick();\n this.key1++;\n}\n},watch:{module:{handler:async function() {\n this.selectedMethod null;\n this.moduleInstance (!this.module) ? null :\n (await this.getNewModuleInstance(this.module));\n}\n,immediate:true}},_:{examples:{count:0}},name:ide-module,template:div class\comp-ide-module\ path\1515962928.\>transition name\slide-hor\ path\1515962928.0\>div v-if\module\ :key\module.name\ path\1515962928.0.0\>h2 :key\module.name\ path\1515962928.0.0.0\>ui-title icon\π¦\ :text\module.name\ path\1515962928.0.0.0.0\>/ui-title>/h2>div class\flex gap-2\ path\1515962928.0.0.1\>ui-select :options\module.source.methods\ item-icon\π΄\ :get-item-text\(m) > m.name\ input-type\value\ v-model\selectedMethod\ path\1515962928.0.0.1.0\>/ui-select>transition name\slide-hor\ path\1515962928.0.0.1.1\>div v-if\selectedMethod\ :key\selectedMethod.name\ path\1515962928.0.0.1.1.0\>ide-module-method-args :method\selectedMethod\ v-model\methodArgs\ path\1515962928.0.0.1.1.0.0\>/ide-module-method-args>ui-button icon\βΆ\ :text\selectedMethod.name\ :click\() > invokeMethod(selectedMethod)\ path\1515962928.0.0.1.1.0.1\>/ui-button>ide-module-method :method\selectedMethod\ path\1515962928.0.0.1.1.0.2\>/ide-module-method>/div>/transition>div v-if\moduleInstance\ :key\key1\ path\1515962928.0.0.1.2\>ide-module-data :module-instance\moduleInstance\ path\1515962928.0.0.1.2.0\>/ide-module-data>ui-action-stack :action-stack\moduleInstance._actionStack\ v-slot\slotProps\ path\1515962928.0.0.1.2.1\>template path\1515962928.0.0.1.2.1.0\>ide-module-action :action\slotProps.action\ path\1515962928.0.0.1.2.1.0.0\>/ide-module-action>/template>/ui-action-stack>/div>div path\1515962928.0.0.1.3\>h3 path\1515962928.0.0.1.3.0\>ui-title icon\π\ text\Log\ path\1515962928.0.0.1.3.0.0\>/ui-title>/h3>ui-value-array :value\logItems\ :reverse\true\ path\1515962928.0.0.1.3.1\>/ui-value-array>/div>/div>/div>/transition>/div>}},{name:ide.performance.inspector,path:\\ide\\performance\\inspector\\_.ws.yaml,source:{dom:{.inspector:{v-if:false,h2:{v-text:β Performance},on_mouseenter:isHovered true,on_mouseleave:isHovered false,transition:{name:slide,.warning:{v-if:isHovered,v-text:Refresh is paused}},div:{v-text:Frequent operations are throttled for performance sake.},ui.value:{:value:logItems,on_input:query:refresh2}}},data:{logs:{},logItems:,isHovered:false},mounted:function() {\n this.refresh();\n}\n,methods:{refresh:function(force) {\n if (force || (!this.isHovered)) this.refresh2();\n setTimeout(this.refresh.bind(this), 1000);\n}\n,refresh2:function(query) {\n this.logItems this.getLogItems();\n}\n,getLogItems:function() {\n const logItems Object.values(this.logs)\n .map(logItem > ({\n component: `π¦ ${logItem.context.name}`,\n operation: this.getOperationName(logItem),\n invokes: logItem.invokes,\n \average (ms)\: Math.round(logItem.elapsed.average),\n \total (ms)\: Math.round(logItem.elapsed.total),\n }));\n return logItems;\n}\n,getOperationName:function(logItem) {\n const icon ({\n \event\: \β‘\,\n \computed\: \π‘\,\n \watcher\: \π\,\n \method\: \π΄\,\n })logItem.type || \β\;\n return `${icon} ${logItem.name}`;\n}\n,afterCompEvent:function(compEvent) {\n const log this.getCompEventLog(compEvent);\n log.invokes++;\n log.elapsed.min Math.min(log.elapsed.min, compEvent.elapsed);\n log.elapsed.max Math.max(log.elapsed.max, compEvent.elapsed);\n log.elapsed.total + compEvent.elapsed;\n log.elapsed.average (log.elapsed.total / log.invokes);\n log.last.measurements.push(compEvent.elapsed);\n if (log.last.measurements.length > 100) {\n log.last.measurements.shift();\n }\n}\n,getCompEventLog:function(compEvent) {\n const contextName compEvent.context.$options.name;\n const logKey contextName, compEvent.type, compEvent.name;\n const log (this.logslogKey (this.logslogKey || {\n key: logKey,\n context: {\n name: contextName,\n },\n compEvent: {\n type: compEvent.type,\n name: compEvent.name,\n },\n last: {\n measurements: ,\n },\n invokes: 0,\n elapsed: {\n total: 0,\n min: 0,\n max: 0,\n average: 0\n }\n }));\n return log;\n}\n},style:{.inspector:{position:fixed,left:0,bottom:0,opacity:0.5,max-width:10em,max-height:10em,overflow:hidden,padding:1em,border:1px solid #ccc,background:#303030,transition:1s},.inspector:hover:{max-width:50em,max-height:50em,opacity:1},.warning:{text-align:center},.value-as-string:{max-width:40em !important}},_:{examples:{count:0}}}},{name:ide.state.tracker.item,path:\\ide\\state\\tracker\\item.ws.yaml,source:{dom:{tr:{:class:getGridClass(),on_click:$emit(click),td#1:{v-if:icon,v-text:icon},td#2:{v-if:showCompName,class:opacity-30,v-text:item.vueCompName},td#3:{class:text-center,v-text:$root.getIcon(item)},td#4:{v-text:item.key},td#5:{class:newValue,v-if:(valueInGrid && item.newValue),ui.value.preview:{v-if:showValue(item),:value:item.newValue.value},on_mouseenter:onHoverValue,on_mouseleave:onUnhoverValue}}},props:{item:null,icon:null,preview:false,showCompName:false,depth:0},data:{isHoveringOverValue:false,selectedItem:null},mounted:function() {\n //this.$root.$on(\state-changed\, this.onStateChanged.bind(this));\n}\n,methods:{getMethod:function(item) {\n const vue this.$root.vm.getVue(item.uid);\n const methodDatas vue._vueIde.methodDatas;\n return methodDatasitem.key.originalMethod;\n}\n,showValue:function(item) {\n if (\m\.includes(item.type)) return false;\n return true;\n}\n,showMethod:function(item) {\n if (!this.preview) return false;\n if (\m\.includes(item.type)) return true;\n return false;\n}\n,onHoverValue:function() {\n this.isHoveringOverValue true;\n this.$root.$emit(\preview-state-item\, this.item);\n}\n,onUnhoverValue:function() {\n this.isHoveringOverValue false;\n this.$root.$emit(\preview-state-item\, null);\n}\n,onItemClick:function(item) {\n this.selectedItem (this.selectedItem item) ? null : item;\n //this.$root.$emit(\watch-state-item\, { uid: this.uid, key: item.key });\n}\n,showFieldContext:function(item) {\n if (item.type \m\) return false;\n if (typeof(item.newValue) \boolean\) return false;\n if (undefined, null.includes(item.newValue)) return false;\n return true;\n}\n,getMethodBodyColored:function(compName, methodName) {\n let methodBody this.getMethodBody(compName, methodName);\n methodBody Prism.highlight(methodBody, Prism.languages.javascript, javascript);\n return methodBody;\n}\n,getMethodBody:function(compName, methodName) {\n const comp this.$root.getComponent(compName);\n if (!comp) return null;\n const methodBody comp.source.methodsmethodName || comp.sourcemethodName;\n if (!methodBody) return null;\n return methodBody;\n}\n,onStateChanged:function(item) {\n //if (item.key this.item.key) this.refresh();\n}\n,getGridClass:function() {\n const cls ;\n cls.push(this.item.type);\n cls.push(\tr\);\n if (this.preview) cls.push(\preview\);\n return cls;\n}\n,consoleLog:function(value) {\n console.log(value);\n}\n},computed:{valueInGrid:function() {\n return (!this.preview);\n}\n},watch:{selectedItem:{handler:function(selectedItem) {\n this.$emit(\select-item\, selectedItem);\n}\n,immediate:true}},style:{.tr:{white-space:nowrap},td:{padding:0 0.5em},td:first-child:{border-radius:0.5em 0 0 0.5em},td:last-child:{border-radius:0 0.5em 0.5em 0},.grid:{width:min-content,text-wrap:nowrap,overflow:hidden},.grid > *:{overflow:hidden},.grid.preview:{font-size:140%},.comp-name:{opacity:0.5},.newValue:{color:cyan},.oldValue:{opacity:0.5},.comp-ui-textarea:{width:40em,height:20em,font-size:110%}},name:ide-state-tracker-item,_:{examples:{count:0}},template:tr class\comp-ide-state-tracker-item\ :class\getGridClass()\ on_click\$emit(click)\ path\841306122.\>td v-if\icon\ v-text\icon\ path\841306122.0\>/td>td class\opacity-30\ v-if\showCompName\ v-text\item.vueCompName\ path\841306122.1\>/td>td class\text-center\ v-text\$root.getIcon(item)\ path\841306122.2\>/td>td v-text\item.key\ path\841306122.3\>/td>td class\newValue\ v-if\(valueInGrid && item.newValue)\ on_mouseenter\onHoverValue\ on_mouseleave\onUnhoverValue\ path\841306122.4\>ui-value-preview v-if\showValue(item)\ :value\item.newValue.value\ path\841306122.4.0\>/ui-value-preview>/td>/tr>}},{name:ide.state.tracker,path:\\ide\\state\\tracker.ws.yaml,source:{dom:{.flex:{div:{:class:getSliderClass(),h3#1:{ui.title#1:{text:π§ State}},transition#1:{name:slide,table:{class:list1,ide.state.tracker.item:{v-for:field in $root.vm.getFields(uid),:class:getCssClass(field),on_click:toggleWatch(field),:uid:uid,:item:field,:key:uid+.+field.key}}}},transition#2:{name:slide-hor,.watches:{v-if:watchedFieldKeys.length,transition.group:{tag:ul,name:slide,li:{v-for:field in watchedFields,class:clickable,on_click:console.log($root.vm.getVue(uid)field.key),:key:field.key,h3#2:{class:opacity-50,ui.title#2:{:icon:$root.getIcon(field),:text:field.key}},ui.value.any:{:value:field.newValue.value,:preview:false}}}}}}},props:{uid:null},data:{key1:1,watchedFieldKeys:,selectedItem:null},mounted:async function() {\n //this.$root.$on(\state-changed\, this.onStateChanged.bind(this));\n}\n,methods:{getSliderClass:function() {\n const cls {};\n if (this.watchedFieldKeys.length) {\n cls\slider-closed\ true;\n }\n else\n {\n cls\slider-opened\ true;\n }\n return cls;\n}\n,toggleWatch:function(field) {\n if (this.watchedFieldKeys.includes(field.key)) {\n this.watchedFieldKeys this.watchedFieldKeys.filter(w > w ! field.key);\n } else {\n this.watchedFieldKeys.push(field.key);\n }\n}\n,getCssClass:function(item) {\n const cls {};\n cls.clickable true;\n cls.selected (this.watchedFieldKeys.includes(item.key));\n return cls;\n}\n,onStateChanged:function(change) {\n if (!change) return;\n if (this.uid change.uid) this.refresh();\n}\n,refresh:function() {\n this.key1++;\n}\n},computed:{watchedFields:function() {\n const fields this.$root.vm.getFields(this.uid);\n return fields.filter(f > this.watchedFieldKeys.includes(f.key));\n}\n,console:function() {\n return console;\n}\n},style:{.comp-ide-state-tracker:{overflow:hidden},.watches:{max-height:50vh,overflow:auto,padding:1em 2em},.watches ul:{gap:1em},.watches h3:{font-size:1.2rem},.comp-ui-title:{border-radius:0,border-bottom:1px solid #000},.flex:{gap:1em},ul:{display:flex,flex-direction:column-reverse},ul:not(.changes) .grid:{opacity:0.5},tr:hover:{background:#ffffff10,transition:0s}},name:ide-state-tracker,_:{examples:{count:0}},template:div class\comp-ide-state-tracker flex\ path\-483235177.\>div :class\getSliderClass()\ path\-483235177.0\>h3 path\-483235177.0.0\>ui-title text\π§ State\ path\-483235177.0.0.0\>/ui-title>/h3>transition name\slide\ path\-483235177.0.1\>table class\list1\ path\-483235177.0.1.0\>ide-state-tracker-item v-for\field in $root.vm.getFields(uid)\ :class\getCssClass(field)\ on_click\toggleWatch(field)\ :uid\uid\ :item\field\ :key\uid+.+field.key\ path\-483235177.0.1.0.0\>/ide-state-tracker-item>/table>/transition>/div>transition name\slide-hor\ path\-483235177.1\>div class\watches\ v-if\watchedFieldKeys.length\ path\-483235177.1.0\>transition-group tag\ul\ name\slide\ path\-483235177.1.0.0\>li class\clickable\ v-for\field in watchedFields\ on_click\console.log($root.vm.getVue(uid)field.key)\ :key\field.key\ path\-483235177.1.0.0.0\>h3 class\opacity-50\ path\-483235177.1.0.0.0.0\>ui-title :icon\$root.getIcon(field)\ :text\field.key\ path\-483235177.1.0.0.0.0.0\>/ui-title>/h3>ui-value-any :value\field.newValue.value\ :preview\false\ path\-483235177.1.0.0.0.1\>/ui-value-any>/li>/transition-group>/div>/transition>/div>}},{name:ide.title,path:\\ide\\title.ws.yaml,source:{dom:{h3:{v-if:item,ui.title:{:icon:$root.getIcon(item),:text:item.key}}},props:{item:null},name:ide-title,_:{examples:{count:0}},template:h3 class\comp-ide-title\ v-if\item\ path\-1745912300.\>ui-title :icon\$root.getIcon(item)\ :text\item.key\ path\-1745912300.0\>/ui-title>/h3>}},{name:ide.vue.activity.comp.event,path:\\ide\\vue\\activity\\comp.event.ws.yaml,source:{dom:{.flex:{.w-l2:{v-text:compEvent.icon},div#1:{class:w-l8,v-text:compEvent.name},div#2:{ui.value.preview:{v-if:(newValue in compEvent),:value:compEvent.newValue}}}},props:{compEvent:null},methods:null,style:{.flex > *:nth-child(1):{width:10em}},_:{examples:{count:0}}}},{name:ide.vue.activity,path:\\ide\\vue\\activity\\_.ws.yaml,source:{dom:{div#1:{.flex.gap-1:{ui.drawer:{div#2:{ui.checkbox:{v-for:compEventName in compEventNames,:key:compEventName,:text:compEventName,:value-array:hideCompEventNames,:value-key:compEventName,:value-array-exclude:true}}},div#3:{transition.group:{tag:ul,name:list,class:comp-events,li:{v-for:compEvent in visibleCompEvents,:key:compEvent._id,:class:{ comp-event: true, done: (compEvent._id doneCompEventID) },on_mouseenter:onCompEventHover(compEvent),on_mouseleave:onCompEventHover(null),ide.vue.activity.comp.event:{:comp-event:compEvent}}}},div#4:{v-if:false,ui.value:{:value:hoveredCompEvent}}}}},props:{vue:null},data:{hoveredCompEvent:null,targetCompEvent:null,hideCompEventNames:,key1:1},mounted:function() {\n this.goToTargetCompEvent();\n}\n,methods:{goToTargetCompEvent:async function() {\n const noopDelay 100;\n if (this.isAtTargetCompEvent) return setTimeout(this.goToTargetCompEvent.bind(this), noopDelay);\n const direction (this.targetCompEvent._id this.doneCompEventID) ? -1 : 1;\n const doneIndex this.compEvents.findIndex(ce > ce._id this.doneCompEventID);\n const doneCompEvent this.compEventsdoneIndex;\n await this.executeCompEvent(doneCompEvent, direction);\n const nextIndex (doneIndex + direction);\n const nextCompEvent this.compEventsnextIndex;\n this.setDoneCompEventID(nextCompEvent._id);\n // When goint up, when we arrive at the target, execute it\n if ((direction 1) && (this.isAtTargetCompEvent)) {\n await this.executeCompEvent(nextCompEvent, direction);\n }\n //await this.$nextTick();\n this.goToTargetCompEvent();\n}\n,executeCompEvent:async function(compEvent, direction) {\n // Pause the activity tracker\n this.vue().$data._ide_activity.isPaused true;\n // Remove the icon\n const dataKey compEvent.name;\n try\n {\n if (compEvent.type \data\)\n {\n const value (direction 1) ? compEvent.newValue : compEvent.oldValue;\n this.vue()dataKey value;\n }\n }\n finally {\n // Resume the activity tracker\n await this.$nextTick();\n this.vue().$data._ide_activity.isPaused false;\n }\n}\n,onCompEventHover:function(compEvent) {\n this.hoveredCompEvent compEvent;\n this.targetCompEvent compEvent;\n // The first few comp events are initialtrue\n // If target is below them, set it to the first non-initial comp event\n if (this.targetCompEvent && this.targetCompEvent.initial) {\n const firstNonInitialCompEventIndex this.compEvents.findIndex(ce > !ce.initial);\n if (firstNonInitialCompEventIndex ! -1) {\n this.targetCompEvent this.compEvents(firstNonInitialCompEventIndex - 1);\n }\n }\n}\n,setDoneCompEventID:function(newDoneCompEventID) {\n this.vue().$data._ide_activity.doneCompEventID.value newDoneCompEventID;\n}\n,isCompEventVisible:function(compEvent) {\n if (compEvent.type \data\) return true;\n return false;\n}\n},computed:{isAtTargetCompEvent:function() {\n if (!this.targetCompEvent) return true;\n if (this.targetCompEvent._id this.doneCompEventID) return true;\n return false;\n}\n,doneCompEventID:function() {\n return this.vue()?.$data._ide_activity.doneCompEventID.value;\n}\n,visibleCompEvents:function() {\n return this.compEvents\n .filter(this.isCompEventVisible.bind(this))\n .filter(ce > !this.hideCompEventNames.includes(ce.name));\n}\n,compEventNames:function() {\n return this.compEvents\n .filter(this.isCompEventVisible.bind(this))\n .map(ce > ce.name)\n .distinct()\n .sort();\n}\n,compEvents:function() {\n return ...(this.vue()?.$data._ide_activity.items);\n}\n},style:{.comp-events:{display:flex,flex-direction:column-reverse,max-height:60vh,overflow-y:auto},.comp-event:{height:1.5em,transition:0.2s},.done:{background:#88888830}},_:{examples:{count:0}}}},{name:ide.vue.inspector,path:\\ide\\vue\\inspector.ws.yaml,source:{dom:{transition:{name:slide-hor,div#1:{v-if:vue,:key:vue()._uid,div#2:{h2:{ui.title:{icon:π¦,:text:vue().$options.name}},ui.tabs:{:options:π§ state, β activity,v-model:selectedTabIndex,direction:horizontal,template#1:{v-slot:tab0,ide.vue.state:{:vue:vue}},template#2:{v-slot:tab1,ide.vue.activity:{:vue:vue}}}}}}},props:{vue:null},data:{selectedTabIndex:0},methods:null,watch:null,style:{.list1:{margin-top:1em,max-height:40vh,overflow-x:hidden,overflow-y:auto}},name:ide-vue-inspector,_:{examples:{count:0}},template:transition class\comp-ide-vue-inspector\ name\slide-hor\ path\1328580683.\>div v-if\vue\ :key\vue()._uid\ path\1328580683.0\>div path\1328580683.0.0\>h2 path\1328580683.0.0.0\>ui-title icon\π¦\ :text\vue().$options.name\ path\1328580683.0.0.0.0\>/ui-title>/h2>ui-tabs :options\π§ state, β¨ activity, π view, π΄ methods\ v-model\selectedTabIndex\ direction\horizontal\ path\1328580683.0.0.1\>template v-slot\header\ path\1328580683.0.0.1.0\>div class\mt-l1\ path\1328580683.0.0.1.0.0\>/div>/template>template v-slot\tab0\ path\1328580683.0.0.1.1\>div v-text\tab 0\ path\1328580683.0.0.1.1.0\>/div>/template>template v-slot\tab1\ path\1328580683.0.0.1.2\>/template>template v-slot\tab2\ path\1328580683.0.0.1.3\>/template>template v-slot\tab3\ path\1328580683.0.0.1.4\>/template>/ui-tabs>div path\1328580683.0.0.2\>ide-vue-state :vue\vue\ path\1328580683.0.0.2.0\>/ide-vue-state>/div>/div>/div>/transition>}},{name:ide.vue.state.item,path:\\ide\\vue\\state\\item.ws.yaml,source:{dom:{tr:{:class:getGridClass(),on_click:$emit(click),td#1:{v-if:icon,class:icon,v-text:icon},td#2:{v-if:showCompName,class:opacity-30,v-text:item.vueCompName},td#3:{class:text-center,v-text:$root.getIcon(item)},td#4:{v-text:item.key},td#5:{class:newValue,v-if:(valueInGrid && item.newValue),ui.value.preview:{v-if:showValue(item),:value:item.newValue.value},on_mouseenter:onHoverValue,on_mouseleave:onUnhoverValue}}},props:{item:null,icon:null,preview:false,showCompName:false,depth:0},data:{isHoveringOverValue:false,selectedItem:null},mounted:function() {\n //this.$root.$on(\state-changed\, this.onStateChanged.bind(this));\n}\n,methods:{getMethod:function(item) {\n const vue this.$root.vm.getVue(item.uid);\n const methodDatas vue._vueIde.methodDatas;\n return methodDatasitem.key.originalMethod;\n}\n,showValue:function(item) {\n if (\m\.includes(item.type)) return false;\n return true;\n}\n,showMethod:function(item) {\n if (!this.preview) return false;\n if (\m\.includes(item.type)) return true;\n return false;\n}\n,onHoverValue:function() {\n this.isHoveringOverValue true;\n this.$root.$emit(\preview-state-item\, this.item);\n}\n,onUnhoverValue:function() {\n this.isHoveringOverValue false;\n this.$root.$emit(\preview-state-item\, null);\n}\n,onItemClick:function(item) {\n this.selectedItem (this.selectedItem item) ? null : item;\n //this.$root.$emit(\watch-state-item\, { uid: this.uid, key: item.key });\n}\n,showFieldContext:function(item) {\n if (item.type \m\) return false;\n if (typeof(item.newValue) \boolean\) return false;\n if (undefined, null.includes(item.newValue)) return false;\n return true;\n}\n,getMethodBodyColored:function(compName, methodName) {\n let methodBody this.getMethodBody(compName, methodName);\n methodBody Prism.highlight(methodBody, Prism.languages.javascript, javascript);\n return methodBody;\n}\n,getMethodBody:function(compName, methodName) {\n const comp this.$root.getComponent(compName);\n if (!comp) return null;\n const methodBody comp.source.methodsmethodName || comp.sourcemethodName;\n if (!methodBody) return null;\n return methodBody;\n}\n,onStateChanged:function(item) {\n //if (item.key this.item.key) this.refresh();\n}\n,getGridClass:function() {\n const cls ;\n cls.push(this.item.type);\n cls.push(\tr\);\n if (this.preview) cls.push(\preview\);\n return cls;\n}\n,consoleLog:function(value) {\n console.log(value);\n}\n},computed:{valueInGrid:function() {\n return (!this.preview);\n}\n},watch:{selectedItem:{handler:function(selectedItem) {\n this.$emit(\select-item\, selectedItem);\n}\n,immediate:true}},style:{.icon:{width:2em},.tr:{white-space:nowrap},td:{padding:0 0.5em},td:first-child:{border-radius:0.5em 0 0 0.5em},td:last-child:{border-radius:0 0.5em 0.5em 0},.grid:{width:min-content,text-wrap:nowrap,overflow:hidden},.grid > *:{overflow:hidden},.grid.preview:{font-size:140%},.comp-name:{opacity:0.5},.newValue:{color:cyan},.oldValue:{opacity:0.5},.comp-ui-textarea:{width:40em,height:20em,font-size:110%}},name:ide-vue-state-item,_:{examples:{count:0}},template:tr class\comp-ide-vue-state-item\ :class\getGridClass()\ on_click\$emit(click)\ path\506298236.\>td v-if\icon\ v-text\icon\ path\506298236.0\>/td>td class\opacity-30\ v-if\showCompName\ v-text\item.vueCompName\ path\506298236.1\>/td>td class\text-center\ v-text\$root.getIcon(item)\ path\506298236.2\>/td>td v-text\item.key\ path\506298236.3\>/td>td class\newValue\ v-if\(valueInGrid && item.newValue)\ on_mouseenter\onHoverValue\ on_mouseleave\onUnhoverValue\ path\506298236.4\>ui-value-preview v-if\showValue(item)\ :value\item.newValue.value\ path\506298236.4.0\>/ui-value-preview>/td>/tr>}},{name:ide.vue.state,path:\\ide\\vue\\state\\_.ws.yaml,source:{dom:{.flex:{div:{:class:getSliderClass(),transition#1:{name:slide,table:{class:list1,ide.vue.state.item:{v-for:field in getFields(vue()),:class:getCssClass(field),on_click:toggleWatch(field),:vue:vue,:icon:(watchedFieldKeys.includes(field.key) ? π : ),:item:field,:key:vue()._uid+.+field.key}}}},transition#2:{name:slide-hor,.watches:{v-if:watchedFieldKeys.length,transition.group:{tag:ul,name:slide,li:{v-for:field in watchedFields,class:clickable,on_click:console.log(vue()field.key),:key:field.key,h3:{class:opacity-50,ui.title:{:icon:$root.getIcon(field),:text:field.key}},ui.value.any:{:value:field.newValue.value,:preview:false}}}}}}},props:{vue:null},data:{watchedFieldKeys:,selectedItem:null},mounted:async function() {\n //this.$root.$on(\state-changed\, this.onStateChanged.bind(this));\n}\n,methods:{getFields:function(vue) {\n if (!vue) return ;\n let fields ;\n fields.push(...Object.keys(vue.$data || {}).map((k) > {\n return { type: \d\, key: k, newValue: StateValue.from(vue.$datak) };\n }));\n fields.push(...Object.keys(vue.$props || {}).map((k) > {\n return { type: \p\, key: k, newValue: StateValue.from(vue.$propsk) };\n }));\n fields.push(...this.getComputedKeys(vue).map((k) > {\n return { type: \c\, key: k, newValue: StateValue.from(vuek) };\n }));\n fields fields.filter((f) > !f.key.startsWith(\_\));\n fields fields.sortBy((f) > f.type, (f) > f.key);\n return fields;\n}\n,getComputedKeys:function(vue) {\n if (!vue) return ;\n let keys Object.keys(vue._computedWatchers || vue.$options._computedWatchers || {});\n keys keys.filter((k) > !k.startsWith(\$\));\n keys keys.sortBy((k) > k);\n return keys;\n}\n,getSliderClass:function() {\n const cls {};\n if (this.watchedFieldKeys.length) {\n cls\slider-closed\ true;\n }\n else\n {\n cls\slider-opened\ true;\n }\n return cls;\n}\n,toggleWatch:function(field) {\n if (this.watchedFieldKeys.includes(field.key)) {\n this.watchedFieldKeys this.watchedFieldKeys.filter(w > w ! field.key);\n } else {\n this.watchedFieldKeys.push(field.key);\n }\n}\n,getCssClass:function(item) {\n const cls {};\n cls.clickable true;\n cls.selected (this.watchedFieldKeys.includes(item.key));\n return cls;\n}\n,onStateChanged:function(change) {\n if (!change) return;\n if (this.vue()._uid change.uid) this.refresh();\n}\n,refresh:function() {\n this.key1++;\n}\n},computed:{watchedFields:function() {\n const fields this.getFields(this.vue());\n return fields.filter(f > this.watchedFieldKeys.includes(f.key));\n}\n,console:function() {\n return console;\n}\n},style:{.comp-ide-state-tracker:{overflow:hidden},.watches:{max-height:50vh,overflow:auto,padding:1em 2em},.watches ul:{gap:1em},.watches h3:{font-size:1.2rem},.comp-ui-title:{border-radius:0,border-bottom:1px solid #000},.flex:{gap:1em},ul:{display:flex,flex-direction:column-reverse},ul:not(.changes) .grid:{opacity:0.5},tr:hover:{background:#ffffff10,transition:0s}},name:ide-vue-state,_:{examples:{count:0}},template:div class\comp-ide-vue-state flex\ path\2112019429.\>div :class\getSliderClass()\ path\2112019429.0\>h3 path\2112019429.0.0\>ui-title text\π§ State\ path\2112019429.0.0.0\>/ui-title>/h3>transition name\slide\ path\2112019429.0.1\>table class\list1\ path\2112019429.0.1.0\>ide-vue-state-item v-for\field in getFields(vue())\ :class\getCssClass(field)\ on_click\toggleWatch(field)\ :vue\vue\ :item\field\ :key\vue()._uid+.+field.key\ path\2112019429.0.1.0.0\>/ide-vue-state-item>/table>/transition>/div>transition name\slide-hor\ path\2112019429.1\>div class\watches\ v-if\watchedFieldKeys.length\ path\2112019429.1.0\>transition-group tag\ul\ name\slide\ path\2112019429.1.0.0\>li class\clickable\ v-for\field in watchedFields\ on_click\console.log(vue()field.key)\ :key\field.key\ path\2112019429.1.0.0.0\>h3 class\opacity-50\ path\2112019429.1.0.0.0.0\>ui-title :icon\$root.getIcon(field)\ :text\field.key\ path\2112019429.1.0.0.0.0.0\>/ui-title>/h3>ui-value-any :value\field.newValue.value\ :preview\false\ path\2112019429.1.0.0.0.1\>/ui-value-any>/li>/transition-group>/div>/transition>/div>}},{name:ide.vue.node,path:\\ide\\vue.node.ws.yaml,source:{dom:{div:{ui.title:{icon:π¦,:text:getText(),:number:item?.$children.length}}},props:{value:null},methods:{getText:function() {\n return (this.item?.$options?._componentTag || this.item?._vnode.tag);\n}\n},computed:{item:function() {\n return (!this.value) ? null : this.value();\n}\n},name:ide-vue-node,_:{examples:{count:0}},template:div class\comp-ide-vue-node\ path\345070638.\>ui-title icon\π¦\ :text\getText()\ :number\item?.$children.length\ path\345070638.0\>/ui-title>/div>}},{name:ide.workspace,path:\\ide\\workspace.ws.yaml,source:{dom:{div#1:{v-show:true,div#2:{v-if:showWorkspace,class:workspace,div#3:{v-if:false,h3:{ui.title#1:{icon:π,:value:appVuesCount?.toLocaleString()},div#4:{ui.button:{icon:β»,text:reload from server,:click:$root.reloadComponentsFromServer}},select:{v-model:selectedEditor,option:{v-for:editor in component, css,:selected:(selectedEditor editor),:key:editor,v-text:editor}}}},div#5:{v-if:false,ui.title#2:{v-for:entry in appVuesCounts,icon:π,:text:entry0,:number:entry1}},ide.debug:null,div#6:{v-if:true,ide.component.picker:{v-if:(selectedEditor component)},ide.element.picker:{v-if:(selectedEditor css)},ide.performance.inspector:null}}}},props:null,data:{showWorkspace:true,selectedEditor:component,appVuesCount:null,appVuesCounts:null},mounted:function() {\n //this.showWorkspace (window.location.hostname \localhost\);\n this.showWorkspace false;\n this.refresh();\n this.setupCheatCodeListener(inspect, this.enable.bind(this));\n if (this.autoEnable) this.enable();\n}\n,methods:{setupCheatCodeListener:function(triggerCode, action) {\n // If triggerCode + enter is pressed, show the workspace\n let inputSequence ;\n document.addEventListener(keydown, (e) > {\n if (e.key Enter && inputSequence triggerCode) {\n action();\n inputSequence ; // Reset the input sequence\n } else if (e.key.length 1) {\n inputSequence + e.key.toLowerCase(); // Add the key to the sequence\n if (!triggerCode.startsWith(inputSequence)) {\n inputSequence ; // Reset if the sequence doesnt match\n }\n }\n });\n}\n,enable:function() {\n //alertify.message(Inspector enabled);\n this.showWorkspace true;\n}\n,refresh:async function() {\n if (true)\n {\n var allVues vueApp.vm.getDescendants(vueApp);\n var vueNames allVues.map(v > v.$options.name).distinct();\n var counts vueNames\n .map(name > ({ name, count: allVues.filter(v > (v.$options.name name)).length }))\n .sortBy(c > -c.count)\n .map(c > c.name, c.count);\n this.appVuesCount allVues.length;\n this.appVuesCounts counts;\n }\n \n setTimeout(this.refresh.bind(this), 20000);\n}\n},computed:{autoEnable:function() {\n if (vueApp.isDevEnv()) return true;\n if (window.location.hostname \vue-studio.com\) return true;\n return false;\n}\n},name:ide-workspace,style:{.comp-ide-workspace:{display:flex,position:fixed,left:1rem,bottom:1rem,flex-direction:column,max-width:10em,max-height:10em,gap:3em,padding:1rem,overflow:hidden,z-index:1000000,transition:1s},.comp-ide-workspace:hover:{max-width:30vw,max-height:80vh}},_:{examples:{count:0}},template:div class\comp-ide-workspace\ v-show\true\ path\-1163457967.\>div class\workspace\ v-if\showWorkspace\ path\-1163457967.0\>h3 path\-1163457967.0.0\>ui-title icon\π\ :value\appVuesCount?.toLocaleString()\ path\-1163457967.0.0.0\>/ui-title>div path\-1163457967.0.0.1\>ui-button icon\β»\ text\reload from server\ :click\$root.reloadComponentsFromServer\ path\-1163457967.0.0.1.0\>/ui-button>/div>select v-model\selectedEditor\ path\-1163457967.0.0.2\>option v-for\editor in component, css\ :selected\(selectedEditor editor)\ :key\editor\ v-text\editor\ path\-1163457967.0.0.2.0\>/option>/select>/h3>div v-if\false\ path\-1163457967.0.1\>ui-title v-for\entry in appVuesCounts\ icon\π\ :text\entry0\ :number\entry1\ path\-1163457967.0.1.0\>/ui-title>/div>ide-debug>/ide-debug>div class\clickable\ on_click\refresh\ path\-1163457967.0.3\>h2 v-text\Performance\ path\-1163457967.0.3.0\>/h2>ui-value :value\perfStats\ path\-1163457967.0.3.1\>/ui-value>/div>div v-if\true\ path\-1163457967.0.4\>ide-component-picker v-if\(selectedEditor component)\ path\-1163457967.0.4.0\>/ide-component-picker>ide-element-picker v-if\(selectedEditor css)\ path\-1163457967.0.4.1\>/ide-element-picker>/div>/div>div path\-1163457967.1\>ui-html-style v-for\comp in $root.comps\ :key\comp.name\ :component\comp\ path\-1163457967.1.0\>/ui-html-style>/div>/div>}},{name:ui.action.list,path:\\ui\\action\\list.ws.yaml,source:{dom:{div:{v-if:actionStack,transition.group:{tag:ul,name:slide,class:actions,li#1:{v-for:(actionGroup, index) in actionGroups,:key:actionGroup._id,:class:getActionGroupCssClass(actionGroup),.flex.justify-between:{.flex:{ui.expand:{:style:getActionGroupVisibilityStyle(actionGroup),v-model:isActionGroupExpandedactionGroup._id},slot#1:{:action:actionGroup.actions0}},.opacity-50:{:style:getActionGroupVisibilityStyle(actionGroup),v-text:( + actionGroup.actions.length + )}},transition:{name:slide,.actions.ml-l2:{v-if:isActionGroupExpandedactionGroup._id,ul:{li#2:{v-for:(action, index) in actionGroup.actions,on_mouseenter:() > $emit(hovered-action, action),on_mouseleave:() > $emit(hovered-action, null),slot#2:{:action:actionGroup.actions0}}}}}}}}},props:{actionStack:null,action:null},data:{actions:,allActions:,actionGroups:,isActionGroupExpanded:{}},mounted:async function() {\n}\n,methods:{getActionGroupCssClass:function(actionGroup) {\n return {\n done: actionGroup.actions.all(this.isActionDone.bind(this))\n };\n}\n,getActionGroupVisibilityStyle:function(actionGroup) {\n return {\n visibility: ((actionGroup.actions.length > 1) ? visible : hidden)\n };\n}\n,getActionCssClass:function(action, index) {\n return {\n done: this.isActionDone(action)\n };\n}\n,isActionDone:function(action) {\n const doneAction this.actionStack.doneAction;\n return (action._id doneAction._id.value);\n}\n,getActionGroups:async function() {\n let actionGroupID 1;\n const actionGroups ;\n let actionGroup null;\n for (const action of this.actions)\n {\n if (!actionGroup || actionGroup.method ! action.redo.method)\n {\n actionGroup {\n _id: actionGroupID++,\n method: action.redo.method,\n actions: \n };\n actionGroups.push(actionGroup);\n }\n actionGroup.actions.push(action);\n }\n return actionGroups;\n}\n,refresh:async function() {\n this.actions await this.actionStack.getActions(this.action?._id);\n this.allActions await this.actionStack.getAllActions();\n this.actionGroups await this.getActionGroups();\n}\n},watch:{actionStack:{handler:async function(actionStack) {\n actionStack.events.on(\change\, this.refresh.bind(this).debounce(400));\n}\n,immediate:true},action:{handler:async function(action) {\n await this.refresh();\n}\n,immediate:true}},style:{li:{background-color:#202020},.done, .done:hover:{background-color:#404040},li:hover, .done:hover:{border:1px solid #ffffff80},.done:first-child > td:first-child:{border-radius:0.5em 0 0 0},.done:first-child > td:last-child:{border-radius:0 0.5em 0 0},.done:last-child > td:first-child:{border-radius:0em 0 0 0.5em},.done:last-child > td:last-child:{border-radius:0 0 0.5em 0}},_:{examples:{count:0}},name:ui-action-list,template:div class\comp-ui-action-list\ v-if\actionStack\ path\-877239044.\>transition-group class\actions\ tag\ul\ name\slide\ path\-877239044.0\>li v-for\(actionGroup, index) in actionGroups\ :key\actionGroup._id\ :class\getActionGroupCssClass(actionGroup)\ path\-877239044.0.0\>div class\flex justify-between\ path\-877239044.0.0.0\>div class\flex\ path\-877239044.0.0.0.0\>ui-expand :style\getActionGroupVisibilityStyle(actionGroup)\ v-model\isActionGroupExpandedactionGroup._id\ path\-877239044.0.0.0.0.0\>/ui-expand>slot :action\actionGroup.actions0\ path\-877239044.0.0.0.0.1\>/slot>/div>div class\opacity-50\ :style\getActionGroupVisibilityStyle(actionGroup)\ v-text\( + actionGroup.actions.length + )\ path\-877239044.0.0.0.1\>/div>/div>transition name\slide\ path\-877239044.0.0.1\>div class\actions ml-l2\ v-if\isActionGroupExpandedactionGroup._id\ path\-877239044.0.0.1.0\>ul path\-877239044.0.0.1.0.0\>li v-for\(action, index) in actionGroup.actions\ on_mouseenter\() > $emit(hovered-action, action)\ on_mouseleave\() > $emit(hovered-action, null)\ path\-877239044.0.0.1.0.0.0\>slot :action\actionGroup.actions0\ path\-877239044.0.0.1.0.0.0.0\>/slot>/li>/ul>/div>/transition>/li>/transition-group>/div>}},{name:ui.action.stack,path:\\ui\\action\\stack.ws.yaml,source:{dom:{.box:{v-if:actionStack,h3:{ui.title:{icon:β¨,text:Actions,:number:actionStack.actions.count}},.flex.justify-between:{ui.button#1:{class:flex-equal,text:π undo,:click:() > doVerb(undo)},ui.button#2:{class:flex-equal,text:redo π,:click:() > doVerb(redo)},ui.button#3:{class:flex-equal,text:β» all,:click:() > doVerb(doAll)},ui.button#4:{class:flex-equal,text:β clear,:click:() > doVerb(clear)}},div:{ui.context.window:{ref:context1,v-show:hovered.action,:ctrl-right-click:false,ui.value.any:{:value:hovered.action}},ui.action.list:{ref:list1,class:list1,:action-stack:actionStack,on_hovered-action:onHoveredAction,v-slot:slotProps,template:{slot:{:action:slotProps.action}}}}}},props:{actionStack:null},data:{hovered:{action:null}},mounted:function() {\n}\n,methods:{onHoveredAction:function(action) {\n if (this.$refs.context1?.isPinned) return;\n this.hovered.action action;\n}\n,getActions:async function() {\n let actions await this.actionStack.actions.getMany();\n actions actions.map(a > ({\n _id: a._id,\n method: a.redo.noop ? \no.op\ : a.redo.method,\n }));\n actions ...actions.reverse();\n return actions;\n}\n,doVerb:async function(verb) {\n await this.actionStackverb();\n}\n},watch:null,style:{.list1:{max-height:30em,overflow-y:auto},.box:{border:1px solid #ffffff80},ul.actions:{display:flex,flex-direction:column-reverse,font-family:monospace}},_:{examples:{count:0}},name:ui-action-stack,template:div class\comp-ui-action-stack box\ v-if\actionStack\ path\-1417831958.\>h3 path\-1417831958.0\>ui-title icon\β¨\ text\Actions\ :number\actionStack.actions.count\ path\-1417831958.0.0\>/ui-title>/h3>div class\flex justify-between\ path\-1417831958.1\>ui-button class\flex-equal\ text\π undo\ :click\() > doVerb(undo)\ path\-1417831958.1.0\>/ui-button>ui-button class\flex-equal\ text\redo π\ :click\() > doVerb(redo)\ path\-1417831958.1.1\>/ui-button>ui-button class\flex-equal\ text\β» all\ :click\() > doVerb(doAll)\ path\-1417831958.1.2\>/ui-button>ui-button class\flex-equal\ text\β clear\ :click\() > doVerb(clear)\ path\-1417831958.1.3\>/ui-button>/div>div path\-1417831958.2\>ui-context-window ref\context1\ v-show\hovered.action\ :ctrl-right-click\false\ path\-1417831958.2.0\>ui-value-any :value\hovered.action\ path\-1417831958.2.0.0\>/ui-value-any>/ui-context-window>ui-action-list class\list1\ ref\list1\ :action-stack\actionStack\ on_hovered-action\onHoveredAction\ v-slot\slotProps\ path\-1417831958.2.1\>template path\-1417831958.2.1.0\>slot :action\slotProps.action\ path\-1417831958.2.1.0.0\>/slot>/template>/ui-action-list>/div>/div>}},{name:ui.alert.example0,path:\\ui\\alert.example0.ws.yaml,source:{dom:{ui.alert:{ref:alert1,text:β οΈ This is an alert.,on_click:onClick}},methods:{onClick:function() {\n setTimeout(() > {\n this.$refs.alert1.show(β οΈ This is another alert.);\n }, 1000);\n}\n}}},{name:ui.alert,path:\\ui\\alert.ws.yaml,source:{dom:{div#1:{transition:{name:slide2,.alert:{v-if:isVisible,div#2:{v-if:text1,:key:text1,v-text:text1},on_click:onClick,slot:null}}}},props:{text:null,timeout:3000},data:{text1:null,isVisible:true},methods:{show:function(text) {\n if (text) this.text1 text;\n this.isVisible this.text1?.length || this.$slots.default?.length;\n setTimeout(this.hide.bind(this), this.timeout);\n}\n,hide:function() {\n this.isVisible false;\n}\n,onClick:function() {\n this.isVisible false;\n this.$emit(click);\n}\n},watch:{text:{handler:function(text) {\n this.show(text);\n}\n,immediate:true}},example:{dom:{ui.alert:{ref:alert1,text:β οΈ This is an alert.,on_click:onClick}},methods:{onClick:function() {\n setTimeout(() > {\n this.$refs.alert1.show(β οΈ This is another alert.);\n }, 1000);\n}\n}},style:{.alert:{background:#ffffff20,border:1px solid #ffffff40,padding:0.5em 1em,text-align:center,cursor:pointer}},name:ui-alert,frameworks:{vue:<template>\n <div class\comp-ui-alert\>\n <transition name\slide2\>\n <div class\alert\ v-if\isVisible\ :key\text1\ v-text\text1\ on_click\onClick\></div>\n </transition>\n </div>\n</template>\n\n<script>\nexport default {\n name: ui-alert,\n props: {\n text: {\n default: null\n }\n },\n data() {\n return {\n text1: null,\n isVisible: true\n };\n },\n methods: {\n show(text) {\n if (text) this.text1 text;\n this.isVisible true;\n },\n onClick() {\n this.isVisible false;\n this.$emit(click);\n }\n },\n watch: {\n text: {\n handler(text) {\n this.show(text);\n },\n immediate: true\n }\n }\n};\n</script>\n\n<style scoped>\n.alert {\n background: #ffffff20;\n padding: 0.5em 1em;\n text-align: center;\n cursor: pointer;\n}\n</style>\n,react:import React, { useState, useEffect } from react;\n\n// CSS styles\nconst alertStyles {\n background: '#ffffff20',\n padding: '0.5em 1em',\n textAlign: 'center',\n cursor: 'pointer'\n};\n\nfunction UiAlert(props) {\n const text1, setText1 useState(null);\n const isVisible, setIsVisible useState(true);\n\n useEffect(() > {\n show(props.text);\n }, props.text);\n\n const show (text) > {\n if (text) setText1(text);\n setIsVisible(true);\n };\n\n const onClick () > {\n setIsVisible(false);\n // Emitting an event in React is typically done via a callback prop\n if (props.onClick) {\n props.onClick();\n }\n };\n\n return (\n <div className'comp-ui-alert'>\n {/* React doesnt have a built-in transition component like Vue. \n You might want to use libraries like 'react-transition-group' for transitions. */}\n {isVisible && <div className'alert' style{alertStyles} onClick{onClick}>{text1}</div>}\n </div>\n );\n}\n\nexport default UiAlert;\n,angular:<div class\comp-ui-alert\>\n <div *ngIf\isVisible\ class\alert\ (click)\onClick()\>{{ text1 }}</div>\n</div>\n\n\nimport { Component, Input, Output, EventEmitter, OnChanges } from on_angular/core;\n\non_Component({\n selector: app-ui-alert,\n templateUrl: ./ui-alert.component.html,\n styleUrls: ./ui-alert.component.css\n})\nexport class UiAlertComponent implements OnChanges {\n on_Input() text: string | null null;\n on_Output() clickEvent new EventEmittervoid>();\n\n text1: string | null null;\n isVisible true;\n\n ngOnChanges() {\n this.show(this.text);\n }\n\n show(text: string | null) {\n if (text) this.text1 text;\n this.isVisible true;\n }\n\n onClick() {\n this.isVisible false;\n this.clickEvent.emit();\n }\n}\n\n\n.alert {\n background: #ffffff20;\n padding: 0.5em 1em;\n text-align: center;\n cursor: pointer;\n}\n,svelte:<script>\n export let text null;\n let text1 null;\n let isVisible true;\n\n const show (txt) > {\n if (txt) text1 txt;\n isVisible true;\n };\n\n const onClick () > {\n isVisible false;\n // Emitting an event in Svelte\n dispatch(click);\n };\n\n // Watch for changes in text prop\n $: show(text);\n</script>\n\n<div class\comp-ui-alert\>\n {#if isVisible}\n <div class\alert\ on:click{onClick}>{text1}</div>\n {/if}\n</div>\n\n<style>\n .alert {\n background: #ffffff20;\n padding: 0.5em 1em;\n text-align: center;\n cursor: pointer;\n }\n</style>\n},_:{examples:{count:1}},template:div class\comp-ui-alert\ path\-2141174398.\>transition name\slide2\ path\-2141174398.0\>div class\alert\ v-if\isVisible\ on_click\onClick\ path\-2141174398.0.0\>div v-if\text1\ :key\text1\ v-text\text1\ path\-2141174398.0.0.0\>/div>slot>/slot>/div>/transition>/div>}},{name:ui.button.example0,path:\\ui\\button.example0.ws.yaml,source:{dom:{ui.button:{icon:βοΈ,text:Click me,:click:onClick}},methods:{onClick:async function() {\n}\n}}},{name:ui.button,path:\\ui\\button.ws.yaml,source:{dom:{.text-center:{transition:{name:slide2,button:{v-if:!isLoading,on_click:onClick,.flex:{ui.title:{:icon:icon,:text:text},slot:null}}},ui.loading:{:show:isLoading}}},props:{icon:null,text:null,click:null,confirm:null,showLoading:true},data:{isLoading:0},methods:{onClick:async function() {\n if (this.confirm) return alertify.confirm(this.confirm, this._onClick.bind(this));\n this._onClick();\n}\n,_onClick:async function() {\n this.$emit(click);\n if (this.click)\n {\n if (this.showLoading) this.isLoading++;\n try\n {\n await this.click();\n }\n finally\n {\n if (this.showLoading) this.isLoading--;\n }\n }\n}\n},style:{button:{opacity:0.7,user-select:none,transition:0s},button:hover:{opacity:1,transition:0s}},name:ui-button,frameworks:{vue:<template>\n <div class\text-center\>\n <transition name\slide2\>\n <button v-if\!isLoading\ on_click\onClick\ style\user-select: none;\>\n <ui-title :icon\icon\ :text\text\></ui-title>\n </button>\n </transition>\n <ui-loading :show\isLoading\></ui-loading>\n </div>\n</template>\n\n<script>\nexport default {\n name: ui-button,\n props: {\n icon: {\n default: null\n },\n text: {\n default: null\n },\n click: {\n type: Function,\n default: null\n },\n showLoading: {\n type: Boolean,\n default: true\n }\n },\n data() {\n return {\n isLoading: 0\n };\n },\n methods: {\n async onClick() {\n this.$emit(click);\n if (this.click) {\n if (this.showLoading) this.isLoading++;\n try {\n await this.click();\n } finally {\n if (this.showLoading) this.isLoading--;\n }\n }\n }\n }\n};\n</script>\n\n<style scoped>\nbutton {\n user-select: none;\n}\n</style>\n},example:{dom:{ui.button:{icon:βοΈ,text:Click me,:click:onClick}},methods:{onClick:async function() {\n}\n}},_:{examples:{count:1}},template:div class\comp-ui-button text-center\ path\-1914507316.\>transition name\slide2\ path\-1914507316.0\>button v-if\!isLoading\ on_click\onClick\ path\-1914507316.0.0\>ui-title :icon\icon\ :text\text\ path\-1914507316.0.0.0\>/ui-title>/button>/transition>ui-loading :show\isLoading\ path\-1914507316.1\>/ui-loading>/div>}},{name:ui.card.example0,path:\\ui\\card.example0.ws.yaml,source:{dom:{ui.card:{.content:{div:{v-text:This is a card. Hover over it to see the effect. The card component can contan any other component.}}}},style:{.content:{width:15em,padding:1em,aspect-ratio:3 / 2,font-weight:normal,text-shadow:-2px 2px 2px #000}}}},{name:ui.card,path:\\ui\\card.ws.yaml,source:{dom:{.container:{on_mouseenter:onMouseEnter,on_mouseleave:onMouseLeave,on_mousemove:onMouseMove,.card:{ref:card,slot:null,div:{class:glow}}}},data:{bounds:null},mounted:function() {\n}\n,methods:{onMouseEnter:function(e) {\n this.bounds this.$refs.card.getBoundingClientRect();\n}\n,onMouseLeave:function(e) {\n this.$refs.card.style.transform ;\n this.$refs.card.style.background ;\n}\n,onMouseMove:function(e) {\n const $card this.$refs.card;\n\n const mouseX e.clientX;\n const mouseY e.clientY;\n const leftX mouseX - this.bounds.x;\n const topY mouseY - this.bounds.y;\n const center {\n x: leftX - this.bounds.width / 2,\n y: topY - this.bounds.height / 2\n }\n const distance Math.sqrt(center.x**2 + center.y**2);\n \n $card.style.transform `\n scale3d(1.07, 1.07, 1.07)\n rotate3d(\n ${center.y / 100},\n ${-center.x / 100},\n 0,\n ${Math.log(distance)* 2}deg\n )\n `;\n \n $card.querySelector(.glow).style.backgroundImage `\n radial-gradient(\n circle at\n ${center.x * 2 + this.bounds.width/2}px\n ${center.y * 2 + this.bounds.height/2}px,\n #ffffff55,\n #0000000f\n )\n `;\n}\n},style:{.container:{perspective:600px},.card:{font-weight:bold,box-shadow:0 1px 5px #00000099,border-radius:0.5rem,background-size:cover,position:relative,overflow:hidden,transition-duration:300ms,transition-property:transform, box-shadow,transition-timing-function:ease-out,transform:rotate3d(0)},.card:hover:{transition-duration:150ms,box-shadow:0 5px 20px 5px #00000044},.card .glow:{position:absolute,width:100%,height:100%,left:0,top:0,background-image:radial-gradient(circle at 50% -20%, #ffffff22, #0000000f),pointer-events:none}},example:{dom:{ui.card:{.content:{div:{v-text:This is a card. Hover over it to see the effect. The card component can contan any other component.}}}},style:{.content:{width:15em,padding:1em,aspect-ratio:3 / 2,font-weight:normal,text-shadow:-2px 2px 2px #000}}},name:ui-card,_:{examples:{count:1}},template:div class\comp-ui-card container\ on_mouseenter\onMouseEnter\ on_mouseleave\onMouseLeave\ on_mousemove\onMouseMove\ path\-484662742.\>div class\card\ ref\card\ path\-484662742.0\>slot>/slot>div class\glow\ path\-484662742.0.1\>/div>/div>/div>}},{name:ui.chart,path:\\ui\\chart.ws.yaml,source:{dom:{.card:{:class:getCssClass(),h2:{class:header,v-if:header,span:{v-text:header},.sum:{v-text:sum}},.top-right:{ui.checkbox:{text:cumulative,v-model:isCumulative}},.chart.flex:{.column1:{ui.num#1:{class:opacity-50,:value:scaled(minValue)},ui.num#2:{:value:scaled(middleValue)},ui.num#3:{class:opacity-50,:value:scaled(maxValue)}},div:{canvas:{ref:canvas1,class:ml-l1,:width:canvasWidth,:height:(canvasWidth / 2),on_mousemove:onMouseMove,on_mouseout:onMouseOut}}},.flex.flex-column.justify-center.items-center:{.title:{.icon:{v-text:icon},.text:{v-text:title}},ui.num:{:value:scaled(hoveredData || total)}}}},props:{icon:null,header:null,total:null,title:null,getValue:x > x,data:,scale:1,color:null},data:{canvasWidth:400,hoveredIndex:null,isCumulative:false},methods:{getCssClass:function() {\n const cls {};\n if (!this.cData?.length) cls.empty true;\n if (this.color) cls`${this.color}` true;\n return cls;\n}\n,drawChart:function(data) {\n if (!data?.length) return;\n if (!this.ctx) return;\n\n this.ctx.clearRect(0, 0, this.width, this.height);\n this.ctx.beginPath();\n this.ctx.moveTo(this.paddingX, this.paddingY + this.chartHeight);\n for (let i 0; i data.length; i++) {\n const x this.paddingX + i * this.step;\n const y this.paddingY + this.chartHeight - (this.getValueFunc(datai) - this.min) * this.stepY;\n this.drawBar(x, this.getValueFunc(datai), #ffffff80);\n }\n this.ctx.lineTo(this.paddingX + this.chartWidth, this.paddingY + this.chartHeight);\n this.ctx.fillStyle rgba(255, 255, 255, 0.5);\n this.ctx.fill();\n this.ctx.strokeStyle #ffffff80;\n this.ctx.stroke();\n}\n,drawBar:function(x, value, color, maxDisplayValue) {\n let y this.paddingY + this.chartHeight - ((value - this.min) * this.stepY);\n this.ctx.fillStyle color;\n this.ctx.fillRect(x, y, this.step, this.chartHeight - y + this.paddingY);\n}\n,onMouseMove:function(e) {\n if (!this.canvas) return;\n const rect this.canvas.getBoundingClientRect();\n const scaleX this.canvas.width / rect.width;\n const x e.offsetX;\n const i Math.floor((x - this.paddingX) / this.step * scaleX);\n this.hoveredIndex i;\n}\n,onMouseOut:function(e) {\n this.hoveredIndex null;\n}\n,getValueFunc:function(value) {\n let func this.getValue;\n if (typeof func string) func eval(func);\n return func(value);\n}\n,scaled:function(value) {\n return value;\n return Math.round(value * this.scale);\n}\n,toCumulative:function(data) {\n const result ;\n let sum 0;\n for (let i 0; i data.length; i++) {\n sum + this.getValueFunc(datai);\n result.push(sum);\n }\n return result;\n}\n},watch:{cData:{handler:async function(cData) {\n await this.$nextTick();\n this.drawChart(cData);\n}\n,immediate:true,deep:true},hoveredIndex:{handler:async function(newIndex, oldIndex) {\n if (newIndex oldIndex) return;\n await this.$nextTick();\n this.drawChart(this.cData);\n if (newIndex ! null) {\n const value this.getValueFunc(this.cDatanewIndex);\n this.drawBar(this.hoveredX, value, #ffffff80);\n }\n}\n,immediate:true,deep:true},isCumulative:{handler:async function() {\n this.drawChart(this.cData);\n}\n}},computed:{cData:function() {\n if (this.isCumulative) return this.toCumulative(this.data);\n return this.data;\n}\n,canvas:function() { return this.$refs.canvas1; },ctx:function() { return this.canvas?.getContext(2d); },width:function() { return this.canvas?.width; },height:function() { return this.canvas?.height; },padding:function() { return 0; },paddingX:function() { return this.width * this.padding; },paddingY:function() { return this.height * this.padding; },chartWidth:function() { return this.width - this.paddingX * 2; },chartHeight:function () { return this.height - this.paddingY * 2; },step:function() { return this.chartWidth / this.cData.length; },stepY:function() { return this.chartHeight / this.range; },sum:function() {\n return Math.round((this.data||).filter(v > v).sum());\n}\n,min:function() {\n if (!this.cData?.length) return 0;\n return Math.round(Math.min(...this.cData.map(x > this.getValueFunc(x))));\n}\n,max:function() {\n if (!this.cData?.length) return 0;\n return Math.round(Math.max(...this.cData.map(x > this.getValueFunc(x))) * 1.1);\n}\n,minValue:function() {\n return (this.cData||).filter(v > v).min();\n}\n,averageValue:function() {\n return (this.cData||).filter(v > v).average();\n}\n,middleValue:function() {\n return (this.minValue + this.maxValue) / 2;\n}\n,maxValue:function() {\n return (this.cData||).filter(v > v).max();\n}\n,range:function() {\n return this.max - this.min;\n}\n,hoveredData:function() {\n if (this.hoveredIndex null) return null;\n const value this.cDatathis.hoveredIndex;\n return value;\n}\n,hoveredX:function() {\n if (this.hoveredIndex null) return null;\n return this.paddingX + this.hoveredIndex * this.step;\n}\n},example_not:{dom:{div:{ui.chart:{icon:π,title:Chart,:data:1, 2, 3, 4, 5, 6, 7, 8, 9, 10,:getValue:x > x,:color:green,:header:Header,:total:100,:scale:10,:isCumulative:true}}}},style:{.top-right:{position:absolute,top:0,right:0,width:fit-content,margin:1em},.sum:{display:inline,opacity:0.5,margin-left:1em},.column1:{width:2em !important},canvas:{width:100%},.card:{padding:0.5rem 1rem,background-color:#ffffff30,border:1px solid #e5e5e5,border-radius:0.5em},.green:{background:#00ff0040},.red:{background:#ff000040},.blue:{background:#00a0ff40},.comp-ui-num, .title:{font-size:140%},.column1 .comp-ui-num:nth-child(2):{position:absolute,top:50%,transform:translateY(-50%)},.column1 .comp-ui-num:nth-child(1):{position:absolute,bottom:0}},name:ui-chart,_:{examples:{count:0}},template:div class\comp-ui-chart card\ :class\getCssClass()\ path\-2139450364.\>h2 class\header\ v-if\header\ path\-2139450364.0\>span v-text\header\ path\-2139450364.0.0\>/span>div class\sum\ v-text\sum\ path\-2139450364.0.1\>/div>/h2>div class\top-right\ path\-2139450364.1\>ui-checkbox text\cumulative\ v-model\isCumulative\ path\-2139450364.1.0\>/ui-checkbox>/div>div class\chart flex\ path\-2139450364.2\>div class\column1\ path\-2139450364.2.0\>ui-num class\opacity-50\ :value\scaled(minValue)\ path\-2139450364.2.0.0\>/ui-num>ui-num :value\scaled(middleValue)\ path\-2139450364.2.0.1\>/ui-num>ui-num class\opacity-50\ :value\scaled(maxValue)\ path\-2139450364.2.0.2\>/ui-num>/div>div path\-2139450364.2.1\>canvas class\ml-l1\ ref\canvas1\ :width\canvasWidth\ :height\(canvasWidth / 2)\ on_mousemove\onMouseMove\ on_mouseout\onMouseOut\ path\-2139450364.2.1.0\>/canvas>/div>/div>div class\flex flex-column justify-center items-center\ path\-2139450364.3\>div class\title\ path\-2139450364.3.0\>div class\icon\ v-text\icon\ path\-2139450364.3.0.0\>/div>div class\text\ v-text\title\ path\-2139450364.3.0.1\>/div>/div>ui-num :value\scaled(hoveredData || total)\ path\-2139450364.3.1\>/ui-num>/div>/div>}},{name:ui.chart2,path:\\ui\\chart2.ws.yaml,source:{dom:{.w-100pc:{v-if:every,ui.chart:{v-dim:isBusy,:class:cssClass,:header:getHeader(),:title:null,:data:values,:color:color,:scale:scale},a:{v-text:url,:href:url,target:_blank},.error:{v-if:error,v-text:error}}},props:{entity:null,app:null,category:null,event:null,last:null,every:null,scale:null},data:{values:,isBusy:0,error:null},mounted:function() {\n this.fetchData();\n}\n,methods:{fetchData:async function() {\n this.isBusy++;\n this.values.clear();\n try\n {\n this.values await (await fetch(this.url)).json();\n }\n finally\n {\n this.isBusy--;\n }\n}\n,getHeader:function() {\n return `${this.entity || this.event} in the last ${this.last}`;\n}\n},computed:{url:function() {\n try\n {\n this.error null;\n if (this.entity)\n {\n let url `https://db.memegenerator.net/MemeGenerator/analytics/${this.entity}/since/${this.last.deunitify().unitifyTime()}`;\n return url;\n }\n let { app, category, event, last, every } this;\n last last.deunitify().unitifyTime();\n every every.deunitify().unitifyTime();\n let url `https://db.memegenerator.net/analytics/${app}/${category}/${event}/last/${last}/every/${every}`;\n url url.withoutColors();\n return url;\n }\n catch (ex)\n {\n this.error ex.message;\n return null;\n }\n}\n,color:function() {\n return {\n \requests\: \green\,\n \response.time\: \blue\,\n }this.event || \\;\n}\n,cssClass:function() {\n const cls {};\n return cls;\n if (this.isBusy) cls\opacity-40\ true;\n return cls;\n}\n},watch:{url:{handler:async function() {\n await this.fetchData();\n}\n,immediate:true}},name:ui-chart2,_:{examples:{count:0}},template:div class\comp-ui-chart2 w-100pc\ v-if\every\ path\-1898451794.\>ui-chart v-dim\isBusy\ :class\cssClass\ :header\getHeader()\ :data\values\ :color\color\ :scale\scale\ path\-1898451794.0\>/ui-chart>a v-text\url\ :href\url\ target\_blank\ path\-1898451794.1\>/a>div class\error\ v-if\error\ v-text\error\ path\-1898451794.2\>/div>/div>}},{name:ui.checkbox.list,path:\\ui\\checkbox\\list.ws.yaml,source:{dom:{div:{ui.checkbox#1:{v-if:(items?.length > 10),icon:βοΈ,text:Show only checked,v-model:showOnlyChecked},ui.input.text.box:{type:search,icon:π,hint:search,camouflage:true,v-model:query},.scrollable:{transition.group:{name:list,ui.checkbox#2:{v-for:item in visibleItems,:key:_getItemKey(item),:icon:_getItemIcon(item),:text:_getItemText(item),:value-array:valueArray,:value-key:_getItemKey(item)}}}}},props:{items:null,getItemKey:null,getItemIcon:null,getItemText:null,valueArray:null,sort:true},data:{query:null,showOnlyChecked:false},methods:{_getItemKey:function(item) {\n if (this.getItemKey) return this.getItemKey(item);\n if (typeof item \string\) return item;\n return JSON.stringify(item);\n}\n,_getItemIcon:function(item) {\n if (this.getItemIcon) return this.getItemIcon(item);\n return null;\n}\n,_getItemText:function(item) {\n if (this.getItemText) return this.getItemText(item);\n return item;\n}\n},computed:{visibleItems:function() {\n if (!this.items) return ;\n let items ...this.items;\n if (this.showOnlyChecked) {\n items items.filter(item > this.valueArray?.includes(this._getItemKey(item)));\n }\n if (this.query) {\n items this.items.filter(item > {\n const text this._getItemText(item);\n if (!text) return false;\n return text.toLowerCase().includes(this.query.toLowerCase());\n });\n }\n //if (this.sort) items items.sort(this.compareItems);\n return items;\n}\n,compareItems:function(a, b) {\n const aKey this._getItemKey(a);\n const bKey this._getItemKey(b);\n const aIsChecked this.valueArray.includes(aKey);\n const bIsChecked this.valueArray.includes(bKey);\n if (aIsChecked && !bIsChecked) return -1;\n if (!aIsChecked && bIsChecked) return 1;\n const aText this._getItemText(a);\n const bText this._getItemText(b);\n return aText.localeCompare(bText);\n}\n},watch:{query:{handler:function() {\n this.$emit(\query\, this.query);\n}\n,immediate:true}},style:{.scrollable:{max-height:20em,overflow-y:auto}},_:{examples:{count:0}}}},{name:ui.checkbox,path:\\ui\\checkbox\\_.ws.yaml,source:{dom:{.flex:{:class:getCssClass(),on_mouseenter:$emit(mouseenter),on_mouseleave:$emit(mouseleave),on_click:onClick,input:{type:checkbox,:checked:checkedValue},span#1:{class:clickable,.icon:{v-if:icon,v-text:icon},span#2:{slot:null,span#3:{v-text:text}}}}},props:{value:null,valueArray:null,valueArrayExclude:false,valueKey:null,icon:null,text:null,size:large},data:{value1:null},methods:{getCssClass:function() {\n const dimmed (this.checkedValue ? \\ : \dimmed\);\n return `hoverable ${this.size} ${dimmed}`;\n}\n,onClick:async function() {\n this.onInput(!this.checkedValue);\n this.$emit(\click\);\n}\n,onInput:async function(value) {\n if (this.valueArray && this.valueKey) {\n this.toggleArrayValue(this.valueArray, this.valueKey);\n await this.$nextTick();\n this.$emit(\input\, this.valueArray);\n } else {\n this.value1 value;\n await this.$nextTick();\n this.$emit(\input\, value);\n }\n}\n,toggleArrayValue:function(array, value) {\n if (array.includes(value)) {\n array.splice(array.indexOf(value), 1);\n } else {\n array.push(value);\n }\n}\n},watch:{value:{handler:function(value) {\n this.value1 value;\n}\n,immediate:true}},computed:{checkedValue:function() {\n if (this.valueArray && this.valueKey)\n {\n if (this.valueArrayExclude) return !this.valueArray.includes(this.valueKey);\n return this.valueArray.includes(this.valueKey);\n }\n return this.value1;\n}\n},example1:{dom:{.flex:{div:{ui.checkbox:{v-for:option in options,:text:option,:value-key:option,:value-array:checkedOptions}},pre:{v-text:toYaml(checkedOptions)}}},data:{options:one,two,three,four,checkedOptions:},methods:{toYaml:function(value) {\n return jsyaml.dump(value);\n}\n}},{dom:{ui.checkbox:{text:Check me}}},style:{.icon:{display:inline-block,margin-right:0.3rem},.normal inputtypecheckbox:{width:1em,height:1em},span:{flex-grow:1,font-size:100%,white-space:nowrap,user-select:none},.clickable:null},name:ui-checkbox,_:{examples:{count:0}},template:div class\comp-ui-checkbox flex\ :class\getCssClass()\ on_mouseenter\$emit(mouseenter)\ on_mouseleave\$emit(mouseleave)\ on_click\onInput(!checkedValue)\ path\1049372125.\>input type\checkbox\ :checked\checkedValue\ path\1049372125.0\/>span class\clickable\ path\1049372125.1\>div class\icon\ v-if\icon\ v-text\icon\ path\1049372125.1.0\>/div>span path\1049372125.1.1\>slot>/slot>span v-text\text\ path\1049372125.1.1.1\>/span>/span>/span>/div>}},{name:ui.console,path:\\ui\\console.ws.yaml,source:{dom:{div#1:{v-if:items.length,class:box1,ui.context.window:{ref:context1,:visible:hoveredItem,div#2:{v-if:hoveredItem,ui.value#1:{v-for:arg in hoveredItem.args,:value:arg}}},table:{tr:{v-for:item in visibleItems,:key:item._id,on_mouseenter:() > onItemHover(item, true),on_mouseleave:() > onItemHover(item, false),td#1:{class:opacity-50,v-text:item._id},td#2:{v-for:(arg) in item.args.take(1),ui.value#2:{:value:arg}}}}}},data:{nextItemID:1,items:,hoveredItem:null,maxVisibleItems:30},methods:{onItemHover:function(item, isHover) {\n if (this.$refs.context1?.isPinned) return;\n this.hoveredItem (isHover ? item : null);\n}\n,log:function(...args) {\n this.items.push({ _id: this.nextItemID++, args });\n}\n},computed:{visibleItems:function() {\n return ...this.items\n .slice(-this.maxVisibleItems)\n .reverse();\n}\n},style:{box1:{max-height:20em,overflow:scroll},tr:{height:1.5em},td:{padding:0 0.5em}},_:{examples:{count:0}},name:ui-console,template:div class\comp-ui-console box1\ v-if\items.length\ path\1489973245.\>ui-context-window ref\context1\ :visible\hoveredItem\ path\1489973245.0\>div v-if\hoveredItem\ path\1489973245.0.0\>ui-value v-for\arg in hoveredItem.args\ :value\arg\ path\1489973245.0.0.0\>/ui-value>/div>/ui-context-window>table path\1489973245.1\>tr v-for\item in visibleItems\ :key\item._id\ on_mouseenter\() > onItemHover(item, true)\ on_mouseleave\() > onItemHover(item, false)\ path\1489973245.1.0\>td class\opacity-50\ v-text\item._id\ path\1489973245.1.0.0\>/td>td v-for\(arg) in item.args.take(1)\ path\1489973245.1.0.1\>ui-value :value\arg\ path\1489973245.1.0.1.0\>/ui-value>/td>/tr>/table>/div>}},{name:ui.context.window.example0,path:\\ui\\context\\window.example0.ws.yaml,source:{dom:{div#1:{ui.context.window:{.flex.flex-column.gap-1:{div#2:{v-for:help in helps2,v-text:help},ui.value:{:style:{ width: 25em, height: 10em, overflow: auto },:value:exampleData}}},.box1:{div#3:{v-for:help in helps1,v-text:help}}}},data:{exampleData:null,helps1:Hover to see the context.,Right click to pin.,helps2:The context window can be attached to any element.,It can contain any other elements.},mounted:async function() {\n this.exampleData (await (await fetch(\/fetch?urlhttps://a.4cdn.org/boards.json\)).json()).boards;\n}\n}},{name:ui.context.window,path:\\ui\\context\\window.ws.yaml,source:{dom:{div#1:{ui.mouse#1:{:global:true,:ctrl-right-click:ctrlRightClick,on_move:onMouseMove,on_right-click:e > onRightClick(e, true)},ui.mouse#2:{on_drag:onDrag,transition#1:{name:fade,.context-menu:{v-if:isVisibleOuter,ref:menu1,:class:{ pinned: isPinned, inited: isInited, visible: isVisibleInner },:style:style,div#2:{div#3:{v-if:isPinned,class:close-button,v-text:βοΈ,on_click:isPinnedfalse},transition#2:{name:slide,h2:{v-if:(showTitle) && (icon || title),:key:icon+title,ui.title:{:icon:icon,:title:title}}},div#4:{slot:null,component:{v-if:compName,:is:compName,v-bind:bindProps}}}}}}}},props:{global:false,ctrlRightClick:false,visible:null,icon:null,title:null,showTitle:true,compName:null,bindProps:null,semiTransparent:true,getContextElement:null,windowStyle:null},desc:{global:{true:The context window is not tied to a particular element.\nIt can be used to create a global context menu.\nvisible can control the visibility of the context window from outside.\n,false:The context window is tied to the parent element.},ctrlRightClick:{true:The context window can be pinned by right clicking it with Ctrl pressed.\n,false:The context window can be pinned by right clicking it.},visible:{undefined:The visibility will be controlled by the context window itself.,true, false:The visibility will be controlled from outside. Usually used together with globaltrue.},compName:{null:The slot will be used to render the content of the context window.,string:The context window will contain the component with this name. Use bindProps to pass props to the component.},bindProps:{null:No props will be passed to the compName component inside the context window.,object:The object will be passed as props to the compName component inside the context window.},semiTransparent:{true:When unpinned, the context window will be semi-transparent.,false:The context window will be opaque.},getContextElement:{null:The context window will be tied to the parent element.,function:The context window will be tied to the element returned by this function.}},data:{lastUpdate:0,space:20,mousePos:{x:0,y:0},globalPos:{x:0,y:0},isInited:false,isPinned:false,isInsideContextElement:false,isVisibleOuter:false,isVisibleInner:false,taskQueue:null},mounted:async function() {\n this.bindToParent();\n}\n,unmounted:function() {\n this.unbindFromParent();\n}\n,methods:{bindToParent:function() {\n const element (this.global ? window : this._getContextElement());\n if (!element) return setTimeout(this.bindToParent.bind(this), 100);\n this._onMouseEnterContext this.onMouseEnterContext.bind(this);\n this._onMouseLeaveContext this.onMouseLeaveContext.bind(this);\n element.addEventListener(\mouseenter\, this._onMouseEnterContext);\n element.addEventListener(\mouseleave\, this._onMouseLeaveContext);\n element.addEventListener(\dragenter\, this._onMouseEnterContext);\n element.addEventListener(\dragleave\, this._onMouseLeaveContext);\n element.addEventListener(\drop\, this._onMouseLeaveContext);\n if (element ! window) this.$root.html.when.element.removed(element, this.unbindFromParent.bind(this));\n this.$root.$emit(\context-menu-mounted\, this);\n document.body.appendChild(this.$el);\n}\n,unbindFromParent:function() {\n const element (this.global ? window : this._getContextElement());\n if (!element) return;\n element.removeEventListener(\mouseenter\, this._onMouseEnterContext);\n element.removeEventListener(\mouseleave\, this._onMouseLeaveContext);\n element.removeEventListener(\dragenter\, this._onMouseEnterContext);\n element.removeEventListener(\dragleave\, this._onMouseLeaveContext);\n element.removeEventListener(\drop\, this._onMouseLeaveContext);\n this.$root.$emit(\context-menu-unmounted\, this);\n this.$el.remove();\n}\n,onDrag:function(dpos) {\n this.globalPos.x + dpos.dx;\n this.globalPos.y + dpos.dy;\n // Since child context menus are positioned relative to the parent\n // we need to update their position in the other direction when dragging the parent\n const childContexts this.$root.vm.getDescendants(this, this.$data._.comp.name);\n for (const child of childContexts) {\n // I have no idea whats going on here\n child.globalPos.x - 0.0001;\n child.globalPos.y - 0.0001;\n }\n}\n,onMouseMove:function(pos) {\n if (this.isPinned) return;\n this.mousePos pos;\n}\n,onMouseEnterContext:function(e) {\n this.isInsideContextElement true;\n}\n,onMouseLeaveContext:function() {\n this.isInsideContextElement false;\n}\n,onRightClick:function(e, global) {\n if (!this.isVisible) return;\n // We unpin it by right clicking the title\n // Global right click is ignored if the menu is pinned\n if (global && this.isPinned) return;\n e.preventDefault();\n e.stopPropagation();\n this.isPinned !this.isPinned;\n}\n,enqueueTask:function(task, delay) {\n if (!this.taskQueue) this.taskQueue ;\n this.taskQueue.add(task);\n if (delay) this.taskQueue.add(async() > await this.$root.wait(delay));\n}\n,nextTaskQueue:async function() {\n if (this.taskQueue.length 0) return;\n const task this.taskQueue.shift();\n await task();\n setTimeout(this.nextTaskQueue.bind(this), 0);\n}\n,_getContextElement:function() {\n if (this.getContextElement) return this.getContextElement();\n return this.$el.parentElement;\n}\n},computed:{isVisible:function() {\n if (this.isPinned) return true;\n // .visible prop allows controlling the visibility from outside\n if (this.visible ! null) return this.visible;\n if (this.global) return true;\n if (this.isInsideContextElement) return true;\n return false;\n}\n,localPos:function() {\n const pos { ...this.globalPos };\n if (this.global) return pos;\n if (!this.$el) return pos;\n const rect this._getContextElement().getBoundingClientRect();\n pos.x - rect.left;\n pos.y - rect.top;\n return pos;\n}\n,style:function()\n{\n const style {};\n style.position (this.global ? \fixed\ : \fixed\);\n const pos (this.global ? this.globalPos : this.localPos);\n style.left ((pos.x + this.space) + \px\);\n style.top ((pos.y + this.space) + \px\);\n if (!this.semiTransparent) style.opacity 1;\n style.transition \all 0.3s, top 0s, left 0s !important\;\n if (this.windowStyle) Object.assign(style, this.windowStyle);\n return style;\n}\n},watch:{isVisible:{handler:async function(isVisible) {\n if (isVisible) {\n this.enqueueTask((() > { this.isVisibleOuter true; }).bind(this), 100);\n this.enqueueTask((() > { this.isVisibleInner true; }).bind(this));\n }\n else {\n this.enqueueTask((() > { this.isVisibleInner false; }).bind(this), 100);\n this.enqueueTask((() > { this.isVisibleOuter false; }).bind(this));\n }\n this.nextTaskQueue();\n}\n,immediate:true},isPinned:{handler:function(isPinned) {\n this.$emit(\pinned\, isPinned);\n if (!isPinned) this.onMouseLeaveContext();\n}\n,deep:true},mousePos:{handler:function() {\n // When the mouse moves, update the position of the context menu\n if (this.isPinned) return;\n this.globalPos this.mousePos;\n}\n,deep:true}},style:{.close-button:{float:right,margin:-0.5em -1.5rem,opacity:0.3,cursor:pointer,z-index:100,transition:0s},.close-button:hover:{opacity:1,transition:0s},.context-menu.visible:{opacity:0.7},.context-menu:{overflow:hidden,padding:1rem 2rem 1rem 1rem,background:linear-gradient(to right, #303030, #101010),box-shadow:-12px 12px 12px #000000,opacity:0,transition:all 0s, transform 0.3s, opacity 0.3s !important,cursor:move,pointer-events:none,z-index:1000},.context-menu.pinned:{opacity:1,border:1px solid #ffffff60,transform:translateY(-5em),pointer-events:all},h2:{border-radius:0,border-bottom:1px solid #000,margin-bottom:0.5em,user-select:none,font-size:2rem}},example:{dom:{div:{ui.context.window:{.flex.flex-column.gap-1:{div:{v-for:help in helps2,v-text:help},ui.value:{:style:{ width: 25em, height: 10em, overflow: auto },:value:exampleData}}},.box1:{div:{v-for:help in helps1,v-text:help}}}},data:{exampleData:null,helps1:Hover to see the context.,Right click to pin.,helps2:The context window can be attached to any element.,It can contain any other elements.},mounted:async function() {\n this.exampleData (await (await fetch(\/fetch?urlhttps://a.4cdn.org/boards.json\)).json()).boards;\n}\n},name:ui-context-window,_:{examples:{count:1}},template:div class\comp-ui-context-window\ path\1458497449.\>ui-mouse :global\true\ :ctrl-right-click\ctrlRightClick\ on_move\onMouseMove\ on_right-click\e > onRightClick(e, true)\ path\1458497449.0\>/ui-mouse>ui-mouse on_drag\onDrag\ path\1458497449.1\>transition name\fade\ path\1458497449.1.0\>div class\context-menu\ v-if\isVisibleOuter\ ref\menu1\ :class\{ pinned: isPinned, inited: isInited, visible: isVisibleInner }\ :style\style\ path\1458497449.1.0.0\>div path\1458497449.1.0.0.0\>div class\close-button\ v-if\isPinned\ v-text\βοΈ\ on_click\isPinnedfalse\ path\1458497449.1.0.0.0.0\>/div>transition name\slide\ path\1458497449.1.0.0.0.1\>h2 v-if\(showTitle) && (icon || title)\ :key\icon+title\ path\1458497449.1.0.0.0.1.0\>ui-title :icon\icon\ :title\title\ path\1458497449.1.0.0.0.1.0.0\>/ui-title>/h2>/transition>div path\1458497449.1.0.0.0.2\>slot>/slot>component v-if\compName\ :is\compName\ v-bind\bindProps\ path\1458497449.1.0.0.0.2.1\>/component>/div>/div>/div>/transition>/ui-mouse>/div>}},{name:ui.css.stylesheet,path:\\ui\\css\\stylesheet.ws.yaml,source:{dom:{style:{v-html:css}},props:{rules:null},methods:{getRulesCss:function(rules) {\n if (!rules) return \\;\n \n let s ;\n for (const e of Object.entries(rules))\n {\n s.push(`${e0} {`);\n for (const r of Object.entries(e1))\n {\n s.push(` ${r0}: ${r1} !important;`);\n }\n s.push(`}`);\n }\n return s.join(\\\n\);\n}\n},computed:{css:function() {\n return this.getRulesCss(this.rules);\n}\n},name:ide-css-stylesheet,_:{examples:{count:0}},template:style class\comp-ide-css-stylesheet\ v-html\css\ path\52333277.\>/style>}},{name:ui.data.changes,path:\\ui\\data\\changes.ws.yaml,source:{dom:{div:{.flex:{v-if:onlyKeys,ui.title#1:{v-for:(dataChange, index) in dataChanges,:icon:getIcon(dataChange),:text:dataChange.path}},table:{v-if:!onlyKeys,tr:{v-for:(dataChange, index) in dataChanges,td#1:{ui.title#2:{:icon:getIcon(dataChange),:text:dataChange.path}},td#2:{class:px-l2,ui.value.preview:{:value:dataChange.rhs || dataChange.item.rhs}}}}}},props:{dataChanges:null,onlyKeys:false},methods:{getText:function(dataChange) {\n let text dataChange.path;\n if (dataChange.kind \A\) text + ` ${dataChange.index}`;\n return text;\n}\n,getIcon:function(dataChange) {\n let icon ;\n if (dataChange.item)\n {\n icon {\n N: π’,\n D: π΄,\n E: π‘,\n }dataChange.item.kind;\n }\n return `π§${icon}`;\n}\n},_:{examples:{count:0}},name:ui-data-changes,template:div class\comp-ui-data-changes\ path\-1299348071.\>div class\flex\ v-if\onlyKeys\ path\-1299348071.0\>ui-title v-for\(dataChange, index) in dataChanges\ :icon\getIcon(dataChange)\ :text\dataChange.path\ path\-1299348071.0.0\>/ui-title>/div>table v-if\!onlyKeys\ path\-1299348071.1\>tr v-for\(dataChange, index) in dataChanges\ path\-1299348071.1.0\>td path\-1299348071.1.0.0\>ui-title :icon\getIcon(dataChange)\ :text\dataChange.path\ path\-1299348071.1.0.0.0\>/ui-title>/td>td class\px-l2\ path\-1299348071.1.0.1\>ui-value-preview :value\dataChange.rhs || dataChange.item.rhs\ path\-1299348071.1.0.1.0\>/ui-value-preview>/td>/tr>/table>/div>}},{name:ui.dnd.draggable.example0,path:\\ui\\dnd\\draggable.example0.ws.yaml,source:{dom:{div:{ui.dnd.draggable:{.box1.text-center:{v-text:Drag me}}}}}},{name:ui.dnd.draggable,path:\\ui\\dnd\\draggable.ws.yaml,source:{dom:{div:{:is:tag,ref:dragElement1,:class:{ draggable: true },draggable:true,on_dragstart:onDragStart,on_dragend:onDragEnd,on_mousemove:onDrag,on_drag:onDrag,ui.mouse:{:global:true,on_move:onDrag},slot:null}},props:{dragItem:null,showDragGhost:true,tag:div},data:{dragElementPos:null,isDragging:false,lastPos:{x:null,y:null}},methods:{onDragStart:function(e) {\n this.isDragging true;\n\n this.dragElementPos { x: e.clientX, y: e.clientY };\n\n if (!this.showDragGhost)\n {\n // Hide the drag ghost\n const img new Image();\n e.dataTransfer.setDragImage(img, 0, 0);\n }\n\n this.$root.dragItem this.dragItem;\n this.$emit(drag-start, this.dragItem);\n}\n,onDragEnd:async function(e) {\n this.isDragging false;\n await this.$nextTick();\n this.$emit(drag-end, this.dragItem);\n this.$root.dragItem null;\n}\n,onDrag:function(e) {\n if (!this.__onDrag) this.__onDrag this._onDrag.throttle(this, 50);\n this.__onDrag(e);\n}\n,_onDrag:function(e) {\n const { x, y } { x: e.clientX, y: e.clientY };\n if (Objects.areEqual(this.lastPos, { x, y })) return;\n this.lastPos { x, y };\n const dep this.dragElementPos;\n if (!dep) return;\n const relativePos { x: (x - dep.x), y: (y - dep.y) };\n const data {\n e,\n relative: {\n pos: relativePos,\n }\n };\n this.$emit(drag, data);\n}\n},style:{.draggable:{cursor:grabbing}},example:{dom:{div:{ui.dnd.draggable:{.box1.text-center:{v-text:Drag me}}}}},_:{examples:{count:1}},name:ui-dnd-draggable,template:div class\comp-ui-dnd-draggable\ ref\dragElement1\ :class\{ draggable: true }\ draggable\true\ on_dragstart\onDragStart\ on_dragend\onDragEnd\ on_mousemove\onDrag\ on_drag\onDrag\ path\-26676257.\>ui-mouse :global\true\ on_move\onDrag\ path\-26676257.0\>/ui-mouse>slot>/slot>/div>}},{name:ui.dnd.dropzone.example0,path:\\ui\\dnd\\dropzone.example0.ws.yaml,source:{dom:{ui.dnd.dropzone:{.box1.w-100pc.text-center:{v-text:Drop here},on_drop-item:onDropItem}},methods:{onDropItem:function(dragItem) {\n alertify.message(\Dropped item\);\n}\n}}},{name:ui.dnd.dropzone,path:\\ui\\dnd\\dropzone.ws.yaml,source:{dom:{div:{:class:{ dropzone: true, drag-over: isDraggedOver },on_dragover:onDragOver,on_dragenter:onDragEnter,on_dragleave:onDragLeave,on_drop:onDrop,on_click:onClick,slot:null}},props:null,data:{isDraggedOver:false},methods:{onDragOver:function(e) {\n this.cancelEvent(e);\n this.isDraggedOver true;\n}\n,onDragEnter:function(e) {\n this.cancelEvent(e);\n this.isDraggedOver true;\n}\n,onDragLeave:function(e) {\n this.cancelEvent(e);\n this.isDraggedOver false;\n}\n,onDrop:function(e) {\n this.cancelEvent(e);\n this.isDraggedOver false;\n const dragItem this.$root.dragItem;\n this.$root.dragItem null;\n this.$emit(drag-over, false);\n this.$emit(drop-item, dragItem);\n}\n,onClick:function(e) {\n this.$emit(click, e);\n}\n,cancelEvent:function(e) {\n e.preventDefault();\n e.stopPropagation();\n}\n},style:{.drag-over:{background-color:rgba(255, 255, 255, 0.1),border:3px dashed rgba(20, 128, 255, 0.5)}},example:{dom:{ui.dnd.dropzone:{.box1.w-100pc.text-center:{v-text:Drop here},on_drop-item:onDropItem}},methods:{onDropItem:function(dragItem) {\n alertify.message(\Dropped item\);\n}\n}},_:{examples:{count:1}},name:ui-dnd-dropzone,template:div class\comp-ui-dnd-dropzone\ :class\{ dropzone: true, drag-over: isDraggedOver }\ on_dragover\onDragOver\ on_dragenter\onDragEnter\ on_dragleave\onDragLeave\ on_drop\onDrop\ on_click\onClick\ path\-2085012855.\>slot>/slot>/div>}},{name:ui.drawer.example0,path:\\ui\\drawer.example0.ws.yaml,source:{dom:{.flex.gap-1:{ui.drawer:{ui.select:{:options:β help, π menu, π οΈ settings,v-model:selectedMenuItem}},div:{v-if:(selectedMenuItem 0),:style:{ width: 8em },v-text:The drawer on the left expands when hovered over.}}},data:{selectedMenuItem:0},watch:{selectedMenuItem:function (value) {\n}\n},style:{.drawer.open, .drawer:hover, .drawer.hovered:{max-width:10em !important,transition:0.6s}}}},{name:ui.drawer,path:\\ui\\drawer.ws.yaml,source:{dom:{.drawer:{on_dragenter:isHovered++,on_dragleave:isHovered--,on_click:isHovered0,:class:cssClass,slot:null}},props:{open:false,direction:vertical},data:{isHovered:0},methods:{getCssClass:function() {\n const cls {};\n clsthis.direction true;\n cls.open this.open;\n cls.hovered this.isHovered;\n return cls;\n}\n},computed:{cssClass:function() {\n return this.getCssClass();\n}\n},style:{.drawer:{max-height:10em,max-width:3em,overflow:hidden,filter:grayscale(1) blur(3px),opacity:0.5,transition:1s},.drawer.horizontal:{max-height:3em,max-width:none},.drawer.open, .drawer:hover, .drawer.hovered:{max-height:60em,max-width:60em,filter:none,opacity:1},.drawer.horizontal.open, .drawer.horizontal:hover, .drawer.horizontal.hovered:{max-height:20em,filter:none,opacity:1}},example:{dom:{.flex.gap-1:{ui.drawer:{ui.select:{:options:β help, π menu, π οΈ settings,v-model:selectedMenuItem}},div:{v-if:(selectedMenuItem 0),:style:{ width: 8em },v-text:The drawer on the left expands when hovered over.}}},data:{selectedMenuItem:0},watch:{selectedMenuItem:function (value) {\n}\n},style:{.drawer.open, .drawer:hover, .drawer.hovered:{max-width:10em !important,transition:0.6s}}},_:{examples:{count:1}},name:ui-drawer,template:div class\comp-ui-drawer drawer\ on_dragenter\isHovered++\ on_dragleave\isHovered--\ on_click\isHovered0\ :class\{ open, hovered: isHovered }\ path\-1860583029.\>slot>/slot>/div>}},{name:ui.elapsed,path:\\ui\\elapsed.ws.yaml,source:{dom:{div:{v-if:is.showing,ui.title:{icon:π,:text:elapsedString}}},data:{started:null,elapsed:null,is:{showing:false}},mounted:function() {\n this.start();\n}\n,methods:{start:function() {\n this.started Date.now();\n this.elapsed 0;\n this.is.showing true;\n this.update();\n}\n,update:async function() {\n this.elapsed (Date.now() - this.started);\n await this.$root.wait(100);\n this.update();\n}\n},computed:{elapsedString:function() {\n if (this.elapsed 1000) {\n return this.elapsed.toString();\n }\n\n return `${(this.elapsed / 1000).toFixed(1)}s`;\n}\n},_:{examples:{count:0}}}},{name:ui.error,path:\\ui\\error.ws.yaml,source:{dom:{transition:{name:slide,.error:{on_click:() > error null,v-if:errorText,v-text:errorText,:key:errorText}}},props:{error:null},computed:{errorText:function() {\n return this.error?.message || this.error;\n}\n},example1:{dom:{ui.error:{error:This is an error.}}},name:ui-error,_:{examples:{count:0}},template:transition class\comp-ui-error\ name\slide\ path\-2137289170.\>div class\error\ on_click\() > error null\ v-if\errorText\ v-text\errorText\ :key\errorText\ path\-2137289170.0\>/div>/transition>}},{name:ui.expand,path:\\ui\\expand.ws.yaml,source:{dom:{.flex:{class:hoverable,on_click:$emit(input, !value),.icon:{v-text:expandIcon},ui.title:{:icon:icon,:text:text,:number:number}}},props:{value:null,icon:null,text:null,number:null},watch:null,computed:{expandIcon:function() {\n return !this.value ? β : β;\n}\n},style:{.flex:hover:{background-color:#ffffff20},.flex > *:{cursor:pointer},.icon:{margin-right:0.3rem},label:{flex-grow:1}},name:ui-expand,_:{examples:{count:0}},template:div class\comp-ui-expand hoverable flex\ on_click\$emit(input, !value)\ path\-1825986764.\>div class\icon\ v-text\expandIcon\ path\-1825986764.0\>/div>ui-title :icon\icon\ :text\text\ :number\number\ path\-1825986764.1\>/ui-title>/div>}},{name:ui.file.dropzone,path:\\ui\\file\\dropzone.ws.yaml,source:{dom:{div:{class:w-100pc h-100pc,ui.loading:{class:absolute-center,v-show:isLoading},.file-dropzone:{v-dim:isLoading,ref:dropArea1,.hint:{v-if:enabled && showHint,v-text:hint},.upload-button:{v-if:enabled && showUploadButton,v-text:π€πΌοΈ,title:π€πΌοΈ upload image,on_click:onClickUpload},input:{class:hidden,type:file,ref:fileInput,on_change:onChangeFileInput},slot:null}}},props:{enabled:true,showHint:true,showUploadButton:true,hint:drop file here},data:{isLoading:0},mounted:function() {\n const dropArea this.$refs.dropArea1;\n dragenter, dragover, dragleave, drop.forEach(eventName > {\n dropArea.addEventListener(eventName, this.onlyIfFiles(this.preventDefaults), false);\n });\n dragenter, dragover.forEach(eventName > {\n dropArea.addEventListener(eventName, this.onlyIfFiles(this.highlight.bind(this)), false);\n });\n dragleave, drop.forEach(eventName > {\n dropArea.addEventListener(eventName, this.onlyIfFiles(this.unhighlight.bind(this)), false);\n });\n dropArea.addEventListener(drop, this.onlyIfFiles(this.handleDrop.bind(this)), false);\n}\n,methods:{onFileDrop:async function(files) {\n this.$emit(file-drop, files);\n}\n,onClickUpload:function (e) {\n this.$refs.fileInput.click();\n}\n,onChangeFileInput:function (e) {\n let files e.target.files;\n this.onFileDrop(files);\n}\n,handleDrop:function (e) {\n if (!this.enabled) return;\n let dt e.dataTransfer;\n let files dt.files;\n this.onFileDrop(files);\n}\n,highlight:function (e) {\n if (!this.enabled) return;\n this.$refs.dropArea1.classList.add(drop-possible);\n}\n,unhighlight:function (e) {\n if (!this.enabled) return;\n this.$refs.dropArea1.classList.remove(drop-possible);\n // Remove tooltip attribute\n this.$refs.dropArea1.removeAttribute(tooltip);\n}\n,preventDefaults:function (e) {\n e.preventDefault()\n e.stopPropagation()\n}\n,onlyIfFiles:function (handler) {\n return function (e) {\n if (!e.dataTransfer.types.includes(Files)) return;\n handler(e);\n }\n}\n},style:{.file-dropzone:{width:100%,height:100%},.hint:{position:absolute,display:flex;,justify-content:center;,align-items:center;,width:100%,height:100%,left:50%,top:50%,transform:translate(-50%, -50%),border:5px dashed #ccc,font-family:monospace,font-size:2em,text-shadow:-0.1em 0.1em 0.1em #000,text-align:center,opacity:0.5,pointer-events:none,transition:0s},.drop-possible .hint:{background:#ffffff20,opacity:1,transition:0s},.upload-button:{position:absolute,width:fit-content !important,height:fit-content !important,top:0,right:0,cursor:pointer,z-index:10,font-size:2rem,filter:grayscale(1),opacity:0.6,text-align:right},.upload-button:hover:{filter:none,opacity:1},.file-dropzone:hover .upload-button:{display:block}},name:ui-file-dropzone,_:{examples:{count:0}},template:div class\comp-ui-file-dropzone w-100pc h-100pc\ path\1956569459.\>ui-loading class\absolute-center\ v-show\isLoading\ path\1956569459.0\>/ui-loading>div class\file-dropzone\ v-dim\isLoading\ ref\dropArea1\ path\1956569459.1\>div class\hint\ v-if\enabled\ v-text\hint\ path\1956569459.1.0\>/div>div class\upload-button\ v-if\enabled && showUploadButton\ v-text\π€πΌοΈ\ title\π€πΌοΈ upload image\ on_click\onClickUpload\ path\1956569459.1.1\>/div>input class\hidden\ type\file\ ref\fileInput\ on_change\onChangeFileInput\ path\1956569459.1.2\/>slot>/slot>/div>/div>}},{name:ui.floating,path:\\ui\\floating.ws.yaml,source:{dom:{div:{:style:floatingStyle,slot:null}},props:{attachTo:null,attachOrigin:null},data:{floatingStyle:null},mounted:function() {\n this.$root.html.when.element.moves(this.$el, this.refresh.bind(this));\n // When the window resizes or scrolls, refresh\n window.addEventListener(resize, this.refresh.bind(this));\n window.addEventListener(scroll, this.refresh.bind(this));\n}\n,methods:{getFloatingStyle:function() {\n if (!this.attachTo) return;\n\n const targetRect this.$root.getAbsoluteRect(this.attachTo);\n const floatingRect this.$el.getBoundingClientRect();\n const origin this.attachOrigin || top left;\n const vertical, horizontal origin.split( );\n\n const parentRect (!this.$el.parentElement) ? null : this.$root.getAbsoluteRect(this.$el.parentElement);\n const rect this.$el.getBoundingClientRect();\n\n const left this.getHorizontalCoordinate(horizontal, targetRect) - (horizontal center ? floatingRect.width / 2 : 0) - (parentRect?.left || 0);\n const top this.getVerticalCoordinate(vertical, targetRect) - (vertical center ? floatingRect.height / 2 : 0) - (parentRect?.top || 0);\n\n //const left (targetRect.left - parentRect.left - (rect.width / 2));\n //const top (targetRect.top - parentRect.top + (rect.height / 2));\n\n return {\n position: absolute,\n left: `${left}px`,\n top: `${top}px`,\n \z-index\: 1000,\n };\n}\n,getHorizontalCoordinate:function(value, rect) {\n return this.getCoordinate(value, width, rect, left);\n}\n,getVerticalCoordinate:function(value, rect) {\n return this.getCoordinate(value, height, rect, top);\n}\n,getCoordinate:function(value, dimension, rect, defaultCoord) {\n switch (value) {\n case top:\n case left:\n return rectdefaultCoord;\n case center:\n return rectdefaultCoord + rectdimension / 2;\n case bottom:\n case right:\n return rectdefaultCoord + rectdimension;\n default:\n return 0;\n }\n}\n,refresh:function() {\n this.floatingStyle this.getFloatingStyle();\n}\n},watch:{attachTo:function(el) {\n // Watch the element, if it moves, refresh\n if (!el) return;\n this.$root.html.when.element.moves(el, this.refresh.bind(this));\n}\n},_:{examples:{count:0}},name:ui-floating,template:div class\comp-ui-floating\ :style\floatingStyle\ path\1522602528.\>slot>/slot>/div>}},{name:ui.gesture.select.box,path:\\ui\\gesture\\select\\box.ws.yaml,source:{dom:{div#1:{ui.mouse:{global:true,on_down:onMouseDown,on_up:onMouseUp,on_move:onMouseMove},div#2:{v-if:false,.x-axis:{:style:xAxisStyle},.y-axis:{:style:yAxisStyle},.debugger:{v-if:false,:style:debuggerStyle,ui.value:{:value:debugInfo}}},transition:{name:fade,.select-box:{v-if:isVisible,:style:selectBoxStyle}}}},props:{surfaceElement:null,surfaceCamera:null,centerCoords:false,isLayerElement:null,showAxes:false},data:{mousePos:null,dragStart:null,dragEnd:null,isVisible:false},mounted:function() {\n // If esc is pressed, cancel the select box\n window.addEventListener(\keydown\, this.onKeyDown);\n}\n,methods:{onKeyDown:function(e) {\n if (e.key ! \Escape\) return;\n this.clear();\n}\n,onMouseDown:function(e) {\n if (e.button ! 0) return;\n if (e.target ! this.surfaceElement) return;\n if (this.dragStart) return;\n if (!this.isLayerElement) throw new Error(\Pass isLayerElement prop to ui.gesture.select.box to know where the select box is active\);\n if (!this.isLayerElement(e.target)) return;\n e.preventDefault();\n e.stopPropagation();\n this.dragStart { x: e.clientX, y: e.clientY };\n this.isVisible false;\n}\n,onMouseUp:function(e) {\n if (e.button ! 0) return;\n if (e.target ! this.surfaceElement) return;\n if (!this.dragStart) return;\n e.preventDefault();\n e.stopPropagation();\n const rect this.rect;\n this.clear();\n if (!this.isMinimumSize(rect?.size)) return;\n this.$emit(\drag-end\, this.adjustPos(this.dragEnd));\n this.$emit(\mark\, this.adjustRect(rect));\n}\n,onMouseMove:function(e) {\n this.mousePos e;\n if (!this.dragStart) return;\n if (!this.isVisible) this.isVisible this.isMinimumSize(this.size);\n this.dragEnd { x: e.x, y: e.y };\n}\n,isMinimumSize:function(size) {\n if (!size) return false;\n if (size.width 10) return false;\n if (size.height 10) return false;\n return true;\n}\n,getCorner:function(minOrMax) {\n const dragStart this.dragStart;\n const dragEnd this.dragEnd;\n if (!dragStart) return null;\n if (!dragEnd) return null;\n const x MathminOrMax(dragStart.x, dragEnd.x);\n const y MathminOrMax(dragStart.y, dragEnd.y);\n return { x, y };\n}\n,getSurfaceCenter:function() {\n const surface this.surfaceElement || window;\n const surfaceRect this.$root.getAbsoluteRect(surface);\n return {\n x: Math.round(surfaceRect.left + surfaceRect.width / 2),\n y: Math.round(surfaceRect.top + surfaceRect.height / 2)\n };\n}\n,adjustRect:function(rect) {\n if (!this.centerCoords) return rect;\n const center this.getSurfaceCenter(\fixed\);\n const pos rect.pos;\n const size rect.size;\n const x pos.x - center.x;\n const y center.y - pos.y;\n const width size.width;\n const height size.height;\n rect this.toCenteredRect({ pos: { x, y }, size: { width, height } });\n rect this.adjustToCamera(rect);\n return rect;\n}\n,adjustPos:function(pos) {\n if (!pos) return null;\n if (!this.centerCoords) return pos;\n const center this.getSurfaceCenter(\fixed\);\n const x pos.x - center.x;\n const y center.y - pos.y;\n pos { x, y };\n pos this.adjustToCamera(pos);\n return pos;\n}\n,toCenteredRect:function(rect) {\n const pos rect.pos;\n const size rect.size;\n const x pos.x + size.width / 2;\n const y pos.y - size.height / 2;\n return { pos: { x, y }, size };\n}\n,adjustToCamera:function(posOrRect) {\n const camera this.surfaceCamera;\n if (!camera) return posOrRect;\n if (posOrRect.pos) {\n const pos posOrRect.pos;\n pos.x (pos.x + camera.pos.x) / camera.scale;\n pos.y (pos.y + camera.pos.y) / camera.scale;\n }\n else {\n const pos posOrRect;\n pos.x (pos.x + camera.pos.x) / camera.scale;\n pos.y (pos.y + camera.pos.y) / camera.scale;\n }\n return posOrRect;\n}\n,clear:function() {\n this.dragStart null;\n this.dragEnd null;\n this.isVisible false;\n}\n},computed:{debugInfo:function() {\n const info {};\n try\n {\n info.mousePos this.adjustPos(this.mousePos);\n info.rect this.adjustRect(this.rect);\n }\n catch (ex)\n {\n info.error ex.message;\n }\n return info;\n}\n,selectBoxStyle:function() {\n if (!this.isVisible) return null;\n const topLeft this.topLeft;\n const size this.size;\n const style {};\n style.position \fixed\;\n style.left `${topLeft.x}px`;\n style.top `${topLeft.y}px`;\n style.width `${size.width}px`;\n style.height `${size.height}px`;\n return style;\n}\n,xAxisStyle:function() {\n const mousePos this.mousePos;\n if (!mousePos) return null;\n const style {};\n style.position \fixed\;\n style.left `${0}px`;\n style.top `${mousePos.y}px`;\n style.width `${100}vw`;\n style.height `${1}px`;\n style.pointerEvents \none\;\n return style;\n}\n,yAxisStyle:function() {\n const mousePos this.mousePos;\n if (!mousePos) return null;\n const style {};\n style.position \fixed\;\n style.left `${mousePos.x}px`;\n style.top `${0}px`;\n style.width `${1}px`;\n style.height `${100}vh`;\n style.pointerEvents \none\;\n return style;\n}\n,debuggerStyle:function() {\n const mousePos this.mousePos;\n if (!mousePos) return null;\n const spacer 20;\n const style {};\n style.position \fixed\;\n style.left `${mousePos.x + spacer}px`;\n style.top `${mousePos.y + spacer}px`;\n style.pointerEvents \none\;\n return style;\n\n}\n,topLeft:function() {\n return this.getCorner(\min\);\n}\n,bottomRight:function() {\n return this.getCorner(\max\);\n}\n,size:function() {\n const topLeft this.topLeft;\n const bottomRight this.bottomRight;\n if (!topLeft) return null;\n if (!bottomRight) return null;\n const width bottomRight.x - topLeft.x;\n const height bottomRight.y - topLeft.y;\n return { width, height };\n}\n,rect:function() {\n if (!this.dragStart) return null;\n if (!this.topLeft) return null;\n return {\n pos: { x: this.topLeft.x, y: this.topLeft.y },\n size: this.size\n }\n}\n},watch:{mousePos:function() {\n this.$emit(\mouse-pos\, this.adjustPos(this.mousePos));\n}\n,dragStart:function() {\n this.$emit(\drag-start\, this.adjustPos(this.dragStart));\n}\n},style:{.select-box:{border:3px dashed yellow,position:fixed,filter:drop-shadow(-3px 3px 1px #000000),transition:opacity 0.3s !important,background:#ffffff10,pointer-events:none,z-index:1000},.x-axis, .y-axis:{border:1px dashed gray,opacity:0.1}},_:{examples:{count:0}},name:ui-gesture-select-box,template:div class\comp-ui-gesture-select-box\ path\-2052114120.\>ui-mouse global\true\ on_down\onMouseDown\ on_up\onMouseUp\ on_move\onMouseMove\ path\-2052114120.0\>/ui-mouse>div v-if\false\ path\-2052114120.1\>div class\x-axis\ :style\xAxisStyle\ path\-2052114120.1.0\>/div>div class\y-axis\ :style\yAxisStyle\ path\-2052114120.1.1\>/div>div class\debugger\ v-if\false\ :style\debuggerStyle\ path\-2052114120.1.2\>ui-value :value\debugInfo\ path\-2052114120.1.2.0\>/ui-value>/div>/div>transition name\fade\ path\-2052114120.2\>div class\select-box\ v-if\isVisible\ :style\selectBoxStyle\ path\-2052114120.2.0\>/div>/transition>/div>}},{name:ui.highlighter,path:\\ui\\highlighter.ws.yaml,source:{dom:{div:{:class:getCssClass(),on_mouseenter:onMouseEnter,on_mouseleave:onMouseLeave,slot:null}},props:{getElements:null},methods:{getCssClass:function() {\n // CSS class is \hoverable\, unless were inside a ui.tree.node\n if (this.$root.vm.getAncestors(this, ui.tree.node, 3).length) return ;\n return hoverable;\n}\n,getElementsArray:function() {\n const elements this.getElements();\n if (Array.isArray(elements)) return elements;\n if (typeof elementsSymbol.iterator function) return ...elements;\n return elements;\n}\n,onMouseEnter:function() {\n this.getElementsArray().forEach(el > el.classList?.add(\highlighted\));\n}\n,onMouseLeave:function() {\n this.getElementsArray().forEach(el > el.classList?.remove(\highlighted\));\n}\n},name:ui-highlighter,_:{examples:{count:0}},template:div class\comp-ui-highlighter\ :class\getCssClass()\ on_mouseenter\onMouseEnter\ on_mouseleave\onMouseLeave\ path\71025671.\>slot>/slot>/div>}},{name:ui.html.style,path:\\ui\\html\\style.ws.yaml,source:{dom:{style:{v-if:!documentHead,:class:component.name,v-html:css}},props:{component:null,documentHead:false},data:{css:null},mounted:function() {\n if (this.documentHead) {\n const css this.getCss(this.component);\n if (!css?.length) return;\n const style document.createElement(\style\);\n style.type \text/css\;\n style.classList.add(this.component.name);\n style.innerHTML css;\n document.head.appendChild(style);\n }\n}\n,methods:{getCss:function(component) {\n if (!component?.source?.style) return null;\n const template this.$root.templates.style;\n let css Handlebars.compile(template)(component);\n css this.htmlDecode(css);\n return css;\n}\n,htmlDecode:function(input) {\n var doc new DOMParser().parseFromString(input, \text/html\);\n return doc.documentElement.textContent;\n}\n},watch:{component:{handler:function(component) {\n this.css this.getCss(component);\n}\n,immediate:true}},name:ui-html-style,_:{examples:{count:0}},template:style class\comp-ui-html-style\ v-if\!documentHead\ :class\component.name\ v-html\css\ path\951734600.\>/style>}},{name:ui.image.options,path:\\ui\\image\\options.ws.yaml,source:{dom:{.options:{:class:filter+-options,:tooltip:filter,div#1:{class:option,v-for:i in 10,:class:getClass(i),on_click:onClick(i),ui.image:{v-if:imageID,:img-style:getStyle(i),:imageID:imageID,:square:true},div#2:{v-if:!imageID,class:box,:style:getStyle(i)}}}},props:{imageID:null,filter:null,reverse:false,value:null},methods:{onClick:function(i) {\n if (i/10 this.value) i null;\n this.$emit(input, i/10);\n}\n,getClass:function(i) {\n const cls {};\n clsselected (i/10 this.value);\n return cls;\n}\n,getStyle:function(i) {\n const valueFunc (this.reverse) ? (i) > 10-i : (i) > i;\n i valueFunc(i);\n return `filter: ${this.filter}(${(this.getValue(i))})`;\n}\n,getValue:function(i) {\n const ratio (this.imageID ? 3 : 1);\n const value (this.filter blur) ? `${i/ratio}px` : (i/10).toFixed(2);\n return value;\n}\n},style:{.box:{aspect-ratio:1/1,background:#ffff0080},.options:{display:grid,grid-template:1fr / repeat(10, 1fr)},.options:not(.grayscale-options):{filter:grayscale(1)},.option:{cursor:pointer,border:2px solid transparent,overflow:hidden,transition:0s},.option:hover:{border:2px solid #ffffff40},.selected:{background:none,border:2px solid}},name:ui-image-options,_:{examples:{count:0}},template:div class\comp-ui-image-options options\ :class\filter+-options\ :tooltip\filter\ path\907340593.\>div class\option\ v-for\i in 10\ :class\getClass(i)\ on_click\onClick(i)\ path\907340593.0\>ui-image v-if\imageID\ :img-style\getStyle(i)\ :imageID\imageID\ :square\true\ path\907340593.0.0\>/ui-image>div class\box\ v-if\!imageID\ :style\getStyle(i)\ path\907340593.0.1\>/div>/div>/div>}},{name:ui.image.select,path:\\ui\\image\\select.ws.yaml,source:{dom:{.flex#1:{ui.image:{:imageID:value,:square:true},ui.file.dropzone:{:show-hint:false,on_file-drop:onFileDrop,.dropzone:{.flex#2:{class:justify-center,div#1:{v-text:dropAreaText},div#2:{ui.loading:null,v-if:isUploading}}}}}},props:{value:null},data:{imageID:null,noBgImageID:null,isUploading:false},methods:{onFileDrop:function (files) {\n if (files.length ! 1) return alertify.error(\One file at a time, please.\);\n this.uploadFile(files0);\n}\n,uploadFile:async function(file) {\n const image await this.$root.uploadFile(file);\n this.$emit(input, image._id);\n}\n},computed:{dropAreaText:function () {\n if (this.isUploading) return \uploadingβ¦\;\n return \π€ drop image\;\n}\n},watch:{isUploading:function (isUploading) {\n this.$emit(uploading, isUploading);\n}\n},style:{.flex:{gap:0.5rem},.comp-ui-image:{width:15% !important},.comp-ui-file-dropzone:{width:85% !important,font-size:160%,text-align:center,font-family:monospace},.dropzone:{border:6px dashed white,opacity:0.3}},name:ui-image-select,_:{examples:{count:0}},template:div class\comp-ui-image-select flex\ path\-1667730935.\>ui-image :imageID\value\ :square\true\ path\-1667730935.0\>/ui-image>ui-file-dropzone on_file-drop\onFileDrop\ path\-1667730935.1\>div class\dropzone\ path\-1667730935.1.0\>div class\justify-center flex\ path\-1667730935.1.0.0\>div v-text\dropAreaText\ path\-1667730935.1.0.0.0\>/div>div v-if\isUploading\ path\-1667730935.1.0.0.1\>ui-loading>/ui-loading>/div>/div>/div>/ui-file-dropzone>/div>}},{name:ui.image,path:\\ui\\image.ws.yaml,source:{dom:{div:{component:{:is:getCompType(),class:image,:url:url,img:{ref:image1,:class:cssClass,:style:imgStyle,:src:src1,on_load:onLoad,on_error:onError},on_click:$emit(click)}}},props:{imageID:null,url:null,src:null,square:null,removeBackground:false,aspectRatio:null,objectPosition:null},data:{width:null,height:null},mounted:async function () {\n window.addEventListener(`resize`, this.recalc.bind(this));\n // Detect if the image element changes its size\n let resizeObserver new ResizeObserver(this.recalc.bind(this));\n resizeObserver.observe(this.$refs.image1);\n}\n,methods:{onLoad:function () {\n this.$emit(\load\, this.$refs.image1.src);\n this.recalc();\n 1,2,3.forEach(i > setTimeout(this.recalc.bind(this), i * 100))\n}\n,onError:function () {\n this.$emit(\error\, this.$refs.image1.src);\n}\n,recalc:function () {\n if (!this.$refs.image1) return;\n let rect this.$refs.image1.getBoundingClientRect();\n this.width Math.round(rect.width);\n this.height Math.round(rect.height);\n this.$emit(\change\);\n}\n,getCssClass:function () {\n return { empty: !this.src, square: this.square };\n}\n,getCompType:function () {\n if (!this.url) return `div`;\n return `ui-link`;\n}\n},computed:{diagonal:function () {\n return Math.round(Math.sqrt(this.width * this.width + this.height * this.height));\n}\n,src1:function () {\n if (this.imageID) return this.$root.url.image(this.imageID, true, this.removeBackground);\n if (this.url) return this.url;\n if (this.src) return this.src;\n return this.emptySrc;\n}\n,emptySrc:function () {\n return /img/empty.png;\n}\n,imgStyle:function () {\n const style {};\n style.aspectRatio this.aspectRatio;\n style.objectPosition this.objectPosition;\n return style;\n}\n,cssClass:function () {\n return this.getCssClass();\n}\n},style:{.comp-ui-image:{overflow:hidden,transition:0s},.image, img:{width:100%,object-fit:cover},.square:{aspect-ratio:1}},name:ui-image,_:{examples:{count:0}},template:div class\comp-ui-image\ path\-2133760639.\>component class\image\ :is\getCompType()\ :url\url\ on_click\$emit(click)\ path\-2133760639.0\>img ref\image1\ :class\cssClass\ :style\imgStyle\ :src\src1\ on_load\onLoad\ on_error\onError\ path\-2133760639.0.0\/>/component>/div>}},{name:ui.infinite.scroll,path:\\ui\\infinite.scroll.ws.yaml,source:{dom:{div:{slot:null}},data:{lastEmit:null},mounted:function() {\n window.addEventListener(scroll, () > this.onScroll());\n}\n,methods:{onScroll:function(force) {\n if ((!force) && (this.lastEmit) && ((Date.now() - this.lastEmit) 400)) return;\n const distanceToBottom document.documentElement.scrollHeight - (window.scrollY + window.innerHeight);\n if (distanceToBottom window.innerHeight) {\n this.lastEmit Date.now();\n this.$emit(scroll);\n }\n}\n},name:ui-infinite-scroll,style:null,_:{examples:{count:0}},template:div class\comp-ui-infinite-scroll\ path\795650189.\>slot>/slot>/div>}},{name:ui.input.background.color.item,path:\\ui\\input\\background\\color\\item.ws.yaml,source:{dom:{.item:{:class:cssClass1,on_mouseenter:onItemHover(colorClass, true),on_mouseleave:onItemHover(colorClass, false),on_click:onItemClick(colorClass)}},props:{colorClass:null,value:null,large:null},methods:{onItemHover:function(colorClass, isHovered) {\n this.$emit(hover, colorClass, isHovered);\n}\n,onItemClick:function(colorClass) {\n if (colorClass this.value) colorClass null;\n this.$emit(input, colorClass);\n}\n},computed:{cssClass1:function() {\n const cls {};\n if (typeof this.colorClass \string\) clsthis.colorClass true;\n if (typeof this.colorClass \object\) Object.assign(cls, this.value);\n cls.selected1 (this.value this.colorClass);\n cls.large this.large;\n return cls;\n}\n},style:{.item.large:{width:10em !important},.item:{width:6em,height:2em,text-shadow:-3px 3px 1px black,box-shadow:inset -6px 6px 12px #000000d0,opacity:0.7,cursor:pointer},.item:hover, .item.selected1:{opacity:1},.item.selected1:{box-shadow:-6px 6px 12px black, inset -4px 4px 8px #ffffffd0,margin-left:0}},_:{examples:{count:0}},name:ui-input-background-color-item,template:div class\comp-ui-input-background-color-item item\ :class\cssClass1\ on_mouseenter\onItemHover(colorClass, true)\ on_mouseleave\onItemHover(colorClass, false)\ on_click\onItemClick(colorClass)\ path\-1984621568.\>/div>}},{name:ui.input.background.color,path:\\ui\\input\\background\\color\\_.ws.yaml,source:{dom:{div#1:{.flex.gap-2:{div#2:{:class:{ has-main-color: (!!selectedMainColor) },div#3:{v-if:(!!selectedMainColor),class:main-color mb-l1,ui.input.background.color.item#1:{:color-class:bg- + selectedMainColor,:value:bg- + selectedMainColor}},ul#1:{class:colors,li#1:{v-for:color in colors,on_click:selectMainColor(color),ui.input.background.color.item#2:{:color-class:bg- + color,:value:bg- + selectedMainColor}}}},transition#1:{name:slide-hor,div#4:{v-if:selectedMainColor,:style:{ width: 30em },transition#2:{name:fade,div#5:{:key:selectedMainColor,.flex.gap-2:{div#6:{.title#1:{v-text:shade},ul#2:{li#2:{v-for:shade in shades,ui.input.background.color.item#3:{:color-class:getShadeClass(selectedMainColor, shade),:value:selectedColorClass,on_hover:onItemHover,on_input:selectedColorClass $event}}}},div#7:{.title#2:{v-text:tranparent},ul#3:{li#3:{v-for:alpha in alphas,ui.input.background.color.item#4:{:color-class:getAlphaClass(selectedMainColor, alpha),:value:selectedColorClass,on_hover:onItemHover,on_input:selectedColorClass $event}}}},div#8:{.title#3:{v-text:gradient},ul#4:{li#4:{v-for:gradColor in gradColors,ui.input.background.color.item#5:{:color-class:getGradClass(selectedMainColor, gradColor),:value:selectedColorClass,on_hover:onItemHover,on_input:selectedColorClass $event,:large:true}}}}}}}}}}}},props:{value:null},data:{selectedMainColor:null,selectedColorClass:null,colors:blue,indigo,purple,pink,red,orange,yellow,pear,green,mint,teal,gray,slategray,brown,wine,almond,shades:darkest,darker,dark,null,light,lighter,lightest,alphas:90,80,70,60,50,40,30,20,10},methods:{init:function(value) {\n if (this._isInited) return;\n this._isInited true;\n if (!value) return;\n const color value.split(-)1;\n this.selectedMainColor color;\n this.selectedColorClass value;\n}\n,onItemHover:function(colorClass, isHovered) {\n this.$emit(value-preview, colorClass, isHovered);\n}\n,selectMainColor:function(color) {\n if (color this.selectedMainColor) color null;\n this.selectedMainColor color;\n}\n,getShadeClass:function(color, shade) {\n return bg, color, shade\n .filter(s > s)\n .join(-);\n}\n,getAlphaClass:function(color, alpha) {\n return bg, color, alpha\n .filter(s > s)\n .join(-);\n}\n,getGradClass:function(color1, color2) {\n if (color1 color2) return `linear-${color1}`;\n return `${color1}-${color2}`;\n}\n},computed:{gradColors:function() {\n return this.selectedMainColor, ...(this.colors.except(this.selectedMainColor));\n}\n},watch:{selectedColorClass:async function() {\n await this.$root.wait(10);\n this.$emit(input, this.selectedColorClass);\n}\n,value:{handler:function(value) {\n this.init(value);\n}\n,immediate:true}},style:{.title:{width:calc(100% - 1.5em),text-align:center,opacity:0.5},.has-main-color .colors:{opacity:0,transition:1s},.has-main-color .main-color:{position:absolute,transition:1s},.has-main-color:hover .main-color:{opacity:0},.has-main-color:hover .colors:{opacity:1},li:{display:flex !important,justify-content:center}},_:{examples:{count:0}},name:ui-input-background-color,template:div class\comp-ui-input-background-color\ path\-1102478111.\>div class\flex gap-2\ path\-1102478111.0\>div :class\{ has-main-color: (!!selectedMainColor) }\ path\-1102478111.0.0\>div class\main-color mb-l1\ v-if\(!!selectedMainColor)\ path\-1102478111.0.0.0\>ui-input-background-color-item :color-class\bg- + selectedMainColor\ :value\bg- + selectedMainColor\ path\-1102478111.0.0.0.0\>/ui-input-background-color-item>/div>ul class\colors\ path\-1102478111.0.0.1\>li v-for\color in colors\ on_click\selectMainColor(color)\ path\-1102478111.0.0.1.0\>ui-input-background-color-item :color-class\bg- + color\ :value\bg- + selectedMainColor\ path\-1102478111.0.0.1.0.0\>/ui-input-background-color-item>/li>/ul>/div>transition name\slide-hor\ path\-1102478111.0.1\>div v-if\selectedMainColor\ :style\{ width: 30em }\ path\-1102478111.0.1.0\>transition name\fade\ path\-1102478111.0.1.0.0\>div :key\selectedMainColor\ path\-1102478111.0.1.0.0.0\>div class\flex gap-2\ path\-1102478111.0.1.0.0.0.0\>div path\-1102478111.0.1.0.0.0.0.0\>div class\title\ v-text\shade\ path\-1102478111.0.1.0.0.0.0.0.0\>/div>ul path\-1102478111.0.1.0.0.0.0.0.1\>li v-for\shade in shades\ path\-1102478111.0.1.0.0.0.0.0.1.0\>ui-input-background-color-item :color-class\getShadeClass(selectedMainColor, shade)\ :value\selectedColorClass\ on_hover\onItemHover\ on_input\selectedColorClass $event\ path\-1102478111.0.1.0.0.0.0.0.1.0.0\>/ui-input-background-color-item>/li>/ul>/div>div path\-1102478111.0.1.0.0.0.0.1\>div class\title\ v-text\tranparent\ path\-1102478111.0.1.0.0.0.0.1.0\>/div>ul path\-1102478111.0.1.0.0.0.0.1.1\>li v-for\alpha in alphas\ path\-1102478111.0.1.0.0.0.0.1.1.0\>ui-input-background-color-item :color-class\getAlphaClass(selectedMainColor, alpha)\ :value\selectedColorClass\ on_hover\onItemHover\ on_input\selectedColorClass $event\ path\-1102478111.0.1.0.0.0.0.1.1.0.0\>/ui-input-background-color-item>/li>/ul>/div>div path\-1102478111.0.1.0.0.0.0.2\>div class\title\ v-text\gradient\ path\-1102478111.0.1.0.0.0.0.2.0\>/div>ul path\-1102478111.0.1.0.0.0.0.2.1\>li v-for\gradColor in gradColors\ path\-1102478111.0.1.0.0.0.0.2.1.0\>ui-input-background-color-item :color-class\getGradClass(selectedMainColor, gradColor)\ :value\selectedColorClass\ on_hover\onItemHover\ on_input\selectedColorClass $event\ :large\true\ path\-1102478111.0.1.0.0.0.0.2.1.0.0\>/ui-input-background-color-item>/li>/ul>/div>/div>/div>/transition>/div>/transition>/div>/div>}},{name:ui.input.boolean,path:\\ui\\input\\boolean.ws.yaml,source:{dom:{.flex:{div#1:{input:{type:checkbox,:value:value,on_input:$emit(input, $event.target.value)}},div#2:{v-text:text}}},props:{text:null,value:null},_:{examples:{count:0}}}},{name:ui.input.color,path:\\ui\\input\\color.ws.yaml,source:{dom:{input:{class:color-input,type:color,:value:value,on_input:$emit(input, $event.target.value)}},props:{value:null},style:{.color-input:{min-width:2em,min-height:2em}},desc:{value:Use v-model to bind to a color value.},example1:{dom:{div:{ui.color:{v-for:(color, i) in colors,v-model:colorsi}}},data:{colors:#ff0000,#00ff00,#0000ff}},name:ui-input-color,_:{examples:{count:0}},template:input class\comp-ui-input-color color-input\ type\color\ :value\value\ on_input\$emit(input, $event.target.value)\ path\498432997.\/>}},{name:ui.input.css.value,path:\\ui\\input\\css\\value.ws.yaml,source:{dom:{div:{.flex:{ui.input.range:{min:0,max:100,step:1,v-model:number}}}},props:{value:null},data:{number:null,unit:null},methods:{getCValue:function(number, unit) {\n if (number null) return null;\n return `${number||\\}${unit||\\}`;\n}\n},computed:{cValue:function() {\n return this.getCValue(this.number, this.unit);\n}\n},watch:{cValue:{handler:function(cValue) {\n this.$emit(input, cValue);\n}\n},value:{handler:function(value) {\n if (value this.cValue) return;\n this.number parseInt(value);\n this.unit (value?.replace(this.value1, ) || null);\n if (parseFloat(this.unit)) this.unit \%\;\n}\n,immediate:true,deep:true}},_:{examples:{count:0}},name:ui-input-css-value,template:div class\comp-ui-input-css-value\ path\-1335464632.\>div class\flex\ path\-1335464632.0\>ui-input-range max\100\ step\1\ v-model\number\ path\-1335464632.0.0\>/ui-input-range>/div>/div>}},{name:ui.input.font.size,path:\\ui\\input\\font\\size.ws.yaml,source:{dom:{.box0:{table:{tr:{v-for:(option, index) in options,:key:option,:class:getOptionCssClass(index),:style:{ font-size: option },on_mouseenter:onHoverItem(index, true),on_mouseleave:onHoverItem(index, false),on_click:onClickItem(index),td#1:{.opacity-50:{v-text:option}},td#2:{v-text:text}}}}},props:{value:null,text:Pack my box with five dozen liquor jugs},data:{options:},mounted:function() {\n this.options Array.from({ length: 23 }, (_, i) > this.getOptionValue(i));\n}\n,methods:{onHoverItem:function(index, isHover) {\n const value this.getOptionValue(index);\n this.$emit(value-preview, { index, value, isHover });\n}\n,onClickItem:async function(index) {\n let value this.getOptionValue(index);\n if (value this.value) value null;\n this.$emit(input, value);\n}\n,getOptionCssClass:function(index) {\n const cls {};\n const value this.getOptionValue(index);\n cls\opacity-40\ (value ! \100%\) && (value ! this.value);\n cls\selected\ (value this.value);\n return cls;\n}\n,getOptionValue:function(i) {\n return `${((0.8 + (i / 10)) * 100).toFixed(0)}%`;\n}\n},style:{.box0:{max-width:40em,max-height:20em,overflow-x:hidden,overflow-y:auto,white-space:nowrap},tr:hover:{background:#ffffff20},td:first-child:{padding:0 0.5em,text-align:center},.selected:{border:2px solid gray}},_:{examples:{count:0}},name:ui-input-font-size,template:div class\comp-ui-input-font-size box0\ path\951361986.\>table path\951361986.0\>tr v-for\(option, index) in options\ :key\option\ :class\getOptionCssClass(index)\ :style\{ font-size: option }\ on_mouseenter\onHoverItem(index, true)\ on_mouseleave\onHoverItem(index, false)\ on_click\onClickItem(index)\ path\951361986.0.0\>td path\951361986.0.0.0\>div class\opacity-50\ v-text\option\ path\951361986.0.0.0.0\>/div>/td>td v-text\text\ path\951361986.0.0.1\>/td>/tr>/table>/div>}},{name:ui.input.layout.direction,path:\\ui\\input\\layout\\direction.ws.yaml,source:{dom:{ui.input.layout.examples:{:options:options,:value:value,on_input:$emit(input, $event)}},props:{value:null},data:{options:{cssClass:flex-row justify-center,value:horizontal},{cssClass:flex-column justify-center,value:vertical}},_:{examples:{count:0}},name:ui-input-layout-direction,template:ui-input-layout-examples class\comp-ui-input-layout-direction\ :options\options\ :value\value\ on_input\$emit(input, $event)\ path\-1569384455.\>/ui-input-layout-examples>}},{name:ui.input.layout.example,path:\\ui\\input\\layout\\example.ws.yaml,source:{dom:{.flex:{:class:cssClass,.item:{v-for:(i, index) in itemsArray,div:{v-if:showNumber,v-text:(index + 1)}}}},props:{items:3,cssClass:null,showNumber:false},computed:{itemsArray:function() {\n return Array.from({ length: this.items });\n}\n},style:{.item:{display:flex,align-items:center,justify-content:center,width:5em,height:3em,background:#ffffff40,box-shadow:-4px 4px 4px black}},_:{examples:{count:0}}}},{name:ui.input.layout.examples,path:\\ui\\input\\layout\\examples.ws.yaml,source:{dom:{div#1:{.flex.examples.gap-1:{:class:mainFlexClass,div#2:{v-for:option in options,.option:{:class:{ selected: isSelected(option) },on_click:onClickOption(option),ui.input.layout.example:{:css-class:option.cssClass,:show-number:showNumber}},h3:{class:opacity-50 text-center,v-text:(option.text || option.value)}}}}},data:null,props:{direction:null,options:null,value:null,showNumber:null},methods:{onClickOption:function(option) {\n let value option?.value;\n if (value this.value) value null;\n this.$emit(input, value);\n}\n,isSelected:function(option) {\n return (option.value this.value);\n}\n},computed:{mainFlexClass:function() {\n const direction (this.direction \horizontal\ ? \row\ : \column\);\n return \flex\, direction.join(\-\);\n}\n},watch:null,style:{.option:{padding:1em 0,background:#ffffff20,opacity:0.6,cursor:pointer},.option:hover:{opacity:0.8},.option.selected, .option.selected:hover:{border:3px solid white,opacity:1}},_:{examples:{count:0}},name:ui-input-layout-direction,template:div class\comp-ui-input-layout-direction\ path\-1569384455.\>h2 v-text\value\ path\-1569384455.0\>/h2>div class\flex gap-3\ path\-1569384455.1\>div v-for\option in options\ :class\{ clickable: true, selected: isSelected(option) }\ on_click\onClickOption(option)\ path\-1569384455.1.0\>h3 class\text-center\ v-text\option.value\ path\-1569384455.1.0.0\>/h3>ui-input-layout-example :css-class\option.cssClass\ path\-1569384455.1.0.1\>/ui-input-layout-example>/div>/div>/div>}},{name:ui.input.layout.item.size,path:\\ui\\input\\layout\\item\\size.ws.yaml,source:{dom:{div#1:{div#2:{div#3:{h3#1:{v-text:width},ui.input.css.value#1:{v-model:size.width}},div#4:{h3#2:{v-text:height},ui.input.css.value#2:{v-model:size.height}}}}},props:{value:null},data:{size:null},watch:{size:{handler:function(size) {\n if (Objects.areEqual(size, this.value)) return;\n this.$emit(input, size);\n}\n,deep:true},value:{handler:function(value) {\n this.size Objects.clone(value || { width: null, height: null });\n}\n,immediate:true,deep:true}},_:{examples:{count:0}},name:ui-input-layout-item-size,template:div class\comp-ui-input-layout-item-size\ path\1501733494.\>div path\1501733494.0\>div path\1501733494.0.0\>h3 v-text\width\ path\1501733494.0.0.0\>/h3>ui-input-css-value v-model\size.width\ path\1501733494.0.0.1\>/ui-input-css-value>/div>div path\1501733494.0.1\>h3 v-text\height\ path\1501733494.0.1.0\>/h3>ui-input-css-value v-model\size.height\ path\1501733494.0.1.1\>/ui-input-css-value>/div>/div>/div>}},{name:ui.input.layout.justify,path:\\ui\\input\\layout\\justify.ws.yaml,source:{dom:{ui.input.layout.examples:{:style:{ width: 25em },direction:vertical,:options:options,:value:value,on_input:$emit(input, $event)}},props:{value:null},data:{options:{cssClass:null,value:start},{cssClass:null,value:end},{cssClass:null,value:center},{cssClass:null,value:between},{cssClass:null,value:around}},mounted:function() {\n for (const option of this.options) {\n option.cssClass `justify-${option.value}`;\n }\n}\n,_:{examples:{count:0}},name:ui-input-layout-justify,template:ui-input-layout-examples class\comp-ui-input-layout-justify\ :style\{ width: 25em }\ direction\vertical\ :options\options\ :value\value\ on_input\$emit(input, $event)\ path\41505162.\>/ui-input-layout-examples>}},{name:ui.input.layout.order,path:\\ui\\input\\layout\\order.ws.yaml,source:{dom:{ui.input.layout.examples:{:options:options,:value:value,:show-number:true,on_input:$emit(input, $event)}},props:{direction:null,value:null},data:{options:{cssClass:null,value:normal},{cssClass:null,value:reversed}},mounted:function() {\n for (const option of this.options) {\n const direction (this.direction \horizontal\ ? \row\ : \column\);\n const reverse ((option.value \reversed\) ? \reverse\ : \\)\n option.cssClass \flex\, direction, reverse\n .filter(s > s)\n .join(\-\);\n }\n}\n,_:{examples:{count:0}},name:ui-input-layout-order,template:ui-input-layout-examples class\comp-ui-input-layout-order\ :options\options\ :value\value\ :show-number\true\ on_input\$emit(input, $event)\ path\652600520.\>/ui-input-layout-examples>}},{name:ui.input.layout,path:\\ui\\input\\layout\\_.ws.yaml,source:{dom:{div:{h2:{ui.title:{icon:π§©,text:layout}},ui.tabs:{:options:𧩠direction, π order, π« item size, π« justify,direction:vertical,:can-select-none:true,template#1:{v-slot:tab0,ui.input.layout.direction:{v-model:direction}},template#2:{v-slot:tab1,ui.input.layout.order:{:direction:direction,v-model:order}},template#3:{v-slot:tab2,ui.input.layout.item.size:{v-model:item.size}},template#4:{v-slot:tab3,ui.input.layout.justify:{v-model:item.justify}}}}},props:{value:null},data:{direction:null,order:null,item:{size:null,justify:null}},computed:{layout:function() {\n return {\n direction: this.direction,\n order: this.order,\n item: {\n size: this.itemSize,\n justify: this.itemJustify,\n },\n };\n}\n},watch:{layout:{handler:function(layout) {\n if (Objects.areEqual(layout, this.value)) return;\n this.$emit(input, layout);\n}\n,deep:true},value:{handler:function(layout) {\n this.direction layout?.direction;\n this.order layout?.order;\n this.item layout?.item || { size: null, justify: null };\n}\n,immediate:true,deep:true}},_:{examples:{count:0}},name:ui-input-layout,template:div class\comp-ui-input-layout\ path\-1483325720.\>h2 path\-1483325720.0\>ui-title icon\π§©\ text\layout\ path\-1483325720.0.0\>/ui-title>/h2>ui-tabs :options\𧩠direction, π order, π« item size, π« justify\ direction\vertical\ :can-select-none\true\ path\-1483325720.1\>template v-slot\tab0\ path\-1483325720.1.0\>ui-input-layout-direction v-model\direction\ path\-1483325720.1.0.0\>/ui-input-layout-direction>/template>template v-slot\tab1\ path\-1483325720.1.1\>ui-input-layout-order :direction\direction\ v-model\order\ path\-1483325720.1.1.0\>/ui-input-layout-order>/template>template v-slot\tab2\ path\-1483325720.1.2\>ui-input-layout-item-size v-model\item.size\ path\-1483325720.1.2.0\>/ui-input-layout-item-size>/template>template v-slot\tab3\ path\-1483325720.1.3\>ui-input-layout-justify v-model\item.justify\ path\-1483325720.1.3.0\>/ui-input-layout-justify>/template>/ui-tabs>/div>}},{name:ui.input.range,path:\\ui\\input\\range.ws.yaml,source:{dom:{.flex:{div:{input:{type:range,:value:tempValue,:min:min,:max:max,:step:step,on_input:onValueChange},.text-center.opacity-50:{v-text:tempValue}},ui.button:{icon:βοΈ,on_click:setValue(null)}}},props:{text:null,value:null,min:null,max:null,step:null},data:{tempValue:null},methods:{setValue:function(value) {\n this.onValueChange({ target: { value } });\n}\n,onValueChange:async function(e) {\n const value (e.target.value null) ? null : parseInt(e.target.value);\n this.tempValue value;\n if (!this.__onValueChange) this.__onValueChange this._onValueChange.debounce(100);\n this.__onValueChange(value);\n}\n,_onValueChange:function(value) {\n this.$emit(input, value);\n}\n},watch:{value:{handler:function(value) {\n if (this._isInited) return;\n this._isInited true;\n this.tempValue value;\n}\n,immediate:true}},style:null,name:ui-input-range,_:{examples:{count:0}},template:div class\comp-ui-input-range flex\ path\511870399.\>div path\511870399.0\>input type\range\ :value\tempValue\ :min\min\ :max\max\ :step\step\ on_input\onValueChange\ path\511870399.0.0\/>div class\text-center opacity-50\ v-text\tempValue\ path\511870399.0.1\>/div>/div>ui-button icon\βοΈ\ on_click\setValue(null)\ path\511870399.1\>/ui-button>/div>}},{name:ui.input.slider,path:\\ui\\input\\slider.ws.yaml,source:{dom:{.slider:{:style:{ cursor: n-resize },on_mouseenter:contextIsVisible++,on_mouseleave:contextIsVisible--,on_mousedown:onMouseDown,v-drag:onDrag}},props:{value:null,orientation:null},data:{contextIsVisible:0},mounted:function () {\n document.addEventListener(\mouseup\, () > {\n this.$emit(\changing\, false);\n if (this.contextIsVisible) this.contextIsVisible--;\n });\n}\n,methods:{onMouseDown:function () {\n this.$emit(\changing\, true);\n this.contextIsVisible++;\n}\n,onDrag:function (e) {\n const delta false ? -e.deltaX : e.deltaY;\n this.$emit(\input\, (this.value - delta * 0.3), this.value);\n}\n},computed:{isHorizontal:function () {\n return (this.orientation \horizontal\);\n}\n},style:{.slider:{width:100%,height:100%,overflow:visible,cursor:n-resize}},name:ui-input-slider,_:{examples:{count:0}},template:div class\comp-ui-input-slider slider\ :style\{ cursor: n-resize }\ on_mouseenter\contextIsVisible++\ on_mouseleave\contextIsVisible--\ on_mousedown\onMouseDown\ v-drag\onDrag\ path\-1273250657.\>/div>}},{name:ui.input.text.box,path:\\ui\\input\\text\\box.ws.yaml,source:{dom:{div:{v-if:!multiline,:class:{ disabled: !enabled, camouflage },.icon:{v-if:icon,v-text:icon},input:{ref:input1,:class:{ hasIcon: icon },:style:textBoxStyle,:type:type,:placeholder:hint,:value:value,:disabled:!enabled,on_input:onInput}},textarea:{ref:textarea1,v-else-if:multiline,:value:value,:placeholder:hint,on_focus:$emit(focus),on_blur:$emit(blur),on_input:onTextAreaInput,on_keydown:onTextAreaKeyDown}},props:{type:text,value:null,hint:null,icon:null,enabled:true,multiline:false,autoResize:false,camouflage:false,textBoxStyle:null,debounce:0},data:{_onInput:null},methods:{onInput:function(e) {\n const self this;\n const input e.target;\n if (!this._onInput) this._onInput ((value) > {\n self.$emit(input, value);\n }).debounce(this.debounce);\n this._onInput(input.value);\n this.resizeInput(input);\n}\n,onTextAreaInput:function(e) {\n const textarea e.target;\n this.$emit(input, textarea.value);\n this.resizeTextArea(textarea);\n}\n,resizeInput:function(input) {\n if (!this.autoResize) return;\n if (!input) return;\n const chars (Math.max(input.value.length, 8) + 2);\n const width `${chars}ch`;\n input.style.width \\;\n input.style.width `${width}`;\n}\n,resizeTextArea:function(textarea, heightLimit) {\n if (!this.autoResize) return;\n heightLimit heightLimit || 200;\n let height Math.max(50, Math.min(textarea.scrollHeight, heightLimit));\n height `${height}px`;\n textarea.style.height \\;\n textarea.style.height `${height}`;\n} \n,onTextAreaKeyDown:function(e) {\n if (e.key Tab) {\n e.preventDefault();\n let start e.target.selectionStart;\n let end e.target.selectionEnd;\n let value e.target.value;\n e.target.value value.substring(0, start) + \ \ + value.substring(end);\n e.target.selectionStart e.target.selectionEnd start + 2;\n }\n return false;\n}\n},watch:{value:{handler:async function(value) {\n await this.$nextTick();\n this.resizeInput(this.$refs.input1);\n if (this.multiline) {\n this.resizeTextArea(this.$refs.textarea1);\n }\n}\n,immediate:true}},name:ui-input-text-box,style:{.camouflage:not(:hover) input, .camouflage:not(:hover) textarea:{border:none,background:no-repeat,box-shadow:none,opacity:0.5},input.hasIcon:{padding-left:2em !important},.icon:{position:absolute,margin:0.25em,width:fit-content}},_:{examples:{count:0}},template:div class\comp-ui-input-text-box\ v-if\!multiline\ :class\{ disabled: !enabled, camouflage }\ path\739613128.\>div class\icon\ v-if\icon\ v-text\icon\ path\739613128.0\>/div>input ref\input1\ :class\{ hasIcon: icon }\ :style\textBoxStyle\ :type\type\ :placeholder\hint\ :value\value\ :disabled\!enabled\ on_input\onInput\ path\739613128.1\/>/div>textarea ref\textarea1\ v-else-if\multiline\ :value\value\ :placeholder\hint\ on_focus\$emit(focus)\ on_blur\$emit(blur)\ on_input\onTextAreaInput\ on_keydown\onTextAreaKeyDown\>/textarea>}},{name:ui.json.editor,path:\\ui\\json\\editor.ws.yaml,source:{dom:{div:{ui.input.text.box:{:multiline:true,v-model:yaml,on_focus:isFocused true,on_blur:isFocused false},.error:{v-if:error,v-text:error}}},props:{value:null},data:{yaml:,isFocused:false,error:null},methods:{updateYamlFromObject:function() {\n let yaml jsyaml.dump(this.value);\n yaml yaml.replace(/ null/g, \\);\n this.yaml yaml;\n}\n},watch:{value:\n{\n handler: function() {\n if (this.isFocused) return;\n this.updateYamlFromObject();\n },\n immediate: true\n}\n,yaml:\n{\n handler() {\n try\n {\n this.error null;\n let jso jsyaml.load(this.yaml);\n this.$emit(input, jso);\n }\n catch (ex)\n {\n this.error ex.message;\n }\n }\n}\n,isFocused:\n{\n handler(newValue) {\n if (newValue) return;\n // While editing, were not updating the YAML from the object\n // because that would cause the cursor to jump around\n // When we lose focus, we update the YAML from the object\n this.updateYamlFromObject();\n }\n}\n},name:ui-json-editor,_:{examples:{count:0}},template:div class\comp-ui-json-editor\ path\-208761639.\>ui-input-text-area v-model\yaml\ on_focus\isFocused true\ on_blur\isFocused false\ path\-208761639.0\>/ui-input-text-area>div class\error\ v-if\error\ v-text\error\ path\-208761639.1\>/div>/div>}},{name:ui.keyboard,path:\\ui\\keyboard.ws.yaml,source:{dom:{div:null},data:{ctrl:false,alt:false},mounted:function() {\n // Capture all keyboard events\n window.addEventListener(\keydown\, this.onKeyDownOrUp);\n window.addEventListener(\keyup\, this.onKeyDownOrUp);\n}\n,methods:{onKeyDownOrUp:function(e) {\n this.ctrl e.ctrlKey;\n this.alt e.altKey;\n}\n},watch:{ctrl:function(ctrl) {\n this.$emit(ctrl, ctrl);\n}\n,alt:function(alt) {\n this.$emit(alt, alt);\n}\n},name:ui-keyboard,_:{examples:{count:0}},template:div class\comp-ui-keyboard\>/div>}},{name:ui.large.title,path:\\ui\\large\\title.ws.yaml,source:{dom:{.title:{v-text:text}},props:{text:null},style:{.title:{width:auto,min-height:1em,font-size:8vh,font-family:Times,line-height:0.8,padding:0 0 0.2em,-webkit-mask-image:-webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(0, 0, 0, 0.4)), color-stop(40%, rgba(0, 0, 0, 1)), color-stop(100%, rgba(0, 0, 0, 0.4))),white-space:normal,text-shadow:-3px 3px 3px black,z-index:30,transition:1s}},name:ui-large-title,_:{examples:{count:0}},template:div class\comp-ui-large-title title\ v-text\text\ path\-699352693.\>/div>}},{name:ui.leader.line,path:\\ui\\leader.line.ws.yaml,source:{dom:{ui.floating:{ref:floating1,v-if:true,:attach-to:middleLabelElement,attach-origin:center center,.leader-line-middle:{slot:{name:middle}}}},props:{from:null,to:null,visible:true,color:yellow,startPlug:null,endPlug:null,linePath:fluid},data:{leaderLine:null,leaderLineElement:null,middleLabelElement:null,flashColors:},mounted:this.redraw();\nthis.refresh();\n,unmounted:this.remove();\n,methods:{flash:function() {\n if (!this.leaderLine) return;\n const yellow \#606000\;\n this.flashColors this.tweenColors(yellow, this.color, 360);\n}\n,flashOneFrame:function() {\n if (!this.leaderLine) return;\n if (!this.flashColors.length) return;\n const color this.flashColors.shift();\n this.leaderLine.color color;\n if (!this.flashColors.length) return;\n requestAnimationFrame(() > this.flashOneFrame());\n}\n,refresh:function(again 2) {\n try\n {\n const fromEl this.getEdgeElement(this.from);\n const toEl this.getEdgeElement(this.to);\n\n if (!fromEl || !toEl) return this.remove();\n\n if (this.leaderLine && (this.leaderLine.start fromEl) && (this.leaderLine.end toEl))\n {\n this.redraw();\n return;\n }\n\n this.remove();\n\n if ((!fromEl) || (!toEl)) return this.remove();\n if (!fromEl.isConnected || !toEl.isConnected) return this.remove();\n\n const fromRect fromEl.getBoundingClientRect();\n const toRect toEl.getBoundingClientRect();\n\n if (!fromRect.x && !fromRect.y) return this.remove();\n if (!toRect.x && !toRect.y) return this.remove();\n\n this.leaderLine new LeaderLine(\n fromEl,\n toEl,\n {\n path: this.linePath,\n color: this.color,\n startPlug: this.startPlug,\n endPlug: this.endPlug,\n middleLabel: this.middleLabel,\n dropShadow: {\n dx: -3,\n dy: 3,\n blur: 0.2\n }\n }\n );\n\n // If fromEl or toEls DOM position changes, redraw the leader line\n this.$root.html.when.element.moves(fromEl, this.redraw.bind(this));\n this.$root.html.when.element.moves(toEl, this.redraw.bind(this));\n \n this.setVisibility(this.visible);\n }\n finally\n {\n if (again) setTimeout(() > { this.refresh(again - 1); }, 1000);\n }\n}\n,redraw:function(onlyOnce false) {\n if (this.leaderLine)\n {\n if (this.isConnected(this.leaderLine))\n {\n this.leaderLine.color this.color;\n this.leaderLine.position();\n }\n else\n {\n this.remove();\n }\n }\n\n if (this.$el.isConnected) {\n if (!onlyOnce)\n {\n //setTimeout(() > { this.redraw(false); }, 100);\n }\n }\n else\n {\n this.remove();\n }\n}\n,setVisibility:function(visible) {\n if (!this.leaderLine) return;\n if (visible) this.leaderLine.show();\n else this.leaderLine.hide();\n}\n,isConnected:function(leaderLine) {\n const fromEl leaderLine.start;\n const toEl leaderLine.end;\n return (fromEl.isConnected && toEl.isConnected);\n}\n,remove:function() {\n if (!this.leaderLine) return;\n this.leaderLine.remove();\n this.leaderLine null;\n}\n,getLeaderLineElement:function() {\n if (!this.leaderLine) return null;\n return document.getElementById(`leader-line-${this.leaderLine._id}-line-path`).parentElement.parentElement;\n}\n,getEdgeElement:function(vue) {\n const getElement () > {\n if (!vue) return null;\n if (typeof vue \function\) {\n const el vue();\n if (el?.$el) return el.$el;\n return el;\n }\n return vue;\n }\n const el getElement();\n return el;\n}\n,tweenColors:function(startColor, endColor, steps) {\n const start {\n r: parseInt(startColor.substring(1, 3), 16),\n g: parseInt(startColor.substring(3, 5), 16),\n b: parseInt(startColor.substring(5, 7), 16),\n };\n\n const end {\n r: parseInt(endColor.substring(1, 3), 16),\n g: parseInt(endColor.substring(3, 5), 16),\n b: parseInt(endColor.substring(5, 7), 16),\n };\n\n const step {\n r: (end.r - start.r) / (steps - 1),\n g: (end.g - start.g) / (steps - 1),\n b: (end.b - start.b) / (steps - 1),\n };\n\n const colors ;\n\n for (let i 0; i steps; i++) {\n const r Math.round(start.r + step.r * i).toString(16).padStart(2, 0);\n const g Math.round(start.g + step.g * i).toString(16).padStart(2, 0);\n const b Math.round(start.b + step.b * i).toString(16).padStart(2, 0);\n colors.push(`#${r}${g}${b}`);\n }\n\n return colors;\n}\n},computed:{middleLabel:function() {\n return `test`;\n}\n},watch:{from:function(from) {\n this.refresh();\n}\n,to:function(to) {\n this.refresh();\n}\n,color:function(newColor, oldColor) {\n this.flashColors this.tweenColors(oldColor, newColor, 120);\n}\n,flashColors:function(flashColors) {\n requestAnimationFrame(this.flashOneFrame.bind(this));\n}\n,visible:function(visible) {\n this.setVisibility(visible);\n}\n,leaderLine:function(leaderLine) {\n this.leaderLineElement this.getLeaderLineElement();\n}\n,leaderLineElement:function(leaderLineElement) {\n // Find the text> element with the text being the middle label\n const textElements leaderLineElement?.querySelectorAll(\text\);\n if (this.middleLabelElement textElements?.0) return;\n this.middleLabelElement textElements?.0;\n}\n},style:{.leader-line-middle:{display:flex,justify-content:center,align-items:center}},_:{examples:{count:0}},name:ui-leader-line,template:ui-floating class\comp-ui-leader-line\ ref\floating1\ v-if\true\ :attach-to\middleLabelElement\ attach-origin\center center\ path\125299039.\>div class\leader-line-middle\ path\125299039.0\>slot name\middle\ path\125299039.0.0\>/slot>/div>/ui-floating>}},{name:ui.link,path:\\ui\\link.ws.yaml,source:{dom:{a:{class:clickable2,:target:target,:href:(!enabled ? null : url),on_click:onClick,div:{v-if:text,v-text:text},slot:null}},props:{text:null,url:null,target:null,enabled:true},methods:{onClick:function(e) {\n if (!this.url) return;\n if (this.target) return;\n e.preventDefault();\n e.stopPropagation();\n this.$root.navigateTo(this.url);\n this.$emit(\navigate\, this.url);\n}\n},style:null,name:ui-link,_:{examples:{count:0}},template:a class\comp-ui-link clickable2\ :target\target\ :href\(!enabled ? null : url)\ on_click\onClick\ path\-484387052.\>div v-if\text\ v-text\text\ path\-484387052.0\>/div>slot>/slot>/a>}},{name:ui.linq.evaluator,path:\\ui\\linq\\evaluator.ws.yaml,source:{dom:{div:{ui.error:{v-for:error in errors,:error:error}}},props:{input:null,operation:null},data:{isDirty:0,output:null,errors:},methods:{evaluateOps:function(context, input, operations) {\n this.errors ;\n const datas ;\n datas.push(input);\n if (!operations?.length) return datas;\n let prevOperation null;\n for (const operation of operations) {\n try\n {\n const output this.evaluate(context, datas.last(), operation, prevOperation);\n datas.push(output);\n }\n catch (ex)\n {\n datas.push(datas.last());\n this.errors.push(ex.message);\n }\n prevOperation operation;\n }\n return datas;\n}\n,evaluate:function(context, input, operation, prevOperation) {\n if (!input) return null;\n if (!operation) return input;\n const method this`${operation.type}`.replace(/\\./g, \_\);\n if (!method) throw new Error(`Method ${operation.type} not found`);\n const args input, operation, prevOperation;\n if (operation.type \custom.expression\) args.unshift(context);\n const output method(...args);\n return output;\n}\n,select_field:function(input, op) {\n if (!op?.path?.length) return input;\n return Objects.getProperty(input, op?.path.join(\.\));\n}\n,select_fields:function(input, op) {\n if (!op?.fields?.length) return input;\n if (Array.isArray(input)) {\n return input.map(item > Objects.getObjectFields(item, op?.fields));\n }\n if (typeof input \object\) {\n return Objects.getObjectFields(input, op?.fields);\n }\n return input;\n}\n,flat_map:function(input, op) {\n if (!Array.isArray(input)) return input;\n const key1 Object.keys(input0)0;\n return input.flatMap(item > itemkey1);\n}\n,custom_expression:function(context, input, op, prevOperation) {\n if (!op?.func) return input;\n const func this.getFuncDecl(op.func);\n if (func.argNames.length > 1) throw new Error(\Custom expression can have at most one argument\);\n const argNames ;\n const argValues ;\n if (prevOperation.type \select.field\) {\n const field prevOperation.path.last();\n argNames.push(field);\n argValues.push(Objects.clone(input));\n }\n if (func.argNames.length) {\n argNames.push(func.argNames0);\n argValues.push(Objects.clone(input));\n }\n argNames.push(...Object.keys(context));\n argValues.push(...Objects.clone(Object.values(context)));\n const rtFunc eval(`(${argNames.join(\,\)}) > { ${func.body} }`);\n const output rtFunc(...argValues);\n return output;\n}\n,getFuncDecl:function(code) {\n // Initialize argNames and body\n let argNames ;\n let body code;\n\n // Regular expression to match the outermost function (function declaration or arrow function)\n const functionPattern /(function\\s*\\w*\\s*\\(^)*\\)|\\(^)*\\)\\s*>)\\s*{(\\s\\S*)}/;\n\n // Check if the code matches the function pattern\n const match code.match(functionPattern);\n\n if (match) {\n // Extract argument names\n const argsPattern /\\((^)*)\\)/;\n const argsMatch match1.match(argsPattern);\n\n if (argsMatch) {\n argNames argsMatch1.split(,).map(arg > arg.trim());\n }\n\n // Extract the body\n body match2;\n } else if (code.startsWith(\`\) && code.endsWith(\`\)) {\n // If code is \${...}\, add \return\ before it\n body `return ${code}`;\n }\n\n return { argNames, body };\n}\n,no_op:function(input, op) {\n return Objects.clone(input);\n}\n},watch:{output:{handler:function(output) {\n this.$emit(\output\, output);\n}\n},input:{handler:function(input) {\n this.isDirty++;\n}\n,immediate:true},operation:{handler:function(operation) {\n this.isDirty++;\n}\n,immediate:true,deep:true},isDirty:{handler:function() {\n this.output this.evaluate(this.input, this.operation);\n}\n}},_:{examples:{count:0}},name:ui-linq-evaluator,template:div class\comp-ui-linq-evaluator\ path\-1130530213.\>ui-error v-for\error in errors\ :error\error\ path\-1130530213.0\>/ui-error>/div>}},{name:ui.linq.no.op,path:\\ui\\linq\\no\\op.ws.yaml,source:{dom:{div#1:{v-if:operation,div#2:{v-text:no op}}},props:{input:null,value:null},data:{operation:null},methods:null,watch:{operation:{handler:function(operation) {\n this.$emit(\input\, operation);\n}\n,deep:true},value:{handler:function(value) {\n this.operation value;\n}\n,immediate:true}},_:{examples:{count:0}},name:ui-linq-no-op,template:div class\comp-ui-linq-no-op\ v-if\operation\ path\453366106.\>div v-text\no op\ path\453366106.0\>/div>/div>}},{name:ui.linq.operation.any,path:\\ui\\linq\\operation\\any.ws.yaml,source:{dom:{div:{v-if:operation,.box1:{component:{:is:getLinqCompName(operation.type),:context:context,:input:input,:prev-operation:prevOperation,v-model:operation}}}},props:{context:null,input:null,value:null,prevOperation:null},data:{operation:null},methods:{getLinqCompName:function(type) {\n return `ui.linq.ops.${type}`.replace(/\\./g, \-\);\n}\n},watch:{operation:{handler:function(operation) {\n this.$emit(\update\, operation);\n}\n,deep:true},value:{handler:function(value) {\n this.operation value;\n}\n,immediate:true}},_:{examples:{count:0}},name:ui-linq-operation-any,template:div class\comp-ui-linq-operation-any\ v-if\operation\ path\-320222959.\>div class\box1\ path\-320222959.0\>component :is\getLinqCompName(operation.type)\ :context\context\ :input\input\ :prev-operation\prevOperation\ v-model\operation\ path\-320222959.0.0\>/component>/div>/div>}},{name:ui.linq.operation,path:\\ui\\linq\\operation\\_.ws.yaml,source:{dom:{div:{ui.linq.operation.any:{:context:context,:input:input,:prev-operation:prevOperation,v-model:operation}}},props:{context:null,input:null,value:null,prevOperation:null},data:{operation:null},methods:null,watch:{operation:{handler:function(operation) {\n this.$emit(\input\, operation);\n}\n,deep:true},value:{handler:function(value) {\n this.operation value;\n}\n,immediate:true}},style:null,_:{examples:{count:0}},name:ui-linq-operation,template:div class\comp-ui-linq-operation\ path\-188258413.\>ui-linq-operation-any :context\context\ :input\input\ :prev-operation\prevOperation\ v-model\operation\ path\-188258413.0\>/ui-linq-operation-any>/div>}},{name:ui.linq.ops.custom.expression,path:\\ui\\linq\\ops\\custom\\expression.ws.yaml,source:{dom:{div#1:{v-if:operation,pre:{.flex#1:{div#2:{class:opacity-50 larger-text,v-text:function (},.flex#2:{v-for:(argName, index) in argNames,div#3:{ui.context.window:{ui.value:{:value:argValuesargName}},ui.title:{class:larger-text,icon:π§,:text:argName}},div#4:{v-if:(index (argNames.length - 1)),v-text:, }},div#5:{class:opacity-50 larger-text,v-text:) {}},ui.input.text.box:{:hint:hint,multiline:true,v-model:operation.func},div#6:{class:opacity-50 larger-text,v-text:}}}}},props:{context:null,input:null,value:null,prevOperation:null},data:{operation:null},methods:null,computed:{argValues:function() {\n const values {};\n valuesthis.argNames.first() this.input;\n for (const argName of this.contextArgNames) {\n valuesargName this.contextargName;\n }\n return values;\n}\n,argNames:function() {\n return ...this.operationArgNames, ...this.contextArgNames;\n}\n,hint:function() {\n let argName (this.contextArgNames.first() || this.operationArgNames.first());\n return `return ${argName}.name;`;\n}\n,operationArgNames:function() {\n if (this.input this.context?.this.contextArgNames.first()) return ;\n if (this.prevOperation) {\n const prev this.prevOperation;\n if (prev.type \select.field\) {\n return prev.path.last();\n }\n }\n return ;\n}\n,contextArgNames:function() {\n if (!this.context) return ;\n return Object.keys(this.context);\n}\n},watch:{operation:{handler:function(operation) {\n this.$emit(\input\, operation);\n}\n,deep:true},value:{handler:function(value) {\n this.operation value;\n}\n,immediate:true}},style:{.larger-text:{font-size:120%},pre:{font-size:120%,background:#303030}},_:{examples:{count:0}},name:ui-linq-ops-custom-expression,template:div class\comp-ui-linq-ops-custom-expression\ v-if\operation\ path\-1313227483.\>pre path\-1313227483.0\>div class\flex\ path\-1313227483.0.0\>div class\opacity-50 larger-text\ v-text\function (\ path\-1313227483.0.0.0\>/div>div class\flex\ v-for\(argName, index) in argNames\ path\-1313227483.0.0.1\>div path\-1313227483.0.0.1.0\>ui-context-window path\-1313227483.0.0.1.0.0\>ui-value :value\argValuesargName\ path\-1313227483.0.0.1.0.0.0\>/ui-value>/ui-context-window>ui-title class\larger-text\ icon\π§\ :text\argName\ path\-1313227483.0.0.1.0.1\>/ui-title>/div>div v-if\(index < (argNames.length - 1))\ v-text\, \ path\-1313227483.0.0.1.1\>/div>/div>div class\opacity-50 larger-text\ v-text\) {\ path\-1313227483.0.0.2\>/div>/div>ui-input-text-box :hint\hint\ multiline\true\ v-model\operation.func\ path\-1313227483.0.1\>/ui-input-text-box>div class\opacity-50 larger-text\ v-text\}\ path\-1313227483.0.2\>/div>/pre>/div>}},{name:ui.linq.ops.flat.map,path:\\ui\\linq\\ops\\flat\\map.ws.yaml,source:{dom:{div:{v-if:operation,.text-center:{v-text:flat map}}},props:{input:null,value:null},data:{operation:null},methods:null,watch:{operation:{handler:function(operation) {\n this.$emit(\input\, operation);\n}\n,deep:true},value:{handler:function(value) {\n this.operation value;\n}\n,immediate:true}},_:{examples:{count:0}},name:ui-linq-ops-flat-map,template:div class\comp-ui-linq-ops-flat-map\ v-if\operation\ path\2105344887.\>div class\text-center\ v-text\flat map\ path\2105344887.0\>/div>/div>}},{name:ui.linq.ops.picker,path:\\ui\\linq\\ops\\picker.ws.yaml,source:{dom:{div#1:{ui.context.window:{v-if:false,component:{v-if:hoveredOption,:is:getLinqCompName(hoveredOption.type),:input:input,:value:getOperation(hoveredOption)}},div#2:{v-for:option in options,.clickable:{v-if:(input && (eval(option.if))(input)),on_mouseenter:() > hoveredOption option,on_mouseleave:() > hoveredOption null,on_click:() > onClickOption(option),.flex.justify-center:{ui.title:{:icon:option.icon,:text:option.type}}}}}},props:{input:null},data:{hoveredOption:null,options:{icon:π§,type:select.field,default:{path:},if:(obj) > (typeof obj object && !Array.isArray(obj))},{icon:π«,type:select.fields,default:{fields:},if:(obj) > ((typeof obj object) && (Object.keys(obj).length > 1)) ||\n(Array.isArray(obj) && (Object.keys(obj0).length > 1))\n},{icon:β,type:flat.map,default:{},if:(obj) > Array.isArray(obj) && (Object.keys(obj0).length 1)},{icon:π΄,type:custom.expression,default:{func:null},if:(obj) > true}},computed:{eval:function() {\n return eval;\n}\n},methods:{getOperation:function(option) {\n const op {};\n op.type option.type;\n Object.assign(op, option.default);\n return op;\n}\n,getLinqCompName:function(type) {\n return `ui.linq.ops.${type}`.replace(/\\./g, -);\n}\n,onClickOption:function(option) {\n const op this.getOperation(option);\n this.$emit(select, op);\n}\n},_:{examples:{count:0}},name:ui-linq-ops-picker,template:div class\comp-ui-linq-ops-picker\ path\1581852318.\>ui-context-window v-if\false\ path\1581852318.0\>component v-if\hoveredOption\ :is\getLinqCompName(hoveredOption.type)\ :input\input\ :value\getOperation(hoveredOption)\ path\1581852318.0.0\>/component>/ui-context-window>div v-for\option in options\ path\1581852318.1\>div class\clickable\ v-if\(input && (eval(option.if))(input))\ on_mouseenter\() > hoveredOption option\ on_mouseleave\() > hoveredOption null\ on_click\() > onClickOption(option)\ path\1581852318.1.0\>div class\flex justify-center\ path\1581852318.1.0.0\>ui-title :icon\option.icon\ :text\option.type\ path\1581852318.1.0.0.0\>/ui-title>/div>/div>/div>/div>}},{name:ui.linq.ops.select.field,path:\\ui\\linq\\ops\\select\\field.ws.yaml,source:{dom:{div:{v-if:operation,ui.value.path.picker:{:obj:input,v-model:operation.path}}},props:{input:null,value:null},data:{operation:null},methods:null,watch:{operation:{handler:function(operation) {\n this.$emit(\input\, operation);\n}\n,deep:true},value:{handler:function(value) {\n this.operation value;\n}\n,immediate:true}},_:{examples:{count:0}},name:ui-linq-ops-select-field,template:div class\comp-ui-linq-ops-select-field\ v-if\operation\ path\1698785176.\>ui-value-path-picker :obj\input\ v-model\operation.path\ path\1698785176.0\>/ui-value-path-picker>/div>}},{name:ui.linq.ops.select.fields,path:\\ui\\linq\\ops\\select\\fields.ws.yaml,source:{dom:{div:{v-if:operation,ui.value.field.picker:{:obj:fieldsObj,v-model:operation.fields}}},props:{input:null,value:null},data:{operation:null},methods:null,computed:{fieldsObj:function() {\n if (Array.isArray(this.input)) return this.input0;\n return this.input;\n}\n},watch:{operation:{handler:function(operation) {\n this.$emit(\input\, operation);\n}\n,deep:true},value:{handler:function(value) {\n this.operation value;\n}\n,immediate:true}},_:{examples:{count:0}},name:ui-linq-ops-select-fields,template:div class\comp-ui-linq-ops-select-fields\ v-if\operation\ path\1122733019.\>ui-value-field-picker :obj\fieldsObj\ v-model\operation.fields\ path\1122733019.0\>/ui-value-field-picker>/div>}},{name:ui.linq,path:\\ui\\linq\\_.ws.yaml,source:{dom:{div#1:{.operations.box1:{div#2:{div#3:{v-for:(operation, index) in operations,:key:operation._id,div#4:{.show-on-hover-container:{.operation:{ui.linq.operation:{:context:context,:input:datas?.index,:value:operation,:prev-operation:operationsindex - 1,on_input:(operation) > $set(operations, index, operation)},.delete-button.show-on-hover-2:{ui.button:{:icon:isConfirmedindex ? β : β,on_click:onClickDelete(index)}}}},.next:{v-text:β}}}},div#5:{.show-on-hover-container:{div#6:{.text-center:{v-text:β}},.show-on-hover:{ui.linq.ops.picker:{:input:datas?.last(),on_select:addOperation}}}},ui.linq.evaluator:{ref:evaluator1}}}},props:{context:null,input:null,value:null},data:{operations:,datas:,isConfirmed:{}},mounted:,methods:{onClickDelete:function(index) {\n if (this.isConfirmedindex) return this.operations.splice(index, 1);\n this.$set(this.isConfirmed, index, true);\n setTimeout(() > this.$delete(this.isConfirmed, index), 1000);\n}\n,evaluateChain:function() {\n this.datas this.$refs.evaluator1?.evaluateOps(this.context, this.input, this.operations);\n}\n,addOperation:function(operation) {\n if (!operation._id) operation._id (this.operations.length + 1);\n this.operations.add(operation);\n}\n},watch:{input:{handler:async function(input) {\n await this.$nextTick();\n this.evaluateChain();\n}\n,immediate:true},operations:{handler:async function(operations) {\n this.evaluateChain();\n this.$emit(\input\, operations);\n}\n,deep:true},value:{handler:function(operations) {\n this.operations (operations || );\n}\n,immediate:true}},style:{.operations.box1:null,.operation:{display:flex,justify-items:center,gap:1em,width:fit-content,margin:auto},.delete-button:{max-width:0},.show-on-hover-container:hover .delete-button:{max-width:5em},.value-preview:{display:flex,justify-content:center,max-height:10em,overflow-x:hidden,overflow-y:auto},.value-preview > *:{max-width:15em,max-height:10em},.value-preview .value-as-string:{max-width:15em},.show-on-hover-container:hover > .show-on-hover.hor:{max-width:3em},.next:{font-size:160%,text-align:center}},_:{examples:{count:0}},name:ui-linq,template:div class\comp-ui-linq\ path\-484387046.\>div class\operations box1\ path\-484387046.0\>div path\-484387046.0.0\>div v-for\(operation, index) in operations\ :key\operation._id\ path\-484387046.0.0.0\>div path\-484387046.0.0.0.0\>div class\show-on-hover-container\ path\-484387046.0.0.0.0.0\>div class\operation\ path\-484387046.0.0.0.0.0.0\>ui-linq-operation :context\context\ :input\datas?.index\ :value\operation\ :prev-operation\operationsindex - 1\ on_input\(operation) > $set(operations, index, operation)\ path\-484387046.0.0.0.0.0.0.0\>/ui-linq-operation>div class\delete-button show-on-hover-2\ path\-484387046.0.0.0.0.0.0.1\>ui-button :icon\isConfirmedindex ? β : β\ on_click\onClickDelete(index)\ path\-484387046.0.0.0.0.0.0.1.0\>/ui-button>/div>/div>/div>div class\next\ v-text\β\ path\-484387046.0.0.0.0.1\>/div>/div>/div>/div>div path\-484387046.0.1\>div class\show-on-hover-container\ path\-484387046.0.1.0\>div path\-484387046.0.1.0.0\>div class\text-center\ v-text\β\ path\-484387046.0.1.0.0.0\>/div>/div>div class\show-on-hover\ path\-484387046.0.1.0.1\>ui-linq-ops-picker :input\datas?.last()\ on_select\addOperation\ path\-484387046.0.1.0.1.0\>/ui-linq-ops-picker>/div>/div>/div>ui-linq-evaluator ref\evaluator1\ path\-484387046.0.2\>/ui-linq-evaluator>/div>/div>}},{name:ui.list,path:\\ui\\list.ws.yaml,source:{dom:{div#1:{transition.group:{tag:ul,name:list,:class:getMainCssClass(),li:{v-for:indexedItem in visibleItems,:key:_getItemKey(indexedItem.item),:class:getCssClass(indexedItem.index),div#2:{v-html:getItemText(indexedItem.item)},slot:{:index:indexedItem.index,:item:indexedItem.item},on_mouseenter:() > onItemHover(indexedItem),on_mouseleave:() > onItemHover({ item: null, index: null }),on_click:() > onItemClick(indexedItem)}}}},props:{items:null,value:null,valueType:index,selectedIndex:null,direction:vertical,isItemVisible:null,getItemKey:null,canSelectNone:true},data:{mySelectedIndex:null},methods:{_isItemVisible:function(item) {\n if (this.isItemVisible) return this.isItemVisible(item);\n return true;\n}\n,_getItemKey:function(item) {\n if (item.id) return item.id;\n const stringKey (typeof item string) ? item : JSON.stringify(item);\n if (this.getItemKey) return this.getItemKey(item) || stringKey;\n return this.$root.getKey(item) || stringKey;\n}\n,getItemText:function(item) {\n if (this.$slots.default) return null;\n if (this.$scopedSlots.default) return null;\n if (typeof item string) return item;\n return item;\n}\n,getMainCssClass:function() {\n const cls {\n menu3: true,\n };\n clsthis.direction true;\n return cls;\n}\n,onItemHover:function(e) {\n this.$emit(item-hover, e);\n}\n,onItemClick:function(e) {\n const newIndex (e.index this.mySelectedIndex) ? null : e.index;\n if ((newIndex null) && !this.canSelectNone) return;\n this.mySelectedIndex newIndex;\n const value (this.valueType index) ? newIndex : this.itemsnewIndex;\n this.$emit(input, value);\n}\n,getCssClass:function(index) {\n return {\n selected: (index this.mySelectedIndex),\n };\n}\n},computed:{visibleItems:function() {\n return (this.items||)\n .map((item, index) > ({\n item,\n index,\n }))\n .filter((item) > this._isItemVisible(item.item));\n}\n,index:function() {\n return this.mySelectedIndex;\n}\n,item:function() {\n if (!this.items) return null;\n return this.itemsthis.mySelectedIndex;\n}\n},watch:{value:{handler:function(value) {\n this.mySelectedIndex (this.valueType index) ? value : this.items.indexOf(value);\n}\n,immediate:true},selectedIndex:{handler:function() {\n this.mySelectedIndex this.selectedIndex;\n}\n,immediate:true}},name:ui-list,style:{.horizontal:{display:flex,flex-direction:row},.horizontal > *:{flex-grow:1,text-align:center}},_:{examples:{count:0}},template:div class\comp-ui-list\ path\-484386888.\>transition-group tag\ul\ name\list\ :class\getMainCssClass()\ path\-484386888.0\>li v-for\indexedItem in visibleItems\ :key\_getItemKey(indexedItem.item)\ :class\getCssClass(indexedItem.index)\ on_mouseenter\() > onItemHover(indexedItem)\ on_mouseleave\() > onItemHover({ item: null, index: null })\ on_click\() > onItemClick(indexedItem)\ path\-484386888.0.0\>div v-html\getItemText(indexedItem.item)\ path\-484386888.0.0.0\>/div>slot :index\indexedItem.index\ :item\indexedItem.item\ path\-484386888.0.0.1\>/slot>/li>/transition-group>/div>}},{name:ui.loading,path:\\ui\\loading.ws.yaml,source:{dom:{transition:{name:slide2,.flex.justify-center:{v-if:show,img:{class:loading,:src:$root.loadingImageUrl},.timer:{v-if:showMs,.number:{v-text:elapsedNumber},.unit:{v-text:elapsedUnit}}}}},props:{show:true,showMs:false},data:{isRunning:true,started:null,elapsed:0},mounted:function() {\n this.start();\n}\n,unmounted:function() {\n this.stop();\n}\n,methods:{start:function() {\n this.started Date.now();\n this.ms 0;\n this.isRunning true;\n this.updateElapsed();\n}\n,stop:function() {\n this.isRunning false;\n}\n,updateElapsed:function() {\n if (!this.isRunning) return;\n this.elapsed Math.round((Date.now() - this.started));\n //setTimeout(this.updateElapsed.bind(this), 100);\n}\n},computed:{elapsedUnitified:function() {\n if (!this.elapsed) return null;\n if (this.elapsed 1000) return `${this.elapsed}ms`;\n if (this.elapsed 60 * 1000) return `${(this.elapsed / 1000).toFixed(1)}s`;\n return `${(this.elapsed / 1000).toFixed(1)}s`;\n}\n,elapsedNumber:function() {\n return parseFloat(this.elapsedUnitified);\n}\n,elapsedUnit:function() {\n return this.elapsedUnitified?.replace(this.elapsedNumber, \\);\n}\n},watch:{show:{handler:function(show) {\n if (show) {\n this.start();\n }\n}\n,immediate:true}},style:{.timer:{font-size:80%,opacity:0.4,white-space:nowrap},.number:{color:green},.unit:null,.loading:{max-width:min-content}},name:ui-loading,_:{examples:{count:0}},template:transition class\comp-ui-loading\ name\slide2\ path\875113442.\>div class\flex justify-center\ v-if\show\ path\875113442.0\>img class\loading\ :src\$root.loadingImageUrl\ path\875113442.0.0\/>div class\timer\ v-if\showMs\ path\875113442.0.1\>div class\number\ v-text\elapsedNumber\ path\875113442.0.1.0\>/div>div class\unit\ v-text\elapsedUnit\ path\875113442.0.1.1\>/div>/div>/div>/transition>}},{name:ui.mouse,path:\\ui\\mouse.ws.yaml,source:{dom:{div:{slot:null}},props:{global:false,ctrlRightClick:true},data:{pos:{},hoveredElement:null,posQueue:,isMounted:false,dragStart:null,posSmoother:null,smoothPos:null,moveThrottleRate:0.01},mounted:function() {\n this.isMounted true;\n this.bindToElement();\n}\n,unmounted:function() {\n this.isMounted false;\n alertify.message(\unmounted\);\n}\n,methods:{bindToElement:function() {\n const element this.getElement();\n if (!element) {\n setTimeout(this.bindToElement.bind(this), 100);\n return;\n }\n element.addEventListener(\mousedown\, this.onMouseDown);\n element.addEventListener(\mouseup\, this.onMouseUp);\n window.addEventListener(\mousemove\, this.onMouseMove.throttle(this, this.moveThrottleRate * 1000));\n element.addEventListener(\contextmenu\, this.onContextMenu);\n}\n,onMouseDown:function(e) {\n if (!this.global && e.target.tagName ! \DIV\) return;\n if (e.button ! 0) return;\n if (this.dragStart) return;\n this.dragStart { x: e.clientX, y: e.clientY };\n this.$emit(\down\, e);\n}\n,onMouseUp:function(e) {\n if (e.button ! 0) return;\n this.dragStart null;\n this.$emit(\up\, e);\n}\n,onMouseMove:function(e) {\n const pos { x: e.clientX, y: e.clientY };\n if (Objects.areEqual(this.pos, pos)) return;\n this.pos pos;\n}\n,onContextMenu:function(e) {\n if (this.ctrlRightClick && !e.ctrlKey) return;\n //e.preventDefault();\n e.stopPropagation();\n this.$emit(\right-click\, e);\n}\n,updateHoveredElement:function(pos) {\n if (!this.__updateHoveredElement) this.__updateHoveredElement this._updateHoveredElement.throttle(this, 400);\n this.__updateHoveredElement(pos);\n}\n,_updateHoveredElement:function(pos) {\n var el document.elementFromPoint(pos.x, pos.y);\n this.hoveredElement el;\n}\n,onPosChanged:async function(pos) {\n this.$emit(\move\, pos);\n if (this.dragStart) {\n const delta { dx: pos.x - this.dragStart.x, dy: pos.y - this.dragStart.y };\n this.dragStart pos;\n this.$emit(\drag\, delta);\n }\n}\n,getElement:function() {\n return (this.global ? window : this.$el.parentElement);\n}\n,cancelEvent:function(e) {\n e.preventDefault();\n e.stopPropagation();\n}\n},watch:{pos:{handler:function(pos) {\n //if (!this.posSmoother) this.posSmoother new MovingPositionSmoother(pos, (this.moveThrottleRate * 2), this.onPosChanged.bind(this));\n //this.posSmoother.updateThrottled(pos);\n this.onPosChanged(pos);\n this.updateHoveredElement(pos);\n}\n,deep:false},hoveredElement:function(newHoveredElement) {\n this.$emit(\hovered-element\, newHoveredElement);\n}\n},name:ui-mouse,_:{examples:{count:0}},template:div class\comp-ui-mouse\ path\-2129987381.\>slot>/slot>/div>}},{name:ui.movable,path:\\ui\\movable.ws.yaml,source:{dom:{.movable:{:class:{ enabled: enabled },on_mousedown:onMouseDown,on_mousemove:onMouseMove,on_mouseup:onMouseUp,on_mouseout:onMouseUp,slot:null}},props:{value:null,enabled:true},data:{isDragging:false,dragStart:null,dragStartPos:null},mounted:function() {\n}\n,methods:{onMouseDown:function(e) {\n if (!this.enabled) return;\n if (e.button ! 0) return;\n\n e.preventDefault();\n e.stopPropagation();\n\n this.isDragging true;\n this.dragStart { x: e.clientX, y: e.clientY };\n}\n,onMouseMove:function(e) {\n if (!this.enabled) return;\n if (!this.isDragging) return;\n\n e.preventDefault();\n e.stopPropagation();\n\n const dx e.clientX - this.dragStart.x;\n const dy e.clientY - this.dragStart.y;\n\n const normalizedDrag {\n dx: dx / this.$el.parentElement.offsetWidth,\n dy: dy / this.$el.parentElement.offsetHeight\n };\n \n const normalizedScale -(dy / this.$el.parentElement.offsetHeight) * 2;\n\n if (this.value)\n {\n const trans JSON.parse(JSON.stringify(this.value));\n if (e.ctrlKey)\n {\n trans.scale + normalizedScale;\n }\n else\n {\n const pos trans.pos;\n pos.x + normalizedDrag.dx;\n pos.y + normalizedDrag.dy;\n }\n this.$emit(input, trans);\n }\n\n if (e.ctrlKey)\n {\n this.$emit(\scale-by\, normalizedScale);\n }\n else\n {\n this.$emit(\drag-by\, normalizedDrag);\n }\n\n this.dragStart { x: e.clientX, y: e.clientY };\n}\n,onMouseUp:function(e) {\n if (!this.enabled) return;\n e.preventDefault();\n e.stopPropagation();\n\n this.isDragging false;\n}\n},style:{.movable.enabled:{cursor:move},.movable:{user-select:none}},name:ui-movable,_:{examples:{count:0}},template:div class\comp-ui-movable movable\ :class\{ enabled: enabled }\ on_mousedown\onMouseDown\ on_mousemove\onMouseMove\ on_mouseup\onMouseUp\ on_mouseout\onMouseUp\ path\1781914900.\>slot>/slot>/div>}},{name:ui.notifications,path:\\ui\\notifications.ws.yaml,source:{dom:{div#1:{transition.group:{name:list,.note:{v-for:note in notes,:key:note.id,ui.button:{class:close-button,text:β,on_click:deleteNote(note)},ui.link:{:url:$root.itemToUrl(note.item),on_navigate:deleteNote(note),div#2:{v-if:note.text,v-text:note.text},component:{v-if:note.componentName,:is:note.componentName.replace(., -),:item:note.item,:note:true}}}}}},data:{notes:,noteID:1},mounted:function() {\n this.$root.$on(notify, (note) > {\n note.id this.noteID++;\n this.notes.push(note);\n });\n}\n,methods:{deleteNote:function(note) {\n this.notes this.notes.filter(n > n.id ! note.id);\n}\n},style:{.note:{background:#303030,padding:1em,box-shadow:-1em 1em 2em #000, 1px -1px 1px gray},.close-button:{width:min-content;,position:absolute;,z-index:1000;,right:-0.5em;,top:-0.5em;,box-shadow:-0.5em 0.5em 1em #000}},example1:{dom:{div:{ui.button:{text:Notify,on_click:notify}}},methods:{notify:function() {\n this.$root.$emit(\notify\, {\n text: \Notification from button click\\n });\n return;\n this.$refs.notes1.notify({\n componentName: ui.text,\n item: {\n text: Hello World\n }\n });\n}\n}},name:ui-notifications,_:{examples:{count:0}},template:div class\comp-ui-notifications\ path\-732312818.\>transition-group name\list\ path\-732312818.0\>div class\note\ v-for\note in notes\ :key\note.id\ path\-732312818.0.0\>ui-button class\close-button\ text\β\ on_click\deleteNote(note)\ path\-732312818.0.0.0\>/ui-button>ui-link :url\$root.itemToUrl(note.item)\ on_navigate\deleteNote(note)\ path\-732312818.0.0.1\>div v-if\note.text\ v-text\note.text\ path\-732312818.0.0.1.0\>/div>component v-if\note.componentName\ :is\note.componentName.replace(., -)\ :item\note.item\ :note\true\ path\-732312818.0.0.1.1\>/component>/ui-link>/div>/transition-group>/div>}},{name:ui.num,path:\\ui\\num.ws.yaml,source:{dom:{.flex:{div:{v-text:number},.letter:{v-text:unit}}},props:{value:null},data:null,computed:{humanized:function() {\n return this.value?.humanize();\n}\n,number:function() {\n // Get everything except the unit\n return this.humanized?.match(/^a-zA-Z+/)?.first();\n}\n,unit:function() {\n return this.humanized?.match(/a-zA-Z+/)?.first();\n}\n},methods:null,style:{.flex:{align-items:baseline;},.letter:{font-size:70%;,opacity:0.4;}},name:ui-num,_:{examples:{count:0}},template:div class\comp-ui-num flex\ path\-846907092.\>div v-text\number\ path\-846907092.0\>/div>div class\letter\ v-text\unit\ path\-846907092.1\>/div>/div>}},{name:ui.number,path:\\ui\\number.ws.yaml,source:{dom:{.card:{.top:{.icon:{v-text:icon},.number:{v-text:formatNumber(value)},.unit:{v-text:unit}},.text:{v-text:text}}},props:{value:null,icon:null,text:null,unit:null},methods:{formatNumber:function(number) {\n if (number null) return null;\n if (typeof number string) number parseFloat(number);\n return number.toLocaleString();\n}\n},style:{.card:{line-height:1,display:inline-block},.card > div:{text-align:center},.top:{display:flex,align-items:baseline,margin:auto,width:min-content,white-space:nowrap},.number:{font-size:100%},.unit:{font-size:90%,opacity:0.4},.icon:{font-size:100%,margin:auto},.text:{font-size:110%,opacity:0.6,line-height:1.2em}},name:ui-number,_:{examples:{count:0}},template:div class\comp-ui-number card\ path\-1571183645.\>div class\top\ path\-1571183645.0\>div class\icon\ v-text\icon\ path\-1571183645.0.0\>/div>div class\number\ v-text\formatNumber(value)\ path\-1571183645.0.1\>/div>div class\unit\ v-text\unit\ path\-1571183645.0.2\>/div>/div>div class\text\ v-text\text\ path\-1571183645.1\>/div>/div>}},{name:ui.pager,path:\\ui\\pager.ws.yaml,source:{dom:{.pager-buttons:{.pager-button:{v-for:i in getPageIndexes(pageCount),v-text:(i + 1),:class:{ selected: (i value) },on_click:onClickPage(i)}}},props:{itemsCount:null,pageSize:null,value:null},methods:{getPageIndexes:function(pageCount) {\n return Array.from({ length: pageCount }, (v, i) > i);\n}\n,onClickPage:function(pageIndex) {\n this.$emit(\input\, pageIndex);\n}\n},computed:{pageCount:function() {\n return Math.ceil(this.itemsCount / this.pageSize);\n}\n},style:{.pager-buttons:{display:flex,justify-content:center,gap:0.5em},.pager-button:{padding:0.5em 1em,border-radius:0.5em,background:#80808030,cursor:pointer},.pager-button:hover:{background:#80808040},.pager-button.selected, .pager-button.selected:hover:{background:#80808080 !important}},_:{examples:{count:0}}}},{name:ui.section,path:\\ui\\section.ws.yaml,source:{dom:{div#1:{ui.expand:{:text:title,:value:(opposite ^ value),on_input:$emit(input, (opposite ^ $event))},transition:{name:slide2,div#2:{v-show:(opposite ^ value),slot:null}}}},props:{title:null,value:null,opposite:false},name:ui-section,_:{examples:{count:0}},template:div class\comp-ui-section\ path\-1786263157.\>ui-expand :text\title\ :value\(opposite ^ value)\ on_input\$emit(input, (opposite ^ $event))\ path\-1786263157.0\>/ui-expand>transition name\slide2\ path\-1786263157.1\>div v-show\(opposite ^ value)\ path\-1786263157.1.0\>slot>/slot>/div>/transition>/div>}},{name:ui.select,path:\\ui\\select.ws.yaml,source:{dom:{div#1:{div#2:{:style:{ max-width: ((direction horizontal) ? null : null) },ui.input.text.box:{v-if:showSearchBox,icon:π,type:search,:hint:searchHint,v-model:query},.list-container:{div#3:{v-if:(typetoggle),transition:{name:slide2,.clickable:{:key:valueIndex,v-html:getOptionText(valueIndex),on_click:toggleValue($event, +1),on_contextmenu:toggleValue($event, -1)}}},select:{v-if:(typedropdown),option:{v-for:(item, index) in options,:value:index,v-html:item},:value:valueIndex,on_input:onInput(parseInt($event.target.value))},ui.list:{v-if:(typelist),v-slot:slotProps,:items:options,:selected-index:valueIndex,:direction:direction,:is-item-visible:_isOptionVisible,:get-item-key:_getItemKey,:can-select-none:canSelectNone,template:{slot:{:item:slotProps.item},ui.title:{v-if:showText,:icon:_getItemIcon(slotProps.item),:html:__getItemText(slotProps.item),:number:_getItemNumber(slotProps.item)}},on_item-hover:onItemHover($event),on_input:onInput($event)}}}}},props:{options:null,value:0,inputType:index,direction:vertical,showText:true,searchHint:null,showSearch:null,type:list,itemIcon:null,isOptionVisible:null,getItemIcon:null,getItemText:null,getItemNumber:null,getItemTooltip:null,getItemKey:null,canSelectNone:true},data:{query:null},methods:{_isOptionVisible:function(item) {\n const isQueryFilter (this.query && this.query.length) ? this.__getItemText(item).toLowerCase().includes(this.query.toLowerCase()) : true;\n const isOptionVisibleFilter this.isOptionVisible ? this.isOptionVisible(item) : true;\n return isQueryFilter && isOptionVisibleFilter;\n}\n,getOptionText:function(index) {\n let s this.optionsindex;\n if (this.getItemText) s this.getItemText(s);\n if (this.itemIcon) s `${this.itemIcon} ${s}`;\n if (this.type \toggle\) {\n if (s?.length > 2) s `${s}`;\n }\n return s;\n}\n,getOptionTooltip:function(index) {\n if (this.getItemTooltip) return this.getItemTooltip(this.optionsindex);\n return null;\n}\n,onItemHover:function(e) {\n this.$emit(\item-hover\, e);\n}\n,onInput:function(index) {\n const value this.inputType \index\ ? index : this.optionsindex;\n if (this.value value) value null;\n this.$emit(\input\, value);\n}\n,_getItemKey:function(item) {\n if (this.getItemKey) return this.getItemKey(item);\n if (this.getItemText) return this.getItemText(item);\n return this.item;\n}\n,_getItemIcon:function(item) {\n if (this.getItemIcon) return this.getItemIcon(item);\n return null;\n}\n,__getItemText:function(item) {\n let s this._getItemText(item);\n if (this.itemIcon) s `${this.itemIcon} ${s}`;\n return s;\n}\n,_getItemText:function(item) {\n if (this.getItemText) return this.getItemText(item);\n const text item;\n return text;\n}\n,_getItemNumber:function(item) {\n if (this.getItemNumber) return this.getItemNumber(item);\n return null;\n}\n,toggleValue:function(e, delta) {\n e.preventDefault();\n e.stopPropagation();\n const index this.valueIndex;\n let newIndex (index + delta) % this.options.length;\n if (newIndex 0) newIndex this.options.length - 1;\n this.onInput(newIndex);\n}\n},computed:{valueIndex:function() {\n if (this.inputType \index\) return this.value;\n return this.options?.indexOf(this.value);\n}\n,showSearchBox:function() {\n if (typeof this.showSearch \boolean\) return this.showSearch;\n return (this.type \list\ && this.options?.length > 10);\n}\n},watch:{query:function() {\n this.$emit(\input:query\, this.query);\n}\n},name:ui-select,style:{div:{white-space:nowrap},.list-container:{max-height:30em;,overflow-x:hidden;,overflow-y:auto;},.comp-ui-list:{user-select:none},li:{margin:0 !important,padding:0.2em 0.5em},li.selected:{border:1px solid #ffffff80,box-shadow:-6px 6px 6px black},li div:{white-space:nowrap},.clickable:{text-align:center,user-select:none,padding:0 0.5em},.clickable:hover:{background:#ffffff20}},_:{examples:{count:0}},template:div class\comp-ui-select\ path\-1442841194.\>div :style\{ max-width: ((direction horizontal) ? null : null) }\ path\-1442841194.0\>ui-input-text-box v-if\showSearchBox\ icon\π\ type\search\ :hint\searchHint\ v-model\query\ path\-1442841194.0.0\>/ui-input-text-box>div class\list-container\ path\-1442841194.0.1\>div v-if\(typetoggle)\ path\-1442841194.0.1.0\>transition name\slide2\ path\-1442841194.0.1.0.0\>div class\clickable\ :key\valueIndex\ v-html\getOptionText(valueIndex)\ on_click\toggleValue($event, +1)\ on_contextmenu\toggleValue($event, -1)\ path\-1442841194.0.1.0.0.0\>/div>/transition>/div>select v-if\(typedropdown)\ :value\valueIndex\ on_input\onInput(parseInt($event.target.value))\ path\-1442841194.0.1.1\>option v-for\(item, index) in options\ :value\index\ v-html\item\ path\-1442841194.0.1.1.0\>/option>/select>ui-list v-if\(typelist)\ v-slot\slotProps\ :items\options\ :selected-index\valueIndex\ :direction\direction\ :is-item-visible\_isOptionVisible\ :get-item-key\_getItemKey\ :can-select-none\canSelectNone\ on_item-hover\onItemHover($event)\ on_input\onInput($event)\ path\-1442841194.0.1.2\>template path\-1442841194.0.1.2.0\>slot :item\slotProps.item\ path\-1442841194.0.1.2.0.0\>/slot>ui-title v-if\showText\ :icon\_getItemIcon(slotProps.item)\ :html\__getItemText(slotProps.item)\ path\-1442841194.0.1.2.0.1\>/ui-title>/template>/ui-list>/div>/div>/div>}},{name:ui.share,path:\\ui\\share.ws.yaml,source:{dom:{.flex.justify-around:{.a2a_kit.a2a_kit_size_32.a2a_default_style:{:data-a2a-url:url,:data-a2a-title:imageUrl,a#1:{class:a2a_dd,href:https://www.addtoany.com/share},a#2:{class:a2a_button_facebook},a#3:{class:a2a_button_twitter},a#4:{class:a2a_button_email},ui.link:{:url:url,:text:π,:target:_blank}}}},props:{item:null},mounted:function() {\n this.$nextTick(() > {\n a2a.init(page);\n });\n setTimeout(() > {\n a2a.init(page);\n }, 1000);\n}\n,computed:{url:function() {\n return (this.$root.url.item(this.item, true));\n}\n,imageUrl:function() {\n return this.$root.url.itemImage(this.item, true);\n}\n},style:{.a2a_kit:{width:fit-content},.comp-ui-link:{position:relative,top:0.25em,font-size:160%}},name:ui-share,_:{examples:{count:0}},template:div class\comp-ui-share flex justify-around\ path\-2124674043.\>div class\a2a_kit a2a_kit_size_32 a2a_default_style\ :data-a2a-url\url\ :data-a2a-title\imageUrl\ path\-2124674043.0\>a class\a2a_dd\ href\https://www.addtoany.com/share\ path\-2124674043.0.0\>/a>a class\a2a_button_facebook\ path\-2124674043.0.1\>/a>a class\a2a_button_twitter\ path\-2124674043.0.2\>/a>a class\a2a_button_email\ path\-2124674043.0.3\>/a>ui-link :url\url\ :text\π\ :target\_blank\ path\-2124674043.0.4\>/ui-link>/div>/div>}},{name:ui.sticky,path:\\ui\\sticky.ws.yaml,source:{dom:{div:{:style:getStyle(),slot:null}},data:null,mounted:function() {\n}\n,methods:{getStyle:\nfunction() {\n return {\n top: this.top\n };\n}\n},props:{top:null},computed:null,style:{.comp-ui-sticky:{position:sticky,z-index:10}},name:ui-sticky,_:{examples:{count:0}},template:div class\comp-ui-sticky\ :style\getStyle()\ path\-1429079421.\>slot>/slot>/div>}},{name:ui.table,path:\\ui\\table.ws.yaml,source:{dom:{.card:{table:{thead:{th:{v-for:key in Object.keys(tableData0),v-text:key}},tbody:{tr:{v-for:item in tableData,on_click:itemClick(item),td:{v-for:key in Object.keys(item),.content:{v-text:itemkey}}}}}}},props:{icon:null,title:null,data:{default:}},methods:{itemClick:\nfunction(item) {\n this.$emit(item-click, item);\n}\n},computed:{tableData:\nfunction() {\n if (!this.data?.length) return ;\n if (this.data.map(v > typeof v).find(t > t number)) {\n return this.data.map(value > ({ value }));\n }\n return this.data;\n}\n},style:{.content:{height:1.5em,overflow:hidden},tr:hover:{background-color:null},td:{padding-right:1em}},name:ui-table,_:{examples:{count:0}},template:div class\comp-ui-table card\ path\-2123958284.\>table path\-2123958284.0\>thead path\-2123958284.0.0\>th v-for\key in Object.keys(tableData0)\ v-text\key\ path\-2123958284.0.0.0\>/th>/thead>tbody path\-2123958284.0.1\>tr v-for\item in tableData\ on_click\itemClick(item)\ path\-2123958284.0.1.0\>td v-for\key in Object.keys(item)\ path\-2123958284.0.1.0.0\>div class\content\ v-text\itemkey\ path\-2123958284.0.1.0.0.0\>/div>/td>/tr>/tbody>/table>/div>}},{name:ui.tabs,path:\\ui\\tabs.ws.yaml,source:{dom:{div#1:{:class:class1,:style:style1,ui.select:{:class:{ corner: (typetoggle) },:options:(options||).map(option > _getOptionHtml(option)),:getUrl:getUrl,:direction:direction,:type:type,:show-search:showSearch,:can-select-none:canSelectNone,on_item-hover:onItemHover,v-model:selectedTabIndex},div#2:{class:flex-grow-1,slot#1:{name:header},div#3:{v-for:(option, index) in options,class:not-selected,transition:{:name:(transitionName||defaultTransitionName),.tab:{v-if:(index activeIndex),:style:getTabStyle(index),slot#2:{:name:tab + index}}}}}}},props:{options:null,getOptionText:null,getOptionHtml:null,getUrl:null,direction:vertical,value:null,transitionName:null,showSearch:null,canSelectNone:false},data:{hoveredTabIndex:null,selectedTabIndex:0},methods:{getTabStyle:function(index) {\n const style {};\n if (index this.selectedTabIndex) {\n style.opacity \1 !important\;\n }\n return style;\n}\n,onItemHover:function(e) {\n this.hoveredTabIndex e.index;\n}\n,_getOptionHtml:function(option) {\n const getOptionHtml (option) > {\n if (this.getOptionHtml) return this.getOptionHtml(option);\n if (this.getOptionText) return this.getOptionText(option)?.textToHtml();\n return option;\n }\n let html getOptionHtml(option);\n if (jpg, jpeg, png.some(ext > html.endsWith(. + ext))) {\n html `img src\${html}\ />`;\n }\n return html;\n}\n},computed:{activeIndex:function() {\n if (this.selectedTabIndex ! null) return this.selectedTabIndex;\n return this.hoveredTabIndex;\n}\n,defaultTransitionName:function() {\n if (this.direction vertical) return slide-hor-ver;\n return slide;\n}\n,type:function() {\n if (this.direction toggle) return toggle;\n return list;\n}\n,class1:function() {\n const cls {};\n clsthis.direction true;\n return cls;\n}\n,style1:function() {\n const style {};\n style.display flex;\n style.flexDirection ((this.direction \vertical\) ? \row\ : \column\);\n style.gap \1em\;\n return style;\n}\n},watch:{direction:{handler:function(direction) {\n //this.selectedTabIndex null;\n}\n,immediate:true},selectedTabIndex:{handler:function(newIndex) {\n this.$emit(input, newIndex);\n}\n,immediate:true},hoveredTabIndex:{handler:function(newIndex) {\n if (!this.options) return;\n this.$emit(option-hover, newIndex);\n}\n,immediate:true},value:{handler:function(value) {\n if (!this.options) return;\n const newIndex value;\n if (newIndex this.selectedTabIndex) return;\n this.selectedTabIndex newIndex;\n}\n,immediate:true}},style:{.not-selected .tab:{opacity:0.3 !important},.menu3.vertical li:{display:flex},.menu3.vertical li::after:{content:β―,opacity:0.1 !important,margin-left:2em,flex-grow:1,text-align:right},.comp-ui-select div:{width:100%},.comp-ui-select img:{display:block,width:1.5em,aspect-ratio:1,margin:auto},.comp-ui-select:{margin-bottom:0.1em},.corner:{position:absolute,z-index:10,transform:scale(1.5),top:-0.6em,right:-1em},li:{margin-bottom:0}},name:ui-tabs,_:{examples:{count:0}},template:div class\comp-ui-tabs\ :class\class1\ :style\style1\ path\-484156776.\>ui-select :class\{ corner: (typetoggle) }\ :options\(options||).map(option > _getOptionHtml(option))\ :getUrl\getUrl\ :direction\direction\ :type\type\ :show-search\showSearch\ :can-select-none\canSelectNone\ on_item-hover\onItemHover\ v-model\selectedTabIndex\ path\-484156776.0\>/ui-select>div class\flex-grow-1\ path\-484156776.1\>slot name\header\ path\-484156776.1.0\>/slot>div class\not-selected\ v-for\(option, index) in options\ path\-484156776.1.1\>transition :name\(transitionName||defaultTransitionName)\ path\-484156776.1.1.0\>div class\tab\ v-if\(index activeIndex)\ :style\getTabStyle(index)\ path\-484156776.1.1.0.0\>slot :name\tab + index\ path\-484156776.1.1.0.0.0\>/slot>/div>/transition>/div>/div>/div>}},{name:ui.time,path:\\ui\\time.ws.yaml,source:{dom:{.opacity-20:{v-text:timeAgo(value)}},props:{value:null},style:{.comp-ui-time:{text-shadow:-2px 2px 1px #000000}},methods:{timeAgo:\nfunction (dt) {\n dt new Date(dt);\n const now new Date();\n const seconds Math.round(Math.abs((now - dt) / 1000));\n const minutes Math.round(Math.abs(seconds / 60));\n const hours Math.round(Math.abs(minutes / 60));\n const days Math.round(Math.abs(hours / 24));\n if (Number.isNaN(seconds)) {\n return ;\n }\n if (seconds 45) {\n return a few seconds ago;\n }\n if (seconds 90) {\n return a minute ago;\n }\n if (minutes 60) {\n return minutes + \ minutes ago\;\n }\n if (hours 24) {\n return hours + \ hours ago\;\n }\n return ;\n if (days 7) {\n return days + \ days ago\;\n }\n if (days 30) {\n return Math.round(days / 7) + \ weeks ago\;\n }\n if (days 365) {\n return Math.round(days / 30) + \ months ago\;\n }\n return Math.round(days / 365) + \ years ago\;\n}\n},name:ui-time,_:{examples:{count:0}},template:div class\comp-ui-time opacity-20\ v-text\timeAgo(value)\ path\-484148761.\>/div>}},{name:ui.title,path:\\ui\\title.ws.yaml,source:{dom:{div#1:{on_click:$emit(click),class:flex justify-between,:class:{ wrap },.counter:{v-if:hasCounter,v-text:(counter) + .},.icon:{:class:iconClass,v-if:icon,v-text:icon},.text:{slot:null,div#2:{v-html:cHtml}},.number.ml-1.opacity-40:{v-if:number,v-text:getNumberText()}}},props:{counter:null,icon:null,text:null,html:null,value:null,number:null,largeIcon:false,wrap:true},methods:{getNumberText:function() {\n if (this.number undefined) return ;\n if (this.number null) return ;\n if (typeof this.number \number\) return this.number.humanize();\n return this.number;\n}\n,getIconClass:function() {\n const cls ;\n if (this.icon \π\) cls.push(\opacity-50\);\n if (this.largeIcon) cls.push(\fs-l1\);\n return cls.join( );\n}\n},computed:{hasCounter:function() {\n return (this.counter ! null) && (this.counter ! undefined);\n}\n,cHtml:function() {\n if (this.html) return this.html;\n return this.text, this.value\n .filter(s > s)\n .join( )\n .textToHtml();\n}\n,iconClass:function() {\n return this.getIconClass();\n}\n},style:{.counter:{opacity:0.3},.icon:{text-align:center},.flex:{gap:0.5em},.text:{flex-grow:1 !important},.number:null,div:not(.wrap):{white-space:nowrap,text-wrap:nowrap}},name:ui-title,_:{examples:{count:0}},template:div class\comp-ui-title flex\ on_click\$emit(click)\ path\-2123702658.\>div class\counter\ v-if\hasCounter\ v-text\(counter) + .\ path\-2123702658.0\>/div>div class\icon\ :class\iconClass\ v-if\icon\ v-text\icon\ path\-2123702658.1\>/div>div path\-2123702658.2\>slot>/slot>div v-html\cHtml\ path\-2123702658.2.1\>/div>/div>div class\ml-1 opacity-40\ v-if\number\ v-text\getNumberText()\ path\-2123702658.3\>/div>/div>}},{name:ui.tooltip,path:\\ui\\tooltip.ws.yaml,source:{dom:{ui.context.window:{:semi-transparent:false,pinnable:false,slot:null,:get-context-element:getContextElement}},_:{examples:{count:0}},methods:{getContextElement:function() {\n return this.$el.parentElement;\n}\n},name:ui-tooltip,template:ui-context-window class\comp-ui-tooltip\ :semi-transparent\false\ :get-context-element\getContextElement\ path\-601613655.\>slot>/slot>/ui-context-window>}},{name:ui.track.size,path:\\ui\\track\\size.ws.yaml,source:{dom:{div:{ref:div1,slot:null}},data:{size:null},mounted:function () {\n window.addEventListener(`resize`, this.recalc.bind(this));\n // Detect if the image element changes its size\n let resizeObserver new ResizeObserver(this.recalc.bind(this));\n resizeObserver.observe(this.$refs.div1);\n}\n,methods:{recalc:function () {\n if (!this.$refs.div1) return;\n let rect this.$refs.div1.getBoundingClientRect();\n const width this.width Math.round(rect.width);\n const height this.height Math.round(rect.height);\n const diagonal Math.round(Math.sqrt(width * width + height * height));\n const size this.size { width, height, diagonal };\n this.$emit(\input\, size);\n}\n},name:ui-track-size,_:{examples:{count:0}},template:div class\comp-ui-track-size\ ref\div1\ path\759638622.\>slot>/slot>/div>}},{name:ui.tree.node,path:\\ui\\tree.node.ws.yaml,source:{dom:{div#1:{.tree-node:{:class:getCssClass(),ui.expand:{class:opacity-50,v-if:showUiExpand,v-model:isExpanded},div#2:{class:w-l2,v-if:!showUiExpand},component:{v-if:itemType,:is:getItemType(),:item:getItem(node),v-bind:itemProps},on_click:onNodeClick,on_dblclick:onNodeDoubleClick,on_mouseenter:onMouseEnter,on_mouseleave:onMouseLeave,on_dragenter:onMouseEnter,on_dragleave:onMouseLeave,on_dragover:onMouseEnter,on_dragout:onMouseLeave,slot:null},transition:{name:slide-fast,ul:{v-if:isExpanded,class:ml-3,li:{v-for:child in getChildItems(node),ui.tree.node:{:node:child,:depth:(depth + 1),:initial-expanded:initialExpanded,:expandable:expandable,:item-type:getItemType(),:get-item:getItem,:get-item-key:getItemKey,:get-children:getChildren,:selected-node:selectedNode,:item-props:itemProps,on_node-click:onChildClick,on_node-hover:onChildHover,on_node-unhover:onChildUnhover,on_node-hovered:onChildHovered}}}}}},props:{node:null,depth:null,initialExpanded:false,expandable:true,itemType:null,getItem:null,getItemKey:null,getChildren:null,selectedNode:null,itemProps:null},data:{isInited:false,isExpanded:null},methods:{getCssClass:function() {\n return {\n hoverable: true,\n selected: this.isSelected,\n expandable: this.expandable,\n };\n}\n,onNodeClick:function() {\n if (this.isSelected)\n {\n //this.children null;\n }\n else\n {\n this.children this.getChildren(this.node);\n }\n const node Objects.areEqual(this.node, this.selectedNode) ? null : this.node;\n this.$emit(node-click, node);\n}\n,onNodeDoubleClick:function() {\n this.isExpanded !this.isExpanded;\n}\n,onMouseEnter:function() {\n this.$emit(node-hover, this.node);\n this.$emit(\node-hovered\, this.node, true);\n}\n,onMouseLeave:function() {\n this.$emit(node-unhover, this.node);\n this.$emit(\node-hovered\, this.node, false);\n}\n,onChildClick:function(child) {\n this.$emit(node-click, child);\n}\n,onChildHover:function (child) {\n this.$emit(node-hover, child);\n this.$emit(\node-hovered\, child, true);\n}\n,onChildUnhover:function (child) {\n this.$emit(node-unhover, child);\n this.$emit(\node-hovered\, child, false);\n}\n,onChildHovered:function (child, isHovered) {\n this.$emit(\node-hovered\, child, isHovered);\n}\n,getItemType:function() {\n return this.itemType?.replace(/\\./g, -);\n}\n,getChildItems:function(node) {\n if (!this.isExpanded) return ;\n return this.getChildren(node);\n}\n},computed:{isSelected:function() {\n return Objects.areEqual(this.node, this.selectedNode);\n}\n,showUiExpand:function() {\n if (!this.node) return false;\n if (!this.getChildren(this.node)?.length) return false;\n return this.expandable;\n}\n},watch:{initialExpanded:{handler:function(newVal, oldVal) {\n if (this.isInited) return;\n this.isInited true;\n this.isExpanded (typeof newVal boolean) ? !!newVal : (this.depth newVal);\n}\n,immediate:true}},style:{.tree-node:{display:flex,padding-right:1em,user-select:none},.tree.node.expandable:{display:grid,grid-template:1fr / 1.5em 1fr},.comp-ui-expand:{margin-right:0.3em},.comp-ui-expand .icon:{font-size:100% !important,border:none !important},li:{transition:0.3s !important}},name:ui-tree-node,_:{examples:{count:0}},template:div class\comp-ui-tree-node\ path\2053324664.\>div class\tree-node\ :class\getCssClass()\ on_click\onNodeClick\ on_dblclick\onNodeDoubleClick\ on_mouseenter\onMouseEnter\ on_mouseleave\onMouseLeave\ on_dragenter\onMouseEnter\ on_dragleave\onMouseLeave\ on_dragover\onMouseEnter\ on_dragout\onMouseLeave\ path\2053324664.0\>ui-expand class\opacity-50\ v-if\showUiExpand\ v-model\isExpanded\ path\2053324664.0.0\>/ui-expand>div class\w-l2\ v-if\!showUiExpand\ path\2053324664.0.1\>/div>component v-if\itemType\ :is\getItemType()\ :item\getItem(node)\ v-bind\itemProps\ path\2053324664.0.2\>/component>slot>/slot>/div>transition name\slide-fast\ path\2053324664.1\>ul class\ml-3\ v-if\isExpanded\ path\2053324664.1.0\>li v-for\child in getChildItems(node)\ path\2053324664.1.0.0\>ui-tree-node :node\child\ :depth\(depth + 1)\ :initial-expanded\initialExpanded\ :expandable\expandable\ :item-type\getItemType()\ :get-item\getItem\ :get-item-key\getItemKey\ :get-children\getChildren\ :selected-node\selectedNode\ :item-props\itemProps\ on_node-click\onChildClick\ on_node-hover\onChildHover\ on_node-unhover\onChildUnhover\ on_node-hovered\onChildHovered\ path\2053324664.1.0.0.0\>/ui-tree-node>/li>/ul>/transition>/div>}},{name:ui.tree.example0,path:\\ui\\tree.example0.ws.yaml,source:{dom:{ui.tree:{:root:root,div:null}},data:{root:null},mounted:function() {\n this.root ({\n item: \root\,\n children: \n {\n item: \node 1\,\n children: \n { item: \node 1.1\ }\n \n },\n {\n item: \node 2\,\n children: \n { item: \node 2.1\ }\n \n }\n \n });\n}\n}},{name:ui.tree,path:\\ui\\tree.ws.yaml,source:{dom:{ul:{v-if:root,li:{ui.tree.node:{:node:root,:depth:0,:initial-expanded:initialExpanded,:expandable:initialExpandable,:item-type:itemType,:get-item:getItem || ((node) > node?.item),:get-item-key:getItemKey || $root.getKey,:get-children:getChildren || ((node) > node.children||),:selected-node:selectedNode,:item-props:itemProps,on_node-click:onChildClick,on_node-hover:onChildHover,on_node-unhover:onChildUnhover,on_node-hovered:onChildHovered}}}},props:{root:null,initialExpanded:false,expandable:true,itemType:null,getItem:null,getItemKey:null,getChildren:null,itemProps:null},data:{selectedNode:null},methods:{selectNode:function(node) {\n this.selectedNode node;\n}\n,onChildClick:function(child) {\n this.$emit(node-click, child);\n this.selectedNode (child this.selectedNode) ? null : child;\n}\n,onChildHover:function (child) {\n this.$emit(node-hover, child);\n}\n,onChildUnhover:function (child) {\n this.$emit(node-unhover, child);\n}\n,onChildHovered:function (child, isHovered) {\n this.$emit(node-hovered, child, isHovered);\n}\n},computed:{initialExpandable:function() {\n if (typeof this.initialExpanded boolean) return !this.initialExpanded;\n return this.expandable;\n}\n,depth:function() {\n return 0;\n}\n},watch:{selectedNode:function(newVal, oldVal) {\n this.$emit(node-select, newVal);\n}\n},style:{ul.comp-ui-tree:{max-height:50vh,scroll:auto,padding:0 2em 0 0}},example:{dom:{ui.tree:{:root:root,div:null}},data:{root:null},mounted:function() {\n this.root ({\n item: \root\,\n children: \n {\n item: \node 1\,\n children: \n { item: \node 1.1\ }\n \n },\n {\n item: \node 2\,\n children: \n { item: \node 2.1\ }\n \n }\n \n });\n}\n},name:ui-tree,_:{examples:{count:1}},template:ul class\comp-ui-tree\ v-if\root\ path\-484140360.\>li path\-484140360.0\>ui-tree-node :node\root\ :depth\0\ :initial-expanded\initialExpanded\ :expandable\initialExpandable\ :item-type\itemType\ :get-item\getItem || ((node) > node?.item)\ :get-item-key\getItemKey || $root.getKey\ :get-children\getChildren || ((node) > node.children||)\ :selected-node\selectedNode\ :item-props\itemProps\ on_node-click\onChildClick\ on_node-hover\onChildHover\ on_node-unhover\onChildUnhover\ on_node-hovered\onChildHovered\ path\-484140360.0.0\>/ui-tree-node>/li>/ul>}},{name:ui.tween,path:\\ui\\tween.ws.yaml,source:{dom:{.slots:{:class:{ hide: !slotsAreVisible },div:{ref:vSlots,v-for:i in 0, 1,:class:getSlotClass(i),slot:{:name:slot + i}}}},props:{visibleIndex:0},data:{visibleIndex1:0,slotsAreVisible:true},methods:{transitionSlots:function(e) {\n e?.preventDefault();\n e?.stopPropagation();\n const duration 1000;\n const sourceIndex this.visibleIndex1;\n const targetIndex (sourceIndex + 1) % 2;\n // Find tween elements, meaning that they transition to each other.\n // Find all class names that begin with tween- on the elements\n const sourceElements ...this.$refs.vSlotssourceIndex.querySelectorAll(*);\n const targetElements ...this.$refs.vSlotstargetIndex.querySelectorAll(*);\n const sourceTweenElements sourceElements.filter(el > ...el.classList.some(cls > cls.startsWith(tween-)));\n const targetTweenElements targetElements.filter(el > ...el.classList.some(cls > cls.startsWith(tween-)));\n const sourceTweenClasses sourceTweenElements.flatMap(el > ...el.classList.filter(cls > cls.startsWith(tween-)));\n const targetTweenClasses targetTweenElements.flatMap(el > ...el.classList.filter(cls > cls.startsWith(tween-)));\n const tweenClasses ...sourceTweenClasses, ...targetTweenClasses.distinct();\n\n // Find all the pairs of elements that have the same tween class\n const tweenPairs tweenClasses.map(cls > {\n const sourceEl sourceTweenElements.find(el > el.classList.contains(cls));\n const targetEl targetTweenElements.find(el > el.classList.contains(cls));\n const opacity {\n start: parseFloat(window.getComputedStyle(sourceEl).opacity),\n end: parseFloat(window.getComputedStyle(targetEl).opacity),\n }\n return { sourceEl, targetEl, opacity };\n });\n\n const vSourceSlot this.$refs.vSlotssourceIndex;\n const vTargetSlot this.$refs.vSlotstargetIndex;\n\n this.slotsAreVisible false;\n\n // Hide the original tween pair elements (since were tweening their clones)\n //for (const { sourceEl, targetEl } of tweenPairs) {\n // sourceEl.style.visibility hidden;\n // targetEl.style.visibility hidden;\n //}\n\n for (const { sourceEl, targetEl, opacity } of tweenPairs) {\n this.tween(sourceEl, sourceEl, targetEl, opacity, duration);\n this.tween(targetEl, sourceEl, targetEl, opacity, duration);\n }\n this.fade(vSourceSlot, duration, 1, 0);\n this.fade(vTargetSlot, duration, 0, 1);\n setTimeout(() > {\n this.visibleIndex1 targetIndex;\n this.slotsAreVisible true;\n // Show the original tween pair elements\n //for (const { sourceEl, targetEl } of tweenPairs) {\n // sourceEl.style.visibility ;\n // targetEl.style.visibility ;\n //}\n }, (duration - 100));\n}\n,tween:function(el, sourceEl, targetEl, opacity, duration) {\n const tweenValue this.tweenValue;\n\n const startTime Date.now();\n\n const startRect sourceEl.getBoundingClientRect();\n const endRect targetEl.getBoundingClientRect();\n\n const startFontSize parseFloat(window.getComputedStyle(el).fontSize);\n const scaleFont endRect.width / startRect.width;\n const endFontSize startFontSize * scaleFont;\n\n const documentScrollLeft1 document.documentElement.scrollLeft;\n const documentScrollTop1 document.documentElement.scrollTop;\n\n // Clone the element and set its styles\n const cloneEl el.cloneNode(true);\n this.copyStyle(cloneEl, el);\n cloneEl.style.position fixed;\n cloneEl.style.top `${startRect.top}px`;\n cloneEl.style.left `${startRect.left}px`;\n cloneEl.style.transformOrigin top left;\n cloneEl.style.opacity opacity.start;\n cloneEl.style.visibility ;\n document.body.appendChild(cloneEl);\n\n function animate() {\n const elapsed Date.now() - startTime;\n const progress Math.min(elapsed / duration, 1);\n\n let x tweenValue(startRect.left, endRect.left, progress);\n x + (documentScrollLeft1 - document.documentElement.scrollLeft);\n let y tweenValue(startRect.top, endRect.top, progress);\n y + (documentScrollTop1 - document.documentElement.scrollTop);\n const width tweenValue(startRect.width, endRect.width, progress);\n const height tweenValue(startRect.height, endRect.height, progress);\n const opacityValue tweenValue(opacity.start, opacity.end, progress);\n const fontSize tweenValue(startFontSize, endFontSize, progress);\n\n cloneEl.style.top `${y}px`;\n cloneEl.style.left `${x}px`;\n cloneEl.style.width `${width}px`;\n cloneEl.style.height `${height}px`;\n cloneEl.style.opacity opacityValue;\n //cloneEl.style.fontSize `${fontSize}px`;\n\n if (progress 1) {\n // Hide the original element\n if (el.style.visibility ! hidden) setTimeout(() > {\n el.style.visibility hidden;\n }, 10);\n requestAnimationFrame(animate);\n } else {\n // Animation is done, revert to original styles\n document.body.removeChild(cloneEl); // Remove the cloned element\n el.style.visibility ; // Show the original element\n }\n }\n\n requestAnimationFrame(animate);\n}\n,fade:function(el, duration, startOpacity 1, endOpacity 0) {\n const startTime Date.now();\n const originalOpacity window.getComputedStyle(el).opacity; // Get the original opacity before animation\n\n const tweenValue this.tweenValue;\n\n function animate() {\n const elapsed Date.now() - startTime;\n const progress Math.min(elapsed / duration, 1);\n const opacity tweenValue(startOpacity, endOpacity, progress);\n\n el.style.opacity opacity;\n\n if (progress 1) {\n requestAnimationFrame(animate);\n } else {\n // Animation is done, revert to original opacity\n //el.style.opacity originalOpacity;\n }\n }\n\n requestAnimationFrame(animate);\n}\n,tweenValue:function(startValue, endValue, progress) {\n // Cubic ease-in-out function\n function cubicEaseInOut(t) {\n return t 0.5\n ? 4 * t * t * t\n : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;\n }\n const easedProgress cubicEaseInOut(progress);\n return startValue + (endValue - startValue) * easedProgress;\n}\n,copyStyle:function(targetEl, sourceEl) {\n let computedStyle window.getComputedStyle(sourceEl);\n computedStyle Object.keys(computedStyle)\n .filter(k > parseInt(k) ! k)\n .toMapValue(k > computedStylek);\n Object.assign(targetEl.style, computedStyle);\n}\n,getSlotClass:function(i) {\n const cls {};\n cls.slot true;\n if (i this.visibleIndex1) {\n clsvisible true;\n }\n return cls;\n}\n},watch:{visibleIndex:{handler:function() {\n this.transitionSlots();\n}\n}},style:{.hide, .hide *:{visibility:hidden !important},.slot:{position:absolute,width:100%,opacity:0,pointer-events:none},.visible:{opacity:1,pointer-events:auto}},_:{examples:{count:0}},name:ui-tween,template:div class\comp-ui-tween slots\ :class\{ hide: !slotsAreVisible }\ path\-2123300207.\>div ref\vSlots\ v-for\i in 0, 1\ :class\getSlotClass(i)\ path\-2123300207.0\>slot :name\slot + i\ path\-2123300207.0.0\>/slot>/div>/div>}},{name:ui.value.any,path:\\ui\\value\\any.ws.yaml,source:{dom:{div:{component:{:is:getComponentType(value),:value:visibleValue,:title:title,:preview:false,:depth:(depth + 1),:large:large,:visible-fields:visibleFields,:max-visible-fields:maxVisibleFields,:show-visible-fields-filter:showVisibleFieldsFilter,v-on:$listeners}}},props:{value:null,title:null,depth:0,large:false,visibleFields:null,maxVisibleFields:null,showVisibleFieldsFilter:true},data:null,methods:{getComponentType:function(value) {\n const getType (value) > {\n let typeofValue typeof value;\n if (value null) return \preview\;\n if (Array.isArray(value)) return \array\;\n if (\object\, \boolean\.find(v > v typeofValue)) return typeofValue;\n if (typeof value \string\)\n {\n const isColor value.match(/^#0-9a-f{6}$/i);\n if (isColor) return \color\;\n }\n return \preview\;\n };\n return `ui.value.${getType(value)}`.replace(/\\./g, \-\);\n}\n},computed:{visibleValue:function() {\n if (this.value null) return null;\n if (this.value undefined) return undefined;\n if (!this.selectedPath?.length) return this.value;\n return Objects.getProperty(this.value, this.selectedPath.join(\.\));\n}\n},watch:null,style:{.console-log-button:{position:absolute,bottom:-0.3em,right:-0.5em,font-size:200%,padding:0 0.4em,cursor:pointer,z-index:1000},.console-log-button:hover:{background:#ffffff20}},name:ui-value-any,_:{examples:{count:0}},template:div class\comp-ui-value-any\ path\1299909909.\>component :is\getComponentType(value)\ :value\visibleValue\ :title\title\ :preview\false\ :depth\(depth + 1)\ :large\large\ path\1299909909.0\>/component>/div>}},{name:ui.value.array,path:\\ui\\value\\array.ws.yaml,source:{dom:{div#1:{.flex.gap-1:{div#2:{v-if:(showVisibleFieldsFilter),ui.drawer:{v-if:(fields.length > 1),.box1#1:{ui.checkbox.list:{:items:fields,:get-item-icon:() > π§,:value-array:visibleFields1}}}},.box1#2:{:class:{ reversed: reverse },.flex.justify-between:{ui.title:{v-if:false,icon:π§,text:Array,:number:value?.length},ui.input.text.box:{class:search-box,type:search,icon:π,hint:search,camouflage:true,v-model:query}},ui.select:{v-if:false,:options:table, short-list, expanded-list,input-type:value,type:toggle,v-model:view1},ui.context.window:{v-if:false,ref:hoveredItemContext1,:visible:hoveredItem,ui.value#1:{:value:hoveredItem}},transition#1:{name:slide,table#1:{v-if:(view1.includes(list)),tbody#1:{tr:{v-for:(item, index) in visibleItems,td#1:{class:opacity-50,v-text:index},td#2:{ui.value.preview#1:{v-if:(view1 short-list),:value:item},ui.value.any:{v-else-if:(view1 expanded-list),:value:item},ui.value#2:{v-else:null,:value:item}}}}}},transition#2:{name:slide,table#2:{v-if:(view1 table),thead:{transition.group#1:{tag:tr,name:slide-hor,th:{v-for:field in shownFields,:key:field,div#3:{.flex.clickable:{:class:{ selected: (sortByField field) },on_click:onSortByField(field),div#4:{v-text:field},div#5:{v-if:(sortByField field),div#6:{v-text:(sortByFieldDirection 1) ? β² : βΌ}}}}}}},tbody#2:{transition.group#2:{tag:tr,name:slide-hor,v-for:(item, index) in visibleItems,:key:JSON.stringify(item),:class:_getItemClass(item, index),on_mouseenter:() > onItemHover(item, true),on_mouseleave:() > onItemHover(item, false),on_click:() > onItemClick(item, index),td#3:{v-for:field in shownFields,:key:field,ui.value.preview#2:{:value:item?.field}}}}}}},.box1#3:{v-if:false,ui.value:{:value:selected.item}}}}},props:{value:null,reverse:false,view:null,getItemClass:null,maxVisibleItems:500,maxVisibleFields:1000,visibleFields:null,showVisibleFieldsFilter:true},data:{sortByField:null,sortByFieldDirection:1,hoveredItem:null,selected:{item:null},query:null,visibleFields1:null},methods:{onSortByField:function(field) {\n if (this.sortByField field) {\n if (this.sortByFieldDirection -1) {\n this.sortByField null;\n this.sortByFieldDirection 1;\n }\n else {\n this.sortByFieldDirection -1;\n }\n }\n else\n {\n this.sortByField field;\n this.sortByFieldDirection 1;\n }\n}\n,onItemHover:function(item, isHovered) {\n if (this.$refs.hoveredItemContext1?.isPinned) return;\n this.hoveredItem (isHovered ? item : null);\n this.selected.item item;\n}\n,onItemClick:function(item, index) {\n this.$root.html.copyToClipboard(JSON.stringify(item));\n console.log(item);\n this.$emit(\array-item-click\, item, index);\n}\n,getFieldType:function(fieldName) {\n if (!this.value?.length) return null;\n if (this.isImageField(fieldName)) return \image\;\n return (typeof this.value0fieldName);\n}\n,isImageField:function(fieldName) {\n if (!this.value?.length) return false;\n if (.jpg, .jpeg, .png.some(ext > this.value.find(item > itemfieldName?.toString().endsWith(ext)))) return true;\n return false;\n}\n,_getItemClass:function(item, index) {\n const classes ;\n if (this.getItemClass) classes.push(this.getItemClass(item, index));\n return classes;\n}\n,isPrimitive:function(value) {\n return (typeof value) ! \object\;\n}\n},computed:{visibleItems:let items ...this.items;\nif (this.itemsType object)\n{\n items items\n .map(item > Objects.getObjectFields(item, this.shownFields));\n}\nconst query (this.query || ).toLowerCase();\nif (query) items items.filter(item > Objects.getValues(item).some(v > (v?.toString().toLowerCase().includes(query))));\nreturn items;\n,shownFields:if (this.visibleFields1) return this.visibleFields1;\nreturn this.fields;\n,items:let items ...this.value;\nif (this.isPrimitive(items0)) {\n items items.map(item > ({ value: item }));\n}\nitems items\n .take(this.maxVisibleItems || 1000)\n .sortByDirection(this.sortByField, this.sortByFieldDirection);\nreturn items;\n,fields:// Get all the field names from the array of objects\nif (!this.items) return ;\nconst objects this.items\n .take(10)\n .filter(item > !this.isPrimitive(item));\nconst fields objects.map(o > Object.keys(o||{}))\n .flatMap(f > f)\n .distinct()\n .sortBy(f > f)\n .take(this.maxVisibleFields || 1000);\nreturn fields;\n,view1:function() {\n return \table\;\n}\n,itemsType:function() {\n const value this.value;\n const type (!value) ? null : (this.isPrimitive(value0) ? primitive : object);\n return type;\n}\n},watch:{visibleFields:{handler:function(visibleFields) {\n visibleFields?.removeBy(v > !this.fields.includes(v));\n if (!visibleFields?.length) visibleFields null;\n this.visibleFields1 visibleFields;\n}\n,immediate:true},value:{handler:function(value) {\n}\n,immediate:true},query:{handler:function(query) {\n this.$emit(\input:query\, query);\n}\n}},style:{.box1:{border:1px solid #ffffff80,border-radius:0.5em,padding:0.5em,overflow:hidden},.search-box:{max-height:0,overflow:hidden,transition:0.5s},.box1:hover .search-box:{max-height:2em},.reversed > table > tbody:{display:flex,flex-direction:column-reverse},tr *:{max-height:1.5em,line-height:1.1em,overflow:hidden},tr .value-as-string:{max-width:12em},img:{width:5em},tr:{cursor:pointer,transition:0s},tr:hover td:{background-color:#ffffff20,transition:0s},th:{padding-right:1em,opacity:0.5},td:{font-family:monospace,padding:0 0.5em}},_:{examples:{count:0}},name:ui-value-array,template:div class\comp-ui-value-array\ path\-621945022.\>div class\box1\ :class\{ reversed: reverse }\ path\-621945022.0\>div class\flex\ path\-621945022.0.0\>ui-title icon\π§\ text\Array\ :number\value?.length\ path\-621945022.0.0.0\>/ui-title>/div>ui-select v-if\false\ :options\table, short-list, expanded-list\ input-type\value\ type\toggle\ v-model\view1\ path\-621945022.0.1\>/ui-select>ui-context-window v-if\false\ ref\hoveredItemContext1\ :visible\hoveredItem\ path\-621945022.0.2\>ui-value :value\hoveredItem\ path\-621945022.0.2.0\>/ui-value>/ui-context-window>transition name\slide\ path\-621945022.0.3\>table v-if\(view1.includes(list))\ path\-621945022.0.3.0\>tbody path\-621945022.0.3.0.0\>tr v-for\(item, index) in visibleItems\ path\-621945022.0.3.0.0.0\>td class\opacity-50\ v-text\index\ path\-621945022.0.3.0.0.0.0\>/td>td path\-621945022.0.3.0.0.0.1\>ui-value-preview v-if\(view1 short-list)\ :value\item\ path\-621945022.0.3.0.0.0.1.0\>/ui-value-preview>ui-value-any v-else-if\(view1 expanded-list)\ :value\item\ path\-621945022.0.3.0.0.0.1.1\>/ui-value-any>ui-value :value\item\ path\-621945022.0.3.0.0.0.1.2\>/ui-value>/td>/tr>/tbody>/table>/transition>transition name\slide\ path\-621945022.0.4\>table v-if\(view1 table)\ path\-621945022.0.4.0\>thead path\-621945022.0.4.0.0\>tr path\-621945022.0.4.0.0.0\>th v-for\field in visibleFields\ path\-621945022.0.4.0.0.0.0\>div class\clickable\ :class\{ selected: (sortByField field) }\ v-text\field\ on_click\onSortByField(field)\ path\-621945022.0.4.0.0.0.0.0\>/div>/th>/tr>/thead>tbody path\-621945022.0.4.0.1\>tr v-for\(item, index) in visibleItems\ :class\_getItemClass(item, index)\ on_mouseenter\() > onItemHover(item, true)\ on_mouseleave\() > onItemHover(item, false)\ on_click\() > onItemClick(item, index)\ path\-621945022.0.4.0.1.0\>td v-for\field in visibleFields\ path\-621945022.0.4.0.1.0.0\>ui-value-preview :value\item?.field\ path\-621945022.0.4.0.1.0.0.0\>/ui-value-preview>/td>/tr>/tbody>/table>/transition>/div>/div>}},{name:ui.value.boolean,path:\\ui\\value\\boolean.ws.yaml,source:{dom:{ui.title:{:icon:getIcon(value),div:{v-text:(value?.toString())}}},props:{value:null},methods:{getIcon:function(value) {\n return value ? \βοΈ\ : \β\;\n}\n},name:ui-value-boolean,_:{examples:{count:0}},template:ui-title class\comp-ui-value-boolean\ :icon\getIcon(value)\ path\110445265.\>div v-text\(value?.toString())\ path\110445265.0\>/div>/ui-title>}},{name:ui.value.code,path:\\ui\\value\\code.ws.yaml,source:{dom:{pre:{code:{v-text:value}}},props:{value:null},style:{pre:{min-width:10em}},name:ui-value-code,_:{examples:{count:0}},template:pre class\comp-ui-value-code\ path\1642561508.\>code v-text\value\ path\1642561508.0\>/code>/pre>}},{name:ui.value.color,path:\\ui\\value\\color.ws.yaml,source:{dom:{.flex:{div#1:{:style:style},div#2:{:style:{ color: gray },v-text:value}}},props:{value:null},methods:{getStyle:function() {\n const style {};\n style.width \1.5em\;\n style.height \1.5em\;\n if (this.value) style.background this.value;\n return style;\n}\n},computed:{style:function() {\n return this.getStyle();\n}\n},name:ui-value-color,_:{examples:{count:0}},template:div class\comp-ui-value-color flex\ path\-620192692.\>div :style\style\ path\-620192692.0\>/div>div :style\{ color: gray }\ v-text\value\ path\-620192692.1\>/div>/div>}},{name:ui.value.editor.boolean,path:\\ui\\value\\editor\\boolean.ws.yaml,source:{dom:{.flex:{ui.checkbox:{:value:value,on_input:(value) > $emit(input, value),ui.value.boolean:{:value:value}}}},props:{value:null},name:ui-value-editor-boolean,_:{examples:{count:0}},template:div class\comp-ui-value-editor-boolean flex\ path\-2111837730.\>ui-checkbox :value\value\ on_input\(value) > $emit(input, value)\ path\-2111837730.0\>ui-value-boolean :value\value\ path\-2111837730.0.0\>/ui-value-boolean>/ui-checkbox>/div>}},{name:ui.value.editor.string,path:\\ui\\value\\editor\\string.ws.yaml,source:{dom:{ui.input.text.box:{:value:value,on_input:(value) > $emit(input, value)}},props:{value:null},name:ui-value-editor-string,_:{examples:{count:0}},template:ui-input-text-box class\comp-ui-value-editor-string\ :value\value\ on_input\(value) > $emit(input, value)\ path\1808749467.\>/ui-input-text-box>}},{name:ui.value.editor,path:\\ui\\value\\editor.ws.yaml,source:{dom:{component:{:is:getComponentType(value),:value:value,on_input:(value) > $emit(input, value)}},props:{value:null},methods:{getComponentType:function(value) {\n const getType (value) > {\n if (value null) null;\n let type typeof value;\n if (\string\, \boolean\.find(v > v type)) return type;\n return null;\n };\n const type getType(value);\n if (!type) return null;\n return `ui.value.editor.${type}`.replace(/\\./g, \-\);\n}\n},name:ui-value-editor,_:{examples:{count:0}},template:component class\comp-ui-value-editor\ :is\getComponentType(value)\ :value\value\ on_input\(value) > $emit(input, value)\ path\-1999089244.\>/component>}},{name:ui.value.field.picker,path:\\ui\\value\\field\\picker.ws.yaml,source:{dom:{div#1:{v-if:obj,class:field-list,.flex.justify-center:{:key:selectedFields?.join(),ui.value:{:class:{ opacity-60 grayscale: (!selectedFields?.length) },:value:!selectedFields?.length ? select fields : + selectedFields.join(, ) + }},div#2:{div#3:{v-for:field in fields,ui.checkbox:{:key:field,:text:field,:value-array:selectedFields,:value-key:field}}}}},props:{obj:null,value:null},data:{fields:,selectedFields:},watch:{selectedFields:{handler:async function(selectedFields) {\n if (selectedFields?.join(,) this.value?.join(,)) return;\n this.$emit(\input\, selectedFields);\n}\n},obj:{handler:function(obj) {\n this.fields ((!obj) ? : Object.keys(obj))\n .concat(this.selectedFields)\n .distinct();\n}\n,immediate:true},value:{handler:function(value) {\n if (value?.join(,) this.selectedFields.join(,)) return;\n this.selectedFields Objects.clone((!value) ? : value);\n}\n,immediate:true}},style:{.field-list:{max-height:3em,overflow-x:hidden,overflow-y:auto,transition:0.6s},.field-list:hover:{max-height:15em}},_:{examples:{count:0}},name:ui-value-field-picker,template:div class\comp-ui-value-field-picker field-list\ v-if\obj\ path\20302585.\>div class\flex justify-center\ :key\selectedFields?.join()\ path\20302585.0\>ui-value :class\{ opacity-60 grayscale: (!selectedFields?.length) }\ :value\!selectedFields?.length ? select fields : + selectedFields.join(, ) + \ path\20302585.0.0\>/ui-value>/div>div path\20302585.1\>div v-for\field in fields\ path\20302585.1.0\>ui-checkbox :key\field\ :text\field\ :value-array\selectedFields\ :value-key\field\ path\20302585.1.0.0\>/ui-checkbox>/div>/div>/div>}},{name:ui.value.object,path:\\ui\\value\\object\\_.ws.yaml,source:{dom:{div:{on_click:() > consoleLog(value),.flex:{:style:{ gap: 1em },v-if:(title || specialTypeName),.title#1:{v-if:title,v-text:title},.title#2:{class:opacity-50,v-if:false && specialTypeName,v-text:specialTypeName}},pre:{class:pre,ui.value.table:{:value:value,:depth:(depth + 1)}},.console-log-button:{class:clickable,title:console.log(),v-text:π»,on_click:() > consoleLog(value)},ui.alert:{ref:alert1}}},props:{value:null,title:null,depth:0},data:{yamlError:null},methods:{consoleLog:function(value) {\n console.log(value);\n this.$refs.alert1.show(Object logged to browser console.);\n}\n},computed:{type:function() {\n const type Objects.getType(this.value);\n return (type?.name || type);\n}\n,specialTypeName:function() {\n if (!this.value) return null;\n const type Objects.getType(this.value).toString();\n const specialTypeName this.value.constructor?.name;\n return (type specialTypeName) ? null : specialTypeName;\n}\n,yaml:function() {\n try\n {\n this.yamlError null;\n return this.$root.visualizedYaml(this.value);\n }\n catch (ex)\n {\n this.yamlError ex.message;\n return null;\n }\n}\n},watch:null,style:{.comp-ui-value-object:{max-width:50vw},.title1:{opacity:0.5},.box1:{font-size:100%},.console-log-button:{display:none}},name:ui-value-object,_:{examples:{count:0}},template:div class\comp-ui-value-object\ path\-1714629770.\>div class\flex\ :style\{ gap: 1em }\ v-if\(title || specialTypeName)\ path\-1714629770.0\>div class\title\ v-if\title\ v-text\title\ path\-1714629770.0.0\>/div>div class\opacity-50 title\ v-if\false && specialTypeName\ v-text\specialTypeName\ path\-1714629770.0.1\>/div>/div>pre class\pre\ path\-1714629770.1\>ui-value-table :value\value\ :depth\(depth + 1)\ path\-1714629770.1.0\>/ui-value-table>/pre>div class\clickable console-log-button\ title\console.log()\ v-text\π»\ on_click\() > consoleLog(value)\ path\-1714629770.2\>/div>ui-alert ref\alert1\ path\-1714629770.3\>/ui-alert>/div>}},{name:ui.value.path.picker,path:\\ui\\value\\path\\picker.ws.yaml,source:{dom:{div:{class:picker,v-if:isVisible,.parts:{.clickable#1:{ui.title#1:{icon:π§,text:{},on_click:() > selectedPath }},.clickable#2:{v-for:part in selectedPath,on_click:() > selectedPath.splice(selectedPath.indexOf(part) + 1),ui.title#2:{icon:π§,:text:part}},.next-parts:{ul:{li:{v-for:part in nextPathParts,:key:part,class:clickable,on_click:onSelectPart(part),.flex:{ui.title#3:{icon:π§,:text:part}}}}}}}},props:{obj:null,value:null},data:{selectedPath:},methods:{onSelectPart:function(part) {\n this.selectedPath.push(part);\n}\n},computed:{isVisible:function() {\n if (!this.obj) return false;\n if (Objects.getType(this.obj) ! Object) return false;\n return true;\n}\n,node:function() {\n let node this.obj;\n for (const part of this.selectedPath) {\n node nodepart;\n }\n return node;\n}\n,nextPathParts:function() {\n if (!this.node) return ;\n if (Array.isArray(this.node)) return ;\n if (typeof this.node ! object) return ;\n return Object.keys(this.node);\n}\n},watch:{value:{handler:function(value) {\n this.selectedPath Objects.clone((!value) ? : value);\n}\n,immediate:true},selectedPath:{handler:function(selectedPath) {\n if (selectedPath?.join(,) this.value?.join(,)) return;\n this.$emit(\input\, selectedPath);\n}\n}},style:{.picker:{max-height:2em,overflow-x:hidden,overflow-y:auto,transition:0.6s},.picker:hover:{max-height:15em},.parts:{display:flex,gap:0.5em},.next-parts:{filter:grayscale(1),opacity:0.5}},_:{examples:{count:0}},name:ui-value-path-picker,template:div class\comp-ui-value-path-picker picker\ v-if\isVisible\ path\738107552.\>div class\parts\ path\738107552.0\>div class\clickable\ path\738107552.0.0\>ui-title icon\π§\ text\{}\ on_click\() > selectedPath \ path\738107552.0.0.0\>/ui-title>/div>div class\clickable\ v-for\part in selectedPath\ on_click\() > selectedPath.splice(selectedPath.indexOf(part) + 1)\ path\738107552.0.1\>ui-title icon\π§\ :text\part\ path\738107552.0.1.0\>/ui-title>/div>div class\next-parts\ path\738107552.0.2\>ul path\738107552.0.2.0\>li class\clickable\ v-for\part in nextPathParts\ :key\part\ on_click\onSelectPart(part)\ path\738107552.0.2.0.0\>div class\flex\ path\738107552.0.2.0.0.0\>ui-title icon\π§\ :text\part\ path\738107552.0.2.0.0.0.0\>/ui-title>/div>/li>/ul>/div>/div>/div>}},{name:ui.value.preview.function,path:\\ui\\value\\preview\\function.ws.yaml,source:{dom:{div:{.flex:{.icon:{v-text:Ζ},.text:{v-text:value}}}},props:{value:null},methods:null,style:{.icon:{color:brown,transform:scale(1.5);,margin-right:0.5em;},.text:{width:10em,height:1.5em,overflow:hidden,color:chocolate,white-space:pre}},name:ui-value-preview-function,_:{examples:{count:0}},template:div class\comp-ui-value-preview-function\ path\-776676683.\>div class\flex\ path\-776676683.0\>div class\icon\ v-text\Ζ\ path\-776676683.0.0\>/div>div class\text\ v-text\value\ path\-776676683.0.1\>/div>/div>/div>}},{name:ui.value.preview,path:\\ui\\value\\preview.ws.yaml,source:{dom:{div#1:{:class:{ preview: preview },ui.image:{v-if:isImageUrl,:url:value},ui.value.preview.function:{v-else-if:isFunction,:value:value},ui.value.color:{v-else-if:isColor,:value:value},div#2:{v-else-if:true,:class:cssClass,div#3:{:class:{ clickable: true, value-as-string: true },v-text:valueAsString,on_click:(e) > onClickValue(e, valueAsString)},transition:{name:slide,ui.value.any:{v-if:isLargeType && isMoreVisible,:value:value}}}}},props:{value:null,preview:true,large:false},data:{isMoreVisible:false},methods:{onClickValue:function(e, value) {\n e.preventDefault();\n e.stopPropagation();\n if (typeof value \string\) return this.$root.html.copyToClipboard(value);\n this.console.log(value);\n alertify.message(`Logged to console`);\n}\n,getCssClass:function(value) {\n const cls ;\n if (undefined, null.includes(value)) cls.push(\opacity-30\);\n cls.push(this.typeColor);\n if (this.large) cls.push(\large\);\n return cls;\n}\n,valueToString:function(value, depth) {\n if (!depth) depth 0;\n if (depth > 4) return \β¦\;\n if (value undefined) return \undefined\;\n if (value null) return \null\;\n if (value instanceof Date) return value.toShortString();\n if (typeof value \string\) {\n if (!value.length) return `ββ`;\n return `${!this.preview ? value : value}`;\n }\n if (typeof value \number\) return value.toString();\n if (typeof value \boolean\) return value ? \βοΈ\ : \β\;\n if (typeof value \function\) return value.toString();\n if (Array.isArray(value)) return `${value.length}β¦`;\n //if (typeof value \object\) return `{${Object.keys(value).take(5).map(k > `${k}: ${this.valueToString(valuek, depth+1)}`).join(, )}}`;\n if (typeof value \object\) return `{${Object.keys(value).take(10).join(, )}}`;\n return value.toString();\n}\n},computed:{cssClass:function() {\n return this.getCssClass(this.value);\n}\n,type:function() {\n return Objects.getType(this.value)?.name.toLowerCase();\n}\n,typeColor:function() {\n if (this.type \boolean\) return this.value ? \green\ : \red\;\n return ({\n \string\: \yellow\,\n \number\: \green\,\n \object\: \cyan\,\n \array\: \white\\n }this.type) || null;\n}\n,valueAsString:function() {\n return this.valueToString(this.value);\n}\n,isLargeType:function() {\n // object or array\n return (this.type \object\ || this.type \array\);\n}\n,isImageUrl:function() {\n const value this.value;\n if (typeof value ! \string\) return false;\n if (!value.startsWith(\http\)) return false;\n if (\.png\, \.jpg\, \.jpeg\, \.gif\.some(ext > value.endsWith(ext))) return true;\n return false;\n}\n,isFunction:function() {\n const value this.value;\n return typeof value \function\;\n}\n,isColor:function() {\n const value this.value;\n if (typeof value ! \string\) return false;\n if (!value.startsWith(\#\)) return false;\n if (value.length ! 7) return false;\n return true;\n}\n},style:{.large:{font-size:140%},.value-as-string:{white-space:nowrap,overflow:hidden,text-overflow:ellipsis},.comp-ui-image:{width:5em},.preview .comp-ui-image:{width:4em}},name:ui-value-preview,_:{examples:{count:0}},template:div class\comp-ui-value-preview\ :class\{ preview: preview }\ path\-272450959.\>ui-image v-if\isImageUrl\ :url\value\ path\-272450959.0\>/ui-image>ui-value-preview-function v-else-if\isFunction\ :value\value\ path\-272450959.1\>/ui-value-preview-function>ui-value-color v-else-if\isColor\ :value\value\ path\-272450959.2\>/ui-value-color>div v-else-if\true\ :class\cssClass\ path\-272450959.3\>div :class\{ clickable: true, value-as-string: true }\ v-text\valueAsString\ on_click\onClickValue(valueAsString)\ path\-272450959.3.0\>/div>transition name\slide\ path\-272450959.3.1\>ui-value-any v-if\isLargeType && isMoreVisible\ :value\value\ path\-272450959.3.1.0\>/ui-value-any>/transition>/div>/div>}},{name:ui.value.table,path:\\ui\\value\\table.ws.yaml,source:{dom:{div#1:{.opacity-50:{v-if:isEmpty,v-text:emptyText},.flex:{table:{:class:type,v-if:!isEmpty,ui.dnd.draggable:{tag:tr,:drag-item:{ field: { ...row } },v-for:row in rows,on_click:onRowClick(row),th:{class:opacity-40 fw-100,v-if:isPrimitive(row.value),v-text:row.key},td#1:{v-if:isPrimitive(row.value),ui.value.any#1:{:value:row.value,:depth:(depth + 1)}},td#2:{v-if:!isPrimitive(row.value),colspan:2,.clickable:{class:flex,on_click:toggleExpanded(row.key),ui.expand:{class:opacity-40,:value:isExpanded1(row.key),:text:row.key}},transition:{name:slide,.ml-l1:{v-if:isExpanded1(row.key),ui.value.any#2:{:value:row.value,:depth:(depth + 1)}}}}}},div#2:{class:box,ui.value:{:value:selected.item}}}}},props:{value:null,title:null,expandAll:false,depth:0},data:{isExpanded:{},rows:null,selected:{item:null}},methods:{onRowClick:function(row) {\n this.selected.item row.value;\n}\n,getRows:function() {\n const value this.value;\n if (!value) return ;\n if (this.type array) {\n return value.map((value, index) > ({key: index, value}))\n }\n if (this.type object) {\n let entries Object.entries(value)\n .map((key, value) > ({key, value}));\n entries entries\n .exceptBy(this.filteredKeys, e > e0);\n entries entries\n .sort(this.compareEntries);\n return entries;\n }\n}\n,compareEntries:function(a, b) {\n if (this.isImageUrl(a.value) && !this.isImageUrl(b.value)) return -1;\n if (!this.isImageUrl(a.value) && this.isImageUrl(b.value)) return 1;\n if (this.isImageUrl(a.value) && this.isImageUrl(b.value)) return 0;\n return a.key.localeCompare(b.key);\n}\n,isImageUrl:function(value) {\n const exts png, jpg, jpeg, gif, svg;\n if (typeof value ! string) return false;\n if (!value.startsWith(http)) return false;\n if (!exts.some(ext > value.endsWith(ext))) return false;\n return true;\n}\n,toggleExpanded:function(key) {\n this.$set(this.isExpanded, key, !this.isExpandedkey);\n}\n,isPrimitive:function(value) {\n if (value null) return true;\n return string, number, boolean.includes(typeof value);\n}\n,isExpanded1:function(key) {\n if (this.expandAll) return true;\n return this.isExpandedkey;\n}\n,getType:function(value) {\n if (Array.isArray(value)) {\n return array\n }\n if (typeof value object) {\n return object\n }\n return null;\n}\n},computed:{type:function() {\n return this.getType(this.value);\n}\n,isEmpty:function() {\n return (Object.keys(this.value).length 0);\n}\n,filteredKeys:function() {\n return \__proto__\;\n}\n,emptyText:function() {\n switch (this.type)\n {\n case array: return 0β¦;\n case object: return {β¦};\n default: return ;\n }\n}\n},watch:{value:{handler:function(value) {\n this.rows this.getRows();\n // Expand the first row\n if (this.rows.length && !this.isExpandedthis.rows0.key) {\n this.toggleExpanded(this.rows0.key);\n }\n}\n,immediate:true}},style:{.comp-ui-expand:{width:100%},tr:hover:{background-color:#ffffff10,transition:0s},th:first-child:{padding-left:0.5em,border-radius:0.3em 0 0 0.3em},td:last-child:{padding-right:0.5em,border-radius:0 0.3em 0.3em 0},table.array th:{width:3em},th:{padding-right:1em}},name:ui-value-table,_:{examples:{count:0}},template:div class\comp-ui-value-table\ path\-604919625.\>div class\opacity-50\ v-if\isEmpty\ v-text\emptyText\ path\-604919625.0\>/div>table :class\type\ v-if\!isEmpty\ path\-604919625.1\>tr v-for\row in rows\ path\-604919625.1.0\>th class\opacity-40 fw-100\ v-if\isPrimitive(row.value)\ v-text\row.key\ path\-604919625.1.0.0\>/th>td v-if\isPrimitive(row.value)\ path\-604919625.1.0.1\>ui-value-any :value\row.value\ :depth\(depth + 1)\ path\-604919625.1.0.1.0\>/ui-value-any>/td>td v-if\!isPrimitive(row.value)\ colspan\2\ path\-604919625.1.0.2\>div class\flex clickable\ on_click\toggleExpanded(row.key)\ path\-604919625.1.0.2.0\>ui-expand class\opacity-40\ :value\isExpandedrow.key\ :text\row.key\ path\-604919625.1.0.2.0.0\>/ui-expand>/div>transition name\slide\ path\-604919625.1.0.2.1\>div class\ml-l1\ v-if\isExpandedrow.key\ path\-604919625.1.0.2.1.0\>ui-value-any :value\row.value\ :depth\(depth + 1)\ path\-604919625.1.0.2.1.0.0\>/ui-value-any>/div>/transition>/td>/tr>/table>/div>}},{name:ui.value._.example0,path:\\ui\\value\\_.example0.ws.yaml,source:{dom:{ui.value:{:value:exampleData}},data:{exampleData:null},mounted:async function() {\n this.exampleData (await (await fetch(\/fetch?urlhttps://a.4cdn.org/boards.json\)).json()).boards;\n}\n}},{name:ui.value,path:\\ui\\value\\_.ws.yaml,source:{dom:{ui.value.any:{:class:{ overflow, loading: isLoading },:value:visibleValue,:title:title,:depth:(depth + 1),:large:large,:visible-fields:visibleFields,:max-visible-fields:maxVisibleFields,:show-visible-fields-filter:showVisibleFieldsFilter,v-on:$listeners}},props:{value:null,title:null,depth:0,overflow:false,large:false,visibleFields:null,maxVisibleFields:null,showVisibleFieldsFilter:true},data:{visibleValue:null,isLoading:false},computed:null,watch:{value:{handler:async function(value) {\n this.isLoading true;\n await this.$root.wait(100);\n this.visibleValue value;\n await this.$root.wait(100);\n this.isLoading false;\n}\n,immediate:true}},style:{.overflow:{max-height:30em,overflow:auto},.loading:{filter:grayscale(0)},.loading::after:{position:absolute,width:100%,height:100%,top:0,left:0,background-image:url(/images/loading.gif)}},example:{dom:{ui.value:{:value:exampleData}},data:{exampleData:null},mounted:async function() {\n this.exampleData (await (await fetch(\/fetch?urlhttps://a.4cdn.org/boards.json\)).json()).boards;\n}\n},name:ui-value,_:{examples:{count:1}},template:ui-value-any class\comp-ui-value\ :class\{ overflow, loading: isLoading }\ :value\visibleValue\ :title\title\ :depth\(depth + 1)\ :large\large\ path\-2122101353.\>/ui-value-any>}},{name:ui.video,path:\\ui\\video.ws.yaml,source:{dom:{video:{ref:video1,autoplay:true,muted:true,loop:true,:src:src}},props:{src:null},mounted:function() {\n this.ensureVideoIsPlaying();\n}\n,methods:{ensureVideoIsPlaying:function() {\n try\n {\n if (this.$refs.video1?.paused) this.$refs.video1.play();\n }\n catch (ex) {}\n setTimeout(this.ensureVideoIsPlaying.bind(this), 400);\n}\n},name:ui-video,_:{examples:{count:0}},template:video class\comp-ui-video\ ref\video1\ autoplay\true\ muted\true\ loop\true\ :src\src\ path\-2121871199.\>/video>}},{name:ui.warning,path:\\ui\\warning.ws.yaml,source:{dom:{.warning:{h3:{ui.title:{icon:β οΈ,:text:title,:number:number}},div:{v-html:text},slot:null}},props:{title:null,text:null,number:null},_:{examples:{count:0}}}},{name:ui.window,path:\\ui\\window.ws.yaml,source:{dom:{div#1:{v-if:rect,:style:style,:class:Object.assign({ hovered: (isFullSize), minimized: rect.is.minimized, auto-expand: autoExpand }, (cssClass||{})),on_mouseenter:(e) > { isHovered++; $emit(mouseenter, e); },on_mouseleave:(e) > { isHovered0; $emit(mouseleave, e); },on_dragenter:(e) > { isHovered++; },on_dragleave:(e) > { isHovered--; },.above:{:style:{ width: rect1.size.width+px },on_dragenter:(e) > { isHovered++; },on_dragleave:(e) > { isHovered--; },slot#1:{name:above}},.h-100pc:{.h-100pc:{ui.mouse:{on_up:onMouseUp,on_drag:onMouseDrag},.resize-handle.en:{v-text:,on_mousedown:() > isResizing en},.resize-handle.wn:{v-text:,on_mousedown:() > isResizing wn},.resize-handle.ws:{v-text:,on_mousedown:() > isResizing ws},.resize-handle.es:{v-text:,on_mousedown:() > isResizing es},.window:{ref:window,:style:windowStyle,on_click:() > { isHovered 1; $emit(click); },.header:{v-if:showHeader,.flex.w-100pc:{.flex-grow-1:{slot#2:{name:header}},.buttons:{.flex:{transition:{name:list2,div#2:{:key:rect.is.minimized,v-text:rect.is.minimized ? π : π,on_click:onMinimizeToggle}}}}}},.content:{v-if:showContent,:style:contentStyle,slot#3:{name:content}},.footer:{v-if:false,.flex.justify-between:{div#3:{v-for:size in sizes,ui.button:{:text:size.width + x + size.height,on_click:rect1.size size}}}}}},.left-side:{slot#4:{name:left-side}},.right-side:{slot#5:{name:right-side}}},.below:{:style:{ width: rect1.size.width+px },slot#6:{name:below}}}},props:{rect:null,autoExpand:false,centerCoords:false,surfaceElement:null,surfaceCamera:{pos:{x:0,y:0},scale:1},showHeader:true,windowStyle:null,cssClass:null},data:{sizes:{width:300,height:200},{width:400,height:300},{width:500,height:400},rect1:null,isDraggingMoving:false,isDragging:false,isResizing:false,dragStartPos:{x:0,y:0},dragTimeout:null,isHovered:0},mounted:function() {\n}\n,methods:{move:async function(pos) {\n this.rect1.pos this.adjustPos(pos);\n}\n,onMinimizeToggle:function() {\n this.$emit(\is-minimized\, !this.rect1.is?.minimized);\n}\n,onMouseDrag:async function(dpos) {\n if (!this.isDragging)\n {\n this.isDragging true;\n this.dragStartPos Objects.clone(this.rect1.pos);\n }\n if (this.isResizing)\n {\n const size this.rect1.size;\n size.width + (dpos.dx * 2) * (this.isResizing.includes(\e\) ? 1 : -1);\n size.height + (dpos.dy * 2) * (this.isResizing.includes(\s\) ? 1 : -1);\n this.rect1.size size;\n return;\n }\n this.isDraggingMoving true;\n const pos this.rect1.pos;\n dpos.dy -dpos.dy;\n pos.x + dpos.dx;\n pos.y + dpos.dy;\n this.rect1.pos pos;\n this.$emit(\drag\, { delta: dpos });\n clearTimeout(this.dragTimeout);\n this.dragTimeout setTimeout(() > {\n this.isDraggingMoving false;\n }, 100);\n}\n,onMouseUp:async function() {\n if (!this.isDragging) return;\n const dragType this.isResizing ? \resize\ : \move\;\n this.isDragging false;\n this.isResizing false;\n const pos this.rect1.pos;\n const size this.rect1.size;\n const rect { pos, size };\n //if (Objects.areEqual(pos, this.dragStartPos)) return;\n this.$emit(\drag-stop\, rect, dragType);\n}\n,getSurfaceCenter:function(cssPosition) {\n const surfaceRect this.getSurfaceRect();\n if (cssPosition \fixed\)\n {\n return {\n x: Math.round(surfaceRect.left + surfaceRect.width / 2),\n y: Math.round(surfaceRect.top + surfaceRect.height / 2)\n };\n }\n else\n {\n return {\n x: Math.round(surfaceRect.width / 2),\n y: Math.round(surfaceRect.height / 2)\n };\n }\n}\n,getSurfaceRect:function() {\n const surface this.surfaceElement || window;\n const surfaceRect this.$root.getAbsoluteRect(surface);\n return surfaceRect;\n}\n,getStyleHeight:function() {\n const size this.rect1.size;\n const minimizedHeight 40;\n const fullHeight size.height;\n if (this.isFullSize) return fullHeight;\n if (this.rect1.is?.minimized) return minimizedHeight;\n return fullHeight;\n}\n,adjustPos:function(pos) {\n if (!pos) return pos;\n if (!this.centerCoords) return pos;\n const center this.getSurfaceCenter();\n const x Math.round(pos.x - center.x);\n const y Math.round(center.y - pos.y);\n return { x, y };\n}\n,yamlify:function(obj) {\n return jsyaml.dump(obj);\n}\n},computed:{isFullSize:function() {\n return (!!this.isHovered || !!this.isResizing || !!this.isDragging || !!this.isDraggingMoving);\n}\n,showContent:function() {\n return true;\n if (!this.rect.is.minimized) return true;\n if (this.isHovered) return true;\n if (this.isResizing) return true;\n return false;\n}\n,style:function()\n{\n const rect1 this.rect1;\n if (!rect1) return {};\n const camera this.surfaceCamera;\n const center this.getSurfaceCenter();\n const pos rect1.pos;\n const size rect1.size;\n const style {};\n style.position \absolute\;\n style.width (size.width + \px\);\n style.height (`${this.getStyleHeight()}px`);\n const height parseInt(style.height);\n const x (center.x - camera.pos.x*camera.scale + pos.x*camera.scale - (size.width*camera.scale / 2));\n const y (center.y + camera.pos.y*camera.scale - pos.y*camera.scale - (height*camera.scale / 2));\n style.left `${0}px`;\n style.top `${0}px`;\n style.fontSize `${camera.scale*100}%`;\n style.transform `translate(${x}px, ${y}px)`;\n if (\opacity\ in rect1)\n {\n style.opacity rect1.opacity;\n if (rect1.opacity 0) style\pointer-events\ \none\;\n }\n if (rect1.zOnTop) style\z-index\ 1000;\n if (!this.isDraggingMoving && !this.isResizing) {\n style.transition \all 1s, transform 0.4s, border 0s\;\n }\n return style;\n}\n,contentStyle:function()\n{\n const style {};\n const size this.rect1.size;\n style.width ((size.width - 20) + \px\);\n //style.height (size.height + \px\);\n return style;\n}\n,alertify:function()\n{\n return alertify;\n}\n},watch:{isFullSize:{handler:function(isFullSize) {\n this.$emit(\is-hovered\, !!isFullSize);\n}\n},rect:{handler:function(rect) {\n this.rect1 Objects.clone(rect);\n}\n,immediate:true,deep:true},rect1:{handler:function(rect) {\n this.$emit(\input\, rect);\n}\n,deep:true}},style:{.comp-ui-window:null,.header:{display:flex},.buttons:{max-width:0,opacity:0,transition:1s},.header:hover .buttons:{max-width:10em,transition:1s,opacity:0.3},.buttons:hover:{opacity:1 !important},.buttons > div > div:{height:2em,background:transparent,padding:0.2em,margin:0em,text-align:center,white-space:nowrap,cursor:pointer},.buttons > div > div:hover:{background:#ffffff10},.resize-handle:{position:absolute,width:2em,height:2em,user-select:none,z-index:100},.resize-handle:hover:{background:#ffffff30},.resize-handle.wn:{top:-1em,left:-1em,cursor:nwse-resize},.resize-handle.ws:{bottom:-1em,left:-1em,cursor:nesw-resize},.resize-handle.es:{bottom:-1em,right:-1em,cursor:nwse-resize},.resize-handle.en:{top:-1em,right:-1em,cursor:nesw-resize},.left-side:{position:absolute,top:50%,left:0em,transform:translate(0%, -50%)},.hovered .left-side:{transform:translate(-100%, -50%)},.right-side:{position:absolute,top:50%,right:0em,transform:translate(0, -50%)},.hovered .right-side:{transform:translate(100%, -50%)},.above, .below, .left-side, .right-side:{opacity:0,transition:all 0s, opacity 0.6s, transform 1s !important},.hovered .above, .hovered .below, .hovered .left-side, .hovered .right-side:{opacity:1},.hovered .window:null,.window:{height:100%,padding:0.5em,background:linear-gradient(to right, #303030, #101010),border:1px solid #ffffff30,overflow:hidden,box-shadow:-1em 1em 0.5em #00000080,cursor:move,user-select:none,z-index:90},.content:{height:calc(100% - 2em),overflow:auto},.auto-expand .content:{max-height:0},.auto-expand:hover .content:{max-height:none},.footer:{max-height:0.5em,overflow:hidden},.footer:hover:{max-height:3em},.handle:{position:absolute,right:0,bottom:0,width:1em,height:1em,background:#ffffff20,cursor:se-resize,user-select:none}},_:{examples:{count:0}},name:ui-window,template:div class\comp-ui-window\ v-if\rect\ :style\style\ :class\Object.assign({ hovered: (isFullSize), minimized: rect.is.minimized, auto-expand: autoExpand }, (cssClass||{}))\ on_mouseenter\(e) > { isHovered++; $emit(mouseenter, e); }\ on_mouseleave\(e) > { isHovered0; $emit(mouseleave, e); }\ on_dragenter\(e) > { isHovered++; }\ on_dragleave\(e) > { isHovered--; }\ path\-1324571510.\>div class\above\ :style\{ width: rect1.size.width+px }\ on_dragenter\(e) > { isHovered++; }\ on_dragleave\(e) > { isHovered--; }\ path\-1324571510.0\>slot name\above\ path\-1324571510.0.0\>/slot>/div>div class\h-100pc\ path\-1324571510.1\>div class\h-100pc\ path\-1324571510.1.0\>ui-mouse on_up\onMouseUp\ on_drag\onMouseDrag\ path\-1324571510.1.0.0\>/ui-mouse>div class\resize-handle en\ on_mousedown\() > isResizing en\ path\-1324571510.1.0.1\>/div>div class\resize-handle wn\ on_mousedown\() > isResizing wn\ path\-1324571510.1.0.2\>/div>div class\resize-handle ws\ on_mousedown\() > isResizing ws\ path\-1324571510.1.0.3\>/div>div class\resize-handle es\ on_mousedown\() > isResizing es\ path\-1324571510.1.0.4\>/div>div class\window\ ref\window\ :style\windowStyle\ on_click\() > { isHovered 1; $emit(click); }\ path\-1324571510.1.0.5\>div class\header\ v-if\showHeader\ path\-1324571510.1.0.5.0\>div class\flex w-100pc\ path\-1324571510.1.0.5.0.0\>div class\flex-grow-1\ path\-1324571510.1.0.5.0.0.0\>slot name\header\ path\-1324571510.1.0.5.0.0.0.0\>/slot>/div>div class\buttons\ path\-1324571510.1.0.5.0.0.1\>div class\flex\ path\-1324571510.1.0.5.0.0.1.0\>transition name\list2\ path\-1324571510.1.0.5.0.0.1.0.0\>div :key\rect.is.minimized\ v-text\rect.is.minimized ? π : π\ on_click\onMinimizeToggle\ path\-1324571510.1.0.5.0.0.1.0.0.0\>/div>/transition>/div>/div>/div>/div>div class\content\ v-if\showContent\ :style\contentStyle\ path\-1324571510.1.0.5.1\>slot name\content\ path\-1324571510.1.0.5.1.0\>/slot>/div>div class\footer\ v-if\false\ path\-1324571510.1.0.5.2\>div class\flex justify-between\ path\-1324571510.1.0.5.2.0\>div v-for\size in sizes\ path\-1324571510.1.0.5.2.0.0\>ui-button :text\size.width + x + size.height\ on_click\rect1.size size\ path\-1324571510.1.0.5.2.0.0.0\>/ui-button>/div>/div>/div>/div>/div>div class\left-side\ path\-1324571510.1.1\>slot name\left-side\ path\-1324571510.1.1.0\>/slot>/div>div class\right-side\ path\-1324571510.1.2\>slot name\right-side\ path\-1324571510.1.2.0\>/slot>/div>/div>div class\below\ :style\{ width: rect1.size.width+px }\ path\-1324571510.2\>slot name\below\ path\-1324571510.2.0\>/slot>/div>/div>}},{name:app,path:\\app.ws.yaml,source:{dom:{div#1:{div#2:{.site-loading:{ui.loading:{v-if:$root.isLoading}},site.header:{class:site-width},div#3:{class:header-spacer}},.pages:{:class:{ site-width: true },page.test:null,page.admin.index:null,page.home:null,page.catalog:null,page.thread:null,page.category:null,page.builder:null,page.media:null,page.generators:null,page.generator:null,page.instance:null},.notifications:{ui.notifications:null},div#4:{ui.css.stylesheet:{:rules:$root.newCssRules},div#5:{ui.html.style:{v-for:comp in $root.comps,:key:comp.name,:component:comp,:document-head:true}}}}},props:{comps:null},name:app,style:{.notifications:{position:fixed,bottom:2em,right:2em,width:20em,z-index:1000},.site-loading:{position:fixed,top:50%,left:50%},.site-loading > div:{width:fit-content},.site-width:{width:min(1000px, 90vw),margin:auto,z-index:10},.pages > div:{position:absolute,top:0,padding-bottom:20vh},.comp-site-header:{position:fixed,top:0,margin:0 0 1rem,background-repeat:no-repeat,background-size:cover,background-position:center,transition:0s !important,left:50%,transform:translateX(-50%),z-index:1000},.header-spacer:{height:5rem},div:{width:100%}},_:{examples:{count:0}},template:div class\comp-app\ path\96801.\>div path\96801.0\>div class\site-loading\ path\96801.0.0\>ui-loading v-if\$root.isLoading\ path\96801.0.0.0\>/ui-loading>/div>site-header class\site-width\ path\96801.0.1\>/site-header>div class\header-spacer\ path\96801.0.2\>/div>/div>div class\pages\ :class\{ site-width: true }\ path\96801.1\>page-test>/page-test>page-admin-index>/page-admin-index>page-home>/page-home>page-catalog>/page-catalog>page-thread>/page-thread>page-category>/page-category>page-builder>/page-builder>page-media>/page-media>page-generators>/page-generators>page-generator>/page-generator>page-instance>/page-instance>/div>div class\notifications\ path\96801.2\>ui-notifications>/ui-notifications>/div>div path\96801.3\>ide-css-stylesheet :rules\$root.newCssRules\ path\96801.3.0\>/ide-css-stylesheet>div path\96801.3.1\>ui-html-style v-for\comp in $root.comps\ :key\comp.name\ :component\comp\ path\96801.3.1.0\>/ui-html-style>/div>/div>/div>}},{name:content.article,path:\\content\\article.ws.yaml,source:{dom:{div:{.text:{slot:{name:content}}}},methods:null,style:{.text:{min-height:10rem,-webkit-mask-image:#-webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(0, 0, #0, 1)), color-stop(40%, rgba(0, 0, 0, 1)), color-stop(100%, rgba(0, 0, 0, #0.4)))}},name:content-article,_:{examples:{count:0}},template:div class\comp-content-article\ path\191531137.\>div class\text\ path\191531137.0\>slot name\content\ path\191531137.0.0\>/slot>/div>/div>}},{name:content.meet.the.meme,path:\\content\\meet.the.meme.ws.yaml,source:{dom:{div#1:{h2:{v-text:Meet the Meme},transition:{name:slide,div#2:{v-if:generator,:key:generator?._id,.grid1:{e.generator.square:{:generator:generator},.article1:{v-text:generator.desc.article}},div#3:{class:clear-both}}}}},data:{generator:null,isInited:false},mounted:async function() {\n this.$watch(() > this.$root.params.page, {\n handler: async (page) > {\n if (page ! \home\) {\n this.generator null;\n return;\n }\n await this.init();\n this.isInited true;\n },\n immediate: true\n });\n}\n,methods:{init:async function() {\n this.generator (await this.$root.dbp.generators.sample.popular(1))0;\n}\n},name:content-meet-the-meme,style:{h2:{font-size:3em},.article1:{max-height:10em,overflow:auto},.grid1:{display:grid,grid-template:1fr / 1fr 3fr,gap:1em}},_:{examples:{count:0}},template:div class\comp-content-meet-the-meme\ path\-1242656353.\>h2 v-text\Meet the Meme\ path\-1242656353.0\>/h2>transition name\slide\ path\-1242656353.1\>div v-if\generator\ :key\generator?._id\ path\-1242656353.1.0\>div class\grid1\ path\-1242656353.1.0.0\>e-generator-square :generator\generator\ path\-1242656353.1.0.0.0\>/e-generator-square>div class\article1\ v-text\generator.desc.article\ path\-1242656353.1.0.0.1\>/div>/div>div class\clear-both\ path\-1242656353.1.0.1\>/div>/div>/transition>/div>}},{name:content.poem.full,path:\\content\\poem\\full.ws.yaml,source:{dom:{.box:{.line:{v-for:(line, index) in lines,:class:getLineCssClass(index),v-text:line}}},props:{lines:null},methods:{getLineCssClass:\nfunction(index) {\n if (!index) return null;\n return `ml-l${index}`;\n}\n},name:content-poem-full,style:{.box:{margin:auto,width:fit-content,padding:1rem,-webkit-mask-image:-webkit-gradient(linear, left top, left bottom, from(rgba(0,0,0,0.3)), to(rgba(0,0,0,1)))},.line:{line-height:1em,font-size:200%,font-family:Old Standard TT}},_:{examples:{count:0}},template:div class\comp-content-poem-full box\ path\1035076097.\>div class\line\ v-for\(line, index) in lines\ :class\getLineCssClass(index)\ v-text\line\ path\1035076097.0\>/div>/div>}},{name:content.poem.stanza,path:\\content\\poem\\stanza.ws.yaml,source:{dom:{div:{v-if:item,.lines:{.line.mono:{v-for:line in getLines(),v-text:line}}}},props:{item:null,lines:null},methods:{getLines:function() {\n if (!this.lines) return this.item;\n return this.item.take(this.lines);\n}\n},style:{.comp-content-poem-stanza:{width:100%,height:fit-content,background:linear-gradient(45deg, black, #ffffff30),border:1px solid gray,box-shadow:inset -4px 4px 2px #000},.lines:{padding:1rem},.line:{text-shadow:-5px 5px 3px #000}},name:content-poem-stanza,_:{examples:{count:0}},template:div class\comp-content-poem-stanza\ v-if\item\ path\-1353349913.\>div class\lines\ path\-1353349913.0\>div class\line mono\ v-for\line in getLines()\ v-text\line\ path\-1353349913.0.0\>/div>/div>/div>}},{name:content.recommendations,path:\\content\\recommendations.ws.yaml,source:{dom:{.list:{transition.group:{tag:ul,name:list,li:{v-for:generator in items,e.generator.wide:{:item:generator},:key:generator.generatorID}}}},style:{.list:{display:flex,flex-direction:column,gap:1rem}},props:{items:null},name:content-recommendations,_:{examples:{count:0}},template:div class\comp-content-recommendations list\ path\-1482246043.\>transition-group tag\ul\ name\list\ path\-1482246043.0\>li v-for\generator in items\ :key\generator.generatorID\ path\-1482246043.0.0\>e-generator-wide :item\generator\ path\-1482246043.0.0.0\>/e-generator-wide>/li>/transition-group>/div>}},{name:content.stream,path:\\content\\stream.ws.yaml,source:{dom:{ui.infinite.scroll:{on_scroll:loadMore,transition.group:{tag:ul,name:slide,:class:gridClass,:style:{ gap: gap },li:{class:content-stream-item,v-for:(item, index) in items,:key:$root.getKey(item),div#1:{div#2:{:key:key1},component:{:style:itemStylesindex,:is:itemType.kebabize(),:item:item,v-bind:itemProps}}}},ui.loading:{v-if:isLoading}}},name:content-stream,props:{itemType:null,itemProps:null,getMoreItems:null,gridClass:null,gap:null},data:{pageIndex:0,items:,queue:,visibleItemIndex:null,distancesToVisibility:,isLoading:1,itemStyles:,scrollTop:0,key1:1},mounted:function() {\n this.processQueue();\n this.reset();\n this.$watch(() > this.$root.params.url, this.clear.bind(this), { immediate: true });\n this.$root.$on(\scroll\, this.onScroll.bind(this));\n}\n,methods:{add:function(item) {\n console.log(`item`, item);\n this.scrollTo(this.visibleItemIndex);\n this.items.insertAt(this.visibleItemIndex, item, true);\n}\n,scrollTo:function(index) {\n const items this.getListItemElements();\n const item itemsindex;\n if (!item) return;\n const rect item.getBoundingClientRect();\n const topMargin 250;\n const top rect.top + window.scrollY - topMargin;\n window.scrollTo({ top, behavior: smooth });\n}\n,onScroll:(function() {\n this.scrollTop window.scrollY;\n this.updateVisibleItemIndex();\n this.updateDistancesToVisibility();\n this.updateItemStyles();\n this.key1++;\n}).debounce(100)\n,getItemStyle:function(index) {\n return null;\n if (this.gridClass ! \grid-1\) return null;\n const distance this.distancesToVisibilityindex;\n const getValue (min, scale) > Math.min(1, Math.max(min, 1 - (distance / window.innerHeight * scale)))\n const opacity (getValue(0, 1));\n const grayscale (1 - getValue(0, 1));\n const blur `${Math.round((1 - getValue(0, 0.5)) * 5)}px`;\n return {\n opacity,\n filter: `grayscale(${grayscale}) blur(${blur})`,\n transition: opacity 0.2s, filter 0.2s,\n }\n}\n,getDistanceToVisibility:function(index) {\n // How many pixels until the item is visible (visibleItemIndex index)\n const itemScrollTop this.getItemScrollTop(index);\n const distance (itemScrollTop - this.scrollTop);\n return distance;\n}\n,getItemScrollTop:function(index) {\n const items this.getListItemElements();\n const item itemsindex;\n if (!item) return;\n const rect item.getBoundingClientRect();\n const topMargin 250;\n const top rect.top + window.scrollY - topMargin;\n return top;\n}\n,updateItemStyles:function() {\n for (let i 0; i this.items.length; i++) {\n this.itemStylesi this.getItemStyle(i);\n }\n}\n,updateDistancesToVisibility:function() {\n const count Math.max(this.items.length, this.distancesToVisibility.length);\n for (let i 0; i count; i++) {\n this.distancesToVisibilityi this.getDistanceToVisibility(i);\n }\n}\n,updateVisibleItemIndex:function() {\n const items this.getListItemElements();\n const visibleItemIndex Array.from(items).findIndex(this.isOnScreen.bind(this));\n this.visibleItemIndex visibleItemIndex;\n this.emitVisibleItem();\n}\n,isOnScreen:function(item) {\n const rect item.getBoundingClientRect();\n const viewHeight Math.max(document.documentElement.clientHeight, window.innerHeight);\n return (rect.top > 0) && (rect.bottom viewHeight);\n}\n,reset:async function() {\n this.clear();\n await this.loadMore();\n}\n,clear:function() {\n this.pageIndex 0;\n this.items ;\n}\n,loadMore:function() {\n return new Promise((resolve, reject) > {\n if (!this.getMoreItems) return resolve();\n const pageIndex this.pageIndex++;\n const lastItemID this.items?.last()?._id;\n this.queue.push(async () > {\n this.isLoading++;\n try\n {\n let newItems await this.getMoreItems(pageIndex, lastItemID);\n newItems newItems.exceptBy(this.items, this.$root.getKey);\n this.items.push(...newItems);\n this.updateVisibleItemIndex();\n resolve();\n this.$nextTick(this.onScroll.bind(this));\n }\n finally\n {\n this.isLoading--;\n }\n });\n });\n}\n,processQueue:async function() {\n const next this.queue.shift();\n if (next) await next();\n setTimeout(this.processQueue.bind(this), 300);\n}\n,getListItemElements:function() {\n const items (document.querySelectorAll(li.content-stream-item)||);\n return items; \n}\n,emitVisibleItem:function() {\n this.$emit(\visible-item\, this.visibleItem);\n}\n},computed:{visibleItem:function() {\n return this.itemsthis.visibleItemIndex;\n}\n},watch:{visibleItemIndex:{handler:(function() {\n this.emitVisibleItem();\n}).debounce(100)\n}},style:{ul:{display:grid},.grid-3 > li:{margin-bottom:2em}},_:{examples:{count:0}},template:ui-infinite-scroll class\comp-content-stream\ on_scroll\loadMore\ path\-30902635.\>transition-group tag\ul\ name\slide\ :class\gridClass\ :style\{ gap: gap }\ path\-30902635.0\>li class\content-stream-item\ v-for\(item, index) in items\ :key\$root.getKey(item)\ path\-30902635.0.0\>div path\-30902635.0.0.0\>div :key\key1\ path\-30902635.0.0.0.0\>/div>component :style\itemStylesindex\ :is\itemType.kebabize()\ :item\item\ v-bind\itemProps\ path\-30902635.0.0.0.1\>/component>/div>/li>/transition-group>div :style\{ width: 30em }\ path\-30902635.1\>ui-value :value\items\ path\-30902635.1.0\>/ui-value>/div>ui-loading v-if\isLoading\ path\-30902635.2\>/ui-loading>/ui-infinite-scroll>}},{name:content.threads.recent,path:\\content\\threads\\recent.ws.yaml,source:{dom:{.thread-teasers:{e.thread.teaser:{v-for:thread in threads,:thread:thread,:show-posts:true}}},props:null,data:{threads:},mounted:async function() {\n this.threads await this.$root.dbp.threads.select.recent();\n}\n,style:{.thread-teasers:{display:flex,flex-wrap:wrap},.thread-teasers > div:{width:15em},.comp-e-thread-teaser:{margin-bottom:2em}},name:content-threads-recent,_:{examples:{count:0}},template:div class\comp-content-threads-recent thread-teasers\ path\-1639663019.\>e-thread-teaser v-for\thread in threads\ :thread\thread\ :show-posts\true\ path\-1639663019.0\>/e-thread-teaser>/div>}},{name:content.title,path:\\content\\title.ws.yaml,source:{dom:{div#1:{:class:getCssClass(),div#2:{class:content-title site-width,div#3:{class:background},transition.group:{name:list,tag:ul,li:{:key:title||Date.now(),ui.image:{v-if:imageID,:imageID:imageID,:url:url},ui.large.title:{:text:title}}}},div#4:{class:spacer}}},props:{imageID:null,title:null,url:null},data:{isStuck:false},methods:{onScroll:function() {\n const scrollTop window.scrollY;\n this.isStuck scrollTop > 0;\n}\n,getCssClass:function() {\n return { stuck: this.isStuck };\n}\n},mounted:function() {\n window.addEventListener(scroll, this.onScroll);\n}\n,style:{.stuck .title:{font-size:6vh,transform:translateX(-10%)},.background:{background:linear-gradient(rgba(0, 0, 0, 1), rgba(0, 0, 0, 0)),position:absolute,width:100%,height:7.5rem,top:0},.content-title:{position:fixed,top:7rem,z-index:10,border-radius:0,transition:0s !important},.comp-ui-image:{position:relative,top:1rem,max-width:15% !important,margin:0 1em,float:left,box-shadow:-0.5rem 0.5rem 0.5rem #000000,z-index:20},.comp-ui-image img:{aspect-ratio:1,object-fit:cover,max-height:7rem},.comp-ui-large-title:{padding-top:0.4em !important,z-index:10},.spacer:{height:6rem}},name:content-title,_:{examples:{count:0}},template:div class\comp-content-title\ :class\getCssClass()\ path\-1385872221.\>div class\content-title site-width\ path\-1385872221.0\>div class\background\ path\-1385872221.0.0\>/div>transition-group name\list\ tag\ul\ path\-1385872221.0.1\>li :key\title||Date.now()\ path\-1385872221.0.1.0\>ui-image v-if\imageID\ :imageID\imageID\ :url\url\ path\-1385872221.0.1.0.0\>/ui-image>ui-large-title :text\title\ path\-1385872221.0.1.0.1\>/ui-large-title>/li>/transition-group>/div>div class\spacer\ path\-1385872221.1\>/div>/div>}},{name:e.builder.examples,path:\\e\\builder\\examples.ws.yaml,source:{dom:{div#1:{.builders:{.flex1#1:{v-if:adviceAnimal,div#2:{class:column1,e.builder#1:{:builder:adviceAnimal,:show-help:false,:media-created:onMediaCreated},div#3:{v-if:false,transition.group#1:{name:list,tag:div,class:grid2,e.generator.square:{v-for:generator in moreGenerators,:generator:generator,:key:generator._id}}}},div#4:{class:column2,.list1#1:{div#5:{h2#1:{v-text:adviceAnimal.name.pluralize()},div#6:{v-text:adviceAnimal.desc}},.list1#2:{transition.group#2:{name:list,tag:div,class:list-alternating,e.generator.teaser2:{v-for:generator in teaserGenerators,:generator:generator,:key:generator._id}},.mt-l1:{ui.link:{v-if:teaserGenerators?.length,class:more-link,:url:/advice-animals,:text:see all Advice Animalsβ¦}}}}}},.flex1#2:{v-if:videoVertical,div#7:{class:column2,.list1#3:{div#8:{h2#2:{v-text:videoVertical.name.pluralize()},div#9:{v-text:videoVertical.desc}},.flex.gap-1:{div#10:{e.media#1:{:mediaID:733550349,:editable:true,:media-created:onMediaCreated}},div#11:{e.media#2:{:mediaID:733588104,:editable:true,:media-created:onMediaCreated}}}}},div#12:{class:column1,e.media:{:mediaID:733469675,:editable:true,:media-created:onMediaCreated}},e.builder#2:{v-if:false,class:column1,:builder:videoVertical,:show-help:false,:media-created:onMediaCreated}},.flex1#3:{v-if:(false && famousQuote),e.builder#3:{class:column1,:builder:famousQuote,:show-help:false,:media-created:onMediaCreated},div#13:{class:column2,.list1#4:{div#14:{h2#3:{v-text:famousQuote.name.pluralize()},div#15:{v-text:famousQuote.desc}},div#16:{class:list-alternating}}}}}}},props:null,data:{popularGenerators:null},mounted:async function() {\n // Random page index between 0 and 100\n const pageIndex Math.round((Math.random() * 5) | 0);\n this.popularGenerators (await this.$root.dbp.generators.select.popular(pageIndex));\n}\n,methods:{onMediaCreated:function (media) {\n this.$root.notify(\e.media\, media);\n}\n},computed:{teaserGenerators:function () {\n return this.popularGenerators?.shuffle().take(8);\n}\n,moreGenerators:function () {\n return this.popularGenerators\n ?.filter(g > (!this.teaserGenerators?.find(g2 > (g2._id g._id))))\n .take(10)\n}\n,adviceAnimal:function () {\n return this.builders\Advice-Animal\;\n}\n,videoVertical:function () {\n return this.builders\Video-Vertical\;\n}\n,famousQuote:function () {\n return this.builders\Famous-Quote\;\n}\n,builders:function () {\n const builders {};\n for (const builder of Object.values(this.$root.builders.all))\n {\n buildersbuilder.urlName builder;\n }\n return builders;\n}\n},style:{.builders > div:nth-child(1) .comp-ui-button:{display:none !important},.more-link:{font-size:160%,text-align:center},.builders:{display:flex,flex-direction:column,gap:4em},.grid2:{display:flex,flex-wrap:wrap,justify-content:center,gap:1em},.grid2 > div:{width:30%},.flex1:{display:flex,gap:2em},.list1:{display:flex,flex-direction:column,gap:1em},.column1:{width:33%},.column2:{width:67%},h2:{font-size:3rem},h3:{font-size:1.5rem},.list-alternating:{display:flex,flex-direction:column,gap:1em},.list-alternating > *:nth-child(odd) .flex:{flex-direction:row-reverse},.list-alternating > *:nth-child(even) .flex:{flex-direction:row},.comp-e-template-help:{width:20em}},name:e-builder-examples,template:div class\comp-e-builder-examples\ path\1519228837.\>div class\builders\ path\1519228837.0\>div class\flex1\ v-if\adviceAnimal\ path\1519228837.0.0\>div class\column1\ path\1519228837.0.0.0\>e-builder :builder\adviceAnimal\ :show-help\false\ :media-created\onMediaCreated\ path\1519228837.0.0.0.0\>/e-builder>div v-if\false\ path\1519228837.0.0.0.1\>transition-group class\grid2\ name\list\ tag\div\ path\1519228837.0.0.0.1.0\>e-generator-square v-for\generator in moreGenerators\ :generator\generator\ :key\generator._id\ path\1519228837.0.0.0.1.0.0\>/e-generator-square>/transition-group>/div>/div>div class\column2\ path\1519228837.0.0.1\>div class\list1\ path\1519228837.0.0.1.0\>div path\1519228837.0.0.1.0.0\>h2 v-text\adviceAnimal.name.pluralize()\ path\1519228837.0.0.1.0.0.0\>/h2>div v-text\adviceAnimal.desc\ path\1519228837.0.0.1.0.0.1\>/div>/div>div class\list1\ path\1519228837.0.0.1.0.1\>transition-group class\list-alternating\ name\list\ tag\div\ path\1519228837.0.0.1.0.1.0\>e-generator-teaser2 v-for\generator in teaserGenerators\ :generator\generator\ :key\generator._id\ path\1519228837.0.0.1.0.1.0.0\>/e-generator-teaser2>/transition-group>div class\mt-l1\ path\1519228837.0.0.1.0.1.1\>ui-link class\more-link\ v-if\teaserGenerators?.length\ :url\/advice-animals\ :text\see all Advice Animalsβ¦\ path\1519228837.0.0.1.0.1.1.0\>/ui-link>/div>/div>/div>/div>/div>div class\flex1\ v-if\videoVertical\ path\1519228837.0.1\>div class\column2\ path\1519228837.0.1.0\>div class\list1\ path\1519228837.0.1.0.0\>div path\1519228837.0.1.0.0.0\>h2 v-text\videoVertical.name.pluralize()\ path\1519228837.0.1.0.0.0.0\>/h2>div v-text\videoVertical.desc\ path\1519228837.0.1.0.0.0.1\>/div>/div>div class\flex gap-1\ path\1519228837.0.1.0.0.1\>div path\1519228837.0.1.0.0.1.0\>e-media :mediaID\733550349\ :editable\true\ :media-created\onMediaCreated\ path\1519228837.0.1.0.0.1.0.0\>/e-media>/div>div path\1519228837.0.1.0.0.1.1\>e-media :mediaID\733588104\ :editable\true\ :media-created\onMediaCreated\ path\1519228837.0.1.0.0.1.1.0\>/e-media>/div>/div>/div>/div>div class\column1\ path\1519228837.0.1.1\>e-media :mediaID\733469675\ :editable\true\ :media-created\onMediaCreated\ path\1519228837.0.1.1.0\>/e-media>/div>e-builder class\column1\ v-if\false\ :builder\videoVertical\ :show-help\false\ :media-created\onMediaCreated\ path\1519228837.0.1.2\>/e-builder>/div>div class\flex1\ v-if\(false && famousQuote)\ path\1519228837.0.2\>e-builder class\column1\ :builder\famousQuote\ :show-help\false\ :media-created\onMediaCreated\ path\1519228837.0.2.0\>/e-builder>div class\column2\ path\1519228837.0.2.1\>div class\list1\ path\1519228837.0.2.1.0\>div path\1519228837.0.2.1.0.0\>h2 v-text\famousQuote.name.pluralize()\ path\1519228837.0.2.1.0.0.0\>/h2>div v-text\famousQuote.desc\ path\1519228837.0.2.1.0.0.1\>/div>/div>div class\list-alternating\ path\1519228837.0.2.1.0.1\>/div>/div>/div>/div>/div>/div>,_:{examples:{count:0}}}},{name:e.builder,path:\\e\\builder.ws.yaml,source:{dom:{component:{v-if:builder,:is:$root.getBuilderComponentName(builder),:editable:true,:builder:builder,:key:builder._id,:show-help:showHelp,:media-created:mediaCreated,:cancel:cancel}},props:{builder:null,showHelp:true,mediaCreated:null,cancel:null},name:e-builder,_:{examples:{count:0}},template:component class\comp-e-builder\ v-if\builder\ :is\$root.getBuilderComponentName(builder)\ :editable\true\ :builder\builder\ :key\builder._id\ :show-help\showHelp\ :media-created\mediaCreated\ :cancel\cancel\ path\926534418.\>/component>}},{name:e.comment.create,path:\\e\\comment\\create.ws.yaml,source:{dom:{.grid1:{.media-preview:{class:clickable,on_click:onClickMediaPreview,transition:{name:list,e.media:{v-if:media,:key:getMediaKey(media),:media:media,:square:true,:show-footer:false},e.generator.square:{v-if:!media,:show-tooltip:false,:show-anonymous:true}}},ui.input.text.box:{:hint:hint,:value:value,:multiline:true,on_input:onInputText}}},props:{value:null,media:null,newThread:true},data:null,methods:{onClickMediaPreview:function() {\n this.$emit(click-media-preview);\n}\n,getMediaKey:function(media) {\n if (!media) return null;\n return JSON.stringify(media);\n}\n,onInputText:function(text) {\n this.$emit(input, text);\n}\n},computed:{hint:function () {\n return this.newThread ? \whats on your mind?\ : \commentβ¦\;\n}\n},watch:null,style:{.grid1:{display:flex,gap:1em},.media-preview:{width:6em}},name:e-comment-create,_:{examples:{count:0}},template:div class\comp-e-comment-create grid1\ path\-322969580.\>div class\clickable media-preview\ on_click\onClickMediaPreview\ path\-322969580.0\>transition name\list\ path\-322969580.0.0\>e-media v-if\media\ :key\getMediaKey(media)\ :media\media\ :square\true\ :show-footer\false\ path\-322969580.0.0.0\>/e-media>e-generator-square v-if\!media\ :show-tooltip\false\ :show-anonymous\true\ path\-322969580.0.0.1\>/e-generator-square>/transition>/div>ui-input-text-area :hint\hint\ :value\value\ on_input\onInputText\ path\-322969580.1\>/ui-input-text-area>/div>}},{name:e.comment.list,path:\\e\\comment\\list.ws.yaml,source:{dom:{div:{h3:{v-text:comments.length + comments},ui.list:{:items:topComments,v-slot:slotProps,e.comment:{:item:slotProps.item}}}},props:{entityID:null},data:{comments:},computed:{topComments:function() {\n return this.comments?.sortBy(c > -c.totalVotesScore).take(30);\n}\n},watch:{entityID:{handler:async function() {\n this.comments await this.$root.dbp.comments.select.by(this.entityID);\n}\n,immediate:true}},style:{ul:{gap:3px}},name:e-comment-list,_:{examples:{count:0}},template:div class\comp-e-comment-list\ path\616682934.\>h3 v-text\comments.length + comments\ path\616682934.0\>/h3>ui-list :items\topComments\ v-slot\slotProps\ path\616682934.1\>e-comment :item\slotProps.item\ path\616682934.1.0\>/e-comment>/ui-list>/div>}},{name:e.comment,path:\\e\\comment.ws.yaml,source:{dom:{.comment:{.comment-text:{v-text:item.text},.vote-score:{v-text:item.totalVotesScore}}},props:{item:null},style:{.comment:{display:grid,grid-template:1fr / 1fr 4em,max-height:2em,overflow:hidden,background:#ffffff30,padding:0.3em 0.6em},.comment:hover:{max-height:10em},.vote-score:{text-align:right,opacity:0.5},.vote-score:before:{content:+}},name:e-comment,_:{examples:{count:0}},template:div class\comp-e-comment comment\ path\1645988310.\>div class\comment-text\ v-text\item.text\ path\1645988310.0\>/div>div class\vote-score\ v-text\item.totalVotesScore\ path\1645988310.1\>/div>/div>}},{name:e.format.base,path:\\e\\format\\base.ws.yaml,source:{dom:{div:{:style:mediaStyle,e.template.editor:{:builder:cBuilder,:temp:temp,:editable:editable,:show-help:showHelp,:show-property-editor:showPropertyEditor,:cancel:cancel,:media-created:onMediaCreated}}},props:{builder:null,media:null,editable:false,showHelp:true,showPropertyEditor:false,mediaCreated:null,cancel:null},data:{temp:null},methods:{initFromBuilder:function (builder) {\n if (!builder) return;\n if (this.temp) return;\n this.temp this.$root.builderSourceToTemplate(builder.format, builder.source);\n}\n,onMediaCreated:async function (media) {\n //this.initFromBuilder(this.builder);\n if (this.mediaCreated) await this.mediaCreated(media);\n}\n,getMediaStyle:function (builder) {\n const style {};\n style.margin \0 auto\;\n if (builder?.source?.size?.max?.width) stylemax-width `${(parseInt(builder?.source?.size?.max?.width) + (!this.editable ? 0 : 15))}em`;\n return style;\n}\n},computed:{cBuilder:function () {\n return this.builder || this.$root.builders.allthis.media?.builderID;\n}\n,mediaStyle:function () {\n return this.getMediaStyle(this.cBuilder);\n}\n},watch:{cBuilder:{handler:function(builder) {\n this.initFromBuilder(builder);\n}\n,immediate:true},builder:{handler:function(builder) {\n if (this.cBuilder) return;\n this.cBuilder builder;\n}\n,immediate:true},media:{handler:async function(media) {\n if (!media) return;\n this.temp await this.$root.mediaToTemp(media);\n}\n,immediate:true}},name:e-format-base,_:{examples:{count:0}},template:div class\comp-e-format-base\ :style\mediaStyle\ path\-808258977.\>e-template-editor :builder\cBuilder\ :temp\temp\ :editable\editable\ :show-help\showHelp\ :show-property-editor\showPropertyEditor\ :cancel\cancel\ :media-created\onMediaCreated\ path\-808258977.0\>/e-template-editor>/div>}},{name:e.format.image.grid,path:\\e\\format\\image.grid.ws.yaml,source:{dom:{e.format.base:{:builder:builder,:media:media,:editable:editable,:show-help:showHelp,:media-created:mediaCreated,on_cancel:$emit(cancel)}},props:{builder:null,media:null,editable:false,showHelp:true,mediaCreated:null},data:null,methods:null,name:e-format-image-grid,_:{examples:{count:0}},template:e-format-base class\comp-e-format-image-grid\ :builder\builder\ :media\media\ :editable\editable\ :show-help\showHelp\ :media-created\mediaCreated\ on_cancel\$emit(cancel)\ path\-603568889.\>/e-format-base>}},{name:e.format.layers,path:\\e\\format\\layers.ws.yaml,source:{dom:{e.format.base:{:builder:builder,:media:media,:editable:editable,:show-help:showHelp,:media-created:mediaCreated,:cancel:cancel}},props:{builder:null,media:null,editable:false,showHelp:true,mediaCreated:null,cancel:null},data:null,methods:null,name:e-format-layers,_:{examples:{count:0}},template:e-format-base class\comp-e-format-layers\ :builder\builder\ :media\media\ :editable\editable\ :show-help\showHelp\ :media-created\mediaCreated\ :cancel\cancel\ path\938677584.\>/e-format-base>}},{name:e.format.template,path:\\e\\format\\template.ws.yaml,source:{dom:{div:{e.template.editor:{ref:TemplateEditor1,:temp:item,:show-property-editor:false,on_cancel:$emit(cancel)}}},props:{item:null},name:e-format-template,_:{examples:{count:0}},template:div class\comp-e-format-template\ path\105070856.\>e-template-editor ref\TemplateEditor1\ :temp\item\ :show-property-editor\false\ on_cancel\$emit(cancel)\ path\105070856.0\>/e-template-editor>/div>}},{name:e.generator.large,path:\\e\\generator\\large.ws.yaml,source:{dom:{div:{v-if:generator,ui.image:{ref:image1,:imageID:generator.imageID}}},props:{generator:null},data:null,name:e-generator-large,_:{examples:{count:0}},template:div class\comp-e-generator-large\ v-if\generator\ path\517672151.\>ui-image ref\image1\ :imageID\generator.imageID\ path\517672151.0\>/ui-image>/div>}},{name:e.generator.list,path:\\e\\generator\\list.ws.yaml,source:{dom:{transition.group:{name:list,tag:ul,li:{v-for:generator in generators,:key:generator._id,e.generator.wide2:{:generator:generator}}}},props:{generators:null},data:null,watch:null,style:{li:{margin-top:0.5em}},name:e-generator-list,_:{examples:{count:0}},template:transition-group class\comp-e-generator-list\ name\list\ tag\ul\ path\-398935166.\>li v-for\generator in generators\ :key\generator._id\ path\-398935166.0\>e-generator-wide2 :generator\generator\ path\-398935166.0.0\>/e-generator-wide2>/li>/transition-group>}},{name:e.generator.search,path:\\e\\generator\\search.ws.yaml,source:{dom:{div:{ui.input.text.box:{type:search,icon:π,hint:searchβ¦,v-model:query},transition:{name:slide,ui.loading:{v-if:isSearching}},e.generator.list:{:generators:generators}}},props:null,data:{query:null,generators:,isSearching:true,searchTimer:null},mounted:async function() {\n this.search(this.query);\n}\n,methods:{search:async function(query) {\n this.generators await this.$root.dbp.generators.select.search(query);\n this.isSearching false;\n}\n},watch:{query:{handler:async function(query) {\n this.isSearching true;\n if (this.searchTimer) clearTimeout(this.searchTimer);\n this.searchTimer setTimeout(this.search.bind(this, query), 400);\n}\n,immediate:false}},style:{li:{margin-top:0.5em}},name:e-generator-search,_:{examples:{count:0}},template:div class\comp-e-generator-search\ path\-928430196.\>ui-input-text-box type\search\ icon\π\ hint\searchβ¦\ v-model\query\ path\-928430196.0\>/ui-input-text-box>e-generator-list :generators\generators\ path\-928430196.1\>/e-generator-list>/div>}},{name:e.generator.select,path:\\e\\generator\\select.ws.yaml,source:{dom:{div:{ui.input.text.box:{type:search,icon:π,hint:searchβ¦,v-model:query},ui.loading:{class:absolute-center,v-if:isLoading},.grid1:{ui.image:{v-for:generator in visibleGenerators,:class:{ selected: (dValue?._id generator._id) },:tooltip:generator.displayName,:imageID:generator.imageID,:key:generator.generatorID,:square:true,on_click:() > onClick(generator)}}}},props:{value:null,defaultGeneratorID:null},data:{query:null,dValue:null,generators:null,defaultGenerator:null,isLoading:false,generatorsQueue:null},created:async function() {\n this.generatorsQueue new TaskQueue();\n}\n,mounted:async function() {\n await this.init();\n}\n,methods:{search:async function(query) {\n if (!this.generatorsQueue) this.generatorsQueue new TaskQueue();\n this.generatorsQueue.enqueue(async () > {\n try\n {\n this.generators (await this.getGenerators(query));\n }\n finally\n {\n this.isLoading false;\n }\n });\n}\n,getGenerators:async function(query) {\n if (query) return (await this.$root.dbp.generators.select.search(query));\n if (this.defaultGenerator) {\n let gens (await this.$root.dbp.generators.select.related(this.defaultGenerator?.urlName));\n gens.removeByField(\_id\, this.defaultGenerator?._id)\n gens.unshift(this.defaultGenerator);\n gens gens.filter(g > g);\n return gens;\n }\n return (await this.$root.dbp.generators.select.popular());\n}\n,init:async function () {\n await this.search(this.query);\n}\n,onClick:function (generator) {\n this.$emit(input, generator)\n}\n},watch:{value:{handler:async function(value) {\n this.dValue value;\n}\n,immediate:true},query:{handler:(async function(query) {\n this.search(query);\n}).debounce(400)\n,immediate:true},query2:{handler:function(query) {\n this.isLoading true;\n}\n},defaultGeneratorID:{handler:async function(defaultGeneratorID) {\n this.defaultGenerator (!defaultGeneratorID ? null : (await this.$root.dbp.generators.select.one(defaultGeneratorID)));\n if (this.defaultGenerator) {\n await this.init();\n this.$emit(input, this.defaultGenerator);\n }\n}\n,immediate:true}},computed:{visibleGenerators:function() {\n const gens ...(this.generators||);\n return gens;\n}\n,query2:function() {\n return this.query;\n}\n},style:{.grid1:{display:flex !important,flex-wrap:wrap;,justify-content:center;,gap:0.3em !important},.grid1 > div:{width:calc(20% - 0.3em)},.comp-ui-image:{filter:grayscale(1),opacity:0.5,cursor:pointer,transition:0.3s},.comp-ui-image:hover:{filter:grayscale(0),opacity:1,transition:0s}},name:e-generator-select,_:{examples:{count:0}},template:div class\comp-e-generator-select\ path\-928114976.\>ui-input-text-box type\search\ icon\π\ hint\searchβ¦\ v-model\query\ path\-928114976.0\>/ui-input-text-box>ui-loading class\absolute-center\ v-if\isLoading\ path\-928114976.1\>/ui-loading>div class\grid1\ path\-928114976.2\>ui-image v-for\generator in visibleGenerators\ :class\{ selected: (dValue?._id generator._id) }\ :tooltip\generator.displayName\ :imageID\generator.imageID\ :key\generator.generatorID\ :square\true\ on_click\() > onClick(generator)\ path\-928114976.2.0\>/ui-image>/div>/div>}},{name:e.generator.small,path:\\e\\generator\\small.ws.yaml,source:{dom:{ui.link:{class:grayish,:url:$root.url.generator(item),.badge:{ui.image:{:imageID:item.imageID}}}},props:{item:null},style:{.title:{font-size:120%},.badge:{display:flex,margin-top:1rem},.comp-ui-image:{width:20% !important,margin-right:1rem}},name:e-generator-small,_:{examples:{count:0}},template:ui-link class\comp-e-generator-small grayish\ :url\$root.url.generator(item)\ path\524478115.\>div class\badge\ path\524478115.0\>ui-image :imageID\item.imageID\ path\524478115.0.0\>/ui-image>/div>/ui-link>}},{name:e.generator.square,path:\\e\\generator\\square.ws.yaml,source:{dom:{div:{ui.image#1:{v-if:!generator,class:anonymous,tooltip:Anonymous,:src:https://upload.wikimedia.org/wikipedia/commons/thumb/a/a6/Anonymous_emblem.svg/1200px-Anonymous_emblem.svg.png,on_click:$emit(click)},ui.link:{v-else-if:generator,:enabled:link,:url:$root.url.generator(generator),ui.image#2:{:tooltip:showTooltip && generator.displayName,:imageID:generator.imageID,:key:generator.generatorID,:square:true,on_click:$emit(click, generator)},.name:{v-text:generator.displayName}}}},props:{generator:null,showTooltip:true,showAnonymous:false,link:true},computed:null,style:{.anonymous:{opacity:0.5},.name:{background:black;,border-radius:0;,position:absolute;,bottom:0;,white-space:nowrap;,overflow:hidden;,text-align:center;}},name:e-generator-square,_:{examples:{count:0}},template:div class\comp-e-generator-square\ path\-916767999.\>ui-image class\anonymous\ v-if\!generator\ tooltip\Anonymous\ :src\https://upload.wikimedia.org/wikipedia/commons/thumb/a/a6/Anonymous_emblem.svg/1200px-Anonymous_emblem.svg.png\ on_click\$emit(click)\ path\-916767999.0\>/ui-image>ui-link v-else-if\generator\ :enabled\link\ :url\$root.url.generator(generator)\ path\-916767999.1\>ui-image :tooltip\showTooltip && generator.displayName\ :imageID\generator.imageID\ :key\generator.generatorID\ :square\true\ on_click\$emit(click, generator)\ path\-916767999.1.0\>/ui-image>div class\name\ v-text\generator.displayName\ path\-916767999.1.1\>/div>/ui-link>/div>}},{name:e.generator.teaser,path:\\e\\generator\\teaser.ws.yaml,source:{dom:{ui.link:{:url:$root.url.generator(item),ui.card1:{div#1:{class:grid-1-3,div#2:{ui.image:{:imageID:item.imageID}},div#3:{content.poem.stanza:{v-if:item.desc?.poem,class:show-on-hover,:item:$root.getRandomStanza(item.desc?.poem),:lines:1}}}}}},props:{item:null},style:{.grid-1-3:{gap:1vw},.comp-content-poem-stanza:{width:100% !important,font-size:140%}},name:e-generator-teaser,_:{examples:{count:0}},template:ui-link class\comp-e-generator-teaser\ :url\$root.url.generator(item)\ path\-899800012.\>ui-card1 path\-899800012.0\>div class\grid-1-3\ path\-899800012.0.0\>div path\-899800012.0.0.0\>ui-image :imageID\item.imageID\ path\-899800012.0.0.0.0\>/ui-image>/div>div path\-899800012.0.0.1\>content-poem-stanza class\show-on-hover\ v-if\item.desc?.poem\ :item\$root.getRandomStanza(item.desc?.poem)\ :lines\1\ path\-899800012.0.0.1.0\>/content-poem-stanza>/div>/div>/ui-card1>/ui-link>}},{name:e.generator.teaser2,path:\\e\\generator\\teaser2.ws.yaml,source:{dom:{ui.link:{v-if:cGenerator,:url:$root.url.generator(cGenerator),.flex.gap-1:{div#1:{:style:{ width: 15% },ui.image:{:imageID:cGenerator.imageID}},div#2:{:style:{ width: 85% },h3:{v-text:cGenerator.displayName},div#3:{v-text:teaserArticle}}}}},props:{generator:null,item:null},computed:{cGenerator:function () {\n return this.generator || this.item;\n}\n,teaserArticle:function () {\n const paragraphs (this.cGenerator.desc?.article?.split(\\\n\)\n .map(p > p.trim())\n .filter(p > p.length > 100)) || ;\n const par (paragraphs1 || paragraphs0);\n const text par?.split(\.\).filter(s > (s?.length > 100))0;\n if (!text) return null;\n return `${text}.`;\n}\n},name:e-generator-teaser2,_:{examples:{count:0}},template:ui-link class\comp-e-generator-teaser2\ v-if\cGenerator\ :url\$root.url.generator(cGenerator)\ path\-2123996546.\>div class\flex gap-1\ path\-2123996546.0\>div :style\{ width: 15% }\ path\-2123996546.0.0\>ui-image :imageID\cGenerator.imageID\ path\-2123996546.0.0.0\>/ui-image>/div>div :style\{ width: 85% }\ path\-2123996546.0.1\>h3 v-text\cGenerator.displayName\ path\-2123996546.0.1.0\>/h3>div v-text\teaserArticle\ path\-2123996546.0.1.1\>/div>/div>/div>/ui-link>}},{name:e.generator.wide,path:\\e\\generator\\wide.ws.yaml,source:{dom:{ui.link:{:url:url,ui.card1:{class:grayish,.show-on-hover-container:{.grid:{ui.image:{:imageID:item.imageID},div:{v-text:item.displayName}},content.poem.stanza:{v-if:false && item.desc?.poem,class:show-on-hover,:item:$root.getRandomStanza(item.desc?.poem)}}}}},props:{item:null},style:{.comp-e-generator-wide:{display:block,margin-bottom:1rem},.comp-ui-image:{display:block},.show-on-hover-container:hover img:{transform:scale(1.5)},.grid:{grid-template:1fr / 1fr 3fr,gap:1rem},img:{aspect-ratio:1,width:100%,object-fit:cover}},computed:{url:function() {\n return `/${this.item.urlName}`;\n}\n},name:e-generator-wide,_:{examples:{count:0}},template:ui-link class\comp-e-generator-wide\ :url\url\ path\-398607945.\>ui-card1 class\grayish\ path\-398607945.0\>div class\show-on-hover-container\ path\-398607945.0.0\>div class\grid\ path\-398607945.0.0.0\>ui-image :imageID\item.imageID\ path\-398607945.0.0.0.0\>/ui-image>div v-text\item.displayName\ path\-398607945.0.0.0.1\>/div>/div>content-poem-stanza class\show-on-hover\ v-if\false && item.desc?.poem\ :item\$root.getRandomStanza(item.desc?.poem)\ path\-398607945.0.0.1\>/content-poem-stanza>/div>/ui-card1>/ui-link>}},{name:e.generator.wide2,path:\\e\\generator\\wide2.ws.yaml,source:{dom:{ui.link:{:url:$root.url.generator(generator),.grid:{class:grayish,ui.image:{:imageID:generator.imageID},div:{v-text:generator.displayName}}}},props:{generator:null},style:{.grid:{grid-template:1fr / 2.5em 1fr,gap:0.5em}},name:e-generator-wide2,_:{examples:{count:0}},template:ui-link class\comp-e-generator-wide2\ :url\$root.url.generator(generator)\ path\528055643.\>div class\grayish grid\ path\528055643.0\>ui-image :imageID\generator.imageID\ path\528055643.0.0\>/ui-image>div v-text\generator.displayName\ path\528055643.0.1\>/div>/div>/ui-link>}},{name:e.instance.create,path:\\e\\instance\\create.ws.yaml,source:{dom:{div#1:{transition#1:{name:slide,e.generator.select:{v-show:!generator && showGeneratorSelect,v-model:generator || tempInstance.generator,on_input:showGeneratorSelect false}},.container:{:class:layout,div#2:{transition#2:{name:slide,e.instance:{class:{ clickable: !generator },v-if:((layout horizontal) || hasText),:item:tempInstance,:key:tempInstance.generator?.generatorID,:show-create-post:false,:show-footer:false,on_click:showGeneratorSelect !showGeneratorSelect}}},.inputs:{input#1:{v-model:tempInstance.text0,placeholder:top text,on_focus:onFocus},input#2:{v-model:tempInstance.text1,placeholder:bottom text,on_focus:onFocus},transition#3:{name:slide,.text-center:{ui.button:{v-if:showCreateButton && hasText,text:create,:click:create}}}}}}},props:{value:null,generator:null,layout:null,showCreateButton:true},data:{tempInstance:getNewTempInstance(),showGeneratorSelect:false,isCreating:false},methods:{create:async function() {\n this.isCreating true;\n try\n {\n const instance await this.$root.dbp.instances.create.one(null, this.tempInstance.generator?._id, null, this.tempInstance.text0, this.tempInstance.text1);\n this.clear();\n this.$emit(\created\, instance);\n }\n finally\n {\n this.isCreating false;\n }\n}\n,clear:function() {\n this.tempInstance.text0 null;\n this.tempInstance.text1 null;\n}\n,onFocus:function(e) {\n if (!this.tempInstance.generator) this.showGeneratorSelect true;\n}\n,getNewTempInstance:function() {\n return { generator: null, imageID: null, text0: null, text1: null };\n}\n},computed:{hasContent:function() {\n return (this.hasGenerator && this.hasText) ? true : false;\n}\n,hasGenerator:function() {\n return !!this.tempInstance.generator;\n}\n,hasText:function() {\n return !!this.tempInstance.text0 || !!this.tempInstance.text1;\n}\n},watch:{value:{handler:function(newValue) {\n this.tempInstance newValue || this.getNewTempInstance();\n}\n,immediate:true},generator:{handler:function(generator) {\n this.tempInstance.generator generator;\n}\n,immediate:true},tempInstance:{handler:function(newTempInstance) {\n this.$emit(\input\, newTempInstance);\n}\n,deep:true},hasContent:function(newHasContent) {\n this.$emit(\has-content\, newHasContent);\n}\n},name:e-instance-create,style:{.container:{margin-bottom:2rem},.horizontal:{display:grid !important,grid-template:1fr / 1fr 3fr,gap:1rem},img:{margin-bottom:1rem},.inputs input:{text-align:center,text-transform:uppercase,padding:0.3em 0.5em !important,margin-bottom:0.5rem},button:{display:block,width:70%,margin:0.5rem auto}},_:{examples:{count:0}},template:div class\comp-e-instance-create\ path\-903297812.\>transition name\slide\ path\-903297812.0\>e-generator-select v-show\!generator && showGeneratorSelect\ v-model\generator || tempInstance.generator\ on_input\showGeneratorSelect false\ path\-903297812.0.0\>/e-generator-select>/transition>div class\container\ :class\layout\ path\-903297812.1\>div path\-903297812.1.0\>transition name\slide\ path\-903297812.1.0.0\>e-instance class\{ clickable: !generator }\ v-if\((layout horizontal) || hasText)\ :item\tempInstance\ :key\tempInstance.generator?.generatorID\ :show-create-post\false\ :show-footer\false\ on_click\showGeneratorSelect !showGeneratorSelect\ path\-903297812.1.0.0.0\>/e-instance>/transition>/div>div class\inputs\ path\-903297812.1.1\>input v-model\tempInstance.text0\ placeholder\top text\ on_focus\onFocus\ path\-903297812.1.1.0\/>input v-model\tempInstance.text1\ placeholder\bottom text\ on_focus\onFocus\ path\-903297812.1.1.1\/>transition name\slide\ path\-903297812.1.1.2\>div class\text-center\ path\-903297812.1.1.2.0\>ui-button v-if\showCreateButton && hasText\ text\create\ :click\create\ path\-903297812.1.1.2.0.0\>/ui-button>/div>/transition>/div>/div>/div>}},{name:e.instance.wide,path:\\e\\instance\\wide.ws.yaml,source:{dom:{div#1:{v-if:instance,div#2:{class:grayish,:url:$root.url.instance(instance),.grid:{ui.image:{:imageID:instance.imageID},div#3:{div#4:{v-text:instance.text0},div#5:{v-text:instance.text1}}}}}},props:{instance:null},style:{.grid:{grid-template:1fr / 4em 1fr,gap:0.5em},div:{text-transform:uppercase,font-family:monospace}},name:e-instance-wide,_:{examples:{count:0}},template:div class\comp-e-instance-wide\ v-if\instance\ path\-1269625149.\>div class\grayish\ :url\$root.url.instance(instance)\ path\-1269625149.0\>div class\grid\ path\-1269625149.0.0\>ui-image :imageID\instance.imageID\ path\-1269625149.0.0.0\>/ui-image>div path\-1269625149.0.0.1\>div v-text\instance.text0\ path\-1269625149.0.0.1.0\>/div>div v-text\instance.text1\ path\-1269625149.0.0.1.1\>/div>/div>/div>/div>/div>}},{name:e.instance,path:\\e\\instance.ws.yaml,source:{dom:{div#1:{on_click:$emit(click),v-if:instance,ui.link:{:url:$root.url.instance(instance),class:instance,div#2:{ui.image#1:{ref:image1,:imageID:imageID,:url:imageUrl,on_change:updateImageSize},div#3:{class:spacer,ui.image#2:{ref:image1,:imageID:imageID,:url:imageUrl}},.texts:{v-if:!instanceImage,.text:{v-for:(text, index) in instance.text0, instance.text1,v-text:text,:style:{ fontSize: fontSizesindex }}}}},.footer:{v-if:showFooter,e.generator.wide2:{v-if:showGenerator,:generator:$root.instanceToGenerator(instance)},ui.share:{v-if:showShare,:item:instance}},e.post.create:{v-if:showCreatePost,:generator:$root.instanceToGenerator(instance),:entityID:instance._id}}},name:e-instance,props:{item:null,instanceImage:false,showFooter:true,showCreatePost:false,showShare:true,instanceID:null},data:{width:null,instance:null},methods:{getFontSize:function (s) {\n if (!s) return 0;\n if (!this.width) return 0;\n const size Math.min(3, Math.max(14, (36 - (s.length / 6))) / 50 * this.width / 150);\n return `${size*1.5}rem`;\n}\n,updateImageSize:function () {\n this.width this.$refs.image1.width;\n}\n},computed:{imageID:function () {\n return this.instanceImage ? null : (this.instance.imageID || this.instance.generator?.imageID);\n}\n,imageUrl:function () {\n if (!this.instanceImage) return null;\n return this.$root.url.itemImage(this.instance);\n}\n,showGenerator:function () {\n if (!this.instance) return false;\n if (this.instance.urlName this.$root.params.urlName) return false;\n return true;\n}\n,fontSizes:function () {\n if (!this.instance) return 0, 0;\n const sizes this.getFontSize(this.instance.text0), this.getFontSize(this.instance.text1);\n return sizes;\n}\n},watch:{item:{handler:function (item) {\n this.instance item;\n}\n,immediate:true},instanceID:{handler:async function (instanceID) {\n if (this.item) return;\n this.instance !instanceID ? null : await this.$root.dbp.instances.select.one(instanceID);\n}\n,immediate:true}},style:{.instance:{display:block,box-shadow:0px 10px 10px #000000a0},.footer:{margin-top:1em},.footer .comp-e-generator-wide2:{font-size:100%},.admin-footer:{display:flex,justify-content:center,margin-top:1rem},.comp-e-post-create:{margin-top:1rem !important},.comp-ui-image:{width:100%},.comp-ui-image, img:{aspect-ratio:auto,object-fit:cover},.instance .comp-ui-image, .texts, .text:{position:absolute},.instance .spacer .comp-ui-image:{position:relative},.spacer:{visibility:hidden},.spacer, .texts:{width:100%,aspect-ratio:auto},.texts:{top:0,height:100%},.text:{text-align:center,display:block,width:100%,top:0,overflow:hidden,color:#fff,line-height:1.2em,font-family:Impact,Oswald,text-transform:uppercase,text-shadow:-2px -2px 0 #000, 2px -2px 0 #000, -2px 2px 0 #000, 2px 2px 0 #000,-webkit-font-smoothing:antialiased,box-sizing:border-box,padding:0.3em,filter:drop-shadow(-2px 4px 2px #00000060),transition:0s},.text:nth-child(2):{top:auto,bottom:0}},_:{examples:{count:0}},template:div class\comp-e-instance\ on_click\$emit(click)\ v-if\instance\ path\643573758.\>ui-link class\instance\ :url\$root.url.instance(instance)\ path\643573758.0\>div path\643573758.0.0\>ui-image ref\image1\ :imageID\imageID\ :url\imageUrl\ on_change\updateImageSize\ path\643573758.0.0.0\>/ui-image>div class\spacer\ path\643573758.0.0.1\>ui-image ref\image1\ :imageID\imageID\ :url\imageUrl\ path\643573758.0.0.1.0\>/ui-image>/div>div class\texts\ v-if\!instanceImage\ path\643573758.0.0.2\>div class\text\ v-for\(text, index) in instance.text0, instance.text1\ v-text\text\ :style\{ fontSize: fontSizesindex }\ path\643573758.0.0.2.0\>/div>/div>/div>/ui-link>div class\footer\ v-if\showFooter\ path\643573758.1\>e-generator-wide2 v-if\showGenerator\ :generator\$root.instanceToGenerator(instance)\ path\643573758.1.0\>/e-generator-wide2>ui-share v-if\showShare\ :item\instance\ path\643573758.1.1\>/ui-share>/div>e-post-create v-if\showCreatePost\ :generator\$root.instanceToGenerator(instance)\ :entityID\instance._id\ path\643573758.2\>/e-post-create>/div>}},{name:e.media.content.item.recaption,path:\\e\\media\\content\\item\\recaption.ws.yaml,source:{dom:{div#1:{div#2:{v-if:item.caption,e.template.caption.editor#1:{:item:item.caption,:minimal:true}},div#3:{v-if:!item.caption,e.template.caption.editor#2:{:item:item,:minimal:true}}}},props:{item:null},name:e-media-content-item-recaption,_:{examples:{count:0}},template:div class\comp-e-media-content-item-recaption\ path\-1916563584.\>div v-if\item.caption\ path\-1916563584.0\>e-template-caption-editor :item\item.caption\ :minimal\true\ path\-1916563584.0.0\>/e-template-caption-editor>/div>div v-if\!item.caption\ path\-1916563584.1\>e-template-caption-editor :item\item\ :minimal\true\ path\-1916563584.1.0\>/e-template-caption-editor>/div>/div>}},{name:e.media.create.feel,path:\\e\\media\\create\\feel.ws.yaml,source:{dom:{div:{.grid:{ui.image:{v-for:i in 8,:class:{ clickable: true },:src:/img/feels/ + i + .webp,:square:true,on_click:onClick(i)}}}},data:{selectedIndex:null},methods:{onClick:function(index) {\n this.$emit(\input\, { type: \feel\, feelID: index });\n this.$emit(\change\);\n}\n},watch:null,style:{.grid:{grid-template:1fr / 1fr 1fr 1fr 1fr,gap:0.3em}},name:e-media-create-feel,_:{examples:{count:0}},template:div class\comp-e-media-create-feel\ path\745103109.\>div class\grid\ path\745103109.0\>ui-image v-for\i in 8\ :class\{ clickable: true }\ :src\/img/feels/ + i + .webp\ :square\true\ on_click\onClick(i)\ path\745103109.0.0\>/ui-image>/div>/div>}},{name:e.media.create.image,path:\\e\\media\\create\\image.ws.yaml,source:{dom:{.box1:{ui.file.dropzone:{:show-hint:false,v-model:imageID,.flex.gap-1:{ui.image:{:imageID:imageID},h3:{class:opacity-50,v-text:drop image to upload}}}}},props:{value:null},data:{imageID:null,emitChange:true},methods:{onImageUpload:async function(imageID) {\n this.emitChange false;\n this.imageID imageID;\n await this.$nextTick();\n this.emitChange true;\n}\n},watch:{imageID:function(imageID) {\n if (!imageID) return this.$emit(\input\, null);\n this.$emit(\input\, { type: \image\, imageID });\n if (this.emitChange) this.$emit(\change\);\n}\n},style:{.comp-ui-image:{width:6em}},name:e-media-create-image,_:{examples:{count:0}},template:div class\comp-e-media-create-image box1\ path\1626364892.\>ui-file-dropzone v-model\imageID\ path\1626364892.0\>div class\flex gap-1\ path\1626364892.0.0\>ui-image :imageID\imageID\ path\1626364892.0.0.0\>/ui-image>h3 class\opacity-50\ v-text\drop image to upload\ path\1626364892.0.0.1\>/h3>/div>/ui-file-dropzone>/div>}},{name:e.media.create.instance,path:\\e\\media\\create\\instance.ws.yaml,source:{dom:{div#1:{transition#1:{name:slide,e.generator.select:{v-show:!generator,v-model:generator,:defaultGeneratorID:contextMedia?.instance?.generatorID}},transition#2:{name:slide,div#2:{v-show:generator,.grid1:{div#3:{e.instance:{class:clickable,:item:instance,:show-footer:false,on_click:generator null}},.inputs:{input#1:{v-model:text0,placeholder:top text},input#2:{v-model:text1,placeholder:bottom text}}},.text-center.opacity-30:{v-text:generator?.displayName}}}}},props:{contextMedia:null},data:{generator:null,text0:null,text1:null},methods:{hasContent:function(instance) {\n if (!instance) return false;\n if (!instance.generator) return false;\n if (!instance.text0 && !instance.text1) return false;\n return true;\n}\n},computed:{instance:function() {\n return { generator: this.generator, text0: this.text0, text1: this.text1 };\n}\n,contentInstance:function() {\n return (!this.hasContent(this.instance)) ? null : this.shortInstance;\n}\n,shortInstance:function() {\n return { generator: this.shortGenerator, text0: this.text0, text1: this.text1 };\n}\n,shortGenerator:function() {\n if (!this.generator) return null;\n const g this.generator;\n const gen { _id: this.generator._id };\n \urlName\, \displayName\, \imageID\.forEach((k) > {\n genk gk;\n });\n return gen;\n}\n},watch:{contentInstance:{handler:(function(contentInstance) {\n const media (!contentInstance) ? null : { type: \instance\, instance: contentInstance };\n this.$emit(\input\, media);\n}).debounce(400)\n,deep:true}},style:{.grid1:{display:grid,grid-template:1fr / 1fr 3fr,gap:0.5em},.inputs input:{text-align:center,text-transform:uppercase,padding:0.3em 0.5em !important,margin-bottom:0.5rem},.clickable *:{cursor:pointer}},name:e-media-create-instance,_:{examples:{count:0}},template:div class\comp-e-media-create-instance\ path\925255284.\>transition name\slide\ path\925255284.0\>e-generator-select v-show\!generator\ v-model\generator\ :defaultGeneratorID\contextMedia?.instance?.generatorID\ path\925255284.0.0\>/e-generator-select>/transition>transition name\slide\ path\925255284.1\>div v-show\generator\ path\925255284.1.0\>div class\grid1\ path\925255284.1.0.0\>div path\925255284.1.0.0.0\>e-instance class\clickable\ :item\instance\ :show-footer\false\ on_click\generator null\ path\925255284.1.0.0.0.0\>/e-instance>/div>div class\inputs\ path\925255284.1.0.0.1\>input v-model\text0\ placeholder\top text\ path\925255284.1.0.0.1.0\/>input v-model\text1\ placeholder\bottom text\ path\925255284.1.0.0.1.1\/>/div>/div>div class\text-center opacity-30\ v-text\generator?.displayName\ path\925255284.1.0.1\>/div>/div>/transition>/div>}},{name:e.media.create,path:\\e\\media\\create.ws.yaml,source:{dom:{div:{:key:key1,ui.tabs:{:options:options,direction:horizontal,v-model:selectedTabIndex,template#1:{v-slot:tab0,component#1:{ref:comp0,:is:getComponentName(0),v-model:medias0,:context-media:contextMedia,on_change:onChangeMedia}},template#2:{v-slot:tab1,component#2:{ref:comp1,:is:getComponentName(1),v-model:medias1,:context-media:contextMedia,on_change:onChangeMedia}},template#3:{v-slot:tab2,component#3:{ref:comp2,:is:getComponentName(2),v-model:medias2,:context-media:contextMedia,on_change:onChangeMedia}}}}},props:{contextMedia:null},data:{options:π animals,π feels,πΌοΈ image,componentNames:instance,feel,image,medias:null,null,null,selectedTabIndex:0,key1:1},methods:{onImageUpload:function(imageID) {\n for (let i 0; i this.medias.length; i++)\n {\n const comp this.$refs`comp${i}`;\n if (comp.onImageUpload) comp.onImageUpload(imageID);\n }\n}\n,onChangeMedia:function() {\n this.$emit(\change\);\n}\n,getComponentName:function(index) {\n return `e-media-create-${this.componentNamesindex.getWords()0}`;\n}\n,refresh:function() {\n this.key1++;\n}\n,clear:function() {\n for (let i 0; i this.medias.length; i++) this.mediasi null;\n this.refresh();\n}\n},computed:{media:function () {\n return this.mediasthis.selectedTabIndex;\n}\n},watch:{media:{handler:function(media) {\n this.$emit(\input\, media);\n}\n,deep:true},contextMedia:{handler:function(contextMedia) {\n if (!contextMedia) return;\n if (contextMedia.instance) {\n const index this.componentNames.indexOf(\instance\);\n this.selectedTabIndex index;\n }\n}\n,immediate:true},selectedTabIndex:{handler:function(index) {\n if (!this.media) this.$emit(\input\, null);\n}\n}},name:e-media-create,_:{examples:{count:0}},template:div class\comp-e-media-create\ :key\key1\ path\-960387793.\>ui-tabs :options\options\ direction\horizontal\ v-model\selectedTabIndex\ path\-960387793.0\>template v-slot:tab0 path\-960387793.0.0\>component ref\comp0\ :is\getComponentName(0)\ v-model\medias0\ :context-media\contextMedia\ on_change\onChangeMedia\ path\-960387793.0.0.0\>/component>/template>template v-slot:tab1 path\-960387793.0.1\>component ref\comp1\ :is\getComponentName(1)\ v-model\medias1\ :context-media\contextMedia\ on_change\onChangeMedia\ path\-960387793.0.1.0\>/component>/template>template v-slot:tab2 path\-960387793.0.2\>component ref\comp2\ :is\getComponentName(2)\ v-model\medias2\ :context-media\contextMedia\ on_change\onChangeMedia\ path\-960387793.0.2.0\>/component>/template>/ui-tabs>/div>}},{name:e.media.menu,path:\\e\\media\\menu.ws.yaml,source:{dom:{div#1:{.flex.ver.gap-2:{div#2:{v-if:$root.isAdmin,ui.button:{:text:β delete,:click:() > $root.dbp.medias.delete.one(media._id)}},ui.share:{v-if:!admin,:item:media}}}},props:{media:null,admin:false},data:null,methods:null,name:e-media-menu,_:{examples:{count:0}},template:div class\comp-e-media-menu\ path\991464018.\>div class\flex ver gap-2\ path\991464018.0\>div v-if\$root.isAdmin\ path\991464018.0.0\>ui-button :text\β delete\ :click\() > $root.dbp.medias.delete.one(media._id)\ path\991464018.0.0.0\>/ui-button>/div>ui-share v-if\!admin\ :item\media\ path\991464018.0.1\>/ui-share>/div>/div>}},{name:e.media.recaption,path:\\e\\media\\recaption.ws.yaml,source:{dom:{div#1:{.flex.justify-around:{ui.button#1:{:text:βοΈ recaption,:click:toggleRecaption}},transition:{name:slide,.mt-l2:{v-if:showRecaption,ul:{class:content-items,li:{v-for:item in contentItems,e.media.content.item.recaption:{:item:item}}},div#2:{class:mt-l2,ui.select:{:options:β¨ start new thread, βοΈ reply in thread,type:dropdown,input-type:index,v-model:replyInThread}},.flex.justify-between.mt-l2:{ui.button#2:{v-if:$root.isAdmin,:text:βοΈ cancel,:click:onCancel},ui.button#3:{v-if:$root.isAdmin,:text:βοΈ post,:click:create}}}}}},props:{media:null,threadMedia:null},data:{dMedia:null,originalMedia:null,contentItems:,originalContentItems:,replyInThread:1,showRecaption:false},methods:{create:async function () {\n const threadMedia (!this.replyInThread ? null : this.threadMedia);\n let media JSON.parse(JSON.stringify(this.dMedia));\n delete media._id;\n\n if (this.replyInThread)\n {\n const post await this.$root.dbp.posts.create.one(null, {_id: threadMedia?._id}, null, media);\n this.$root.$emit(\thread-updated\, null, threadMedia?._id);\n this.$emit(\post-created\, post);\n this.$emit(\thread-updated\);\n }\n else\n {\n media await this.$root.dbp.medias.create.one(media);\n }\n this.$emit(\media-created\, media);\n\n this.toggleRecaption();\n this.clear();\n}\n,clear:function () {\n for (const item of this.contentItems)\n {\n if (item.caption) item.caption.text \\;\n }\n}\n,onCancel:function () {\n this.toggleRecaption();\n this.clear();\n}\n,toggleRecaption:function () {\n this.showRecaption !this.showRecaption;\n}\n,getContentItems:function (item) {\n if (!item?.items) return ;\n const getChildren (item) > {\n return (((item.type \caption\) || item.caption) ? item : null), ...(item.items?.flatMap(getChildren)||)\n .filter(a > a);\n }\n let items getChildren(item);\n return items;\n}\n,findOriginalItem:function (id) {\n return this.originalContentItems.find(it > it.id id);\n}\n},computed:null,watch:{media:{handler:async function (media) {\n this.dMedia media;\n this.originalMedia JSON.parse(JSON.stringify(media));\n const temp await this.$root.mediaToTemp(media);\n this.contentItems this.getContentItems(this.dMedia.content.item);\n this.originalContentItems this.getContentItems(this.originalMedia?.content?.item);\n}\n,immediate:true}},style:{.comp-e-media-recaption:{margin:auto,max-width:20em},.content-items li:{margin-bottom:0.3vh},input, select:{padding:0.2em !important}},name:e-media-recaption,_:{examples:{count:0}},template:div class\comp-e-media-recaption\ path\-2142476480.\>div class\flex justify-around\ path\-2142476480.0\>ui-button :text\βοΈ recaption\ :click\toggleRecaption\ path\-2142476480.0.0\>/ui-button>/div>transition name\slide\ path\-2142476480.1\>div class\mt-l2\ v-if\showRecaption\ path\-2142476480.1.0\>ul class\content-items\ path\-2142476480.1.0.0\>li v-for\item in contentItems\ path\-2142476480.1.0.0.0\>e-media-content-item-recaption :item\item\ path\-2142476480.1.0.0.0.0\>/e-media-content-item-recaption>/li>/ul>div class\mt-l2\ path\-2142476480.1.0.1\>ui-select :options\β¨ start new thread, βοΈ reply in thread\ type\dropdown\ input-type\index\ v-model\replyInThread\ path\-2142476480.1.0.1.0\>/ui-select>/div>div class\flex justify-between mt-l2\ path\-2142476480.1.0.2\>ui-button v-if\$root.isAdmin\ :text\βοΈ cancel\ :click\onCancel\ path\-2142476480.1.0.2.0\>/ui-button>ui-button v-if\$root.isAdmin\ :text\βοΈ post\ :click\create\ path\-2142476480.1.0.2.1\>/ui-button>/div>/div>/transition>/div>}},{name:e.media,path:\\e\\media.ws.yaml,source:{dom:{div#1:{v-if:cMedia,:style:mediaStyle,.flex.flex-column.gap-1:{div#2:{on_click:$emit(click-media-content),ui.image#1:{v-if:(cMedia.typefeel),:src:/img/feels/ + cMedia.feelID + .webp,:square:true},ui.image#2:{v-if:(cMedia.typeimage),:imageID:cMedia.imageID,:square:square},e.instance:{v-if:(cMedia.typeinstance),:item:cMedia.instance,:show-footer:showFooter},component:{v-if:(cMedia.typebuilder),:is:formatComponentName,:media:cMedia,:editable:editable,:show-help:false,:media-created:onMediaCreated}},e.media.menu:{v-if:showMediaMenu,:media:cMedia,:admin:true},e.media.recaption:{v-if:(!note) && (!editable) && (cMedia.typebuilder),:media:cMedia,:threadMedia:threadMedia,on_thread-updated:$emit(thread-updated),on_media-created:onMediaCreated},ui.share:{v-if:note,:item:cMedia}}}},props:{item:null,mediaID:null,media:null,threadMedia:null,editable:false,square:false,showFooter:true,mediaCreated:null,showMediaMenu:false,note:false},data:{cMedia:null},methods:{replyInThread:function () {\n return this.$root.params.threadID;\n}\n,onMediaCreated:function (media) {\n if (this.mediaCreated) this.mediaCreated(media);\n this.$emit(media-created, media);\n}\n,onClickMediaContent:function() {\n this.$emit(click-media-content);\n}\n,getMediaStyle:function (media) {\n if (!media) return {};\n const builder media.builder;\n const style {};\n style.margin \auto\;\n if (media.type \feel\) style.width \5rem\;\n if (builder?.source?.size?.max?.width) stylemax-width `${(parseInt(builder?.source?.size?.max?.width) + (!this.editable ? 0 : 15))}em`;\n return style;\n}\n},computed:{cBuilder:function () {\n return this.$root.builders.allthis.cMedia?.builderID;\n}\n,formatComponentName:function () {\n if (!this.cBuilder) return;\n return `e-format-${this.cBuilder.format.replace(/\\./g, -)}`;\n}\n,mediaStyle:function () {\n return this.getMediaStyle(this.cMedia);\n}\n},watch:{item:{handler:function (item) {\n if (this.cMedia) return;\n this.cMedia item;\n}\n,immediate:true},media:{handler:function (media) {\n if (this.cMedia) return;\n this.cMedia media;\n}\n,immediate:true},mediaID:{handler:async function (mediaID) {\n if (this.cMedia) return;\n this.cMedia !mediaID ? null : await this.$root.dbp.medias.select.one(mediaID);\n}\n,immediate:true}},style:null,name:e-media,_:{examples:{count:0}},template:div class\comp-e-media\ v-if\cMedia\ :style\mediaStyle\ path\864271643.\>div class\flex flex-column gap-1\ path\864271643.0\>div on_click\$emit(click-media-content)\ path\864271643.0.0\>ui-image v-if\(cMedia.typefeel)\ :src\/img/feels/ + cMedia.feelID + .webp\ :square\true\ path\864271643.0.0.0\>/ui-image>ui-image v-if\(cMedia.typeimage)\ :imageID\cMedia.imageID\ :square\square\ path\864271643.0.0.1\>/ui-image>e-instance v-if\(cMedia.typeinstance)\ :item\cMedia.instance\ :show-footer\showFooter\ path\864271643.0.0.2\>/e-instance>component v-if\(cMedia.typebuilder)\ :is\formatComponentName\ :media\cMedia\ :editable\editable\ :show-help\false\ :media-created\onMediaCreated\ path\864271643.0.0.3\>/component>/div>e-media-menu v-if\showMediaMenu\ :media\cMedia\ :admin\true\ path\864271643.0.1\>/e-media-menu>e-media-recaption v-if\(!note) && (!editable) && (cMedia.typebuilder)\ :media\cMedia\ :threadMedia\threadMedia\ on_thread-updated\$emit(thread-updated)\ on_media-created\onMediaCreated\ path\864271643.0.2\>/e-media-recaption>ui-share v-if\note\ :item\cMedia\ path\864271643.0.3\>/ui-share>/div>/div>}},{name:e.post.create,path:\\e\\post\\create.ws.yaml,source:{dom:{.container.flex.ver.gap-1:{v-disable:isLoading,h3:{class:text-center,v-text:!isNewThread ? null : Start a new thread},transition#1:{name:slide,div#1:{v-show:showCreateMedia,e.media.create:{class:mt-l1,ref:createMedia1,v-model:media,:contextMedia:threadMedia,on_change:toggleShowCreateMedia}}},transition#2:{name:slide,div#2:{ui.file.dropzone:{:show-hint:false,:show-upload-button:false,on_input:onImageUpload,e.comment.create:{v-model:text,:media:media,:new-thread:false,on_click-media-preview:toggleShowCreateMedia}}}},div:{transition#3:{name:slide,.flex.justify-around:{transition#4:{name:slide,ui.button#1:{class:ml-2,v-if:media,:text:β,:click:onClearMedia}},transition#5:{name:slide,ui.button#2:{v-if:canPost,text:βοΈ post,:click:post}}}}}}},props:{threadID:null,threadMedia:null,generator:null},data:{media:null,text:null,showCreateMedia:false,isLoading:false},mounted:async function() {\n}\n,methods:{onImageUpload:function(imageID) {\n this.$refs.createMedia1.onImageUpload(imageID);\n}\n,onClearMedia:function() {\n this.media null;\n this.showCreateMedia false;\n}\n,toggleShowCreateMedia:function() {\n this.showCreateMedia !this.showCreateMedia;\n}\n,post:async function() {\n this.isLoading true;\n try\n {\n const { generator, text0, text1 } (this.tempInstance || {});\n const instance !generator ? null : { generatorID: generator.generatorID, text0, text1 };\n const post await this.$root.dbp.posts.create.one(this.threadID, (this.threadID ? null : this.threadMedia), this.text, this.media);\n this.clear();\n this.$emit(created, post);\n }\n finally\n {\n this.isLoading false;\n }\n}\n,clear:async function() {\n this.media null;\n this.text null;\n this.showCreateMedia false;\n this.$refs.createMedia1.clear();\n}\n},watch:{postPreview:{handler:function(postPreview) {\n this.$emit(input-preview, postPreview);\n}\n,immediate:true}},computed:{isNewThread:function() {\n return !this.threadID && !this.threadMedia;\n}\n,postPreview:function() {\n return {\n index: 0,\n text: this.text,\n };\n}\n,canPost:function() {\n if (this.isNewThread) return this.media;\n if (this.media) return true;\n if (this.text) return true;\n return false;\n}\n},style:{.container:{max-width:25em,margin:auto},h3:{text-align:center}},config:{track:{state:true}},name:e-post-create,_:{examples:{count:0}},template:div class\comp-e-post-create container flex ver gap-1\ v-disable\isLoading\ path\1762525697.\>h3 class\text-center\ v-text\!isNewThread ? null : Start a new thread\ path\1762525697.0\>/h3>transition name\slide\ path\1762525697.1\>div v-show\showCreateMedia\ path\1762525697.1.0\>e-media-create class\mt-l1\ ref\createMedia1\ v-model\media\ :contextMedia\threadMedia\ on_change\toggleShowCreateMedia\ path\1762525697.1.0.0\>/e-media-create>/div>/transition>transition name\slide\ path\1762525697.2\>div path\1762525697.2.0\>ui-file-dropzone :show-upload-button\false\ on_input\onImageUpload\ path\1762525697.2.0.0\>e-comment-create v-model\text\ :media\media\ :new-thread\false\ on_click-media-preview\toggleShowCreateMedia\ path\1762525697.2.0.0.0\>/e-comment-create>/ui-file-dropzone>/div>/transition>div path\1762525697.3\>transition name\slide\ path\1762525697.3.0\>div class\flex justify-around\ path\1762525697.3.0.0\>transition name\slide\ path\1762525697.3.0.0.0\>ui-button class\ml-2\ v-if\media\ :text\β\ :click\onClearMedia\ path\1762525697.3.0.0.0.0\>/ui-button>/transition>transition name\slide\ path\1762525697.3.0.0.1\>ui-button v-if\canPost\ text\βοΈ post\ :click\post\ path\1762525697.3.0.0.1.0\>/ui-button>/transition>/div>/transition>/div>/div>}},{name:e.post.menu,path:\\e\\post\\menu.ws.yaml,source:{dom:{div:{.center:{ui.time:{:value:item.created}},.post-menu:{v-if:$root.isAdmin,ui.button:{text:β,:click:onDelete}}}},props:{item:null},methods:{onDelete:function () {\n this.$root.dbp.posts.delete.one(this.item._id);\n this.$emit(\thread-updated\);\n}\n},style:{.center, .post-menu:{display:flex,justify-content:center},.center > div, .post-menu > div:{width:fit-content}},name:e-post-menu,_:{examples:{count:0}},template:div class\comp-e-post-menu\ path\404353956.\>div class\center\ path\404353956.0\>ui-time :value\item.created\ path\404353956.0.0\>/ui-time>/div>div class\post-menu\ v-if\$root.isAdmin\ path\404353956.1\>ui-button text\β\ :click\onDelete\ path\404353956.1.0\>/ui-button>/div>/div>}},{name:e.post,path:\\e\\post.ws.yaml,source:{dom:{div#1:{.post:{v-if:item,:class:getPostClass(item),.post-media:{v-if:item.media,:class:getPostMediaClass(item.media),e.media:{:item:item.media,:thread-media:threadMedia,on_media-created:onClickMediaContent,on_click-media-content:onClickMediaContent}},.post-text:{div#2:{v-html:$root.textToHtml(item.text, { firstLine: ((item.index!0) ? null : post-title) })}},div#3:{class:clear-both},e.post.menu:{:item:item,on_thread-updated:$emit(thread-updated)}},.flex.justify-center.hidden:{e.voter:null}}},props:{item:null,threadMedia:null,teaser:false},data:{enlarged:false},methods:{onClickMediaContent:function () {\n this.enlarged !this.enlarged;\n}\n,getPostClass:function (post) {\n const cls {};\n cls.enlarged this.isEnlarged;\n cls.useless (post.mod?.shitpost > 0.5) || (post.mod?.spam > 0.5);\n return cls;\n}\n,getPostMediaClass:function (media) {\n if (!media) return null;\n const cls ;\n cls.push(`media-${media.type}`);\n if (this.teaser) cls.push(\teaser\);\n return cls;\n}\n},computed:{isEnlarged:function () {\n return ((this.item.index 0) || this.enlarged);\n}\n},style:{.post.useless:{display:none,max-height:2em,overflow:hidden,border:none,box-shadow:none,opacity:0.3},.post.useless:hover:{max-height:20em,opacity:0.6},.teaser:{max-height:15rem,overflow:hidden},.teaser:hover:{max-height:30rem},.comp-e-post-menu:{max-height:0em,overflow:hidden},.post:hover .comp-e-post-menu:{max-height:5em,margin-bottom:0.5em},.post:{background:#ffffff20,border:2px solid gray,box-shadow:inset -6px 6px 2px #000,z-index:10},.post .post-menu:{max-height:0,overflow:hidden,opacity:0,transform:translateY(-1em)},.post:hover .post-menu:{max-height:5em,transition:0.5s linear,opacity:1,transform:translateY(0)},.post .instance:hover:{border:1px solid #000000a0,transition:0s !important},.post .comp-e-media-recaption:{max-height:0,overflow:hidden,opacity:0},.post.enlarged .comp-e-media-recaption:{max-height:40em,opacity:1},.larping-generator:{width:4rem !important,float:left,margin-right:1em,margin-bottom:1em},.post-media:{float:left,width:10em,padding:0.5em,filter:grayscale(0.5),cursor:pointer,z-index:10},.post-media.media-feel:{width:fit-content,margin:0.5em},.post-media:hover, .enlarged .post-media:{filter:none},.post-media a:{cursor:pointer !important},.comp-e-instance .footer:{display:none},.post-title:{font-size:140%},.post-text:{padding:0.5rem,opacity:0.9,word-break:break-word},.enlarged .post-media:{width:100%},.enlarged .post-text:null,.anonymous:{display:none},.greentext:{color:#35c735}},name:e-post,_:{examples:{count:0}},template:div class\comp-e-post\ path\-1357494135.\>div class\post\ v-if\item\ :class\getPostClass(item)\ path\-1357494135.0\>div class\post-media\ v-if\item.media\ :class\getPostMediaClass(item.media)\ path\-1357494135.0.0\>e-media :item\item.media\ :thread-media\threadMedia\ on_media-created\onClickMediaContent\ on_click-media-content\onClickMediaContent\ path\-1357494135.0.0.0\>/e-media>/div>div class\post-text\ path\-1357494135.0.1\>div v-html\$root.textToHtml(item.text, { firstLine: ((item.index!0) ? null : post-title) })\ path\-1357494135.0.1.0\>/div>/div>div class\clear-both\ path\-1357494135.0.2\>/div>e-post-menu :item\item\ on_thread-updated\$emit(thread-updated)\ path\-1357494135.0.3\>/e-post-menu>/div>div class\flex justify-center hidden\ path\-1357494135.1\>e-voter>/e-voter>/div>/div>}},{name:e.teaser,path:\\e\\teaser.ws.yaml,source:{dom:{ui.link:{:url:url,ui.image:{:imageID:imageID,aspect-ratio:2 / 1},h3:{v-text:title}}},props:{imageID:null,title:null,url:null},name:e-teaser,_:{examples:{count:0}},template:ui-link class\comp-e-teaser\ :url\url\ path\1222941689.\>ui-image :imageID\imageID\ aspect-ratio\2 / 1\ path\1222941689.0\>/ui-image>h3 v-text\title\ path\1222941689.1\>/h3>/ui-link>}},{name:e.template.caption.editor,path:\\e\\template\\caption\\editor.ws.yaml,source:{dom:{div#1:{ui.input.text.box:{:hint:item.hint,v-model:item.text},div#2:{v-if:!minimal,ui.select#1:{:options:Oswald, Special Elite,type:dropdown,input-type:value,v-model:item.font},ui.select#2:{:options:white, black,type:dropdown,input-type:value,v-model:item.color},ui.select#3:{:options:left, center, right,type:dropdown,input-type:value,v-model:item.align.h},ui.select#4:{:options:top, center, bottom,type:dropdown,input-type:value,v-model:item.align.v}}}},props:{item:null,minimal:false},style:{input:{text-align:center}},name:e-template-caption-editor,_:{examples:{count:0}},template:div class\comp-e-template-caption-editor\ path\-1537870880.\>ui-input-text-box :hint\item.hint\ v-model\item.text\ path\-1537870880.0\>/ui-input-text-box>div v-if\!minimal\ path\-1537870880.1\>ui-select :options\Oswald, Special Elite\ type\dropdown\ input-type\value\ v-model\item.font\ path\-1537870880.1.0\>/ui-select>ui-select :options\white, black\ type\dropdown\ input-type\value\ v-model\item.color\ path\-1537870880.1.1\>/ui-select>ui-select :options\left, center, right\ type\dropdown\ input-type\value\ v-model\item.align.h\ path\-1537870880.1.2\>/ui-select>ui-select :options\top, center, bottom\ type\dropdown\ input-type\value\ v-model\item.align.v\ path\-1537870880.1.3\>/ui-select>/div>/div>}},{name:e.template.caption.item,path:\\e\\template\\caption\\item.ws.yaml,source:{dom:{div#1:{v-if:item,:class:{ rect: true, editable: isEditable },:style:rectStyle,.text:{ref:sizeRef1,:class:getCssClass(item),:style:itemStyle,div#2:{:class:getTextContentClass(item),v-html:getItemText(item),:title:!isEditable ? : βοΈ edit,on_click:onClickText,:key:key1},transition:{name:slide,ui.input.text.box:{v-if:showEditor,:class:getCssClass(item),v-model:item.text}}}}},name:e-template-caption-item,props:{temp:null,item:null,editable:false},data:{width:null,showEditor:false,key1:1},mounted:function () {\n window.addEventListener(`resize`, this.recalc.bind(this));\n // Detect if the image element changes its size\n let resizeObserver new ResizeObserver(this.recalc.bind(this));\n resizeObserver.observe(this.$refs.sizeRef1);\n}\n,methods:{getItemText:function (item) {\n let text this.$root.textToHtml(item.text);\n if (!text?.length && this.showPlaceholderText) text (item.hint || (\(text)\));\n if (item.hint \quote\) text `\${text}\`;\n return text;\n}\n,onClickText:function () {\n if (this.isEditable)\n {\n this.showEditor !this.showEditor;\n return;\n }\n this.$emit(\click\);\n}\n,onLoad:function () {\n this.recalc();\n 1,2,3.forEach(i > setTimeout(this.recalc.bind(this), i * 100))\n}\n,recalc:function () {\n if (!this.$refs.sizeRef1) return;\n let rect this.$refs.sizeRef1.getBoundingClientRect();\n this.width Math.round(rect.width);\n this.height Math.round(rect.height);\n this.$emit(\change\);\n}\n,getCssClass:function(item) {\n const cls {};\n cls.clickable this.isEditable;\n cls`h-${item.align.h}` true;\n cls`v-${item.align.v}` true;\n return cls;\n}\n,getTextContentClass:function(item) {\n const cls {};\n cls\text-content\ true;\n cls.empty !item.text;\n return cls;\n}\n,getStyle:function(item) {\n const style {};\n style.fontSize this.getFontSize(item.text, item.trans?.scale);\n style.fontFamily item.font;\n if (item.uppercase) style.textTransform \uppercase\;\n style.color item.color;\n const isDark (item.color \black\);\n const outlineColor (isDark ? \white\ : \black\);\n let outlineWidth Math.max(1, Math.round(this.width/400));\n outlineWidth `${(isDark ? outlineWidth : outlineWidth*2)}px`;\n style.textShadow `-1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000`\n .replace(/1px/g, outlineWidth)\n .replace(/#000/g, outlineColor);\n return style;\n}\n,getFontSize:function (s, scale 1) {\n if (!this.width) return 0;\n if (!scale) scale 1;\n const strLen (s?.length || 1);\n let size Math.min(3, Math.max(14, (36 - (strLen / 6))) / 50 * this.width / 150);\n size size * 2;\n if (this.item.scale) size * this.item.scale;\n size (size * scale);\n return `${size}vh`;\n}\n,refresh:function() {\n this.key1++;\n}\n},watch:{item:{handler:function (item) {\n this.refresh();\n}\n,immediate:true,deep:true}},computed:{isEditable:function () {\n if (!this.editable) return false;\n if (!this.item.editable) return false;\n if (this.temp?.layers) return false;\n if (this.temp?.join?.caption?.editors) return false;\n return true;\n}\n,showPlaceholderText:function () {\n return this.isEditable;\n}\n,itemStyle:function () {\n return this.getStyle(this.item);\n}\n,rectStyle:function () {\n const style {};\n const rect (this.item?.rect||{});\n style.left rect.left;\n style.top rect.top;\n style.width rect.width;\n style.height rect.height;\n return style;\n}\n},style:{.rect:not(.editable), .rect:not(.editable) *:{pointer-events:none !important},inputtype\text\:{font-size:100%,padding:0 !important},.h-left:{text-align:left},.h-center:{text-align:center},.h-center input:{text-align:center},.h-right:{text-align:right},.v-top:{top:0},.v-center:{top:50%,transform:translateY(-50%)},.v-bottom:{bottom:0},.text:{width:100%,object-fit:cover,line-height:1em,user-select:none,display:block,overflow:hidden,color:#fff,font-family:Impact,Oswald,-webkit-font-smoothing:antialiased,box-sizing:border-box,padding:0.3em,filter:drop-shadow(-2px 4px 2px #00000080),transition:0s,pointer-events:all},.text-content.empty:{opacity:0.3},.text-content:null,.text-content:hover:null,.text-content::after:{display:none,content:βοΈ,font-size:60%,margin-left:0.5em},.editable > .text > .text-content::after:{display:inline-block}},_:{examples:{count:0}},template:div class\comp-e-template-caption-item\ v-if\item\ :class\{ rect: true, editable: isEditable }\ :style\rectStyle\ path\128142918.\>div class\text\ ref\sizeRef1\ :class\getCssClass(item)\ :style\itemStyle\ path\128142918.0\>div :class\getTextContentClass(item)\ v-html\getItemText(item)\ :title\!isEditable ? : βοΈ edit\ on_click\onClickText\ :key\key1\ path\128142918.0.0\>/div>transition name\slide\ path\128142918.0.1\>ui-input-text-box v-if\showEditor\ :class\getCssClass(item)\ v-model\item.text\ path\128142918.0.1.0\>/ui-input-text-box>/transition>/div>/div>}},{name:e.template.editor,path:\\e\\template\\editor.ws.yaml,source:{dom:{.m-auto:{v-if:temp,:class:getCssClass(),.div1:{:style:getStyle(),div#1:{v-if:showTree,ui.tree:{:root:temp,:initial-expanded:2,item-type:e.template.item.icon,:get-item:(node) > node,:get-children:(node) > node.items,on_node-select:onNodeSelect}},.div2:{ui.file.dropzone:{:enabled:(editable && hasOnlyOneImage),:show-hint:false,:show-upload-button:false,on_input:onImageUpload,ui.movable:{:enabled:editable,on_drag-by:({ dx, dy }) > getOnlyImageComp()?.onItemDragBy(imageItems0, { dx, dy }),on_scale-by:(ds) > getOnlyImageComp()?.onItemScaleBy(imageItems0, ds),e.template.grid.item:{class:main-content,:temp:temp,:item:temp,:editable:editable,on_image-load:(item, src) > onItemImageLoad(item, src),on_image-error:(item, src) > onItemImageError(item, src)}}},div#2:{v-if:editable,e.template.editors:{:temp:temp},.flex.justify-around.mt-l2:{ui.button#1:{v-if:cancel,:text:βοΈ cancel,:click:cancel},ui.button#2:{:text:βοΈ create,:click:createMedia}}},div#3:{v-if:selectedItem && showPropertyEditor,ui.section#1:{:title:selectedItem.type,v-model:showFilters,:opposite:true,transition:{name:slide2,component:{ref:selectedItemEditor1,:is:selectedItemEditorType,:item:selectedItem,on_toggle-disabled:toggleDisabled($event),:key:selectedItemIndex}}},ui.section#2:{v-if:canApplyEffects(selectedItem),title:effects,v-model:showFilters,e.template.item.filters:{:imageID:selectedItem.imageID,v-model:selectedItem.filters,on_input:() > onItemChange(selectedItem)}}}},e.template.help:{v-if:editable && showHelp,:show-visibility-help:hasMoreThanOneImagePerGrid}}}},props:{temp:null,builder:null,editable:false,showPropertyEditor:true,showHelp:true,mediaCreated:null,cancel:null},data:{emptyTemp:null,selectedItemIndex:0,disabled:0,showFilters:false},mounted:async function() {\n await this.init();\n}\n,methods:{createMedia:async function() {\n try\n {\n let media this.getMedia(this.temp);\n const mediaGeneratorContent { item: this.withoutDefaultValues(this.emptyTemp) };\n\n if (false)\n {\n // Check that title is not empty\n if (media.content.items.some(item > item.caption?.text title))\n {\n alertify.error(Click \title\ to edit it.);\n return;\n }\n // Check if all images are empty\n if (media.content.items.every(item > !item.imageID))\n {\n alertify.error(Drop image files from your computer onto boxes to upload.);\n return;\n }\n }\n\n media await this.$root.dbp.medias.create.one(media, mediaGeneratorContent);\n if (this.mediaCreated) await this.mediaCreated(media);\n }\n finally\n {\n }\n}\n,getMedia:function(temp) {\n const item Objects.subtract(temp, this.emptyTemp);\n\n const media {\n created: new Date(),\n type: \builder\,\n builderID: this.builder._id,\n content: { item }\n }\n\n return media;\n}\n,withoutDefaultValues:function(item, key) {\n if (!item) return null;\n if (Array.isArray(item)) {\n if (item.length 0) return ;\n if (typeof(item0) ! \object\) return item;\n return item.map(child > this.withoutDefaultValues(child));\n }\n\n item JSON.parse(JSON.stringify(item));\n\n const allDefaults {\n grid: {\n type: null,\n visible: true,\n grid: null,\n gap: 0.02,\n aspectRatio: null,\n caption: null,\n },\n image: {\n type: null,\n visible: true,\n imageID: null,\n removeBackground: false,\n shadow: {\n blur: 0,\n color: \#000000\,\n opacity: 1,\n x: 0,\n y: 0\n },\n trans: {\n pos: {\n x: 0.5,\n y: 0.5\n },\n scale: 1,\n },\n caption: null,\n },\n caption: {\n type: \caption\,\n visible: true,\n text: \\,\n uppercase: false,\n font: \Arial\,\n editable: true,\n color: \white\,\n align: null\n }\n };\n\n const defaults allDefaultskey||item.type;\n\n for (const key of Object.keys(item))\n {\n if (key \items\) continue;\n if (defaults && (!(key in defaults))) delete itemkey;\n if (itemkey null) delete itemkey;\n if (itemkey {}) delete itemkey;\n if (defaults && Objects.areEqual(itemkey, defaultskey)) delete itemkey;\n if (Object.keys(allDefaults).includes(key)) {\n itemkey this.withoutDefaultValues(itemkey, key);\n if (itemkey null) delete itemkey;\n }\n }\n\n if (item.items) item.items item.items.map(child > this.withoutDefaultValues(child));\n\n return item;\n}\n,init:async function() {\n}\n,onItemImageLoad:function(item, src) {\n const comps this.findComponents(item)\n .filter(c > c.onItemImageLoad);\n comps.forEach(c > c.onItemImageLoad(src));\n}\n,onItemImageError:function(item, src) {\n const comps this.findComponents(item)\n .filter(c > c.onItemImageError);\n comps.forEach(c > c.onItemImageError(src));\n}\n,onImageUpload:function(imageID) {\n if (!this.hasOnlyOneImage) return;\n this.imageItems0.imageID imageID;\n}\n,findComponents:function(item) {\n if (!item) return null;\n return vueApp.vm.getDescendants(this, (c) > c.$props.itemitem);\n}\n,getOnlyImageComp:function() {\n if (!this.hasOnlyOneImage) return;\n return vueApp.vm.getDescendants(this, (c) > c.$data._?.comp?.name\e.template.image.item\)0;\n}\n,canApplyEffects:function(item) {\n if (!item) return false;\n return item.type image;\n}\n,getCssClass:function() {\n return {\n disabled: (this.disabled > 0)\n };\n}\n,getStyle:function() {\n const columns this.showTree ? \1fr\, \4fr\, \1.5fr\ : (this.editable && this.showHelp) ? \1fr\, \15em\ : \1fr\;\n return {\n gridTemplate: `1fr / ${columns.map(c > `${c}`).join( )}`\n };\n}\n,selectItem:function(index) {\n this.selectedItemIndex index;\n}\n,onNodeSelect:function(node) {\n // selectedItem is computed, only the root node\n // When editing specific nodes with the property editor, this would be enabled\n //this.selectedItem node;\n}\n,onItemChange:function(item) {\n}\n,getTabClass:function(index) {\n return {\n clickable: true,\n selected: index this.selectedItemIndex\n };\n}\n,toggleDisabled:function(disabled) {\n if (disabled) this.disabled++;\n else this.disabled--;\n}\n,eval:function(s) {\n return eval(s);\n}\n},computed:{selectedItem:function() {\n return this.temp;\n //return this.temp.itemsthis.selectedItemIndex;\n}\n,selectedItemEditorType:function() {\n if (!this.selectedItem) return;\n return `e-template-${this.selectedItem.type}-editor`;\n}\n,imageItems:function() {\n return this.temp?.items?.filter(item > item.type image) || ;\n}\n,hasOnlyOneImage:function() {\n return this.imageItems.length 1;\n}\n,showTree:function() {\n return this.editable && this.hasMoreThanOneImagePerGrid;\n}\n,hasMoreThanOneImagePerGrid:function() {\n if (!this.temp) return false;\n\n if (this.temp.gridItems?.width 1) return false;\n\n const checkNode (node) > {\n if (node.type ! grid) return false;\n const imageItems node.items.filter(item > item.type image);\n if (imageItems.length > 1) return true;\n for (const child of node.items)\n {\n if (checkNode(child)) return true;\n }\n return false;\n }\n\n return checkNode(this.temp);\n}\n},watch:{builder:async function(builder) {\n}\n,temp:{handler:function(temp) {\n const emptyTemp JSON.parse(JSON.stringify(temp));\n Objects.traverse(emptyTemp, (node, key, value) > {\n if (!node) return;\n const caption (key \caption\) ? node.caption :\n (node.type \caption\) ? node : null;\n if (caption && (\text\ in caption) && (caption.editable)) delete caption.text;\n });\n this.emptyTemp emptyTemp;\n}\n,immediate:true}},name:e-template-editor,style:{.div1:{display:grid,gap:1em},.div1 > div:{overflow:hidden},.div2:{display:flex,flex-direction:column,gap:1em},.tabs:{display:flex,flex-direction:column-reverse,align-items:end,justify-content:start},.tabs inputtype\checkbox\:{position:relative,top:0.1em,transform:scale(0.7)},.tabs li:{transition:0.3s;},.tabs li.selected:{transform:scale(1.2);},.layout-layers:{aspect-ratio:1 / 1,overflow:hidden},.layout-layers .layer:{position:absolute,top:0,left:0,width:100%,height:100%,pointer-events:none},.layout-layers .layer .comp-ui-image:null,.layout-vertical:{border:2px solid #ffffff60,display:flex,flex-direction:column-reverse},.layout-vertical .item:{width:100%},.layout-vertical, .layout-vertical .item:{overflow:hidden},.item:{overflow:hidden},.item.selected, .item.selected:hover:{background:none !important},.message.large-video:{grid-template:1fr / 1fr}},_:{examples:{count:0}},template:div class\comp-e-template-editor m-auto\ v-if\temp\ :class\getCssClass()\ path\-650358312.\>div class\div1\ :style\getStyle()\ path\-650358312.0\>div v-if\showTree\ path\-650358312.0.0\>ui-tree :root\temp\ :initial-expanded\2\ item-type\e.template.item.icon\ :get-item\(node) > node\ :get-children\(node) > node.items\ on_node-select\onNodeSelect\ path\-650358312.0.0.0\>/ui-tree>/div>div class\div2\ path\-650358312.0.1\>ui-file-dropzone :enabled\(editable && hasOnlyOneImage)\ :show-upload-button\false\ on_input\onImageUpload\ path\-650358312.0.1.0\>ui-movable :enabled\editable\ on_drag-by\({ dx, dy }) > getOnlyImageComp()?.onItemDragBy(imageItems0, { dx, dy })\ on_scale-by\(ds) > getOnlyImageComp()?.onItemScaleBy(imageItems0, ds)\ path\-650358312.0.1.0.0\>e-template-grid-item class\main-content\ :temp\temp\ :item\temp\ :editable\editable\ on_image-load\(item, src) > onItemImageLoad(item, src)\ on_image-error\(item, src) > onItemImageError(item, src)\ path\-650358312.0.1.0.0.0\>/e-template-grid-item>/ui-movable>/ui-file-dropzone>div v-if\editable\ path\-650358312.0.1.1\>e-template-editors :temp\temp\ path\-650358312.0.1.1.0\>/e-template-editors>div class\flex justify-around mt-l2\ path\-650358312.0.1.1.1\>ui-button v-if\cancel\ :text\βοΈ cancel\ :click\cancel\ path\-650358312.0.1.1.1.0\>/ui-button>ui-button :text\βοΈ create\ :click\createMedia\ path\-650358312.0.1.1.1.1\>/ui-button>/div>/div>div v-if\selectedItem && showPropertyEditor\ path\-650358312.0.1.2\>ui-section :title\selectedItem.type\ v-model\showFilters\ :opposite\true\ path\-650358312.0.1.2.0\>transition name\slide2\ path\-650358312.0.1.2.0.0\>component ref\selectedItemEditor1\ :is\selectedItemEditorType\ :item\selectedItem\ on_toggle-disabled\toggleDisabled($event)\ :key\selectedItemIndex\ path\-650358312.0.1.2.0.0.0\>/component>/transition>/ui-section>ui-section v-if\canApplyEffects(selectedItem)\ title\effects\ v-model\showFilters\ path\-650358312.0.1.2.1\>e-template-item-filters :imageID\selectedItem.imageID\ v-model\selectedItem.filters\ on_input\() > onItemChange(selectedItem)\ path\-650358312.0.1.2.1.0\>/e-template-item-filters>/ui-section>/div>/div>e-template-help v-if\editable && showHelp\ :show-visibility-help\hasMoreThanOneImagePerGrid\ path\-650358312.0.2\>/e-template-help>/div>/div>}},{name:e.template.editors,path:\\e\\template\\editors.ws.yaml,source:{dom:{transition.group:{tag:ul,name:list,li:{v-for:item in items,:key:item.id,component:{:is:e-template- + item.type + -editor,:temp:temp,:item:item,:minimal:true}}}},props:{temp:null},data:null,computed:{items:function() {\n if (!this.temp) return \n const items ;\n \image\, \caption\, \rainbow\.forEach(type > {\n items.push(...this.temp.items.filter(item > item.type type));\n });\n return items;\n}\n},style:{li:{margin-bottom:0.5em}},name:e-template-editors,_:{examples:{count:0}},template:transition-group class\comp-e-template-editors\ tag\ul\ name\list\ path\1313728923.\>li v-for\item in items\ :key\item.id\ path\1313728923.0\>component :is\e-template- + item.type + -editor\ :temp\temp\ :item\item\ :minimal\true\ path\1313728923.0.0\>/component>/li>/transition-group>}},{name:e.template.grid.editor,path:\\e\\template\\grid\\editor.ws.yaml,source:{dom:{div#1:{v-if:false && item,div#2:{v-text:item.items.length + items},ui.select#1:{v-if:false,:options:layers, vertical, grid,input-type:value,type:dropdown,v-model:item.layout},ui.select#2:{v-if:false,:options:2/3, 1/1, 3/2, 4/3, 5/4, 16/9, 16/10, 21/9,input-type:value,type:dropdown,v-model:item.aspectRatio},ui.input.range:{v-if:false,text:gap,v-model:item.gap,min:0,max:0.1,step:0.01}}},props:{item:null},name:e-template-grid-editor,_:{examples:{count:0}},template:div class\comp-e-template-grid-editor\ v-if\false && item\ path\-1104249974.\>div v-text\item.items.length + items\ path\-1104249974.0\>/div>ui-select :options\layers, vertical, grid\ input-type\value\ type\dropdown\ v-model\item.layout\ path\-1104249974.1\>/ui-select>ui-select :options\2/3, 1/1, 3/2, 4/3, 5/4, 16/9, 16/10, 21/9\ input-type\value\ type\dropdown\ v-model\item.aspectRatio\ path\-1104249974.2\>/ui-select>ui-input-range text\gap\ v-model\item.gap\ max\0.1\ step\0.01\ path\-1104249974.3\>/ui-input-range>/div>}},{name:e.template.grid.item,path:\\e\\template\\grid\\item.ws.yaml,source:{dom:{ui.track.size:{v-if:item,div#1:{:class:flex caption-layout- + item.caption?.align.v,on_input:onSizeChange,div#2:{:key:key1,:class:items container grid + grid-items- + gridWidth + items- + getVisibleItemsCount(item.items) + rotation- + item.rotation + (!item.layers ? : layers),:style:getMainStyle(item),component:{v-for:item in item.items,:key:item.id,v-if:item.visible,:editable:editable,:class:getItemClass(item),:style:getItemStyle(item),:is:getItemType(item),:temp:temp,:item:item,on_image-load:(item, src) > onItemImageLoad(item, src),on_image-error:(item, src) > onItemImageError(item, src),on_file-drop:(item, files) > $emit(file-drop, item, files)}},e.template.caption.item:{v-if:item.caption,:editable:editable,:temp:temp,:item:item.caption,on_click:toggleRotation(item)}}}},props:{temp:null,item:null,editable:false},data:{size:null,mainStyle:null,key1:1},methods:{getMainStyle:function(item) {\n if (!item) return {};\n const style {};\n style.aspectRatio item.aspectRatio;\n const gap 0.02; // item.gap;\n if ((this.size) && (gap)) style.gap `${Math.round(gap * this.size.diagonal)}px`;\n return style;\n}\n,getItemClass:function(item) {\n return {\n item: true,\n selected: (item this.selectedItem),\n };\n}\n,getItemStyle:function(item) {\n if (!item) return;\n let style {};\n const { filters } item;\n const cssFilters ;\n if (filters)\n {\n if (filters.blur) cssFilters.push(`blur(${filters.blur*10}px)`);\n if (filters.transparent) cssFilters.push(`opacity(${1-filters.transparent})`);\n if (filters.grayscale) cssFilters.push(`grayscale(${filters.grayscale})`);\n }\n style.filter cssFilters.join( );\n //if (this.item.layout ! layers)\n style.aspectRatio eval(this.item.aspectRatio);\n return style;\n}\n,getItemType:function(item) {\n return `e-template-${item.type}-item`;\n}\n,onItemImageLoad:function(item, src) {\n this.$emit(\image-load\, item, src);\n}\n,onItemImageError:function(item, src) {\n this.$emit(\image-error\, item, src);\n}\n,onSizeChange:function(size) {\n this.size size;\n //this.refresh();\n //this.mainStyle this.getMainStyle(this.item);\n}\n,toggleRotation:function(item) {\n item.rotation ((item.rotation||0) + 1) % 2;\n this.refresh();\n}\n,getVisibleItemsCount:function(items) {\n if (!items) return 0;\n return items.filter(item > item.visible).length;\n}\n,refresh:function() {\n this.key1++;\n}\n},computed:{gridWidth:function() {\n return (this.item?.gridItems?.width || this.item?.items?.length);\n}\n},watch:null,style:{div:{transition:0s !important},.layers:{aspect-ratio:1 / 1},.layers > .item:{position:absolute,top:0,left:0,width:100%,height:100%},.caption-layout-top:{flex-direction:column-reverse},.caption-layout-bottom:{flex-direction:column},.container:{gap:0.5em},.container.grid-items-1:{gap:0 !important},.items:{width:100%},.items .item:null,.grid-items-1:{grid-template:1fr / 1fr},.grid-items-1 .text:{position:absolute},.grid-items-3, .grid-items-6, .grid-items-9:{grid-template:1fr / 1fr 1fr 1fr},.grid-items-4.items-2.rotation-1:{grid-template:1fr / 1fr 1fr},.grid-items-4.items-2.rotation-1 > div:{aspect-ratio:1 / 2.05 !important,grid-row:1 / span 2},.grid-items-4.items-2 > div:{grid-column:auto !important},.grid-items-4.items-2.rotation-1 div:null,.grid-items-4.items-3:{grid-template:1fr / 1fr 1fr},.grid-items-4.items-3 > div:nth-child(1), .items-2 > div:{aspect-ratio:2.05 / 1 !important,grid-column:1 / span 2},.grid-items-4.items-3.rotation-1 > div:nth-child(1):{aspect-ratio:1 / 2.1 !important,grid-column:1,grid-row:1 / span 2},.items-4:{grid-template:1fr / 1fr 1fr},img.empty:{height:100%}},name:e-template-grid-item,_:{examples:{count:0}},template:ui-track-size class\comp-e-template-grid-item\ v-if\item\ path\-1435649936.\>div :class\flex caption-layout- + item.caption?.align.v\ on_input\onSizeChange\ path\-1435649936.0\>div :key\key1\ :class\items container grid + grid-items- + gridWidth + items- + getVisibleItemsCount(item.items) + rotation- + item.rotation + (!item.layers ? : layers)\ :style\getMainStyle(item)\ path\-1435649936.0.0\>component v-for\item in item.items\ :key\item.id\ v-if\item.visible\ :editable\editable\ :class\getItemClass(item)\ :style\getItemStyle(item)\ :is\getItemType(item)\ :temp\temp\ :item\item\ on_image-load\(item, src) > onItemImageLoad(item, src)\ on_image-error\(item, src) > onItemImageError(item, src)\ on_file-drop\(item, files) > $emit(file-drop, item, files)\ path\-1435649936.0.0.0\>/component>/div>e-template-caption-item v-if\item.caption\ :editable\editable\ :temp\temp\ :item\item.caption\ on_click\toggleRotation(item)\ path\-1435649936.0.1\>/e-template-caption-item>/div>/ui-track-size>}},{name:e.template.help,path:\\e\\template\\help.ws.yaml,source:{dom:{.help:{.message#1:{ui.video#1:{src:/video/interface/image/drop.webm},div#1:{v-text:Drop images to upload.}},.message#2:{ui.video#2:{src:/video/interface/image/move.webm},div#2:{v-text:Drag images to position.}},.message#3:{ui.video#3:{src:/video/interface/image/scale.webm},div#3:{v-text:Ctrl-drag images to resize.}},.message#4:{v-if:showVisibilityHelp,class:large-video,ui.video#4:{src:/video/interface/image/visible.webm},div#4:{v-text:Toggle image visibility using the tree on the left.}},.message#5:{v-if:showVisibilityHelp,class:large-video,ui.video#5:{src:/video/interface/image/rotate.webm},div#5:{v-text:If less than 4 images are visible, click the title (Body, Hair..) to change the layout.}}}},props:{showVisibilityHelp:false},style:{.help .message:{display:grid,grid-template:1fr / 1fr 2fr,gap:1em,text-align:left},.help video:{filter:grayscale(1)}},name:e-template-help,_:{examples:{count:0}},template:div class\comp-e-template-help help\ path\-67625364.\>div class\message\ path\-67625364.0\>ui-video src\/video/interface/image/drop.webm\ path\-67625364.0.0\>/ui-video>div v-text\Drop images to upload.\ path\-67625364.0.1\>/div>/div>div class\message\ path\-67625364.1\>ui-video src\/video/interface/image/move.webm\ path\-67625364.1.0\>/ui-video>div v-text\Drag images to position.\ path\-67625364.1.1\>/div>/div>div class\message\ path\-67625364.2\>ui-video src\/video/interface/image/scale.webm\ path\-67625364.2.0\>/ui-video>div v-text\Ctrl-drag images to resize.\ path\-67625364.2.1\>/div>/div>div class\large-video message\ v-if\showVisibilityHelp\ path\-67625364.3\>ui-video src\/video/interface/image/visible.webm\ path\-67625364.3.0\>/ui-video>div v-text\Toggle image visibility using the tree on the left.\ path\-67625364.3.1\>/div>/div>div class\large-video message\ v-if\showVisibilityHelp\ path\-67625364.4\>ui-video src\/video/interface/image/rotate.webm\ path\-67625364.4.0\>/ui-video>div v-text\If less than 4 images are visible, click the title (Body, Hair..) to change the layout.\ path\-67625364.4.1\>/div>/div>/div>}},{name:e.template.image.editor,path:\\e\\template\\image\\editor.ws.yaml,source:{dom:{.items:{v-if:item,transition#1:{name:slide2,div#1:{transition#2:{name:slide2,.flex.justify-between:{v-if:(item.imageID && !removingBackground),ui.expand:{v-if:false,text:shadow,v-model:showShadowEditor},ui.checkbox:{v-if:temp?.can?.remove?.background,text:remove background,v-model:item.removeBackground}}},e.template.caption.editor:{v-if:item.caption,:item:item.caption,:minimal:true},transition#3:{name:slide2,.error.my-l1:{v-if:error,.flex.gap-1:{ui.image#1:{:style:{ width: 5em },:imageID:item.imageID,:square:true},div#2:{div#3:{v-text:An error occurred.},div#4:{span:{v-text:Try another image or },a:{class:yellow,target:_blank,href:https://www.remove.bg/,v-text:remove.bg}}}}}},transition#4:{name:slide2,.message:{v-if:removingBackground,.flex:{ui.image#2:{:style:{ width: 5em },:imageID:item.imageID,:square:true},div#5:{.fs-m2:{v-text:Removing background},ui.loading:null}}}}}},div:{transition#5:{name:slide2,div#6:{v-if:showShadowEditor,ui.input.range#1:{text:x,v-model:item.shadow.x,min:-1,max:1,step:0.01},ui.input.range#2:{text:y,v-model:item.shadow.y,min:-1,max:1,step:0.01},ui.input.range#3:{text:blur,v-model:item.shadow.blur,min:0,max:1,step:0.01},ui.input.range#4:{text:opacity,v-model:item.shadow.opacity,min:0,max:1,step:0.01}}}}}},props:{temp:null,item:null},data:{removingBackground:false,showMoveScale:false,showShadowEditor:false,processingNewImage:false,error:false},style:{a:hover:{text-decoration:underline},.error:{text-align:left},.comp-ui-image-select:{margin-top:1em}},mounted:async function() {\n this.$watch(() > this.item?.removeBackground, (removeBackground) > {\n this.removingBackground removeBackground;\n });\n this.$watch(() > this.item?.imageID, (imageID) > {\n this.error false;\n if (this.item.removeBackground) {\n this.removingBackground true;\n }\n });\n}\n,methods:{onLayerDragBy:function(dpos) {\n const pos (this.showShadowEditor ? this.item.shadow : this.item.trans.pos);\n pos.x + dpos.dx;\n pos.y + dpos.dy;\n}\n,onLayerScaleBy:function(ds) {\n if (this.showShadowEditor) {\n this.item.shadow.blur + ds;\n }\n else\n {\n this.item.trans.scale + ds;\n }\n}\n,onImageUploading:function(isUploading) {\n if (isUploading) {\n this.processingNewImage true;\n this.item.removeBackground false;\n }\n this.$emit(toggle-disabled, isUploading);\n}\n,onItemImageLoad:function(src) {\n if (src.includes(\.nobg.\))\n {\n this.removingBackground false;\n this.processingNewImage false;\n }\n else\n {\n if (this.processingNewImage)\n {\n // After a user uploads a new image,\n // we wait until the browser loads the image\n // and then mark the checkbox to remove the background.\n this.item.trans.pos.x 0.5;\n this.item.trans.pos.y 0.5;\n this.item.trans.scale 1;\n setTimeout(() > {\n //this.item.removeBackground true;\n }, 100);\n }\n }\n}\n,onItemImageError:function(src) {\n this.removingBackground false;\n this.processingNewImage false;\n this.error true;\n}\n},watch:{processingNewImage:function(newValue) {\n this.$emit(toggle-disabled, newValue);\n}\n},name:e-template-image-editor,_:{examples:{count:0}},template:div class\comp-e-template-image-editor items\ v-if\item\ path\1046603147.\>transition name\slide2\ path\1046603147.0\>div path\1046603147.0.0\>transition name\slide2\ path\1046603147.0.0.0\>div class\flex justify-between\ v-if\(item.imageID && !removingBackground)\ path\1046603147.0.0.0.0\>ui-expand v-if\false\ text\shadow\ v-model\showShadowEditor\ path\1046603147.0.0.0.0.0\>/ui-expand>ui-checkbox v-if\temp?.can?.remove?.background\ text\remove background\ v-model\item.removeBackground\ path\1046603147.0.0.0.0.1\>/ui-checkbox>/div>/transition>e-template-caption-editor v-if\item.caption\ :item\item.caption\ :minimal\true\ path\1046603147.0.0.1\>/e-template-caption-editor>transition name\slide2\ path\1046603147.0.0.2\>div class\error my-l1\ v-if\error\ path\1046603147.0.0.2.0\>div class\flex gap-1\ path\1046603147.0.0.2.0.0\>ui-image :style\{ width: 5em }\ :imageID\item.imageID\ :square\true\ path\1046603147.0.0.2.0.0.0\>/ui-image>div path\1046603147.0.0.2.0.0.1\>div v-text\An error occurred.\ path\1046603147.0.0.2.0.0.1.0\>/div>div path\1046603147.0.0.2.0.0.1.1\>span v-text\Try another image or \ path\1046603147.0.0.2.0.0.1.1.0\>/span>a class\yellow\ target\_blank\ href\https://www.remove.bg/\ v-text\remove.bg\ path\1046603147.0.0.2.0.0.1.1.1\>/a>/div>/div>/div>/div>/transition>transition name\slide2\ path\1046603147.0.0.3\>div class\message\ v-if\removingBackground\ path\1046603147.0.0.3.0\>div class\flex\ path\1046603147.0.0.3.0.0\>ui-image :style\{ width: 5em }\ :imageID\item.imageID\ :square\true\ path\1046603147.0.0.3.0.0.0\>/ui-image>div path\1046603147.0.0.3.0.0.1\>div class\fs-m2\ v-text\Removing background\ path\1046603147.0.0.3.0.0.1.0\>/div>ui-loading>/ui-loading>/div>/div>/div>/transition>/div>/transition>div path\1046603147.1\>transition name\slide2\ path\1046603147.1.0\>div v-if\showShadowEditor\ path\1046603147.1.0.0\>ui-input-range text\x\ v-model\item.shadow.x\ min\-1\ max\1\ step\0.01\ path\1046603147.1.0.0.0\>/ui-input-range>ui-input-range text\y\ v-model\item.shadow.y\ min\-1\ max\1\ step\0.01\ path\1046603147.1.0.0.1\>/ui-input-range>ui-input-range text\blur\ v-model\item.shadow.blur\ max\1\ step\0.01\ path\1046603147.1.0.0.2\>/ui-input-range>ui-input-range text\opacity\ v-model\item.shadow.opacity\ max\1\ step\0.01\ path\1046603147.1.0.0.3\>/ui-input-range>/div>/transition>/div>/div>}},{name:e.template.image.item,path:\\e\\template\\image\\item.ws.yaml,source:{dom:{div:{v-if:item,ui.file.dropzone:{:show-hint:false,:enabled:editable,v-model:item.imageID,ui.movable:{:enabled:editable,on_drag-by:({ dx, dy }) > onItemDragBy(item, { dx, dy }),on_scale-by:(ds) > onItemScaleBy(item, ds),ui.image:{ref:image1,v-if:item,:style:getStyle(item),:imageID:item.imageID,:remove-background:item.removeBackground,on_load:onImageLoad,on_error:onImageError,on_change:refresh}}},e.template.caption.item:{v-if:item.caption,:temp:temp,:item:item.caption,:editable:editable}}},props:{temp:null,item:null,editable:false},mounted:async function () {\n}\n,methods:{onItemDragBy:function(item, dpos) {\n const pos item.trans.pos;\n pos.x + dpos.dx;\n pos.y + dpos.dy;\n}\n,onItemScaleBy:function(item, ds) {\n item.trans.scale + ds;\n}\n,onImageLoad:function(src) {\n this.$emit(image-load, this.item, src);\n}\n,onImageError:function(src) {\n this.$emit(image-error, this.item, src);\n}\n,refresh:function() {\n}\n,getStyle:function(item) {\n if (!item) return;\n let style {};\n style.transform `translate(${(-0.5 + item.trans.pos.x) * 100}%, ${(-0.5 + item.trans.pos.y) * 100}%) scale(${item.trans.scale})`;\n const cssFilters ;\n const image1 this.$refs.image1;\n if (image1 && item.shadow)\n {\n // Apply the opacity to the shadow color\n const color item.shadow.color.replace(/#(..)(..)(..)/, (match, r, g, b) > {\n const opacity Math.round(item.shadow.opacity*255).toString(16);\n return `#${r}${g}${b}${opacity}`;\n });\n const values {\n x: (item.shadow.x*image1.width).toFixed(2),\n y: (item.shadow.y*image1.height).toFixed(2),\n blur: item.shadow.blur/20*image1.diagonal.toFixed(2),\n color: color\n };\n const dropShadow `drop-shadow(${values.x}px ${values.y}px ${values.blur}px ${values.color})`;\n cssFilters.push(dropShadow);\n }\n style.filter cssFilters.join( );\n return style;\n}\n},watch:{item:{handler:async function(item) {\n}\n,deep:true}},style:{.comp-e-template-image-item:{border:1px solid gray},.comp-e-template-caption-item:{position:absolute,top:0,width:100%,height:100%,pointer-events:none}},name:e-template-image-item,_:{examples:{count:0}},template:div class\comp-e-template-image-item\ v-if\item\ path\1623568049.\>ui-file-dropzone :enabled\editable\ v-model\item.imageID\ path\1623568049.0\>ui-movable :enabled\editable\ on_drag-by\({ dx, dy }) > onItemDragBy(item, { dx, dy })\ on_scale-by\(ds) > onItemScaleBy(item, ds)\ path\1623568049.0.0\>ui-image ref\image1\ v-if\item\ :style\getStyle(item)\ :imageID\item.imageID\ :remove-background\item.removeBackground\ on_load\onImageLoad\ on_error\onImageError\ on_change\refresh\ path\1623568049.0.0.0\>/ui-image>/ui-movable>/ui-file-dropzone>e-template-caption-item v-if\item.caption\ :temp\temp\ :item\item.caption\ :editable\editable\ path\1623568049.1\>/e-template-caption-item>/div>}},{name:e.template.item.editor,path:\\e\\template\\item\\editor.ws.yaml,source:{dom:{div:{v-text:item}},props:{item:null},name:e-template-item-editor,_:{examples:{count:0}},template:div class\comp-e-template-item-editor\ v-text\item\ path\644061981.\>/div>}},{name:e.template.item.filters,path:\\e\\template\\item\\filters.ws.yaml,source:{dom:{div:{v-if:value,ui.image.options#1:{:imageID:imageID,filter:blur,v-model:value.blur},ui.image.options#2:{:imageID:imageID,filter:opacity,:reverse:true,v-model:value.transparent},ui.image.options#3:{:imageID:imageID,filter:grayscale,v-model:value.grayscale}}},props:{imageID:null,value:null},data:null,methods:null,name:e-template-item-filters,_:{examples:{count:0}},template:div class\comp-e-template-item-filters\ v-if\value\ path\-475504565.\>ui-image-options :imageID\imageID\ filter\blur\ v-model\value.blur\ path\-475504565.0\>/ui-image-options>ui-image-options :imageID\imageID\ filter\opacity\ :reverse\true\ v-model\value.transparent\ path\-475504565.1\>/ui-image-options>ui-image-options :imageID\imageID\ filter\grayscale\ v-model\value.grayscale\ path\-475504565.2\>/ui-image-options>/div>}},{name:e.template.item.icon,path:\\e\\template\\item\\icon.ws.yaml,source:{dom:{.icon:{on_click:$emit(click),ui.checkbox:{v-model:item.visible,size:normal},div#1:{v-if:hasImage,ui.image:{:imageID:item.imageID,:square:true}},div#2:{v-if:(!hasImage),v-text:getItemTypeIcon(item.type)},div#3:{v-if:(item.type!image),class:no-wrap,v-text:item.caption?.text?.shorten(20)||(+item.type+)}}},props:{item:null},methods:{getItemTypeIcon:function(type) {\n return {\n container: ,\n image: πΌοΈ,\n caption: βοΈ,\n rainbow: π\n }type || ;\n}\n},computed:{hasImage:function() {\n if (!this.item) return false;\n return (this.item.type image) && this.item.imageID;\n}\n},style:{.comp-ui-image:{width:2.2rem !important},.icon:{display:flex,width:5em,font-size:110%},.no-wrap:{white-space:nowrap}},name:e-template-item-icon,_:{examples:{count:0}},template:div class\comp-e-template-item-icon icon\ on_click\$emit(click)\ path\-562339287.\>ui-checkbox v-model\item.visible\ size\normal\ path\-562339287.0\>/ui-checkbox>div v-if\hasImage\ path\-562339287.1\>ui-image :imageID\item.imageID\ :square\true\ path\-562339287.1.0\>/ui-image>/div>div v-if\(!hasImage)\ v-text\getItemTypeIcon(item.type)\ path\-562339287.2\>/div>div class\no-wrap\ v-if\(item.type!image)\ v-text\item.caption?.text?.shorten(20)||(+item.type+)\ path\-562339287.3\>/div>/div>}},{name:e.template.rainbow.editor,path:\\e\\template\\rainbow\\editor.ws.yaml,source:{dom:{div#1:{div#2:{table:{tbody:{tr#1:{th#1:{v-text:pattern},td#1:{ui.select:{v-slot:slotProps,:options:patternOptions,input-type:value,v-model:item.pattern,:show-text:false,template:{img:{class:pattern-image,:src:/img/rainbow/patterns/+slotProps.item+.png}}}}},tr#2:{th#2:{v-text:detail},td#2:{input#1:{type:range,min:2,max:36,v-model:item.slices}}},tr#3:{th#3:{v-text:colors},td#3:{.flex:{ui.button#1:{:text:β,:click:removeColor},input#2:{class:clickable,type:color,v-for:index in item.colorsCount,v-model:item.colorsindex-1},ui.button#2:{:text:β,:click:addColor}}}}}}}}},props:{item:null},data:{patternOptions:radial,lines,checkers,pizza},methods:{onColorChange:function (index, value) {\n this.item.colorsindex value;\n}\n,addColor:function () {\n if (this.item.colorsCount > this.item.colors.length) return;\n this.item.colorsCount++;\n if (this.item.colorsCount > this.item.slices) this.item.slices this.item.colorsCount;\n}\n,removeColor:function () {\n this.item.colorsCount--;\n}\n},watch:{item:{handler:function(item) {\n}\n,deep:true}},style:{button:{padding:0 0.3em !important},ul:{display:flex},li:{flex-grow:1},li > div:{text-align:center},.pattern-image:{filter:grayscale(1) contrast(1) brightness(1.5)}},name:e-template-rainbow-editor,_:{examples:{count:0}},template:div class\comp-e-template-rainbow-editor\ path\637897232.\>div path\637897232.0\>table path\637897232.0.0\>tbody path\637897232.0.0.0\>tr path\637897232.0.0.0.0\>th v-text\pattern\ path\637897232.0.0.0.0.0\>/th>td path\637897232.0.0.0.0.1\>ui-select v-slot\slotProps\ :options\patternOptions\ input-type\value\ v-model\item.pattern\ :show-text\false\ path\637897232.0.0.0.0.1.0\>template path\637897232.0.0.0.0.1.0.0\>img class\pattern-image\ :src\/img/rainbow/patterns/+slotProps.item+.png\ path\637897232.0.0.0.0.1.0.0.0\/>/template>/ui-select>/td>/tr>tr path\637897232.0.0.0.1\>th v-text\detail\ path\637897232.0.0.0.1.0\>/th>td path\637897232.0.0.0.1.1\>input type\range\ min\2\ max\36\ v-model\item.slices\ path\637897232.0.0.0.1.1.0\/>/td>/tr>tr path\637897232.0.0.0.2\>th v-text\colors\ path\637897232.0.0.0.2.0\>/th>td path\637897232.0.0.0.2.1\>div class\flex\ path\637897232.0.0.0.2.1.0\>ui-button :text\β\ :click\removeColor\ path\637897232.0.0.0.2.1.0.0\>/ui-button>input class\clickable\ type\color\ v-for\index in item.colorsCount\ v-model\item.colorsindex-1\ path\637897232.0.0.0.2.1.0.1\/>ui-button :text\β\ :click\addColor\ path\637897232.0.0.0.2.1.0.2\>/ui-button>/div>/td>/tr>/tbody>/table>/div>/div>}},{name:e.template.rainbow.item,path:\\e\\template\\rainbow\\item.ws.yaml,source:{dom:{div:{canvas:{ref:canvas1,width:1000,height:1000}}},props:{item:null},data:{drawTimer:null},mounted:function () {\n window.addEventListener(`resize`, this.draw.bind(this));\n // Detect if the image element changes its size\n let resizeObserver new ResizeObserver(this.draw.bind(this));\n resizeObserver.observe(this.$refs.canvas1);\n}\n,methods:{draw:function () {\n const canvas this.$refs.canvas1;\n if (!canvas) return;\n const ctx canvas.getContext(\2d\);\n const width canvas.width;\n const height canvas.height;\n const slices this.item.slices;\n const colors this.item.colors;\n const colorsCount this.item.colorsCount;\n const pattern this.item.pattern?.toTitleCase();\n if (!pattern) return;\n this`draw${pattern}`(ctx, width, height, slices, colors, colorsCount);\n}\n,drawRadial:function (ctx, width, height, slices, colors, colorsCount) {\n const grd ctx.createRadialGradient(width / 2, height / 2, 0, width / 2, height / 2, width * 2);\n for (let i 0; i slices; i++) {\n grd.addColorStop(i / slices, colorsi % colorsCount);\n }\n grd.addColorStop(1, colors0);\n ctx.fillStyle grd;\n ctx.fillRect(0, 0, width, height);\n}\n,drawLines:function (ctx, width, height, slices, colors, colorsCount) {\n const grd ctx.createLinearGradient(0, 0, width, height);\n for (let i 0; i slices; i++) {\n grd.addColorStop(i / slices, colorsi % colorsCount);\n }\n grd.addColorStop(1, colors0);\n ctx.fillStyle grd;\n ctx.fillRect(0, 0, width, height);\n}\n,drawCheckers:function (ctx, width, height, slices, colors, colorsCount) {\n // Slice the canvas into slices, like a pizza\n const sliceWidth width / slices;\n const sliceHeight height / slices;\n for (let i 0; i slices; i++) {\n for (let j 0; j slices; j++) {\n ctx.fillStyle colors(i + j) % colorsCount;\n ctx.fillRect(i * sliceWidth, j * sliceHeight, sliceWidth, sliceHeight);\n }\n }\n}\n,drawPizza:function (ctx, width, height, slices, colors, colorsCount) {\n const center { x: width / 2, y: height / 2 };\n const angle 2 * Math.PI / slices;\n const radius Math.max(width, height);\n for (let i 0; i slices; i++) {\n ctx.beginPath();\n ctx.moveTo(center.x, center.y);\n ctx.arc(center.x, center.y, radius, i * angle, (i + 1) * angle);\n ctx.closePath();\n ctx.fillStyle colorsi % colorsCount;\n ctx.fill();\n }\n}\n},watch:{item:{handler:function () {\n this.$nextTick(this.draw.bind(this));\n}\n,immediate:true,deep:true}},style:{canvas:{width:100%,height:100%}},name:e-template-rainbow-item,_:{examples:{count:0}},template:div class\comp-e-template-rainbow-item\ path\-1952272266.\>canvas ref\canvas1\ width\1000\ height\1000\ path\-1952272266.0\>/canvas>/div>}},{name:e.thread.catalog,path:\\e\\thread\\catalog.ws.yaml,source:{dom:{div:{.catalog:{transition.group:{name:list,e.thread.teaser:{v-for:thread in threads,:thread:thread,:key:thread._id}}}}},props:null,data:{threads:},mounted:async function() {\n this.$root.isLoading++;\n try\n {\n this.threads await this.$root.dbp.threads.select.all();\n }\n finally\n {\n this.$root.isLoading--;\n }\n}\n,style:{.comp-e-thread-teaser:{display:inline-block,width:15rem,margin:1rem},.catalog:{position:fixed;,top:50%;,left:50%;,transform:translate(-50%, -50%);,width:100vw;,height:90vh;,overflow:auto;,text-align:center;,z-index:1000;},.grid1:{display:flex,flex-wrap:wrap,justify-content:space-evenly},.grid1 > div:{width:15rem,margin-bottom:3rem}},name:e-thread-catalog,_:{examples:{count:0}},template:div class\comp-e-thread-catalog\ path\-751930146.\>div class\catalog\ path\-751930146.0\>transition-group name\list\ path\-751930146.0.0\>e-thread-teaser v-for\thread in threads\ :thread\thread\ :key\thread._id\ path\-751930146.0.0.0\>/e-thread-teaser>/transition-group>/div>/div>}},{name:e.thread.create,path:\\e\\thread\\create.ws.yaml,source:{dom:{div:{transition#1:{name:slide,ui.button#1:{v-if:!showCreateThread,:text:β¨ start a new thread,v-model:showCreateThread}},transition#2:{name:slide,.mt-l2:{v-show:showCreateThread,e.post.create:{on_input-preview:postPreview$event,on_created:onCreatedThread},.mt-l1:{ui.button#2:{:text:βοΈ cancel,:click:onClickCancel}}}}}},props:null,data:{showCreateThread:false,postPreview:null},methods:{onCreatedThread:function(post) {\n console.log(post);\n}\n,onClickCancel:function() {\n this.showCreateThread false;\n}\n},watch:{showCreateThread:function(showCreateThread) {\n this.$emit(\input:columnsFocusLeft\, showCreateThread);\n}\n},name:e-thread-create,_:{examples:{count:0}},template:div class\comp-e-thread-create\ path\-563191913.\>transition name\slide\ path\-563191913.0\>ui-button v-if\!showCreateThread\ :text\β¨ start a new thread\ v-model\showCreateThread\ path\-563191913.0.0\>/ui-button>/transition>transition name\slide\ path\-563191913.1\>div class\mt-l2\ v-show\showCreateThread\ path\-563191913.1.0\>e-post-create on_input-preview\postPreview$event\ on_created\onCreatedThread\ path\-563191913.1.0.0\>/e-post-create>div class\mt-l1\ path\-563191913.1.0.1\>ui-button :text\βοΈ cancel\ :click\onClickCancel\ path\-563191913.1.0.1.0\>/ui-button>/div>/div>/transition>/div>}},{name:e.thread.list,path:\\e\\thread\\list.ws.yaml,source:{dom:{div#1:{ui.loading:{v-if:isLoading && !threads.length},ui.list:{v-slot:slotProps,:items:threads,ui.link:{:class:{ selected: isCurrentThread(slotProps.item) },:url:$root.url.thread(slotProps.item),.grid:{div#2:{e.instance:{:item:firstPost(slotProps.item)?.instance}},ui.title:{:number:slotProps.item.posts.length},div#3:{v-text:getThreadTitle(slotProps.item)}}}}}},data:{threads:,isLoading:false},mounted:async function() {\n this.$watch(() > this.$root.params.url, this.init.bind(this), { immediate: true });\n}\n,methods:{init:async function() {\n this.isLoading true;\n try\n {\n this.threads await this.$root.dbp.threads.select.all();\n }\n finally\n {\n this.isLoading false;\n }\n}\n,isCurrentThread:function(thread) {\n return this.$root.params.url this.$root.url.thread(thread);\n}\n,getThreadTitle:function(thread) {\n const post thread.posts0;\n if (!post) return null;\n return post.text ||\n post.instance?.text1 ||\n post.instance?.text0 ||\n post.instance?.displayName;\n}\n,firstPost:function(thread) {\n return thread.posts0;\n}\n},name:e-thread-list,style:{.grid:{grid-template:1fr / 2rem 2rem 1fr,gap:0.5rem}},_:{examples:{count:0}},template:div class\comp-e-thread-list\ path\-335521287.\>ui-loading v-if\isLoading && !threads.length\ path\-335521287.0\>/ui-loading>ui-list v-slot\slotProps\ :items\threads\ path\-335521287.1\>ui-link :class\{ selected: isCurrentThread(slotProps.item) }\ :url\$root.url.thread(slotProps.item)\ path\-335521287.1.0\>div class\grid\ path\-335521287.1.0.0\>div path\-335521287.1.0.0.0\>e-instance :item\firstPost(slotProps.item)?.instance\ path\-335521287.1.0.0.0.0\>/e-instance>/div>ui-title :number\slotProps.item.posts.length\ path\-335521287.1.0.0.1\>/ui-title>div v-text\getThreadTitle(slotProps.item)\ path\-335521287.1.0.0.2\>/div>/div>/ui-link>/ui-list>/div>}},{name:e.thread.teaser,path:\\e\\thread\\teaser.ws.yaml,source:{dom:{div#1:{v-if:thread,ui.link:{:url:$root.url.thread(thread),e.post#1:{:item:thread.posts0,:teaser:true},.text-center.opacity-50:{ui.time:{:value:thread.lastPostCreated},div#2:{v-text:thread.postsCount + posts}}},div#3:{e.post#2:{v-for:post in thread.posts,:item:post}}}},props:{thread:null,showPosts:false},data:null,watch:null,methods:null,style:{.grid:{grid-template:1fr / repeat(40rem, auto),gap:1em},.clickable2:{opacity:0.8},.clickable2:hover:{background:none,opacity:1}},name:e-thread-teaser,_:{examples:{count:0}},template:div class\comp-e-thread-teaser\ v-if\thread\ path\-88604437.\>ui-link :url\$root.url.thread(thread)\ path\-88604437.0\>e-post :item\thread.posts0\ :teaser\true\ path\-88604437.0.0\>/e-post>div class\text-center opacity-50\ path\-88604437.0.1\>ui-time :value\thread.lastPostCreated\ path\-88604437.0.1.0\>/ui-time>div v-text\thread.postsCount + posts\ path\-88604437.0.1.1\>/div>/div>/ui-link>div path\-88604437.1\>e-post v-for\post in thread.posts\ :item\post\ path\-88604437.1.0\>/e-post>/div>/div>}},{name:e.thread,path:\\e\\thread.ws.yaml,source:{dom:{div#1:{div#2:{transition.group:{tag:ul,name:slide,li:{v-for:(post, index) in visiblePosts,:key:post?._id||0,e.post:{:item:post,:threadMedia:dThreadMedia,on_thread-updated:reload},.text-center.opacity-30:{v-if:teaser && getHiddenPostsCount(index),v-text:( + getHiddenPostsCount(index) + postsβ¦)}}},e.post.create:{v-disable:isLoading,:threadID:thread?._id,:threadMedia:dThreadMedia,on_created:reload},.mt-l2:{class:hidden,ui.button:{v-if:$root.isAdmin,:text:β» reload,:click:reload}}}}},props:{threadID:null,threadMedia:null,teaser:false},data:{thread:null,dThreadMedia:null,threadIsEmpty:false,tasks:null,key1:1,isLoading:0},mounted:async function() {\n this.$root.$on(\thread-updated\, this.onThreadUpdated.bind(this));\n}\n,methods:{ensureInited:function() {\n if (!this.tasks) this.tasks new TaskQueue();\n}\n,onThreadUpdated:async function(threadID, threadMediaID) {\n if (threadMediaID ! this.dThreadMedia?._id) return;\n await this.reload();\n}\n,getHiddenPostsCount:function(index) {\n const post this.visiblePostsindex;\n const nextPost this.visiblePostsindex + 1;\n if (!post || !nextPost) return null;\n return (nextPost.index - post.index - 1);\n}\n,isRelevantThread:function(thread) {\n if (!this.thread) return false;\n if (this.thead._id thread?._id) return true;\n return false;\n}\n,refresh:function() {\n this.key1++;\n}\n,reload:async function() {\n await this.ensureInited();\n this.isLoading++;\n this.tasks.enqueue(this._reload);\n}\n,_reload:async function() {\n // Get the thread\n try\n {\n this.thread await this.$root.dbp.threads.select.one(this.threadID, this.dThreadMedia?._id, this.dThreadMedia?.instance?._id);\n this.threadIsEmpty !this.thread;\n this.refresh();\n }\n finally\n {\n this.isLoading--;\n }\n}\n,clear:function() {\n this.thread null;\n this.threadIsEmpty false;\n}\n},computed:{visiblePosts:function() {\n if (!this.thread) return ;\n let posts1 ...this.thread.posts;\n // OP is shown on the left\n posts1.shift();\n // Sort by score\n posts1.sortBy(p > -p.totalVotesScore);\n if (!this.teaser) return posts1;\n\n // Thread teaser\n let vPosts ;\n // Take the first two and the last two posts\n vPosts.push(...posts1.slice(0, 2));\n vPosts.push(...posts1.slice(-2));\n // Make sure there are no duplicates\n vPosts vPosts.filter((post, index, self) > self.findIndex(p > p._id post._id) index);\n // Return\n return vPosts;\n}\n},watch:{thread:{handler:function() {\n this.refresh();\n}\n},threadID:{handler:async function(threadID) {\n await this.reload();\n}\n,immediate:true},threadMedia:{handler:async function(threadMedia, oldThreadMedia) {\n if (threadMedia?.instance?._id ! oldThreadMedia?.instance?._id)\n {\n this.tasks.enqueue(this.clear);\n this.clear();\n }\n this.dThreadMedia threadMedia;\n if (!threadMedia) return;\n if (this.dThreadMedia.instance)\n {\n // This instance may already have a media\n const existingInstanceMedia await this.$root.dbp.medias.select.byInstance(this.dThreadMedia.instance._id);\n if (existingInstanceMedia)\n {\n this.dThreadMedia existingInstanceMedia;\n }\n await this.reload();\n }\n}\n,immediate:true}},style:{.comp-e-post-create:{transition:opacity 0.1s},.thread-columns:{display:grid,grid-template:1fr / 1fr 1fr,gap:2vw},ul:{margin:auto},li:{margin-bottom:1vh}},name:e-thread,_:{examples:{count:0}},template:div class\comp-e-thread\ path\1226205107.\>div path\1226205107.0\>transition-group tag\ul\ name\slide\ path\1226205107.0.0\>li v-for\(post, index) in visiblePosts\ :key\post?._id||0\ path\1226205107.0.0.0\>e-post :item\post\ :threadMedia\dThreadMedia\ on_thread-updated\reload\ path\1226205107.0.0.0.0\>/e-post>div class\text-center opacity-30\ v-if\teaser && getHiddenPostsCount(index)\ v-text\( + getHiddenPostsCount(index) + postsβ¦)\ path\1226205107.0.0.0.1\>/div>/li>/transition-group>e-post-create v-disable\isLoading\ :threadID\thread?._id\ :threadMedia\dThreadMedia\ on_created\reload\ path\1226205107.0.1\>/e-post-create>div class\hidden mt-l2\ path\1226205107.0.2\>ui-button v-if\$root.isAdmin\ :text\β» reload\ :click\reload\ path\1226205107.0.2.0\>/ui-button>/div>/div>/div>}},{name:e.voter,path:\\e\\voter.ws.yaml,source:{dom:{div:{.flex:{.clickable#1:{v-text:βΌ},.score:{v-text:0},.clickable#2:{v-text:β²}}}},props:null,data:null,style:{.flex:{font-size:140%,gap:0.5em},.score:{opacity:0.4},.clickable:{opacity:0.2},.clickable:hover:{opacity:0.6}},name:e-voter,_:{examples:{count:0}},template:div class\comp-e-voter\ path\872896511.\>div class\flex\ path\872896511.0\>div class\clickable\ v-text\βΌ\ path\872896511.0.0\>/div>div class\score\ v-text\0\ path\872896511.0.1\>/div>div class\clickable\ v-text\β²\ path\872896511.0.2\>/div>/div>/div>}},{name:page.admin.index,path:\\page\\admin\\index.ws.yaml,source:{dom:{site:{:columns:2,page-name:admin,template#1:{v-slot:left},template#2:{v-slot:article,.app:{.column#1:{div#1:{v-if:!entityValue,ui.select#1:{:options:Object.keys(options),v-model:catValue,input-type:value},ui.select#2:{:options:optionscatValue,v-model:eventValue,input-type:value}},.mt-l2:{ui.select#3:{:options:entities,v-model:entityValue,input-type:value}}},.column#2:{ui.select:{:options:lastOptions,v-model:lastValue,input-type:value}},div#2:{.bars:{.bar:{ui.chart2:{:entity:entityValue,:app:MG,:category:catValue,:event:eventValue,:last:lastValue,:every:every}}}}},.flex.gap-1:{page.admin.medias:null,page.admin.posts:null,page.admin.instances:null,div#3:null}}}},data:{entities:Posts,Medias,Instances,options:{network:requests,response.time,site:active.time},catValue:network,eventValue:requests,entityValue:null,lastOptions:1 years,6 months,3 months,2 months,1 months,1 weeks,1 days,1 hours,lastValue:1 hours,barsValue:100},mounted:async function() {\n this.$root.isAdmin true;\n}\n,methods:{getCatOptions:function() {\n}\n},computed:{chartData:function() {\n return Array.from({ length: 10 }, (v, i) > i + 1);\n}\n,every:function() {\n if (!this.lastValue || !this.barsValue) return null;\n if (this.lastValue.endsWith(\hour\)) return (1).minutes().unitifyTime().withoutColors();\n return (this.lastValue.deunitify() / this.barsValue).unitifyTime().withoutColors();\n}\n},style:{.app:{display:flex,gap:1em,padding:1em},.app > div:not(.column):{flex-grow:1},.column:{width:fit-content},.bars:{display:flex,flex-direction:column,gap:1rem},.bar:{width:100%,display:flex,margin:auto,gap:1rem}},name:page-admin-index,_:{examples:{count:0}},template:site class\comp-page-admin-index\ :columns\2\ page-name\admin\ path\-1156850540.\>template v-slot:left path\-1156850540.0\>/template>template v-slot:article path\-1156850540.1\>div class\app\ path\-1156850540.1.0\>div class\column\ path\-1156850540.1.0.0\>div v-if\!entityValue\ path\-1156850540.1.0.0.0\>ui-select :options\Object.keys(options)\ v-model\catValue\ input-type\value\ path\-1156850540.1.0.0.0.0\>/ui-select>ui-select :options\optionscatValue\ v-model\eventValue\ input-type\value\ path\-1156850540.1.0.0.0.1\>/ui-select>/div>div class\mt-l2\ path\-1156850540.1.0.0.1\>ui-select :options\entities\ v-model\entityValue\ input-type\value\ path\-1156850540.1.0.0.1.0\>/ui-select>/div>/div>div class\column\ path\-1156850540.1.0.1\>ui-select :options\lastOptions\ v-model\lastValue\ input-type\value\ path\-1156850540.1.0.1.0\>/ui-select>/div>div path\-1156850540.1.0.2\>div class\bars\ path\-1156850540.1.0.2.0\>div class\bar\ path\-1156850540.1.0.2.0.0\>ui-chart2 :entity\entityValue\ :app\MG\ :category\catValue\ :event\eventValue\ :last\lastValue\ :every\every\ path\-1156850540.1.0.2.0.0.0\>/ui-chart2>/div>/div>/div>/div>div class\flex gap-1\ path\-1156850540.1.1\>page-admin-medias>/page-admin-medias>page-admin-posts>/page-admin-posts>page-admin-instances>/page-admin-instances>div>/div>/div>/template>/site>}},{name:page.admin.instances,path:\\page\\admin\\instances.ws.yaml,source:{dom:{div#1:{h2:{v-text:New Instances},div#2:{div#3:{content.stream:{item-type:e.instance,:get-more-items:getMoreInstances,grid-class:grid-1}}}}},data:null,methods:{getMoreInstances:async function(pageIndex, fromInstanceID) {\n return await this.$root.dbp.instances.select.new(null, fromInstanceID);\n}\n},style:null,name:page-admin-instances,_:{examples:{count:0}},template:div class\comp-page-admin-instances\ path\-1813446336.\>h2 v-text\New Instances\ path\-1813446336.0\>/h2>div path\-1813446336.1\>div path\-1813446336.1.0\>content-stream item-type\e.instance\ :get-more-items\getMoreInstances\ grid-class\grid-1\ path\-1813446336.1.0.0\>/content-stream>/div>/div>/div>}},{name:page.admin.medias,path:\\page\\admin\\medias.ws.yaml,source:{dom:{div#1:{h2:{v-text:New Medias},div#2:{div#3:{content.stream:{item-type:e.media,:item-props:{ showMediaMenu: true },:get-more-items:getMoreMedias,grid-class:grid-1}}}}},data:null,methods:{getMoreMedias:async function(pageIndex, fromMediaID) {\n return await this.$root.dbp.medias.select.new(null, fromMediaID);\n}\n},style:{.columns1 > div:nth-child(1):{width:30%}},name:page-admin-medias,_:{examples:{count:0}},template:div class\comp-page-admin-medias\ path\-1396420211.\>h2 v-text\New Medias\ path\-1396420211.0\>/h2>div path\-1396420211.1\>div path\-1396420211.1.0\>content-stream item-type\e.media\ :item-props\{ showMediaMenu: true }\ :get-more-items\getMoreMedias\ grid-class\grid-1\ path\-1396420211.1.0.0\>/content-stream>/div>/div>/div>}},{name:page.admin.posts,path:\\page\\admin\\posts.ws.yaml,source:{dom:{div#1:{h2:{v-text:New Posts},div#2:{div#3:{content.stream:{item-type:e.post,:get-more-items:getMorePosts,grid-class:grid-1}}}}},data:null,methods:{getMorePosts:async function(pageIndex, fromPostID) {\n return await this.$root.dbp.posts.select.new(null, fromPostID);\n}\n},style:null,name:page-admin-posts,_:{examples:{count:0}},template:div class\comp-page-admin-posts\ path\-1150341227.\>h2 v-text\New Posts\ path\-1150341227.0\>/h2>div path\-1150341227.1\>div path\-1150341227.1.0\>content-stream item-type\e.post\ :get-more-items\getMorePosts\ grid-class\grid-1\ path\-1150341227.1.0.0\>/content-stream>/div>/div>/div>}},{name:page.builder,path:\\page\\builder.ws.yaml,source:{dom:{site:{page-name:builder,:columns:2,template:{v-slot:article,transition:{name:slide-large,keep.alive:{e.builder:{:builder:builder,on_cancel:onCancel}}}}}},props:null,data:{builder:null,urlName:null},mounted:async function() {\n this.$watch(() > this.$root.params.urlName, {\n handler: async () > {\n await this.init(this.$root.params.page, this.$root.params.urlName);\n },\n immediate: true\n });\n}\n,methods:{init:async function (page, urlName) {\n if (page ! \builder\) return;\n if (urlName this.urlName) return;\n this.clear();\n if (!urlName) return;\n this.urlName urlName;\n this.builder await this.$root.getBuilder(urlName);\n}\n,clear:function () {\n this.builder null;\n this.urlName null;\n}\n,onCancel:function () {\n this.$root.navigateTo(/);\n}\n},computed:null,watch:null,name:page-builder,_:{examples:{count:0}},template:site class\comp-page-builder\ page-name\builder\ :columns\2\ path\1227252540.\>template v-slot:article path\1227252540.0\>transition name\slide-large\ path\1227252540.0.0\>keep-alive path\1227252540.0.0.0\>e-builder :builder\builder\ on_cancel\onCancel\ path\1227252540.0.0.0.0\>/e-builder>/keep-alive>/transition>/template>/site>}},{name:page.catalog,path:\\page\\catalog.ws.yaml,source:{dom:{site:{page-name:catalog,:columns:2,template:{v-slot:article,e.thread.catalog:null}}},props:null,data:null,name:page-catalog,_:{examples:{count:0}},template:site class\comp-page-catalog\ page-name\catalog\ :columns\2\ path\1552012218.\>template v-slot:article path\1552012218.0\>e-thread-catalog>/e-thread-catalog>/template>/site>}},{name:page.category,path:\\page\\category.ws.yaml,source:{dom:{site:{page-name:category,template:{v-slot:article,.grid-3:{e.teaser#1:{imageID:679668918,title:Barbie},e.teaser#2:{imageID:680118397,title:Indiana Jones 5},e.teaser#3:{imageID:680118400,title:Oppenheimer},e.teaser#4:{imageID:680118403,title:Nepoleon}},h1:{v-text:Movies}}}},props:null,name:page-category,_:{examples:{count:0}},template:site class\comp-page-category\ page-name\category\ path\871284093.\>template v-slot:article path\871284093.0\>div class\grid-3\ path\871284093.0.0\>e-teaser imageID\679668918\ title\Barbie\ path\871284093.0.0.0\>/e-teaser>e-teaser imageID\680118397\ title\Indiana Jones 5\ path\871284093.0.0.1\>/e-teaser>e-teaser imageID\680118400\ title\Oppenheimer\ path\871284093.0.0.2\>/e-teaser>e-teaser imageID\680118403\ title\Nepoleon\ path\871284093.0.0.3\>/e-teaser>/div>h1 v-text\Movies\ path\871284093.0.1\>/h1>/template>/site>}},{name:page.generator,path:\\page\\generator.ws.yaml,source:{dom:{site:{page-name:generator,:title-image-id:generator?.imageID,:title-text:generator?.displayName,:title-url:$root.url.generator(generator),:title-key:generator?.generatorID,template#1:{v-slot:article,ui.image:{class:hidden mb-l2,imageID:680118409,:aspect-ratio:3/1},transition#1:{name:slide,:key:generator?._id,div#1:{v-if:generator,div#2:{class:float-left w-25pc mr-l1,transition#2:{name:slide,e.generator.large:{:generator:generator,:key:generator?._id}}},h1:{v-text:generator?.displayName},.poem:{:style:{ marginLeft: 27%, width: fit-content },content.poem.stanza:{:item:randomStanza},ui.share:{:item:generator}},.description:{v-if:generator?.desc?.article,v-html:$root.textToHtml(generator.desc.article.replace(Title: , ))},div#3:{class:float-clear}}}},template#2:{v-slot:middle,content.stream:{ref:contentStream1,item-type:e.instance,:get-more-items:getMoreInstances,grid-class:grid-1,on_visible-item:onVisibleSteamInstanceChange}},template#3:{v-slot:left,e.instance.create:{v-if:(showCreateInstance),:generator:generator,on_created:onInstanceCreated},h3:{v-text:See also},e.generator.list:{:generators:recommendationItems}},template#4:{v-slot:right,div:{v-if:threadInstance,.sticky:{:style:{ top: 0px },e.instance.wide:{:instance:threadInstance}},e.thread:{:threadMedia:{type: instance, instance: threadInstance}}}}}},data:{urlName:null,generator:null,instance:null,visibleStreamInstance:null,poem:null,randomStanza:null,recommendationItems:,showCreateInstance:false},mounted:async function() {\n this.$watch(() > this.$root.params.urlName, {\n handler: async () > {\n await this.init(this.$root.params.page, this.$root.params.urlName);\n },\n immediate: true\n });\n}\n,methods:{init:async function(page, urlName) {\n const dbp this.$root.dbp;\n if (page ! \generator\) return;\n if (urlName this.urlName) return;\n this.clear();\n if (!urlName) return;\n this.urlName urlName;\n try\n {\n this.$root.isLoading++;\n this.generator !this.urlName ? null : await dbp.generators.select.one(null, this.urlName);\n this.recommendationItems.replace(async() > await dbp.generators.select.related(this.urlName), 300, gen > gen.generatorID);\n this.$refs.contentStream1?.reset();\n setTimeout(() > {\n this.poem this.generator?.desc?.poem;\n }, 500);\n if (this.$root.params.page \generator\) {\n this.$root.setDocumentTitle(this.generator?.displayName);\n }\n }\n finally\n {\n this.$root.isLoading--;\n }\n}\n,clear:function() {\n this.urlName null;\n this.generator null;\n this.poem null;\n this.recommendationItems ;\n this.$refs.contentStream1?.reset();\n}\n,getMoreInstances:async function(pageIndex) {\n await this.init();\n if (!this.urlName) return ;\n const items await this.$root.dbp.instances.select.popular(\en\, pageIndex, this.urlName)\n return items;\n}\n,getRandomStanzas:function(poem) {\n if (!poem) return ;\n // Return random stanzas\n const stanzas ...poem;\n const result ;\n for (let i 0; i 1; i++) {\n const index Math.floor(Math.random() * stanzas.length);\n result.push(stanzasindex);\n stanzas.splice(index, 1);\n }\n return result;\n}\n,onInstanceCreated:function(instance) {\n this.$root.notify(\e.instance\, instance);\n}\n,onVisibleSteamInstanceChange:function(instance) {\n this.visibleStreamInstance instance;\n}\n},watch:{generator:async function(generator) {\n if (!generator)\n {\n this.instance null;\n this.randomStanza null;\n this.showCreateInstance false;\n return;\n }\n this.instance (await this.$root.dbp.instances.select.popular(\en\, 0, generator.urlName)).shuffle()0;\n this.instance.text0 null;\n this.instance.text1 null;\n this.randomStanza this.getRandomStanzas(generator.desc?.poem)0;\n setTimeout(() > {\n this.showCreateInstance true;\n }, 200);\n}\n},computed:{threadInstance:function() {\n return (this.visibleStreamInstance);\n}\n},style:{.comp-e-teaser:{filter:grayscale(1)},.comp-e-teaser:hover:{filter:grayscale(0)},.description:{max-height:15em,overflow:auto,margin:2em 0},.description h3:{font-size:2rem,display:inline-block},.poem:null,.poem .comp-content-poem-stanza:{margin:1rem auto},.poem .line:nth-child(1):{font-size:160%},.float-clear:{clear:both},.sticky:{padding:0.5em}},name:page-generator,_:{examples:{count:0}},template:site class\comp-page-generator\ page-name\generator\ :title-image-id\generator?.imageID\ :title-text\generator?.displayName\ :title-url\$root.url.generator(generator)\ :title-key\generator?.generatorID\ path\-38884812.\>template v-slot:article path\-38884812.0\>ui-image class\hidden mb-l2\ imageID\680118409\ :aspect-ratio\3/1\ path\-38884812.0.0\>/ui-image>transition name\slide\ :key\generator?._id\ path\-38884812.0.1\>div v-if\generator\ path\-38884812.0.1.0\>div class\float-left w-25pc mr-l1\ path\-38884812.0.1.0.0\>transition name\slide\ path\-38884812.0.1.0.0.0\>e-generator-large :generator\generator\ :key\generator?._id\ path\-38884812.0.1.0.0.0.0\>/e-generator-large>/transition>/div>h1 v-text\generator?.displayName\ path\-38884812.0.1.0.1\>/h1>div class\poem\ :style\{ marginLeft: 27%, width: fit-content }\ path\-38884812.0.1.0.2\>content-poem-stanza :item\randomStanza\ path\-38884812.0.1.0.2.0\>/content-poem-stanza>ui-share :item\generator\ path\-38884812.0.1.0.2.1\>/ui-share>/div>div class\description\ v-if\generator?.desc?.article\ v-html\$root.textToHtml(generator.desc.article.replace(Title: , ))\ path\-38884812.0.1.0.3\>/div>div class\float-clear\ path\-38884812.0.1.0.4\>/div>/div>/transition>/template>template v-slot:middle path\-38884812.1\>content-stream ref\contentStream1\ item-type\e.instance\ :get-more-items\getMoreInstances\ grid-class\grid-1\ on_visible-item\onVisibleSteamInstanceChange\ path\-38884812.1.0\>/content-stream>/template>template v-slot:left path\-38884812.2\>e-instance-create v-if\(showCreateInstance)\ :generator\generator\ on_created\onInstanceCreated\ path\-38884812.2.0\>/e-instance-create>h3 v-text\See also\ path\-38884812.2.1\>/h3>e-generator-list :generators\recommendationItems\ path\-38884812.2.2\>/e-generator-list>/template>template v-slot:right path\-38884812.3\>div v-if\threadInstance\ path\-38884812.3.0\>div class\sticky\ :style\{ top: 0px }\ path\-38884812.3.0.0\>e-instance-wide :instance\threadInstance\ path\-38884812.3.0.0.0\>/e-instance-wide>/div>e-thread :threadMedia\{type: instance, instance: threadInstance}\ path\-38884812.3.0.1\>/e-thread>/div>/template>/site>}},{name:page.generators,path:\\page\\generators.ws.yaml,source:{dom:{site:{page-name:generators,:columns:2,template:{v-slot:middle,h2:{v-text:Advice Animals},content.stream:{ref:contentStream1,item-type:e.generator.teaser2,:get-more-items:getMoreGenerators,grid-class:grid-1a}}}},props:null,data:null,methods:{getMoreGenerators:async function(pageIndex) {\n const items await this.$root.dbp.generators.select.popular(pageIndex)\n return items;\n}\n},style:{h2:{font-size:3rem},.grid-1a:{gap:1em},a:hover:{background:#ffffff30}},name:page-generators,_:{examples:{count:0}},template:site class\comp-page-generators\ page-name\generators\ :columns\2\ path\-1205429057.\>template v-slot:middle path\-1205429057.0\>h2 v-text\Advice Animals\ path\-1205429057.0.0\>/h2>content-stream ref\contentStream1\ item-type\e.generator.teaser2\ :get-more-items\getMoreGenerators\ grid-class\grid-1a\ path\-1205429057.0.1\>/content-stream>/template>/site>}},{name:page.home,path:\\page\\home.ws.yaml,source:{dom:{site:{:columns:2,page-name:home,template#1:{v-slot:article,.grid-3:{class:hidden,e.teaser#1:{imageID:32,title:Advice Animals,url:/c/advice-animals},e.teaser#2:{imageID:679668918,title:Movies,url:/c/movies},e.teaser#3:{imageID:679668921,title:Anonymous Times},e.teaser#4:{imageID:679668909,title:YouTube}}},template#2:{v-slot:left,e.generator.search:null},template#3:{v-slot:middle,.flex.ver.gap-1:{content.meet.the.meme:null,content.stream:{ref:stream1,item-type:e.instance,:item-props:{ showShare: false },:get-more-items:getMoreInstances,grid-class:grid-3}}},template#4:{v-slot:right}}},data:{generators:,uniqueID:1},mounted:async function() {\n this.threads await this.$root.dbp.threads.select.all();\n \n this.$watch(() > this.$root.params.page, {\n handler: async () > {\n await this.init();\n },\n immediate: true\n });\n}\n,methods:{init:async function() {\n if (this.$root.params.page \home\)\n {\n this.$root.setDocumentTitle(null);\n this.$refs.stream1?.reset();\n }\n}\n,getMoreInstances:async function(pageIndex) {\n const items await this.$root.dbp.instances.sample.popular(null, 15);\n return items;\n}\n},style:{.comp-e-thread:{margin-top:6rem},.comp-e-generator-wide img:{aspect-ratio:2 / 1}},name:page-home,_:{examples:{count:0}},template:site class\comp-page-home\ :columns\2\ page-name\home\ path\838274270.\>template v-slot:article path\838274270.0\>div class\hidden grid-3\ path\838274270.0.0\>e-teaser imageID\32\ title\Advice Animals\ url\/c/advice-animals\ path\838274270.0.0.0\>/e-teaser>e-teaser imageID\679668918\ title\Movies\ url\/c/movies\ path\838274270.0.0.1\>/e-teaser>e-teaser imageID\679668921\ title\Anonymous Times\ path\838274270.0.0.2\>/e-teaser>e-teaser imageID\679668909\ title\YouTube\ path\838274270.0.0.3\>/e-teaser>/div>/template>template v-slot:left path\838274270.1\>e-generator-search>/e-generator-search>/template>template v-slot:middle path\838274270.2\>div class\flex ver gap-1\ path\838274270.2.0\>content-meet-the-meme>/content-meet-the-meme>content-stream ref\stream1\ item-type\e.instance\ :item-props\{ showShare: false }\ :get-more-items\getMoreInstances\ grid-class\grid-3\ path\838274270.2.0.1\>/content-stream>/div>/template>template v-slot:right path\838274270.3\>/template>/site>}},{name:page.instance,path:\\page\\instance.ws.yaml,source:{dom:{site:{ref:site1,page-name:instance,:content-not-found:contentNotFound,:recommendation-items:recommendationItems,template#1:{v-slot:left},template#2:{v-slot:middle,e.instance:{class:mb-l6,:item:instance,:instance-image:true},content.stream:{ref:stream1,item-type:e.instance,:get-more-items:getMoreInstances,grid-class:grid-1,on_visible-item:onVisibleSteamInstanceChange}},template#3:{v-slot:right,div:{v-if:threadInstance,.sticky:{v-if:threadInstance,:style:{ top: 0px },e.instance.wide:{:instance:threadInstance}},e.thread:{:threadMedia:{type: instance, instance: threadInstance}}}}}},data:{instance:null,visibleStreamInstance:null,generator:null,recommendationItems:,contentNotFound:false},mounted:async function() {\n this.$watch(() > this.$root.params.page, {\n handler: async () > {\n await this.init(this.$root.params.page, this.$root.params.instanceID);\n },\n immediate: true\n });\n this.$watch(() > this.$root.params.instanceID, {\n handler: async () > {\n await this.init(this.$root.params.page, this.$root.params.instanceID);\n },\n immediate: true\n });\n}\n,methods:{onVisibleSteamInstanceChange:function(instance) {\n this.visibleStreamInstance instance;\n}\n,init:async function(page, instanceID) {\n this.clear();\n if (page ! \instance\) return;\n if (!instanceID) return;\n if (instanceID this.instance?._id) return;\n try\n {\n this.$root.isLoading++;\n const dbp this.$root.dbp;\n this.instance await dbp.instances.select.one(instanceID);\n if (!this.instance) {\n this.contentNotFound true;\n return;\n }\n this.generator await dbp.generators.select.one(this.instance.generatorID);\n this.recommendationItems await dbp.generators.select.related(this.generator.urlName);\n this.$refs.stream1?.reset();\n if (page \instance\) {\n this.$root.setDocumentTitle(this.$root.getInstanceText(this.instance));\n }\n }\n finally\n {\n this.$root.isLoading--;\n }\n}\n,getMoreInstances:async function(pageIndex) {\n // Wait until instance is loaded\n await this.$root.wait(() > this.instance);\n let instances await this.$root.dbp.instances.select.popular(\en\, pageIndex, this.instance?.urlName);\n instances instances.filter(inst > inst._id ! this.instance?._id);\n return instances;\n}\n,clear:function() {\n this.$refs.stream1?.clear();\n this.instance null;\n this.generator null;\n this.recommendationItems ;\n this.contentNotFound false;\n}\n},computed:{threadInstance:function() {\n return (this.visibleStreamInstance || this.instance);\n}\n},watch:{threadInstance:{handler:function(threadInstance) {\n this.$root.setDocumentTitle(this.$root.getInstanceText(threadInstance));\n}\n,immediate:true}},style:{.sticky:{padding:0.5em}},name:page-instance,_:{examples:{count:0}},template:site class\comp-page-instance\ ref\site1\ page-name\instance\ :content-not-found\contentNotFound\ :recommendation-items\recommendationItems\ path\1375900948.\>template v-slot:left path\1375900948.0\>/template>template v-slot:middle path\1375900948.1\>e-instance class\mb-l6\ :item\instance\ :instance-image\true\ path\1375900948.1.0\>/e-instance>content-stream ref\stream1\ item-type\e.instance\ :get-more-items\getMoreInstances\ grid-class\grid-1\ on_visible-item\onVisibleSteamInstanceChange\ path\1375900948.1.1\>/content-stream>/template>template v-slot:right path\1375900948.2\>div v-if\threadInstance\ path\1375900948.2.0\>div class\sticky\ v-if\threadInstance\ :style\{ top: 0px }\ path\1375900948.2.0.0\>e-instance-wide :instance\threadInstance\ path\1375900948.2.0.0.0\>/e-instance-wide>/div>e-thread :threadMedia\{type: instance, instance: threadInstance}\ path\1375900948.2.0.1\>/e-thread>/div>/template>/site>}},{name:page.media,path:\\page\\media.ws.yaml,source:{dom:{site:{page-name:media,:columns-focus-left:columnsFocusLeft,:content-not-found:contentNotFound,template#1:{v-slot:article},template#2:{v-slot:left,e.generator.search:null,.flex.ver.gap-2:{e.thread.create:{v-if:false,on_input:columnsFocusLeft:columnsFocusLeft$event}}},template#3:{v-slot:middle,.flex.gap-2:{transition:{name:slide-large,.flex.ver.gap-2:{e.media:{v-if:media,:media:media,:threadMedia:media,on_thread-updated:onThreadUpdated,on_media-created:(media) > $root.notify(e.media, media)},e.media.menu:{:media:media}}}}},template#4:{v-slot:right,e.thread:{ref:thread1,v-if:media,:threadMedia:media}}}},data:{media:null,temp:null,builder:null,contentNotFound:false,columnsFocusLeft:false},mounted:async function() {\n this.$watch(() > this.$root.params.mediaID, {\n handler: async () > {\n await this.init(this.$root.params.mediaID);\n },\n immediate: true\n });\n}\n,methods:{init:async function() {\n const dbp this.$root.dbp;\n this.clear();\n if (!this.$root.params.mediaID) return;\n try\n {\n this.$root.isLoading++;\n this.media await dbp.medias.select.one(this.$root.params.mediaID);\n if (!this.media) this.contentNotFound true;\n if (this.$root.params.page \media\) {\n this.$root.setDocumentTitle(this.$root.getMediaText(this.media));\n }\n }\n finally\n {\n this.$root.isLoading--;\n }\n}\n,clear:function() {\n this.media null;\n this.contentNotFound false;\n this.$refs.contentStream1?.clear();\n}\n,onThreadUpdated:function(...args) {\n this.$refs.thread1?.reload();\n}\n,getMoreMedias:async function(pageIndex, fromMediaID) {\n if (!this.media?.builderID) return ;\n if (!fromMediaID) fromMediaID this.media?._id;\n return await this.$root.dbp.medias.select.new(this.media?.builderID, fromMediaID);\n}\n},watch:{media:{handler:async function(media) {\n this.builder !media ? null : await this.$root.getBuilder(media.builderID);\n}\n}},style:null,name:page-media,_:{examples:{count:0}},template:site class\comp-page-media\ page-name\media\ :columns-focus-left\columnsFocusLeft\ :content-not-found\contentNotFound\ path\221009861.\>template v-slot:article path\221009861.0\>/template>template v-slot:left path\221009861.1\>e-generator-search>/e-generator-search>div class\flex ver gap-2\ path\221009861.1.1\>e-thread-create v-if\false\ on_input:columnsFocusLeft\columnsFocusLeft$event\ path\221009861.1.1.0\>/e-thread-create>/div>/template>template v-slot:middle path\221009861.2\>div class\flex gap-2\ path\221009861.2.0\>transition name\slide-large\ path\221009861.2.0.0\>div class\flex ver gap-2\ path\221009861.2.0.0.0\>e-media v-if\media\ :media\media\ :threadMedia\media\ on_thread-updated\onThreadUpdated\ on_media-created\(media) > $root.notify(e.media, media)\ path\221009861.2.0.0.0.0\>/e-media>e-media-menu :media\media\ path\221009861.2.0.0.0.1\>/e-media-menu>/div>/transition>/div>/template>template v-slot:right path\221009861.3\>e-thread ref\thread1\ v-if\media\ :threadMedia\media\ path\221009861.3.0\>/e-thread>/template>/site>}},{name:page.test,path:\\page\\test.ws.yaml,source:{dom:{site:{page-name:test,:columns:2,template:{v-slot:article,.div1:{div:{ui.select:{:options:builders,input-type:value,:get-item-key:(item) > item._id,:get-item-text:(item) > item.name,v-model:selectedBuilder}},.width1:{transition:{name:slide-large,keep.alive:{e.builder:{:builder:selectedBuilder}}}}}}}},props:null,data:{builders:,selectedBuilder:null},mounted:async function() {\n this.builders await this.$root.dbp.builders.select.all();\n}\n,computed:null,watch:null,style:{.article > .div1:{display:flex,gap:1em},.width1:{width:40em,margin:auto}},name:page-test,_:{examples:{count:0}},template:site class\comp-page-test\ page-name\test\ :columns\2\ path\838622353.\>template v-slot:article path\838622353.0\>div class\div1\ path\838622353.0.0\>div path\838622353.0.0.0\>ui-select :options\builders\ input-type\value\ :get-item-key\(item) > item._id\ :get-item-text\(item) > item.name\ v-model\selectedBuilder\ path\838622353.0.0.0.0\>/ui-select>/div>div class\width1\ path\838622353.0.0.1\>transition name\slide-large\ path\838622353.0.0.1.0\>keep-alive path\838622353.0.0.1.0.0\>e-builder :builder\selectedBuilder\ path\838622353.0.0.1.0.0.0\>/e-builder>/keep-alive>/transition>/div>/div>/template>/site>}},{name:page.thread,path:\\page\\thread.ws.yaml,source:{dom:{site:{page-name:thread,:columns-focus-left:columnsFocusLeft,:content-not-found:contentNotFound,template#1:{v-slot:left,.flex.ver.gap-2:{e.thread.create:{on_input:columnsFocusLeft:columnsFocusLeft$event},ui.link:{:text:π catalog,url:/catalog}}},template#2:{v-slot:middle,e.post:{:item:$refs.thread1?.thread?.posts0}},template#3:{v-slot:right,.flex.gap-2:{transition:{name:slide-large,e.thread:{ref:thread1,:threadID:threadID,:threadMedia:{ _id: threadMediaID }}}}}}},data:{threadID:null,threadMediaID:null,contentNotFound:false,columnsFocusLeft:false},mounted:async function() {\n this.$watch(() > this.$root.params.threadID, this.$root.params.mediaID, {\n handler: async () > {\n await this.init(this.$root.params.threadID, this.$root.params.mediaID);\n },\n immediate: true\n });\n}\n,methods:{init:async function(threadID, threadMediaID) {\n this.threadID threadID;\n this.threadMediaID threadMediaID;\n}\n},watch:null,name:page-thread,style:null,_:{examples:{count:0}},template:site class\comp-page-thread\ page-name\thread\ :columns-focus-left\columnsFocusLeft\ :content-not-found\contentNotFound\ path\-1535040951.\>template v-slot:left path\-1535040951.0\>div class\flex ver gap-2\ path\-1535040951.0.0\>e-thread-create on_input:columnsFocusLeft\columnsFocusLeft$event\ path\-1535040951.0.0.0\>/e-thread-create>ui-link :text\π catalog\ url\/catalog\ path\-1535040951.0.0.1\>/ui-link>/div>/template>template v-slot:middle path\-1535040951.1\>e-post :item\$refs.thread1?.thread?.posts0\ path\-1535040951.1.0\>/e-post>/template>template v-slot:right path\-1535040951.2\>div class\flex gap-2\ path\-1535040951.2.0\>transition name\slide-large\ path\-1535040951.2.0.0\>e-thread ref\thread1\ :threadID\threadID\ :threadMedia\{ _id: threadMediaID }\ path\-1535040951.2.0.0.0\>/e-thread>/transition>/div>/template>/site>}},{name:site.banner,path:\\site\\banner.ws.yaml,source:{dom:{div#1:{div#2:{class:image}}},style:{.image:{width:calc(100% - 4em),height:calc(100% - 1em),min-width:20em,min-height:4em,margin:0.3em 0 0 3em,filter:grayscale(1),border-radius:0.5em,background-size:cover!important,background-position:50% 30%!important}},name:site-banner,_:{examples:{count:0}},template:div class\comp-site-banner\ path\1842927539.\>div class\image\ path\1842927539.0\>/div>/div>}},{name:site.header,path:\\site\\header.ws.yaml,source:{dom:{.header:{.div1:{:style:getStyle(),site.logo:null},.h-menu:{v-if:false,ui.link:{v-for:builder in $root.builders.mainMenu,:text:builder.name,:url:$root.url.builder(builder)}}}},name:site-header,mounted:function() {\n this.init();\n}\n,methods:{init:function() {\n return;\n const header document.querySelector(.header);\n const initialHeight header.clientHeight / window.innerHeight * 100;\n const scrollRate 0.1;\n // Slowly scroll the header to be smaller as the user scrolls\n window.addEventListener(scroll, function() {\n const scrollPosition window.pageYOffset || document.documentElement.scrollTop;\n // Calculate the new height of the header based on scroll position\n const newHeight Math.max(initialHeight - scrollPosition * scrollRate, 15);\n // Apply the new height to the header\n const heightVh `${newHeight}vh`;\n header.style.height heightVh;\n });\n}\n,getStyle:function() {\n // get a random number between 0 and 20 inclusive\n const index Math.floor(Math.random() * 21);\n const style {};\n //style.backgroundImage `url(/img/banners/(${index}).jpg)`;\n return style;\n}\n},style:{.comp-ui-large-title:{position:absolute;,bottom:2rem},.header:{background-color:black,border-radius:0},.div1:{width:100%,display:flex,filter:grayscale(1) brightness(0.8)},.h-menu:{display:flex,justify-content:space-around,font-size:160%}},_:{examples:{count:0}},template:div class\comp-site-header header\ path\2017999636.\>div class\div1\ :style\getStyle()\ path\2017999636.0\>site-logo>/site-logo>/div>div class\h-menu\ v-if\false\ path\2017999636.1\>ui-link v-for\builder in $root.builders.mainMenu\ :text\builder.name\ :url\$root.url.builder(builder)\ path\2017999636.1.0\>/ui-link>/div>/div>}},{name:site.logo,path:\\site\\logo.ws.yaml,source:{dom:{ui.link:{url:/,div:{.meme:{v-text:meme},.generator:{v-text:generator}}}},style:{.comp-site-logo:{background:black;,padding:1em;,position:relative;},.meme:{font-size:6vh},.generator:{font-size:3vh},div:{font-family:impact,text-transform:uppercase,line-height:1em,text-align:center,top:-0.1rem,text-shadow:-6px 6px 3px #000,opacity:1}},name:site-logo,_:{examples:{count:0}},template:ui-link class\comp-site-logo\ url\/\ path\-578776078.\>div path\-578776078.0\>div class\meme\ v-text\meme\ path\-578776078.0.0\>/div>div class\generator\ v-text\generator\ path\-578776078.0.1\>/div>/div>/ui-link>}},{name:site.main,path:\\site\\main.ws.yaml,source:{dom:{div#1:{transition:{name:fade,content.title:{class:hidden,v-if:titleText,:imageID:titleImageId,:title:titleText,:url:titleUrl,:key:titleKey}},.article:{slot#1:{name:article}},div#2:{:class:columnsClass,.left:{ui.sticky#1:{top:140px,div#3:{slot#2:{name:left},h2#1:{v-if:recommendationItems?.length,v-text:See also},content.recommendations:{:items:recommendationItems}}}},.middle:{ui.error:{:error:$root.error},h2#2:{v-if:contentNotFound,class:error,v-text:Content not found},slot#3:{name:middle}},.right:{ui.sticky#2:{top:140px,.right-height:{slot#4:{name:right}}}}}}},props:{titleImageId:null,titleText:null,titleUrl:null,titleKey:null,recommendationItems:null,columnsFocusLeft:false,contentNotFound:false,columns:3},computed:{columnsClass:function() {\n const cls {};\n clscolumns true;\n clscolumns- + this.columns true;\n clscolumns-focus-left this.columnsFocusLeft;\n return cls;\n}\n},style:{.columns-focus-left:{grid-template:1fr / 1fr 1fr !important},.columns-focus-left .middle:{filter:blur(5px) grayscale(1),opacity:0.5},.article:{margin-top:3rem},.comp-site-main:null,.right-height:{max-height:calc(100vh - 180px),overflow:auto},.error:{margin-bottom:3rem}},name:site-main,_:{examples:{count:0}},template:div class\comp-site-main\ path\-578759680.\>transition name\fade\ path\-578759680.0\>content-title class\hidden\ v-if\titleText\ :imageID\titleImageId\ :title\titleText\ :url\titleUrl\ :key\titleKey\ path\-578759680.0.0\>/content-title>/transition>div class\article\ path\-578759680.1\>slot name\article\ path\-578759680.1.0\>/slot>/div>div :class\columnsClass\ path\-578759680.2\>div class\left\ path\-578759680.2.0\>ui-sticky top\140px\ path\-578759680.2.0.0\>div path\-578759680.2.0.0.0\>slot name\left\ path\-578759680.2.0.0.0.0\>/slot>h2 v-if\recommendationItems?.length\ v-text\See also\ path\-578759680.2.0.0.0.1\>/h2>content-recommendations :items\recommendationItems\ path\-578759680.2.0.0.0.2\>/content-recommendations>/div>/ui-sticky>/div>div class\middle\ path\-578759680.2.1\>ui-error :error\$root.error\ path\-578759680.2.1.0\>/ui-error>h2 class\error\ v-if\contentNotFound\ v-text\Content not found\ path\-578759680.2.1.1\>/h2>slot name\middle\ path\-578759680.2.1.2\>/slot>/div>div class\right\ path\-578759680.2.2\>ui-sticky top\140px\ path\-578759680.2.2.0\>div class\right-height\ path\-578759680.2.2.0.0\>slot name\right\ path\-578759680.2.2.0.0.0\>/slot>/div>/ui-sticky>/div>/div>/div>}},{name:site.sidebar,path:\\site\\sidebar.ws.yaml,source:{dom:{div:{ui.list:{item-type:generator.small}}},name:site-sidebar,style:null,_:{examples:{count:0}},template:div class\comp-site-sidebar\ path\-576601163.\>ui-list item-type\generator.small\ path\-576601163.0\>/ui-list>/div>}},{name:site,path:\\site.ws.yaml,source:{dom:{div#1:{transition:{name:fade,div#2:{:class:getCssClass(),v-if:(this.pageName $root.params.page),div#3:{site.sidebar:null,site.main:{:columns:columns,:title-image-id:titleImageId,:title-text:titleText,:title-url:titleUrl,:title-key:titleKey,:recommendation-items:recommendationItems,:columns-focus-left:columnsFocusLeft,:content-not-found:contentNotFound,template#1:{v-slot:article,slot#1:{name:article}},template#2:{v-slot:left,slot#2:{name:left}},template#3:{v-slot:middle,slot#3:{name:middle}},template#4:{v-slot:right,slot#4:{name:right}}}}}}}},name:site,props:{titleImageId:null,titleText:null,titleUrl:null,titleKey:null,getMoreItems:null,recommendationItems:null,pageName:null,columns:3,columnsFocusLeft:false,contentNotFound:false},methods:{getCssClass:function() {\n const cls {};\n clssite-width true;\n return cls;\n}\n},style:{.comp-site:{position:relative,margin:auto,padding:0}},_:{examples:{count:0}},template:div class\comp-site\ path\3530567.\>transition name\fade\ path\3530567.0\>div :class\getCssClass()\ v-if\(this.pageName $root.params.page)\ path\3530567.0.0\>div path\3530567.0.0.0\>site-sidebar>/site-sidebar>site-main :columns\columns\ :title-image-id\titleImageId\ :title-text\titleText\ :title-url\titleUrl\ :title-key\titleKey\ :recommendation-items\recommendationItems\ :columns-focus-left\columnsFocusLeft\ :content-not-found\contentNotFound\ path\3530567.0.0.0.1\>template v-slot:article path\3530567.0.0.0.1.0\>slot name\article\ path\3530567.0.0.0.1.0.0\>/slot>/template>template v-slot:left path\3530567.0.0.0.1.1\>slot name\left\ path\3530567.0.0.0.1.1.0\>/slot>/template>template v-slot:middle path\3530567.0.0.0.1.2\>slot name\middle\ path\3530567.0.0.0.1.2.0\>/slot>/template>template v-slot:right path\3530567.0.0.0.1.3\>slot name\right\ path\3530567.0.0.0.1.3.0\>/slot>/template>/site-main>/div>/div>/transition>/div>}};/script>script>window.templates {module:class {{name}}\r\n{\r\n {{#each data}}\r\n {{@key}} {{{this}}};\r\n {{/each}}\r\n\r\n static async _new()\r\n {\r\n const instance new {{namespace}}.{{name}}();\r\n\r\n const persister await Data.Persister.Memory.new();\r\n const varName \test1\;\r\n const actionStack await Actionable.ActionStack.new(persister, varName);\r\n instance._actionStack actionStack;\r\n instance._actionStack.executeDoable instance._executeDoable.bind(instance);\r\n\r\n return instance;\r\n }\r\n\r\n {{#each methods}}\r\n {{methodSignature \\ name args}}\r\n {\r\n const args ...arguments;\r\n\r\n const oldData this._getModuleData();\r\n\r\n await this._actionStack.enteringMethod();\r\n\r\n try\r\n {\r\n const actionResult await this._{{name}}(...args);\r\n\r\n const newData this._getModuleData();\r\n\r\n const dataChanges Diff.getChanges(oldData, newData);\r\n\r\n const action {\r\n redo: {\r\n method: \{{name}}\,\r\n args: args\r\n },\r\n undo: actionResult.undo,\r\n _info: {\r\n dataChanges: dataChanges\r\n }\r\n };\r\n\r\n await this._actionStack.add(action, { exitingMethod: true });\r\n\r\n return actionResult.returnValue;\r\n }\r\n catch (ex)\r\n {\r\n this._actionStack.exitAction();\r\n throw ex;\r\n }\r\n\r\n }\r\n {{/each}}\r\n\r\n async _executeDoable(doable)\r\n {\r\n const method this`_${doable.method}`;\r\n const returnValue await method.apply(this, doable.args);\r\n }\r\n\r\n _getModuleData()\r\n {\r\n const data {};\r\n const keys Object.keys(this)\r\n .filter(this._includeDataKey.bind(this));\r\n for (const key of keys)\r\n {\r\n datakey thiskey;\r\n }\r\n return Objects.clone(data);\r\n }\r\n\r\n _includeDataKey(key)\r\n {\r\n if (key.startsWith(\_\)) return false;\r\n const value thiskey;\r\n const type typeof value;\r\n if (type \function\) return false;\r\n return true;\r\n }\r\n\r\n {{#each methods}}\r\n {{methodSignature \_\ name args}}\r\n {\r\n {{{code}}}\r\n }\r\n {{/each}}\r\n},vue:{\r\n mixins: ,\r\n props: {\r\n {{#each props}}\r\n {{@key}}: {\r\n default: {{{or this null}}}\r\n },\r\n {{/each}}\r\n },\r\n data: function () {\r\n return {\r\n {{#each data}}\r\n {{@key}}: {{{or this null}}},\r\n {{/each}}\r\n _: {\r\n comp: {\r\n name: `{{unkebabize name}}`,\r\n },\r\n log: {\r\n elapsed: {\r\n minimum: 1000,\r\n }\r\n }\r\n }\r\n }\r\n },\r\n created: {{{addCode created \\}}},\r\n mounted: {{{addCode mounted \\}}},\r\n unmounted: {{{addCode unmounted \\}}},\r\n methods: {\r\n {{#each methods}}\r\n {{@key}}: {{{addCode this \if (window.vueIdeApp?.isPauseOnMethod(this.$options._componentTag, {{method}})) debugger;\ @key \\}}},\r\n {{/each}}\r\n },\r\n computed: {\r\n {{#each computed}}\r\n {{#if get}}\r\n {{@key}}: {\r\n get: {{{addCode get \\}}},\r\n },\r\n {{else}}\r\n {{@key}}: {{{addCode this \\ @key \\}}},\r\n {{/if}}\r\n {{/each}}\r\n },\r\n watch: { \r\n {{#each watch}}\r\n {{#if handler}}\r\n {{@key}}: {\r\n handler: {{{addCode handler \\ @key \\}}},\r\n immediate: {{{or immediate false}}},\r\n deep: {{{or deep false}}},\r\n },\r\n {{else}}\r\n {{@key}}: {{{this}}},\r\n {{/if}}\r\n {{/each}}\r\n },\r\n template: `{{{dom dom name}}}`\r\n}\r\n,style:{{#each source.style}}\r\n{{prefixCssSelectors ../name @key}}\r\n{\r\n {{#each this}}\r\n {{#if @key}}\r\n {{@key}}: {{{this}}};\r\n {{/if}}\r\n {{/each}}\r\n}\r\n{{/each}}\r\n};/script>script>window.helpers {or:(context, a, b) > {\n if (a ! undefined) return JSON.stringify(a);\n return JSON.stringify(b);\n}\n,dom:(context, dom, compName, compType) > {\n return context.toTemplate(context, dom, 0, compName, compType).join(\\\n\);\n}\n,hasKey:(context, object, key, options) > {\n if (!object) return false;\n if (typeof object ! \object\) return false;\n const hasKey (key in object);\n return hasKey;\n}\n,addCode:(context, methodBody, startCode, methodName, endCode) > {\n const findOuterBraces (str) > {\n let first -1;\n let last -1;\n let depth 0;\n for (let i 0; i str.length; i++) {\n if (stri \{\) {\n if (first -1) first i;\n depth++;\n } else if (stri \}\) {\n depth--;\n if (depth 0) last i;\n }\n }\n return { first, last };\n };\n \n try {\n // Initialize and sanitize startCode and endCode\n startCode (startCode || \\).trim().replace(\{{method}}\, methodName);\n endCode (endCode || \\).trim().replace(\{{method}}\, methodName);\n\n // Handle empty or commented-out method bodies\n if (!methodBody?.length) methodBody \function() {}\;\n methodBody methodBody.replace(/^\\s*\\/\\/.*$/gm, \\).trim();\n\n // Wrap in a function block if not already wrapped\n if (!\function\, \async\.some(s > methodBody.startsWith(s))) {\n methodBody `function() {\\n${methodBody}\\n}`;\n if (/\\bawait\\b/.test(methodBody)) {\n methodBody `async ${methodBody}`;\n }\n }\n\n // Find the positions of the outermost braces\n const { first, last } findOuterBraces(methodBody);\n\n // Extract the method body inside the outermost braces\n let wrappedBody methodBody.substring(first + 1, last).trim();\n\n if (!startCode.length && !endCode.length) return methodBody; // Return the original method body if no startCode or endCode is provided\n\n // Insert startCode and endCode\n wrappedBody `\n ${startCode}\n try\n {\n ${wrappedBody}\n }\n finally\n {\n ${endCode}\n }\n `;\n\n // Reconstruct the final method body\n const finalMethodBody `${methodBody.substring(0, first + 1)}\\n${wrappedBody}\\n${methodBody.substring(last)}`;\n\n return finalMethodBody;\n } catch (error) {\n console.error(`Error in addCode: ${error.message}`);\n return methodBody; // Return the original method body in case of an error\n }\n}\n,css:(context, style, compName, compType) > {\n // Convert style object like:\n // .selector:\n // color: red\n // to CSS\n const toCss (style, prefix) > {\n const css ;\n for (const key in style) {\n if (style.hasOwnProperty(key)) {\n const value stylekey;\n if (typeof value \object\) {\n css.push(`${prefix}${key} {`);\n css.push(toCss(value, prefix + \ \));\n css.push(\}\);\n } else {\n css.push(`${prefix}${key}: ${value};`);\n }\n }\n }\n return css.join(\\\n\);\n };\n return toCss(style, \\);\n}\n,prefixCssSelectors:(context, compName, selectors) > {\n const s ;\n const scopeClass `comp-${compName.replace(/\\./g, \-\)}`;\n const classSelectors selectors.split(,).map(s > s.trim()).filter(s > s.startsWith(\.\));\n const otherSelectors selectors.split(,).map(s > s.trim()).filter(s > !s.startsWith(\.\));\n s.push(...classSelectors.map(s > `.${scopeClass}${s}`));\n s.push(...classSelectors.map(s > `.${scopeClass} ${s}`));\n s.push(...otherSelectors.map(s > `.${scopeClass} ${s}`));\n return s.join(\, \);\n}\n,unkebabize:(context, str) > {\n return str?.replace(/-/g, \.\);\n}\n,methodSignature:(context, prefix, name, args) > {\n return `async ${prefix}${name}(${(args||).join(\, \)})`;\n}\n};/script>script>window.config {params:{params:{page:{get:function(url) {\n if (url \/\) return \home\;\n if (url \/test\) return \test\;\n if (url \/admin\) return \admin\;\n if (url.startsWith(\/catalog\)) return \catalog\;\n if (url.startsWith(\/advice-animals\)) return \generators\;\n if (url.startsWith(\/b/\)) return \builder\;\n if (url.startsWith(\/t/\)) return \thread\;\n if (url.startsWith(\/m/\)) return \media\;\n if (url.startsWith(\/instance/\)) return \instance\;\n if (url.startsWith(\/c/\)) return \category\;\n return \generator\;\n}\n},urlName:{get:function(url) {\n if (url \/\) return null;\n if (url \/admin\) return null;\n if (\instance\, \t\.some(a > url.startsWith(`/${a}/`))) return null;\n if (\c\, \b\.some(a > url.startsWith(`/${a}/`))) return url.split(\/\)2;\n return url.split(\/\)1;\n}\n},threadID:{get:function(url) {\n if (!url.startsWith(\/t/\)) return null;\n return parseInt(url.split(\/\)2);\n}\n},mediaID:{get:function(url) {\n if (!url.startsWith(\/m/\)) return null;\n return parseInt(url.split(\/\)2);\n}\n},instanceID:{get:function(url) {\n if (!url.startsWith(\/instance/\)) return null;\n return parseInt(url.split(\/\)2);\n}\n},url:{get:function() {\n return window.location.pathname;\n}\n}}}};/script>script src/script/ide.js?_uid-645258157 defertrue>/script>script src/script/startup.js?_uid-645258157 defertrue>/script>/head>/html>body>div idapp>app refapp :keykey1>/app>/div>/body>
View on OTX
|
View on ThreatMiner
Please enable JavaScript to view the
comments powered by Disqus.
Data with thanks to
AlienVault OTX
,
VirusTotal
,
Malwr
and
others
. [
Sitemap
]