beer.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659
  1. const _emptyNodeList = [];
  2. function isTouchable() {
  3. return window.matchMedia("(pointer: coarse)").matches;
  4. }
  5. function isDark() {
  6. return window.matchMedia("(prefers-color-scheme: dark)").matches;
  7. }
  8. async function wait(milliseconds) {
  9. await new Promise((resolve) => setTimeout(resolve, milliseconds));
  10. }
  11. function guid() {
  12. return "fxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
  13. const r = Math.random() * 16 | 0;
  14. const v = c === "x" ? r : r & 3 | 8;
  15. return v.toString(16);
  16. });
  17. }
  18. function query(selector, element) {
  19. try {
  20. return typeof selector === "string" ? (element ?? document).querySelector(selector) : selector;
  21. } catch {
  22. return null;
  23. }
  24. }
  25. function queryAll(selector, element) {
  26. try {
  27. return typeof selector === "string" ? (element ?? document).querySelectorAll(selector) : selector ?? _emptyNodeList;
  28. } catch {
  29. return _emptyNodeList;
  30. }
  31. }
  32. function hasClass(element, name) {
  33. return (element == null ? void 0 : element.classList.contains(name)) ?? false;
  34. }
  35. function hasTag(element, name) {
  36. var _a;
  37. return ((_a = element == null ? void 0 : element.tagName) == null ? void 0 : _a.toLowerCase()) === name;
  38. }
  39. function hasType(element, name) {
  40. var _a;
  41. return ((_a = element == null ? void 0 : element.type) == null ? void 0 : _a.toLowerCase()) === name;
  42. }
  43. function addClass(element, name) {
  44. if (element instanceof NodeList)
  45. for (let i = 0; i < element.length; i++)
  46. element[i].classList.add(name);
  47. else
  48. element == null ? void 0 : element.classList.add(name);
  49. }
  50. function removeClass(element, name) {
  51. if (element instanceof NodeList)
  52. for (let i = 0; i < element.length; i++)
  53. element[i].classList.remove(name);
  54. else
  55. element == null ? void 0 : element.classList.remove(name);
  56. }
  57. function on(element, name, callback, useCapture = true) {
  58. if (element == null ? void 0 : element.addEventListener)
  59. element.addEventListener(name, callback, useCapture);
  60. }
  61. function off(element, name, callback, useCapture = true) {
  62. if (element == null ? void 0 : element.removeEventListener)
  63. element.removeEventListener(name, callback, useCapture);
  64. }
  65. function insertBefore(newElement, element) {
  66. var _a;
  67. (_a = element == null ? void 0 : element.parentNode) == null ? void 0 : _a.insertBefore(newElement, element);
  68. }
  69. function prev(element) {
  70. return element == null ? void 0 : element.previousElementSibling;
  71. }
  72. function next(element) {
  73. return element == null ? void 0 : element.nextElementSibling;
  74. }
  75. function parent(element) {
  76. return element == null ? void 0 : element.parentElement;
  77. }
  78. function create(htmlAttributesAsJson) {
  79. const element = document.createElement("div");
  80. for (let i = 0, keys = Object.keys(htmlAttributesAsJson), n = keys.length; i < n; i++) {
  81. const key = keys[i];
  82. const value = htmlAttributesAsJson[key];
  83. element.setAttribute(key, value);
  84. }
  85. return element;
  86. }
  87. function blurActiveElement() {
  88. var _a;
  89. (_a = document.activeElement) == null ? void 0 : _a.blur();
  90. }
  91. function queryAllDataUi(id) {
  92. return queryAll('[data-ui="#' + id + '"]');
  93. }
  94. function queryDataUi(id) {
  95. return query('[data-ui="#' + id + '"]');
  96. }
  97. function updateAllClickable(element) {
  98. if (element.id && hasClass(element, "page"))
  99. element = queryDataUi(element.id) ?? element;
  100. const container = parent(element);
  101. if (!hasClass(container, "tabs") && !hasClass(container, "tabbed") && !hasTag(container, "nav"))
  102. return;
  103. const as = queryAll("a", container);
  104. for (let i = 0; i < as.length; i++)
  105. removeClass(as[i], "active");
  106. addClass(element, "active");
  107. }
  108. function updatePlaceholder(element) {
  109. if (!element.placeholder)
  110. element.placeholder = " ";
  111. }
  112. function onClickLabel(e) {
  113. const label = e.currentTarget;
  114. const field = parent(label);
  115. const input = query("input:not([type=file], [type=checkbox], [type=radio]), select, textarea", field);
  116. if (input)
  117. input.focus();
  118. }
  119. function onFocusInput(e) {
  120. const input = e.currentTarget;
  121. updateInput(input);
  122. }
  123. function onBlurInput(e) {
  124. const input = e.currentTarget;
  125. updateInput(input);
  126. }
  127. function onChangeFile(e) {
  128. const input = e.currentTarget;
  129. updateFile(input);
  130. }
  131. function onChangeColor(e) {
  132. const input = e.currentTarget;
  133. updateColor(input);
  134. }
  135. function onKeydownFile(e) {
  136. const input = e.currentTarget;
  137. updateFile(input, e);
  138. }
  139. function onKeydownColor(e) {
  140. const input = e.currentTarget;
  141. updateColor(input, e);
  142. }
  143. function onInputTextarea(e) {
  144. const textarea = e.currentTarget;
  145. updateTextarea(textarea);
  146. }
  147. function onPasswordIconClick(e) {
  148. var _a;
  149. const icon = e.currentTarget;
  150. const input = query("input", parent(icon));
  151. if (input && ((_a = icon.textContent) == null ? void 0 : _a.includes("visibility")))
  152. input.type = input.type === "password" ? "text" : "password";
  153. }
  154. function updateAllLabels() {
  155. const labels = queryAll(".field > label");
  156. for (let i = 0; i < labels.length; i++)
  157. on(labels[i], "click", onClickLabel);
  158. }
  159. function updateAllInputs() {
  160. const inputs = queryAll(".field > input:not([type=file], [type=color], [type=range])");
  161. for (let i = 0; i < inputs.length; i++) {
  162. on(inputs[i], "focus", onFocusInput);
  163. on(inputs[i], "blur", onBlurInput);
  164. updateInput(inputs[i]);
  165. }
  166. }
  167. function updateAllSelects() {
  168. const selects = queryAll(".field > select");
  169. for (let i = 0; i < selects.length; i++) {
  170. on(selects[i], "focus", onFocusInput);
  171. on(selects[i], "blur", onBlurInput);
  172. }
  173. }
  174. function updateAllFiles() {
  175. const files = queryAll(".field > input[type=file]");
  176. for (let i = 0; i < files.length; i++) {
  177. on(files[i], "change", onChangeFile);
  178. updateFile(files[i]);
  179. }
  180. }
  181. function updateAllColors() {
  182. const colors = queryAll(".field > input[type=color]");
  183. for (let i = 0; i < colors.length; i++) {
  184. on(colors[i], "change", onChangeColor);
  185. updateColor(colors[i]);
  186. }
  187. }
  188. function updateAllTextareas() {
  189. const textareas = queryAll(".field.textarea > textarea");
  190. for (let i = 0; i < textareas.length; i++) {
  191. on(textareas[i], "focus", onFocusInput);
  192. on(textareas[i], "blur", onBlurInput);
  193. on(textareas[i], "input", onInputTextarea);
  194. updateTextarea(textareas[i]);
  195. }
  196. }
  197. function updateAllPasswordIcons() {
  198. const icons = queryAll("input[type=password] ~ :is(i, a)");
  199. for (let i = 0; i < icons.length; i++)
  200. on(icons[i], "click", onPasswordIconClick);
  201. }
  202. function updateInput(input) {
  203. if (hasType(input, "number") && !input.value)
  204. input.value = "";
  205. updatePlaceholder(input);
  206. }
  207. function updateFile(input, e) {
  208. if ((e == null ? void 0 : e.key) === "Enter") {
  209. const previousInput = prev(input);
  210. if (!hasType(previousInput, "file"))
  211. return;
  212. previousInput.click();
  213. return;
  214. }
  215. const nextInput = next(input);
  216. if (!hasType(nextInput, "text"))
  217. return;
  218. nextInput.value = input.files ? Array.from(input.files).map((x) => x.name).join(", ") : "";
  219. nextInput.readOnly = true;
  220. on(nextInput, "keydown", onKeydownFile, false);
  221. updateInput(nextInput);
  222. }
  223. function updateColor(input, e) {
  224. if ((e == null ? void 0 : e.key) === "Enter") {
  225. const previousInput = prev(input);
  226. if (!hasType(previousInput, "color"))
  227. return;
  228. previousInput.click();
  229. return;
  230. }
  231. const nextInput = next(input);
  232. if (!hasType(nextInput, "text"))
  233. return;
  234. nextInput.readOnly = true;
  235. nextInput.value = input.value;
  236. on(nextInput, "keydown", onKeydownColor, false);
  237. updateInput(nextInput);
  238. }
  239. function updateTextarea(textarea) {
  240. updatePlaceholder(textarea);
  241. const field = parent(textarea);
  242. field.removeAttribute("style");
  243. if (hasClass(field, "min"))
  244. field.style.setProperty("---size", `${Math.max(textarea.scrollHeight, field.offsetHeight)}px`);
  245. }
  246. function updateAllFields() {
  247. updateAllLabels();
  248. updateAllInputs();
  249. updateAllSelects();
  250. updateAllFiles();
  251. updateAllColors();
  252. updateAllTextareas();
  253. updateAllPasswordIcons();
  254. }
  255. function onInputDocument(e) {
  256. const input = e.target;
  257. if (!hasTag(input, "input") && !hasTag(input, "select"))
  258. return;
  259. if (input.type === "range") {
  260. input.focus();
  261. updateRange(input);
  262. } else {
  263. updateAllRanges();
  264. }
  265. }
  266. function onFocusRange(e) {
  267. if (!isTouchable())
  268. return;
  269. const input = e.target;
  270. const label = parent(input);
  271. if (hasClass(label, "vertical"))
  272. document.body.classList.add("no-scroll");
  273. }
  274. function onBlurRange(e) {
  275. if (!isTouchable())
  276. return;
  277. const input = e.target;
  278. const label = parent(input);
  279. if (hasClass(label, "vertical"))
  280. document.body.classList.remove("no-scroll");
  281. }
  282. function updateAllRanges() {
  283. const body = document.body;
  284. const ranges = queryAll(".slider > input[type=range]");
  285. if (!ranges.length)
  286. off(body, "input", onInputDocument, false);
  287. else
  288. on(body, "input", onInputDocument, false);
  289. for (let i = 0; i < ranges.length; i++)
  290. updateRange(ranges[i]);
  291. }
  292. function updateRange(input) {
  293. on(input, "focus", onFocusRange);
  294. on(input, "blur", onBlurRange);
  295. const label = parent(input);
  296. const bar = query("span", label);
  297. const inputs = queryAll("input", label);
  298. if (!inputs.length || !bar)
  299. return;
  300. const rootSize = parseInt(getComputedStyle(document.documentElement).getPropertyValue("--size")) || 16;
  301. const thumb = hasClass(label, "max") ? 0 : 0.25 * rootSize * 100 / inputs[0].offsetWidth;
  302. const percents = [];
  303. const values = [];
  304. for (let i = 0, n = inputs.length; i < n; i++) {
  305. const min = parseFloat(inputs[i].min) || 0;
  306. const max = parseFloat(inputs[i].max) || 100;
  307. const value = parseFloat(inputs[i].value) || 0;
  308. const percent2 = (value - min) * 100 / (max - min);
  309. const fix = thumb / 2 - thumb * percent2 / 100;
  310. percents.push(percent2 + fix);
  311. values.push(value);
  312. }
  313. let percent = percents[0];
  314. let start2 = 0;
  315. let end = 100 - start2 - percent;
  316. let value1 = values[0];
  317. let value2 = values[1] || 0;
  318. if (inputs.length > 1) {
  319. percent = Math.abs(percents[1] - percents[0]);
  320. start2 = percents[1] > percents[0] ? percents[0] : percents[1];
  321. end = 100 - start2 - percent;
  322. if (value2 > value1) {
  323. value1 = values[1] || 0;
  324. value2 = values[0];
  325. }
  326. }
  327. label.style.setProperty("---start", `${start2}%`);
  328. label.style.setProperty("---end", `${end}%`);
  329. label.style.setProperty("---value1", `'${value1}'`);
  330. label.style.setProperty("---value2", `'${value2}'`);
  331. }
  332. function updateAllSliders() {
  333. updateAllRanges();
  334. }
  335. const _lastTheme = {
  336. light: "",
  337. dark: ""
  338. };
  339. function getMode() {
  340. var _a;
  341. return ((_a = document == null ? void 0 : document.body) == null ? void 0 : _a.classList.contains("dark")) ? "dark" : "light";
  342. }
  343. function lastTheme() {
  344. if (_lastTheme.light && _lastTheme.dark)
  345. return _lastTheme;
  346. const body = document.body;
  347. const light = document.createElement("body");
  348. light.className = "light";
  349. body.appendChild(light);
  350. const dark = document.createElement("body");
  351. dark.className = "dark";
  352. body.appendChild(dark);
  353. const fromLight = getComputedStyle(light);
  354. const fromDark = getComputedStyle(dark);
  355. const variables = ["--primary", "--on-primary", "--primary-container", "--on-primary-container", "--secondary", "--on-secondary", "--secondary-container", "--on-secondary-container", "--tertiary", "--on-tertiary", "--tertiary-container", "--on-tertiary-container", "--error", "--on-error", "--error-container", "--on-error-container", "--background", "--on-background", "--surface", "--on-surface", "--surface-variant", "--on-surface-variant", "--outline", "--outline-variant", "--shadow", "--scrim", "--inverse-surface", "--inverse-on-surface", "--inverse-primary", "--surface-dim", "--surface-bright", "--surface-container-lowest", "--surface-container-low", "--surface-container", "--surface-container-high", "--surface-container-highest"];
  356. for (let i = 0, n = variables.length; i < n; i++) {
  357. _lastTheme.light += variables[i] + ":" + fromLight.getPropertyValue(variables[i]) + ";";
  358. _lastTheme.dark += variables[i] + ":" + fromDark.getPropertyValue(variables[i]) + ";";
  359. }
  360. body.removeChild(light);
  361. body.removeChild(dark);
  362. return _lastTheme;
  363. }
  364. function updateTheme(source) {
  365. const context = globalThis;
  366. const body = document.body;
  367. if (!source || !context.materialDynamicColors)
  368. return lastTheme();
  369. const mode = getMode();
  370. if (source.light && source.dark) {
  371. _lastTheme.light = source.light;
  372. _lastTheme.dark = source.dark;
  373. body.setAttribute("style", source[mode]);
  374. return source;
  375. }
  376. return context.materialDynamicColors(source).then((theme) => {
  377. const toCss = (data) => {
  378. let style = "";
  379. for (let i = 0, keys = Object.keys(data), n = keys.length; i < n; i++) {
  380. const key = keys[i];
  381. const value = data[key];
  382. const kebabCase = key.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g, "$1-$2").toLowerCase();
  383. style += "--" + kebabCase + ":" + value + ";";
  384. }
  385. return style;
  386. };
  387. _lastTheme.light = toCss(theme.light);
  388. _lastTheme.dark = toCss(theme.dark);
  389. body.setAttribute("style", _lastTheme[mode]);
  390. return _lastTheme;
  391. });
  392. }
  393. function updateMode(value) {
  394. const context = globalThis;
  395. const body = document.body;
  396. if (!body)
  397. return value;
  398. if (!value)
  399. return getMode();
  400. if (value === "auto")
  401. value = isDark() ? "dark" : "light";
  402. body.classList.remove("light", "dark");
  403. body.classList.add(value);
  404. const lastThemeStyle = value === "light" ? _lastTheme.light : _lastTheme.dark;
  405. if (context.materialDynamicColors)
  406. body.setAttribute("style", lastThemeStyle);
  407. return getMode();
  408. }
  409. const _dialogs = [];
  410. function onKeydownDialog(e) {
  411. if (e.key === "Escape") {
  412. const dialog = e.currentTarget;
  413. void updateDialog(dialog, dialog);
  414. }
  415. }
  416. function focusOnDialogOrElement(dialog) {
  417. const element = query("[autofocus]", dialog) ?? dialog;
  418. element.focus();
  419. }
  420. function closeDialog(dialog, overlay) {
  421. removeClass(queryAllDataUi(dialog.id), "active");
  422. removeClass(dialog, "active");
  423. removeClass(overlay, "active");
  424. dialog.close();
  425. _dialogs.pop();
  426. const previousDialog = _dialogs[_dialogs.length - 1];
  427. if (previousDialog)
  428. previousDialog.focus();
  429. else if (isTouchable())
  430. document.body.classList.remove("no-scroll");
  431. }
  432. async function openDialog(dialog, overlay, isModal, from) {
  433. if (!hasTag(from, "button") && !hasClass(from, "button") && !hasClass(from, "chip"))
  434. addClass(from, "active");
  435. addClass(overlay, "active");
  436. addClass(dialog, "active");
  437. if (isModal)
  438. dialog.showModal();
  439. else
  440. dialog.show();
  441. await wait(90);
  442. if (!isModal)
  443. on(dialog, "keydown", onKeydownDialog, false);
  444. _dialogs.push(dialog);
  445. if (isTouchable())
  446. document.body.classList.add("no-scroll");
  447. focusOnDialogOrElement(dialog);
  448. }
  449. function onClickOverlay(e) {
  450. const overlay = e.currentTarget;
  451. const dialog = next(overlay);
  452. if (hasTag(dialog, "dialog"))
  453. closeDialog(dialog, overlay);
  454. }
  455. async function updateDialog(from, dialog) {
  456. blurActiveElement();
  457. let overlay = prev(dialog);
  458. const isActive = hasClass(dialog, "active") || dialog.open;
  459. const isModal = hasClass(dialog, "modal");
  460. if (!isModal)
  461. off(dialog, "keydown", onKeydownDialog, false);
  462. if (!hasClass(overlay, "overlay")) {
  463. overlay = create({ class: "overlay" });
  464. insertBefore(overlay, dialog);
  465. await wait(90);
  466. }
  467. if (!isModal)
  468. on(overlay, "click", onClickOverlay, false);
  469. if (isActive)
  470. closeDialog(dialog, overlay);
  471. else
  472. void openDialog(dialog, overlay, isModal, from);
  473. }
  474. let _timeoutMenu;
  475. function onClickDocument(e) {
  476. off(document.body, "click", onClickDocument);
  477. const body = e.target;
  478. const menus = queryAll("menu.active");
  479. for (let i = 0; i < menus.length; i++)
  480. updateMenu(body, menus[i], e);
  481. }
  482. function focusOnMenuOrInput(menu) {
  483. setTimeout(() => {
  484. const input = query(".field > input", menu);
  485. if (input)
  486. input.focus();
  487. else
  488. menu.focus();
  489. }, 90);
  490. }
  491. function updateMenu(from, menu, e) {
  492. if (_timeoutMenu)
  493. clearTimeout(_timeoutMenu);
  494. _timeoutMenu = setTimeout(() => {
  495. on(document.body, "click", onClickDocument);
  496. if (!hasTag(document.activeElement, "input"))
  497. blurActiveElement();
  498. const isActive = hasClass(menu, "active");
  499. const isEvent = (e == null ? void 0 : e.target) === from;
  500. const isChild = !!from.closest("menu");
  501. if (!isActive && isChild || isActive && isEvent) {
  502. removeClass(menu, "active");
  503. return;
  504. }
  505. removeClass(queryAll("menu.active"), "active");
  506. addClass(menu, "active");
  507. focusOnMenuOrInput(menu);
  508. }, 90);
  509. }
  510. let _timeoutSnackbar;
  511. function onClickSnackbar(e) {
  512. const snackbar = e.currentTarget;
  513. removeClass(snackbar, "active");
  514. if (_timeoutSnackbar)
  515. clearTimeout(_timeoutSnackbar);
  516. }
  517. function updateSnackbar(snackbar, milliseconds) {
  518. blurActiveElement();
  519. const activeSnackbars = queryAll(".snackbar.active");
  520. for (let i = 0; i < activeSnackbars.length; i++)
  521. removeClass(activeSnackbars[i], "active");
  522. addClass(snackbar, "active");
  523. on(snackbar, "click", onClickSnackbar);
  524. if (_timeoutSnackbar)
  525. clearTimeout(_timeoutSnackbar);
  526. if (milliseconds === -1)
  527. return;
  528. _timeoutSnackbar = setTimeout(() => {
  529. removeClass(snackbar, "active");
  530. }, milliseconds ?? 6e3);
  531. }
  532. function updatePage(page) {
  533. const container = parent(page);
  534. if (container)
  535. removeClass(queryAll(":scope > .page", container), "active");
  536. addClass(page, "active");
  537. }
  538. function onPointerDownRipple(e) {
  539. updateRipple(e);
  540. }
  541. function updateRipple(e) {
  542. const element = e.currentTarget;
  543. const rect = element.getBoundingClientRect();
  544. const diameter = Math.max(rect.width, rect.height);
  545. const radius = diameter / 2;
  546. const x = e.clientX - rect.left - radius;
  547. const y = e.clientY - rect.top - radius;
  548. const rippleContainer = document.createElement("div");
  549. rippleContainer.className = "ripple-js";
  550. const ripple = document.createElement("div");
  551. ripple.style.inlineSize = ripple.style.blockSize = `${diameter}px`;
  552. ripple.style.left = `${x}px`;
  553. ripple.style.top = `${y}px`;
  554. ripple.addEventListener("animationend", () => {
  555. rippleContainer.remove();
  556. });
  557. rippleContainer.appendChild(ripple);
  558. element.appendChild(rippleContainer);
  559. }
  560. function updateAllRipples() {
  561. const ripples = queryAll(".slow-ripple, .ripple, .fast-ripple");
  562. for (let i = 0; i < ripples.length; i++)
  563. on(ripples[i], "pointerdown", onPointerDownRipple);
  564. }
  565. let _timeoutMutation;
  566. let _mutation;
  567. function onMutation() {
  568. if (_timeoutMutation)
  569. clearTimeout(_timeoutMutation);
  570. _timeoutMutation = setTimeout(async () => await ui(), 180);
  571. }
  572. async function run(from, to, options, e) {
  573. if (!to) {
  574. to = query(from.getAttribute("data-ui"));
  575. if (!to)
  576. return;
  577. }
  578. updateAllClickable(from);
  579. if (hasTag(to, "dialog")) {
  580. await updateDialog(from, to);
  581. return;
  582. }
  583. if (hasTag(to, "menu")) {
  584. updateMenu(from, to, e);
  585. return;
  586. }
  587. if (hasClass(to, "snackbar")) {
  588. updateSnackbar(to, options);
  589. return;
  590. }
  591. if (hasClass(to, "page")) {
  592. updatePage(to);
  593. return;
  594. }
  595. if (hasClass(to, "active")) {
  596. removeClass(from, "active");
  597. removeClass(to, "active");
  598. return;
  599. }
  600. addClass(to, "active");
  601. }
  602. function onClickElement(e) {
  603. void run(e.currentTarget, null, null, e);
  604. }
  605. function onKeydownElement(e) {
  606. if (e.key === "Enter")
  607. void run(e.currentTarget, null, null, e);
  608. }
  609. function setup() {
  610. if (_mutation)
  611. return;
  612. _mutation = new MutationObserver(onMutation);
  613. _mutation.observe(document.body, { childList: true, subtree: true });
  614. onMutation();
  615. }
  616. function updateAllDataUis() {
  617. const elements = queryAll("[data-ui]");
  618. for (let i = 0, n = elements.length; i < n; i++) {
  619. on(elements[i], "click", onClickElement);
  620. if (hasTag(elements[i], "a") && !elements[i].getAttribute("href"))
  621. on(elements[i], "keydown", onKeydownElement);
  622. }
  623. }
  624. function ui(selector, options) {
  625. if (selector) {
  626. if (selector === "setup") {
  627. setup();
  628. return;
  629. }
  630. if (selector === "guid")
  631. return guid();
  632. if (selector === "mode")
  633. return updateMode(options);
  634. if (selector === "theme")
  635. return updateTheme(options);
  636. const to = query(selector);
  637. if (!to)
  638. return;
  639. void run(to, to, options);
  640. }
  641. updateAllDataUis();
  642. updateAllFields();
  643. updateAllSliders();
  644. updateAllRipples();
  645. }
  646. function start() {
  647. var _a;
  648. const context = globalThis;
  649. const body = (_a = context == null ? void 0 : context.document) == null ? void 0 : _a.body;
  650. if (body && !body.classList.contains("dark") && !body.classList.contains("light"))
  651. updateMode("auto");
  652. on(context, "load", setup, false);
  653. context.ui = ui;
  654. }
  655. start();
  656. export {
  657. ui as default,
  658. ui
  659. };