diff --git a/scripts/vendor-dependencies.mjs b/scripts/vendor-dependencies.mjs index d3a7fec..c6fce59 100644 --- a/scripts/vendor-dependencies.mjs +++ b/scripts/vendor-dependencies.mjs @@ -11,6 +11,8 @@ import { fileURLToPath } from "node:url"; const dependencies = { "twind.min.js": "https://cdn.twind.style", + "htm+preact.min.js": + "https://unpkg.com/htm@3.1.1/preact/standalone.module.js", "lucide.min.js": "https://unpkg.com/lucide@0.104.0/dist/umd/lucide.min.js", "jscolor.min.js": "https://cdnjs.cloudflare.com/ajax/libs/jscolor/2.5.1/jscolor.min.js", diff --git a/src/browser/api.js b/src/browser/api.js index e981503..c21c01b 100644 --- a/src/browser/api.js +++ b/src/browser/api.js @@ -49,7 +49,7 @@ const initDatabase = (namespace) => { }, populate: async (obj) => { return new Promise((res, _rej) => { - chrome.storage.local.set(obj, () => res(value)); + chrome.storage.local.set(obj, () => res(obj)); }); }, }; diff --git a/src/common/utils.js b/src/common/utils.js index 36b6cd8..401da37 100644 --- a/src/common/utils.js +++ b/src/common/utils.js @@ -1,332 +1,332 @@ /** * notion-enhancer: api - * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (c) 2022 dragonwocky (https://dragonwocky.me/) * (https://notion-enhancer.github.io/) under the MIT license */ -/** - * log-based shading of an rgb color, from - * https://stackoverflow.com/questions/5560248/programmatically-lighten-or-darken-a-hex-color-or-rgb-and-blend-colors - * @param {number} shade - a decimal amount to shade the color. - * 1 = white, 0 = the original color, -1 = black - * @param {string} color - the rgb color - * @returns {string} the shaded color - */ -export const rgbLogShade = (shade, color) => { - const int = parseInt, - round = Math.round, - [a, b, c, d] = color.split(","), - t = shade < 0 ? 0 : shade * 255 ** 2, - p = shade < 0 ? 1 + shade : 1 - shade; - return ( - "rgb" + - (d ? "a(" : "(") + - round((p * int(a[3] == "a" ? a.slice(5) : a.slice(4)) ** 2 + t) ** 0.5) + - "," + - round((p * int(b) ** 2 + t) ** 0.5) + - "," + - round((p * int(c) ** 2 + t) ** 0.5) + - (d ? "," + d : ")") - ); -}; +// /** +// * log-based shading of an rgb color, from +// * https://stackoverflow.com/questions/5560248/programmatically-lighten-or-darken-a-hex-color-or-rgb-and-blend-colors +// * @param {number} shade - a decimal amount to shade the color. +// * 1 = white, 0 = the original color, -1 = black +// * @param {string} color - the rgb color +// * @returns {string} the shaded color +// */ +// export const rgbLogShade = (shade, color) => { +// const int = parseInt, +// round = Math.round, +// [a, b, c, d] = color.split(","), +// t = shade < 0 ? 0 : shade * 255 ** 2, +// p = shade < 0 ? 1 + shade : 1 - shade; +// return ( +// "rgb" + +// (d ? "a(" : "(") + +// round((p * int(a[3] == "a" ? a.slice(5) : a.slice(4)) ** 2 + t) ** 0.5) + +// "," + +// round((p * int(b) ** 2 + t) ** 0.5) + +// "," + +// round((p * int(c) ** 2 + t) ** 0.5) + +// (d ? "," + d : ")") +// ); +// }; -/** - * pick a contrasting color e.g. for text on a variable color background - * using the hsp (perceived brightness) constants from http://alienryderflex.com/hsp.html - * @param {number} r - red (0-255) - * @param {number} g - green (0-255) - * @param {number} b - blue (0-255) - * @returns {string} the contrasting rgb color, white or black - */ -export const rgbContrast = (r, g, b) => { - return Math.sqrt(0.299 * (r * r) + 0.587 * (g * g) + 0.114 * (b * b)) > 165.75 - ? "rgb(0,0,0)" - : "rgb(255,255,255)"; -}; +// /** +// * pick a contrasting color e.g. for text on a variable color background +// * using the hsp (perceived brightness) constants from http://alienryderflex.com/hsp.html +// * @param {number} r - red (0-255) +// * @param {number} g - green (0-255) +// * @param {number} b - blue (0-255) +// * @returns {string} the contrasting rgb color, white or black +// */ +// export const rgbContrast = (r, g, b) => { +// return Math.sqrt(0.299 * (r * r) + 0.587 * (g * g) + 0.114 * (b * b)) > 165.75 +// ? "rgb(0,0,0)" +// : "rgb(255,255,255)"; +// }; -let _hotkeyListenersActivated = false, - _hotkeyEventListeners = [], - _documentObserver, - _documentObserverListeners = []; -const _documentObserverEvents = []; +// let _hotkeyListenersActivated = false, +// _hotkeyEventListeners = [], +// _documentObserver, +// _documentObserverListeners = []; +// const _documentObserverEvents = []; -/** - * wait until a page is loaded and ready for modification - * @param {array=} selectors - wait for the existence of elements that match these css selectors - * @returns {Promise} a promise that will resolve when the page is ready - */ -export const whenReady = (selectors = []) => { - return new Promise((res, _rej) => { - const onLoad = () => { - const interval = setInterval(isReady, 100); - function isReady() { - const ready = selectors.every((selector) => document.querySelector(selector)); - if (!ready) return; - clearInterval(interval); - res(true); - } - isReady(); - }; - if (document.readyState !== "complete") { - document.addEventListener("readystatechange", (_event) => { - if (document.readyState === "complete") onLoad(); - }); - } else onLoad(); - }); -}; +// /** +// * wait until a page is loaded and ready for modification +// * @param {array=} selectors - wait for the existence of elements that match these css selectors +// * @returns {Promise} a promise that will resolve when the page is ready +// */ +// export const whenReady = (selectors = []) => { +// return new Promise((res, _rej) => { +// const onLoad = () => { +// const interval = setInterval(isReady, 100); +// function isReady() { +// const ready = selectors.every((selector) => document.querySelector(selector)); +// if (!ready) return; +// clearInterval(interval); +// res(true); +// } +// isReady(); +// }; +// if (document.readyState !== "complete") { +// document.addEventListener("readystatechange", (_event) => { +// if (document.readyState === "complete") onLoad(); +// }); +// } else onLoad(); +// }); +// }; -/** - * parse the current location search params into a usable form - * @returns {Map} a map of the url search params - */ -export const queryParams = () => new URLSearchParams(window.location.search); +// /** +// * parse the current location search params into a usable form +// * @returns {Map} a map of the url search params +// */ +// export const queryParams = () => new URLSearchParams(window.location.search); -/** - * replace special html characters with escaped versions - * @param {string} str - * @returns {string} escaped string - */ -export const escape = (str) => - str - .replace(/&/g, "&") - .replace(//g, ">") - .replace(/'/g, "'") - .replace(/"/g, """) - .replace(/\\/g, "\"); +// /** +// * replace special html characters with escaped versions +// * @param {string} str +// * @returns {string} escaped string +// */ +// export const escape = (str) => +// str +// .replace(/&/g, "&") +// .replace(//g, ">") +// .replace(/'/g, "'") +// .replace(/"/g, """) +// .replace(/\\/g, "\"); -/** - * a tagged template processor for raw html: - * stringifies, minifies, and syntax highlights - * @example web.raw`

hello

` - * @returns {string} the processed html - */ -export const raw = (str, ...templates) => { - const html = str - .map( - (chunk) => - chunk + - (["string", "number"].includes(typeof templates[0]) - ? templates.shift() - : escape(JSON.stringify(templates.shift(), null, 2) ?? "")) - ) - .join(""); - return html.includes(" line.trim()) - .filter((line) => line.length) - .join(" "); -}; +// /** +// * a tagged template processor for raw html: +// * stringifies, minifies, and syntax highlights +// * @example web.raw`

hello

` +// * @returns {string} the processed html +// */ +// export const raw = (str, ...templates) => { +// const html = str +// .map( +// (chunk) => +// chunk + +// (["string", "number"].includes(typeof templates[0]) +// ? templates.shift() +// : escape(JSON.stringify(templates.shift(), null, 2) ?? "")) +// ) +// .join(""); +// return html.includes(" line.trim()) +// .filter((line) => line.length) +// .join(" "); +// }; -/** - * create a single html element inc. attributes and children from a string - * @example web.html`

hello

` - * @returns {Element} the constructed html element - */ -export const html = (str, ...templates) => { - const $fragment = document.createRange().createContextualFragment(raw(str, ...templates)); - return $fragment.children.length === 1 ? $fragment.children[0] : $fragment.children; -}; +// /** +// * create a single html element inc. attributes and children from a string +// * @example web.html`

hello

` +// * @returns {Element} the constructed html element +// */ +// export const html = (str, ...templates) => { +// const $fragment = document.createRange().createContextualFragment(raw(str, ...templates)); +// return $fragment.children.length === 1 ? $fragment.children[0] : $fragment.children; +// }; -/** - * appends a list of html elements to a parent - * @param $container - the parent element - * @param $elems - the elements to be appended - * @returns {Element} the updated $container - */ -export const render = ($container, ...$elems) => { - $elems = $elems - .map(($elem) => ($elem instanceof HTMLCollection ? [...$elem] : $elem)) - .flat(Infinity) - .filter(($elem) => $elem); - $container.append(...$elems); - return $container; -}; +// /** +// * appends a list of html elements to a parent +// * @param $container - the parent element +// * @param $elems - the elements to be appended +// * @returns {Element} the updated $container +// */ +// export const render = ($container, ...$elems) => { +// $elems = $elems +// .map(($elem) => ($elem instanceof HTMLCollection ? [...$elem] : $elem)) +// .flat(Infinity) +// .filter(($elem) => $elem); +// $container.append(...$elems); +// return $container; +// }; -/** - * removes all children from an element without deleting them/their behaviours - * @param $container - the parent element - * @returns {Element} the updated $container - */ -export const empty = ($container) => { - while ($container.firstChild && $container.removeChild($container.firstChild)); - return $container; -}; +// /** +// * removes all children from an element without deleting them/their behaviours +// * @param $container - the parent element +// * @returns {Element} the updated $container +// */ +// export const empty = ($container) => { +// while ($container.firstChild && $container.removeChild($container.firstChild)); +// return $container; +// }; -/** - * loads/applies a css stylesheet to the page - * @param {string} path - a url or within-the-enhancer filepath - */ -export const loadStylesheet = (path) => { - const $stylesheet = html``; - render(document.head, $stylesheet); - return $stylesheet; -}; +// /** +// * loads/applies a css stylesheet to the page +// * @param {string} path - a url or within-the-enhancer filepath +// */ +// export const loadStylesheet = (path) => { +// const $stylesheet = html``; +// render(document.head, $stylesheet); +// return $stylesheet; +// }; -/** - * copy text to the clipboard - * @param {string} str - the string to copy - * @returns {Promise} - */ -export const copyToClipboard = async (str) => { - try { - await navigator.clipboard.writeText(str); - } catch { - const $el = document.createElement("textarea"); - $el.value = str; - $el.setAttribute("readonly", ""); - $el.style.position = "absolute"; - $el.style.left = "-9999px"; - document.body.appendChild($el); - $el.select(); - document.execCommand("copy"); - document.body.removeChild($el); - } -}; +// /** +// * copy text to the clipboard +// * @param {string} str - the string to copy +// * @returns {Promise} +// */ +// export const copyToClipboard = async (str) => { +// try { +// await navigator.clipboard.writeText(str); +// } catch { +// const $el = document.createElement("textarea"); +// $el.value = str; +// $el.setAttribute("readonly", ""); +// $el.style.position = "absolute"; +// $el.style.left = "-9999px"; +// document.body.appendChild($el); +// $el.select(); +// document.execCommand("copy"); +// document.body.removeChild($el); +// } +// }; -/** - * read text from the clipboard - * @returns {Promise} - */ -export const readFromClipboard = () => { - return navigator.clipboard.readText(); -}; +// /** +// * read text from the clipboard +// * @returns {Promise} +// */ +// export const readFromClipboard = () => { +// return navigator.clipboard.readText(); +// }; -const triggerHotkeyListener = (event, hotkey) => { - const inInput = document.activeElement.nodeName === "INPUT" && !hotkey.listenInInput; - if (inInput) return; - const modifiers = { - metaKey: ["meta", "os", "win", "cmd", "command"], - ctrlKey: ["ctrl", "control"], - shiftKey: ["shift"], - altKey: ["alt"], - }, - pressed = hotkey.keys.every((key) => { - key = key.toLowerCase(); - for (const modifier in modifiers) { - const pressed = modifiers[modifier].includes(key) && event[modifier]; - if (pressed) { - // mark modifier as part of hotkey - modifiers[modifier] = []; - return true; - } - } - if (key === "space") key = " "; - if (key === "plus") key = "+"; - if (key === event.key.toLowerCase()) return true; - }); - if (!pressed) return; - // test for modifiers not in hotkey - // e.g. to differentiate ctrl+x from ctrl+shift+x - for (const modifier in modifiers) { - const modifierPressed = event[modifier], - modifierNotInHotkey = modifiers[modifier].length > 0; - if (modifierPressed && modifierNotInHotkey) return; - } - hotkey.callback(event); -}; +// const triggerHotkeyListener = (event, hotkey) => { +// const inInput = document.activeElement.nodeName === "INPUT" && !hotkey.listenInInput; +// if (inInput) return; +// const modifiers = { +// metaKey: ["meta", "os", "win", "cmd", "command"], +// ctrlKey: ["ctrl", "control"], +// shiftKey: ["shift"], +// altKey: ["alt"], +// }, +// pressed = hotkey.keys.every((key) => { +// key = key.toLowerCase(); +// for (const modifier in modifiers) { +// const pressed = modifiers[modifier].includes(key) && event[modifier]; +// if (pressed) { +// // mark modifier as part of hotkey +// modifiers[modifier] = []; +// return true; +// } +// } +// if (key === "space") key = " "; +// if (key === "plus") key = "+"; +// if (key === event.key.toLowerCase()) return true; +// }); +// if (!pressed) return; +// // test for modifiers not in hotkey +// // e.g. to differentiate ctrl+x from ctrl+shift+x +// for (const modifier in modifiers) { +// const modifierPressed = event[modifier], +// modifierNotInHotkey = modifiers[modifier].length > 0; +// if (modifierPressed && modifierNotInHotkey) return; +// } +// hotkey.callback(event); +// }; -/** - * register a hotkey listener to the page - * @param {array|string} keys - the combination of keys that will trigger the hotkey. - * key codes can be tested at http://keycode.info/ and are case-insensitive. - * available modifiers are 'alt', 'ctrl', 'meta', and 'shift'. - * can be provided as a + separated string. - * @param {function} callback - called whenever the keys are pressed - * @param {object=} opts - fine-tuned control over when the hotkey should be triggered - * @param {boolean=} opts.listenInInput - whether the hotkey callback should be triggered - * when an input is focused - * @param {boolean=} opts.keydown - whether to listen for the hotkey on keydown. - * by default, hotkeys are triggered by the keyup event. - */ -export const addHotkeyListener = ( - keys, - callback, - { listenInInput = false, keydown = false } = {} -) => { - if (typeof keys === "string") keys = keys.split("+"); - _hotkeyEventListeners.push({ keys, callback, listenInInput, keydown }); +// /** +// * register a hotkey listener to the page +// * @param {array|string} keys - the combination of keys that will trigger the hotkey. +// * key codes can be tested at http://keycode.info/ and are case-insensitive. +// * available modifiers are 'alt', 'ctrl', 'meta', and 'shift'. +// * can be provided as a + separated string. +// * @param {function} callback - called whenever the keys are pressed +// * @param {object=} opts - fine-tuned control over when the hotkey should be triggered +// * @param {boolean=} opts.listenInInput - whether the hotkey callback should be triggered +// * when an input is focused +// * @param {boolean=} opts.keydown - whether to listen for the hotkey on keydown. +// * by default, hotkeys are triggered by the keyup event. +// */ +// export const addHotkeyListener = ( +// keys, +// callback, +// { listenInInput = false, keydown = false } = {} +// ) => { +// if (typeof keys === "string") keys = keys.split("+"); +// _hotkeyEventListeners.push({ keys, callback, listenInInput, keydown }); - if (!_hotkeyListenersActivated) { - _hotkeyListenersActivated = true; - document.addEventListener("keyup", (event) => { - for (const hotkey of _hotkeyEventListeners.filter(({ keydown }) => !keydown)) { - triggerHotkeyListener(event, hotkey); - } - }); - document.addEventListener("keydown", (event) => { - for (const hotkey of _hotkeyEventListeners.filter(({ keydown }) => keydown)) { - triggerHotkeyListener(event, hotkey); - } - }); - } -}; -/** - * remove a listener added with web.addHotkeyListener - * @param {function} callback - */ -export const removeHotkeyListener = (callback) => { - _hotkeyEventListeners = _hotkeyEventListeners.filter( - (listener) => listener.callback !== callback - ); -}; +// if (!_hotkeyListenersActivated) { +// _hotkeyListenersActivated = true; +// document.addEventListener("keyup", (event) => { +// for (const hotkey of _hotkeyEventListeners.filter(({ keydown }) => !keydown)) { +// triggerHotkeyListener(event, hotkey); +// } +// }); +// document.addEventListener("keydown", (event) => { +// for (const hotkey of _hotkeyEventListeners.filter(({ keydown }) => keydown)) { +// triggerHotkeyListener(event, hotkey); +// } +// }); +// } +// }; +// /** +// * remove a listener added with web.addHotkeyListener +// * @param {function} callback +// */ +// export const removeHotkeyListener = (callback) => { +// _hotkeyEventListeners = _hotkeyEventListeners.filter( +// (listener) => listener.callback !== callback +// ); +// }; -/** - * add a listener to watch for changes to the dom - * @param {onDocumentObservedCallback} callback - * @param {string[]=} selectors - */ -export const addDocumentObserver = (callback, selectors = []) => { - if (!_documentObserver) { - const handle = (queue) => { - while (queue.length) { - const event = queue.shift(), - matchesAddedNode = ($node, selector) => - $node instanceof Element && - ($node.matches(selector) || - $node.matches(`${selector} *`) || - $node.querySelector(selector)), - matchesTarget = (selector) => - event.target.matches(selector) || - event.target.matches(`${selector} *`) || - [...event.addedNodes].some(($node) => matchesAddedNode($node, selector)); - for (const listener of _documentObserverListeners) { - if (!listener.selectors.length || listener.selectors.some(matchesTarget)) { - listener.callback(event); - } - } - } - }; - _documentObserver = new MutationObserver((list, _observer) => { - if (!_documentObserverEvents.length) - requestIdleCallback(() => handle(_documentObserverEvents)); - _documentObserverEvents.push(...list); - }); - _documentObserver.observe(document.body, { - childList: true, - subtree: true, - attributes: true, - }); - } - _documentObserverListeners.push({ callback, selectors }); -}; +// /** +// * add a listener to watch for changes to the dom +// * @param {onDocumentObservedCallback} callback +// * @param {string[]=} selectors +// */ +// export const addDocumentObserver = (callback, selectors = []) => { +// if (!_documentObserver) { +// const handle = (queue) => { +// while (queue.length) { +// const event = queue.shift(), +// matchesAddedNode = ($node, selector) => +// $node instanceof Element && +// ($node.matches(selector) || +// $node.matches(`${selector} *`) || +// $node.querySelector(selector)), +// matchesTarget = (selector) => +// event.target.matches(selector) || +// event.target.matches(`${selector} *`) || +// [...event.addedNodes].some(($node) => matchesAddedNode($node, selector)); +// for (const listener of _documentObserverListeners) { +// if (!listener.selectors.length || listener.selectors.some(matchesTarget)) { +// listener.callback(event); +// } +// } +// } +// }; +// _documentObserver = new MutationObserver((list, _observer) => { +// if (!_documentObserverEvents.length) +// requestIdleCallback(() => handle(_documentObserverEvents)); +// _documentObserverEvents.push(...list); +// }); +// _documentObserver.observe(document.body, { +// childList: true, +// subtree: true, +// attributes: true, +// }); +// } +// _documentObserverListeners.push({ callback, selectors }); +// }; -/** - * remove a listener added with web.addDocumentObserver - * @param {onDocumentObservedCallback} callback - */ -export const removeDocumentObserver = (callback) => { - _documentObserverListeners = _documentObserverListeners.filter( - (listener) => listener.callback !== callback - ); -}; +// /** +// * remove a listener added with web.addDocumentObserver +// * @param {onDocumentObservedCallback} callback +// */ +// export const removeDocumentObserver = (callback) => { +// _documentObserverListeners = _documentObserverListeners.filter( +// (listener) => listener.callback !== callback +// ); +// }; -/** - * @callback onDocumentObservedCallback - * @param {MutationRecord} event - the observed dom mutation event - */ +// /** +// * @callback onDocumentObservedCallback +// * @param {MutationRecord} event - the observed dom mutation event +// */ diff --git a/src/core/client.js b/src/core/client.js new file mode 100644 index 0000000..f854e80 --- /dev/null +++ b/src/core/client.js @@ -0,0 +1,29 @@ +/** + * notion-enhancer + * (c) 2022 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +import "../vendor/twind.min.js"; +import * as lucide from "../vendor/lucide.min.js"; +import { html } from "../vendor/htm+preact.min.js"; + +export default async () => { + // const sidebarSelector = + // ".notion-sidebar-container .notion-sidebar > div:nth-child(3) > div > div:nth-child(2)"; + // await web.whenReady([sidebarSelector]); + + console.log(lucide); + + const $sidebarLink = html``; + //
${await fs.getText("media/colour.svg")}
+ // $sidebarLink.addEventListener("click", env.focusMenu); +}; diff --git a/src/core/menu.html b/src/core/menu.html new file mode 100644 index 0000000..33433ab --- /dev/null +++ b/src/core/menu.html @@ -0,0 +1,12 @@ + + + + + + + notion-enhancer menu + + +

hello world

+ + diff --git a/src/core/mod.json b/src/core/mod.json index 16453de..8f8d48d 100644 --- a/src/core/mod.json +++ b/src/core/mod.json @@ -36,9 +36,19 @@ "type": "file", "key": "customStyles", "description": "Adds the styles from an uploaded .css file to Notion. Use this if you would like to customise the current theme or otherwise tweak Notion's appearance." + }, + { + "type": "heading", + "label": "Advanced" + }, + { + "type": "toggle", + "key": "debugMode", + "description": "Activates built-in debugging tools accessible through the application menu.", + "value": false } ], "clientStyles": [], - "clientScripts": [], + "clientScripts": ["client.js"], "electronScripts": [] } diff --git a/src/electron/api.cjs b/src/electron/api.cjs index de3f8a2..1818a7f 100644 --- a/src/electron/api.cjs +++ b/src/electron/api.cjs @@ -65,8 +65,8 @@ const initDatabase = (namespace) => { dump = db.prepare(`SELECT * FROM ${table}`), populate = db.transaction((obj) => { for (const key in obj) { - if (select.get(key)) update.run(value, key); - else insert.run(key, value); + if (select.get(key)) update.run(obj[key], key); + else insert.run(key, obj[key]); } }); diff --git a/src/vendor/htm+preact.min.js b/src/vendor/htm+preact.min.js new file mode 100644 index 0000000..e24f87b --- /dev/null +++ b/src/vendor/htm+preact.min.js @@ -0,0 +1 @@ +var e,n,_,t,o,r,u,l={},i=[],c=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function s(e,n){for(var _ in n)e[_]=n[_];return e}function f(e){var n=e.parentNode;n&&n.removeChild(e)}function a(n,_,t){var o,r,u,l={};for(u in _)"key"==u?o=_[u]:"ref"==u?r=_[u]:l[u]=_[u];if(arguments.length>2&&(l.children=arguments.length>3?e.call(arguments,2):t),"function"==typeof n&&null!=n.defaultProps)for(u in n.defaultProps)void 0===l[u]&&(l[u]=n.defaultProps[u]);return p(n,l,o,r,null)}function p(e,t,o,r,u){var l={type:e,props:t,key:o,ref:r,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==u?++_:u};return null!=n.vnode&&n.vnode(l),l}function h(e){return e.children}function d(e,n){this.props=e,this.context=n}function v(e,n){if(null==n)return e.__?v(e.__,e.__.__k.indexOf(e)+1):null;for(var _;n0?p(m.type,m.props,m.key,null,m.__v):m)){if(m.__=_,m.__b=_.__b+1,null===(y=H[a])||y&&m.key==y.key&&m.type===y.type)H[a]=void 0;else for(d=0;d=t.__.length&&t.__.push({}),t.__[e]}function G(e){return R=1,z(ie,e)}function z(e,n,_){var t=j(L++,2);return t.t=e,t.__c||(t.__=[_?_(n):ie(void 0,n),function(e){var n=t.t(t.__[0],e);t.__[0]!==n&&(t.__=[n,t.__[1]],t.__c.setState({}))}],t.__c=N),t.__}function J(e,_){var t=j(L++,3);!n.__s&&le(t.__H,_)&&(t.__=e,t.__H=_,N.__H.__h.push(t))}function K(e,_){var t=j(L++,4);!n.__s&&le(t.__H,_)&&(t.__=e,t.__H=_,N.__h.push(t))}function Q(e){return R=5,Y(function(){return{current:e}},[])}function X(e,n,_){R=6,K(function(){"function"==typeof e?e(n()):e&&(e.current=n())},null==_?_:_.concat(e))}function Y(e,n){var _=j(L++,7);return le(_.__H,n)&&(_.__=e(),_.__H=n,_.__h=e),_.__}function Z(e,n){return R=8,Y(function(){return e},n)}function ee(e){var n=N.context[e.__c],_=j(L++,9);return _.c=e,n?(null==_.__&&(_.__=!0,n.sub(N)),n.props.value):e.__}function ne(e,_){n.useDebugValue&&n.useDebugValue(_?_(e):e)}function _e(e){var n=j(L++,10),_=G();return n.__=e,N.componentDidCatch||(N.componentDidCatch=function(e){n.__&&n.__(e),_[1](e)}),[_[0],function(){_[1](void 0)}]}function te(){I.forEach(function(e){if(e.__P)try{e.__H.__h.forEach(re),e.__H.__h.forEach(ue),e.__H.__h=[]}catch(_){e.__H.__h=[],n.__e(_,e.__v)}}),I=[]}n.__b=function(e){N=null,O&&O(e)},n.__r=function(e){V&&V(e),L=0;var n=(N=e.__c).__H;n&&(n.__h.forEach(re),n.__h.forEach(ue),n.__h=[])},n.diffed=function(e){q&&q(e);var _=e.__c;_&&_.__H&&_.__H.__h.length&&(1!==I.push(_)&&W===n.requestAnimationFrame||((W=n.requestAnimationFrame)||function(e){var n,_=function(){clearTimeout(t),oe&&cancelAnimationFrame(n),setTimeout(e)},t=setTimeout(_,100);oe&&(n=requestAnimationFrame(_))})(te)),N=void 0},n.__c=function(e,_){_.some(function(e){try{e.__h.forEach(re),e.__h=e.__h.filter(function(e){return!e.__||ue(e)})}catch(t){_.some(function(e){e.__h&&(e.__h=[])}),_=[],n.__e(t,e.__v)}}),B&&B(e,_)},n.unmount=function(e){$&&$(e);var _=e.__c;if(_&&_.__H)try{_.__H.__.forEach(re)}catch(e){n.__e(e,_.__v)}};var oe="function"==typeof requestAnimationFrame;function re(e){var n=N;"function"==typeof e.__c&&e.__c(),N=n}function ue(e){var n=N;e.__c=e.__(),N=n}function le(e,n){return!e||e.length!==n.length||n.some(function(n,_){return n!==e[_]})}function ie(e,n){return"function"==typeof n?n(e):n}var ce=function(e,n,_,t){var o;n[0]=0;for(var r=1;r=5&&((o||!e&&5===t)&&(u.push(t,0,o,_),t=6),e&&(u.push(t,e,0,_),t=6)),o=""},i=0;i"===n?(t=1,o=""):o=n+o[0]:r?n===r?r="":o+=n:'"'===n||"'"===n?r=n:">"===n?(l(),t=1):t&&("="===n?(t=5,_=o,o=""):"/"===n&&(t<5||">"===e[i][c+1])?(l(),3===t&&(u=u[0]),t=u,(u=u[0]).push(2,0,t),t=0):" "===n||"\t"===n||"\n"===n||"\r"===n?(l(),t=2):o+=n),3===t&&"!--"===o&&(t=4,u=u[0])}return l(),u}(e)),n),arguments,[])).length>1?n:n[0]}.bind(a);export{a as h,fe as html,M as render,d as Component,F as createContext,G as useState,z as useReducer,J as useEffect,K as useLayoutEffect,Q as useRef,X as useImperativeHandle,Y as useMemo,Z as useCallback,ee as useContext,ne as useDebugValue,_e as useErrorBoundary};