{"name":{"html":"<div v-if=\"P.name\"></div>","script":"new Object({\n    mounted() {\n      console.log(\"name mounted\", this)\n    },\n    methods: {},\n    middleware: {\n      $: (data, username, isSelf) => {\n        return data\n      },\n      name: (data, username, isSelf) => {\n        return data\n      },\n    },\n  })","back":"new Object({\r\n  $(data, sync, UUID, userPrivate, userPublic) {\r\n    return data\r\n  },\r\n})\r\n"},"party":{"html":"<!-- TODO: Try adding a <script> tag to this with document.onmousemove -->\n  <div v-if=\"P.party\">\n    <div v-if=\"P.party.pos &amp;&amp; P.party.pos.x &amp;&amp; P.party.pos.y\" class=\"absolute z-50 transition-all\" style=\"pointer-events: none\" :style=\"{'left': P.party.pos.x + 'px', 'top': P.party.pos.y + 'px' }\">\n      <!-- Upcoming feature -->\n      <img class=\"inline-block object-cover w-20 h-20 rounded-full\" :src=\"P.party.pic\" :alt=\"auth.username\">\n      <div class=\"inline-block\">\n        <div v-if=\"P.party.wayOut === 'DOWN'\">\n          <i class=\"fas fa-chevron-down\"></i>\n        </div>\n        <div v-if=\"P.party.wayOut === 'UP'\">\n          <i class=\"fas fa-chevron-up\"></i>\n        </div>\n      </div>\n      <span v-if=\"P.party.wayOut === undefined\" class=\"absolute bottom-0 left-0 inline-block w-3 h-3 border border-white rounded-full\" :class=\"{'bg-green-600': P.party.status === crowwwd.ONLINE, 'bg-yellow-600': P.party.status === crowwwd.AWAY, 'bg-gray-600': P.party.status === undefined}\"></span>\n      <i class=\"fas fa-mobile-alt\" v-show=\"P.party.isMobile\" style=\"color: deepskyblue\"></i>\n      <span class=\"text-white\" style=\"background-color: rgba(0, 0, 0, 0.5)\">{{username}} ({{P.party.percent}})</span>\n    </div>\n  </div>","script":"new Object({\n    private: {},\n    mounted() {\n      // TODO: Relocate\n      const mobileCheck = () => {\n        let check = false\n        ;(function (a) {\n          if (\n            /(android|bb\\d+|meego).+mobile|avantgo|bada\\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(\n              a\n            ) ||\n            /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\\-(n|u)|c55\\/|capi|ccwa|cdm\\-|cell|chtm|cldc|cmd\\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\\-s|devi|dica|dmob|do(c|p)o|ds(12|\\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\\-|_)|g1 u|g560|gene|gf\\-5|g\\-mo|go(\\.w|od)|gr(ad|un)|haie|hcit|hd\\-(m|p|t)|hei\\-|hi(pt|ta)|hp( i|ip)|hs\\-c|ht(c(\\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\\-(20|go|ma)|i230|iac( |\\-|\\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\\/)|klon|kpt |kwc\\-|kyo(c|k)|le(no|xi)|lg( g|\\/(k|l|u)|50|54|\\-[a-w])|libw|lynx|m1\\-w|m3ga|m50\\/|ma(te|ui|xo)|mc(01|21|ca)|m\\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\\-2|po(ck|rt|se)|prox|psio|pt\\-g|qa\\-a|qc(07|12|21|32|60|\\-[2-7]|i\\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\\-|oo|p\\-)|sdk\\/|se(c(\\-|0|1)|47|mc|nd|ri)|sgh\\-|shar|sie(\\-|m)|sk\\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\\-|v\\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\\-|tdg\\-|tel(i|m)|tim\\-|t\\-mo|to(pl|sh)|ts(70|m\\-|m3|m5)|tx\\-9|up(\\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\\-|your|zeto|zte\\-/i.test(\n              a.substr(0, 4)\n            )\n          )\n            check = true\n        })(navigator.userAgent || navigator.vendor || window.opera)\n        return check\n      }\n\n      console.log({ ttt: this })\n\n      this.send(\"party\", {\n        xpath: \"/html/body\",\n        percent: 0,\n        isMobile: mobileCheck(),\n        status: this.crowwwd.ONLINE,\n        pic: `/img/${Math.round(Math.random() * 9)}.jpg`, // TODO: Improve so that it is not sent everytime\n      })\n\n      document.addEventListener(\"mouseover\", (e) => {\n        try {\n          const el = e.target || e.srcElement\n\n          this.self.party.xpath = xpath(el)\n          this.self.party.status = this.crowwwd.ONLINE\n\n          clearTimeout(this.awayTimeout)\n          this.awayTimeout = setTimeout(() => {\n            this.self.party.status = this.crowwwd.AWAY\n            this.sync(\"party\")\n          }, 5000)\n\n          this.sync(\"party\")\n        } catch (e) {\n          /* Ignore when we are not in the DOM */\n        }\n      })\n\n      document.addEventListener(\"scroll\", (event) => {\n        const max = document.documentElement.scrollHeight - window.innerHeight\n        const percent = Math.round((window.scrollY * 100) / max)\n        this.self.party.percent = percent\n        this.sync(\"party\")\n      })\n    },\n    middleware: {\n      $: (data, username, isSelf) => {\n        return data\n      },\n      party: (data, username, isSelf) => {\n        let rect\n\n        if (!data.isMobile) {\n          try {\n            rect = xpath(data.xpath).getBoundingClientRect()\n          } catch (e) {\n            rect = { x: 0, y: 0 }\n          }\n          data.pos = {\n            x: Math.round(rect.x + document.documentElement.scrollLeft),\n            y: Math.round(rect.y + document.documentElement.scrollTop),\n          }\n        } else {\n          data.pos = {\n            x: 50,\n            y:\n              (data.percent * (document.documentElement.scrollHeight - window.innerHeight)) / 100 +\n              window.innerHeight / 2 +\n              1,\n          }\n        }\n\n        if (data.pos.y > scrollY + innerHeight) {\n          data.wayOut = \"DOWN\"\n          data.pos.y = scrollY + innerHeight - 70\n        } else if (data.pos.y < scrollY) {\n          data.wayOut = \"UP\"\n          data.pos.y = scrollY\n        } else {\n          data.wayOut = undefined\n        }\n\n        return data\n      },\n    },\n  })","back":"new Object({\r\n  $(data, sync, UUID, userPrivate, userPublic) {\r\n    return data\r\n  },\r\n})\r\n"},"shout":{"html":"<div v-if=\"P.shout\">\n    <div v-for=\"path in Object.keys(P.shout.messages)\">\n      <div class=\"absolute z-50\" style=\"pointer-events: none\" :style=\"{'left': P.shout.messages[path].pos.x + 'px', 'top': P.shout.messages[path].pos.y + 'px' }\">\n        <span class=\"text-sm text-white\" style=\"position: relative; background-color: rgba(0, 0, 0, 0.5); left: 4px; top: -10px\">\n          {{username}}: {{Object.values(P.shout.messages[path].txt).join('')}}\n        </span>\n      </div>\n    </div>\n  </div>","script":"new Object({\n    mounted() {\n      this.self.shout.messages = {}\n      let currentElement = null\n\n      document.addEventListener(\"mouseover\", (e) => {\n        try {\n          currentElement = xpath(e.target || e.srcElement)\n        } catch (e) {\n          /* Ignore when we are not in the DOM */\n        }\n      })\n\n      window.addEventListener(\"keypress\", (e) => {\n        if (!currentElement) return // Bailout when we do not have an element\n        if ([\"TEXTAREA\", \"INPUT\"].includes(currentElement.tagName)) return // Bailout when we are typing in an input field\n\n        const timestamp = new Date().getTime()\n        if (!this.self.shout.messages[currentElement]) this.self.shout.messages[currentElement] = { txt: {}, pos: {} }\n        this.self.shout.messages[currentElement].txt[timestamp] = e.key\n        this.sync(\"shout\")\n      })\n    },\n    methods: {\n      // TODO: Implement plugins this way\n      onKeyPress: (e) => {\n        console.log(\"Key pressed:\", e.key)\n      },\n    },\n    middleware: {\n      $: (data, username, isSelf) => {\n        return data\n      },\n      shout: (data, username, isSelf) => {\n        Object.keys(data.messages).forEach((k) => {\n          if (!Object.keys(data.messages[k].pos).length) {\n            let rect\n            try {\n              rect = xpath(k).getBoundingClientRect()\n            } catch (e) {\n              rect = { x: 0, y: 0 }\n            }\n\n            data.messages[k].pos = {\n              x: Math.round(rect.x + document.documentElement.scrollLeft),\n              y: Math.round(rect.y + document.documentElement.scrollTop),\n            }\n          }\n        })\n\n        return data\n      },\n    },\n  })","back":"new Object({\r\n  $(data, sync, UUID, userPrivate, userPublic) {\r\n    return data\r\n  },\r\n})\r\n"},"usernameMenu":{"html":"<div v-if=\"P.usernameMenu &amp;&amp; username === auth.username\" class=\"fixed bottom-20 left-0\" style=\"z-index: 99999\">\n    <div style=\"\n        display: flex;\n        align-items: center;\n        gap: 5px;\n        padding: 5px 5px;\n        background: rgba(255, 255, 255, 0.94);\n        border: 1px solid rgba(0, 0, 0, 0.08);\n        border-radius: 12px;\n        box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);\n        backdrop-filter: blur(6px);\n      \">\n      <input placeholder=\"Set new username\" v-model=\"settings.menu.newUsername\" style=\"\n          height: 36px;\n          min-width: 180px;\n          border: 1px solid #d1d5db;\n          border-radius: 10px;\n          padding: 0 12px;\n          margin-bottom: 0;\n          outline: none;\n          font-size: 14px;\n          color: #111827;\n          background: #fff;\n        \" @keyup.enter=\"setUsername()\">\n      <button @click=\"setUsername()\" style=\"\n          height: 35px;\n          width: 5px;\n          margin-bottom: 0;\n          border: none;\n          border-radius: 10px;\n          background: #111827;\n          color: #fff;\n          cursor: pointer;\n          display: flex;\n          align-items: center;\n          justify-content: center;\n        \">\n        <i class=\"fas fa-save\"></i>\n      </button>\n    </div>\n  </div>","script":"new Object({\n    private: {},\n    middleware: {\n      $: (data) => data,\n      usernameMenu: (data) => data,\n    },\n  })","back":"new Object({\r\n  $(data) {\r\n    return data\r\n  },\r\n})\r\n"}}