Sleazy Fork is available in English.

Exhentai Enhancer

improve UX of Gallery Page, Multi-Page Viewer and Front Page

  1. // ==UserScript==
  2. // @name Exhentai Enhancer
  3. // @name:en Exhentai Enhancer
  4. // @name:zh-TW Exhentai Enhancer
  5. // @name:zh-CN Exhentai Enhancer
  6. // @namespace https://github.com/sk2589822/Exhentai-Enhancer
  7. // @version 1.15.5
  8. // @author sk2589822
  9. // @description improve UX of Gallery Page, Multi-Page Viewer and Front Page
  10. // @description:en improve UX of Gallery Page, Multi-Page Viewer and Front Page
  11. // @description:zh-TW 改善 Gallery Page、Multi-Page Viewer 和 Front Page 的使用者體驗
  12. // @description:zh-CN 改善 Gallery Page、Multi-Page Viewer 和 Front Page 的使用者體驗
  13. // @license MIT
  14. // @icon https://vitejs.dev/logo.svg
  15. // @supportURL https://github.com/sk2589822/Exhentai-Enhancer/issues
  16. // @match https://exhentai.org/*
  17. // @match https://e-hentai.org/*
  18. // @require https://cdn.jsdelivr.net/npm/vue@3.5.12/dist/vue.global.prod.js
  19. // @grant GM.getValue
  20. // @grant GM.registerMenuCommand
  21. // @grant GM.setValue
  22. // @grant GM_addStyle
  23. // @grant GM_addValueChangeListener
  24. // @grant GM_getValue
  25. // @grant GM_setValue
  26. // @grant unsafeWindow
  27. // ==/UserScript==
  28.  
  29. (t=>{if(typeof GM_addStyle=="function"){GM_addStyle(t);return}const e=document.createElement("style");e.textContent=t,document.head.append(e)})(' @charset "UTF-8";.Vue-Toastification__container{z-index:9999;position:fixed;padding:4px;width:600px;box-sizing:border-box;display:flex;min-height:100%;color:#fff;flex-direction:column;pointer-events:none}@media only screen and (min-width : 600px){.Vue-Toastification__container.top-left,.Vue-Toastification__container.top-right,.Vue-Toastification__container.top-center{top:1em}.Vue-Toastification__container.bottom-left,.Vue-Toastification__container.bottom-right,.Vue-Toastification__container.bottom-center{bottom:1em;flex-direction:column-reverse}.Vue-Toastification__container.top-left,.Vue-Toastification__container.bottom-left{left:1em}.Vue-Toastification__container.top-left .Vue-Toastification__toast,.Vue-Toastification__container.bottom-left .Vue-Toastification__toast{margin-right:auto}@supports not (-moz-appearance: none){.Vue-Toastification__container.top-left .Vue-Toastification__toast--rtl,.Vue-Toastification__container.bottom-left .Vue-Toastification__toast--rtl{margin-right:unset;margin-left:auto}}.Vue-Toastification__container.top-right,.Vue-Toastification__container.bottom-right{right:1em}.Vue-Toastification__container.top-right .Vue-Toastification__toast,.Vue-Toastification__container.bottom-right .Vue-Toastification__toast{margin-left:auto}@supports not (-moz-appearance: none){.Vue-Toastification__container.top-right .Vue-Toastification__toast--rtl,.Vue-Toastification__container.bottom-right .Vue-Toastification__toast--rtl{margin-left:unset;margin-right:auto}}.Vue-Toastification__container.top-center,.Vue-Toastification__container.bottom-center{left:50%;margin-left:-300px}.Vue-Toastification__container.top-center .Vue-Toastification__toast,.Vue-Toastification__container.bottom-center .Vue-Toastification__toast{margin-left:auto;margin-right:auto}}@media only screen and (max-width : 600px){.Vue-Toastification__container{width:100vw;padding:0;left:0;margin:0}.Vue-Toastification__container .Vue-Toastification__toast{width:100%}.Vue-Toastification__container.top-left,.Vue-Toastification__container.top-right,.Vue-Toastification__container.top-center{top:0}.Vue-Toastification__container.bottom-left,.Vue-Toastification__container.bottom-right,.Vue-Toastification__container.bottom-center{bottom:0;flex-direction:column-reverse}}.Vue-Toastification__toast{display:inline-flex;position:relative;max-height:800px;min-height:64px;box-sizing:border-box;margin-bottom:1rem;padding:22px 24px;border-radius:8px;box-shadow:0 1px 10px #0000001a,0 2px 15px #0000000d;justify-content:space-between;font-family:Lato,Helvetica,Roboto,Arial,sans-serif;max-width:600px;min-width:326px;pointer-events:auto;overflow:hidden;transform:translateZ(0);direction:ltr}.Vue-Toastification__toast--rtl{direction:rtl}.Vue-Toastification__toast--default{background-color:#1976d2;color:#fff}.Vue-Toastification__toast--info{background-color:#2196f3;color:#fff}.Vue-Toastification__toast--success{background-color:#4caf50;color:#fff}.Vue-Toastification__toast--error{background-color:#ff5252;color:#fff}.Vue-Toastification__toast--warning{background-color:#ffc107;color:#fff}@media only screen and (max-width : 600px){.Vue-Toastification__toast{border-radius:0;margin-bottom:.5rem}}.Vue-Toastification__toast-body{flex:1;line-height:24px;font-size:16px;word-break:break-word;white-space:pre-wrap}.Vue-Toastification__toast-component-body{flex:1}.Vue-Toastification__toast.disable-transition{animation:none!important}.Vue-Toastification__close-button{font-weight:700;font-size:24px;line-height:24px;background:transparent;outline:none;border:none;padding:0 0 0 10px;cursor:pointer;transition:.3s ease;align-items:center;color:#fff;opacity:.3;transition:visibility 0s,opacity .2s linear}.Vue-Toastification__close-button:hover,.Vue-Toastification__close-button:focus{opacity:1}.Vue-Toastification__toast:not(:hover) .Vue-Toastification__close-button.show-on-hover{opacity:0}.Vue-Toastification__toast--rtl .Vue-Toastification__close-button{padding-left:unset;padding-right:10px}@keyframes scale-x-frames{0%{transform:scaleX(1)}to{transform:scaleX(0)}}.Vue-Toastification__progress-bar{position:absolute;bottom:0;left:0;width:100%;height:5px;z-index:10000;background-color:#ffffffb3;transform-origin:left;animation:scale-x-frames linear 1 forwards}.Vue-Toastification__toast--rtl .Vue-Toastification__progress-bar{right:0;left:unset;transform-origin:right}.Vue-Toastification__icon{margin:auto 18px auto 0;background:transparent;outline:none;border:none;padding:0;transition:.3s ease;align-items:center;width:20px;height:100%}.Vue-Toastification__toast--rtl .Vue-Toastification__icon{margin:auto 0 auto 18px}@keyframes bounceInRight{0%,60%,75%,90%,to{animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;transform:translate3d(3000px,0,0)}60%{opacity:1;transform:translate3d(-25px,0,0)}75%{transform:translate3d(10px,0,0)}90%{transform:translate3d(-5px,0,0)}to{transform:none}}@keyframes bounceOutRight{40%{opacity:1;transform:translate3d(-20px,0,0)}to{opacity:0;transform:translate3d(1000px,0,0)}}@keyframes bounceInLeft{0%,60%,75%,90%,to{animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;transform:translate3d(-3000px,0,0)}60%{opacity:1;transform:translate3d(25px,0,0)}75%{transform:translate3d(-10px,0,0)}90%{transform:translate3d(5px,0,0)}to{transform:none}}@keyframes bounceOutLeft{20%{opacity:1;transform:translate3d(20px,0,0)}to{opacity:0;transform:translate3d(-2000px,0,0)}}@keyframes bounceInUp{0%,60%,75%,90%,to{animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;transform:translate3d(0,3000px,0)}60%{opacity:1;transform:translate3d(0,-20px,0)}75%{transform:translate3d(0,10px,0)}90%{transform:translate3d(0,-5px,0)}to{transform:translateZ(0)}}@keyframes bounceOutUp{20%{transform:translate3d(0,-10px,0)}40%,45%{opacity:1;transform:translate3d(0,20px,0)}to{opacity:0;transform:translate3d(0,-2000px,0)}}@keyframes bounceInDown{0%,60%,75%,90%,to{animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;transform:translate3d(0,-3000px,0)}60%{opacity:1;transform:translate3d(0,25px,0)}75%{transform:translate3d(0,-10px,0)}90%{transform:translate3d(0,5px,0)}to{transform:none}}@keyframes bounceOutDown{20%{transform:translate3d(0,10px,0)}40%,45%{opacity:1;transform:translate3d(0,-20px,0)}to{opacity:0;transform:translate3d(0,2000px,0)}}.Vue-Toastification__bounce-enter-active.top-left,.Vue-Toastification__bounce-enter-active.bottom-left{animation-name:bounceInLeft}.Vue-Toastification__bounce-enter-active.top-right,.Vue-Toastification__bounce-enter-active.bottom-right{animation-name:bounceInRight}.Vue-Toastification__bounce-enter-active.top-center{animation-name:bounceInDown}.Vue-Toastification__bounce-enter-active.bottom-center{animation-name:bounceInUp}.Vue-Toastification__bounce-leave-active:not(.disable-transition).top-left,.Vue-Toastification__bounce-leave-active:not(.disable-transition).bottom-left{animation-name:bounceOutLeft}.Vue-Toastification__bounce-leave-active:not(.disable-transition).top-right,.Vue-Toastification__bounce-leave-active:not(.disable-transition).bottom-right{animation-name:bounceOutRight}.Vue-Toastification__bounce-leave-active:not(.disable-transition).top-center{animation-name:bounceOutUp}.Vue-Toastification__bounce-leave-active:not(.disable-transition).bottom-center{animation-name:bounceOutDown}.Vue-Toastification__bounce-leave-active,.Vue-Toastification__bounce-enter-active{animation-duration:.75s;animation-fill-mode:both}.Vue-Toastification__bounce-move{transition-timing-function:ease-in-out;transition-property:all;transition-duration:.4s}@keyframes fadeOutTop{0%{transform:translateY(0);opacity:1}to{transform:translateY(-50px);opacity:0}}@keyframes fadeOutLeft{0%{transform:translate(0);opacity:1}to{transform:translate(-50px);opacity:0}}@keyframes fadeOutBottom{0%{transform:translateY(0);opacity:1}to{transform:translateY(50px);opacity:0}}@keyframes fadeOutRight{0%{transform:translate(0);opacity:1}to{transform:translate(50px);opacity:0}}@keyframes fadeInLeft{0%{transform:translate(-50px);opacity:0}to{transform:translate(0);opacity:1}}@keyframes fadeInRight{0%{transform:translate(50px);opacity:0}to{transform:translate(0);opacity:1}}@keyframes fadeInTop{0%{transform:translateY(-50px);opacity:0}to{transform:translateY(0);opacity:1}}@keyframes fadeInBottom{0%{transform:translateY(50px);opacity:0}to{transform:translateY(0);opacity:1}}.Vue-Toastification__fade-enter-active.top-left,.Vue-Toastification__fade-enter-active.bottom-left{animation-name:fadeInLeft}.Vue-Toastification__fade-enter-active.top-right,.Vue-Toastification__fade-enter-active.bottom-right{animation-name:fadeInRight}.Vue-Toastification__fade-enter-active.top-center{animation-name:fadeInTop}.Vue-Toastification__fade-enter-active.bottom-center{animation-name:fadeInBottom}.Vue-Toastification__fade-leave-active:not(.disable-transition).top-left,.Vue-Toastification__fade-leave-active:not(.disable-transition).bottom-left{animation-name:fadeOutLeft}.Vue-Toastification__fade-leave-active:not(.disable-transition).top-right,.Vue-Toastification__fade-leave-active:not(.disable-transition).bottom-right{animation-name:fadeOutRight}.Vue-Toastification__fade-leave-active:not(.disable-transition).top-center{animation-name:fadeOutTop}.Vue-Toastification__fade-leave-active:not(.disable-transition).bottom-center{animation-name:fadeOutBottom}.Vue-Toastification__fade-leave-active,.Vue-Toastification__fade-enter-active{animation-duration:.75s;animation-fill-mode:both}.Vue-Toastification__fade-move{transition-timing-function:ease-in-out;transition-property:all;transition-duration:.4s}@keyframes slideInBlurredLeft{0%{transform:translate(-1000px) scaleX(2.5) scaleY(.2);transform-origin:100% 50%;filter:blur(40px);opacity:0}to{transform:translate(0) scaleY(1) scaleX(1);transform-origin:50% 50%;filter:blur(0);opacity:1}}@keyframes slideInBlurredTop{0%{transform:translateY(-1000px) scaleY(2.5) scaleX(.2);transform-origin:50% 0%;filter:blur(240px);opacity:0}to{transform:translateY(0) scaleY(1) scaleX(1);transform-origin:50% 50%;filter:blur(0);opacity:1}}@keyframes slideInBlurredRight{0%{transform:translate(1000px) scaleX(2.5) scaleY(.2);transform-origin:0% 50%;filter:blur(40px);opacity:0}to{transform:translate(0) scaleY(1) scaleX(1);transform-origin:50% 50%;filter:blur(0);opacity:1}}@keyframes slideInBlurredBottom{0%{transform:translateY(1000px) scaleY(2.5) scaleX(.2);transform-origin:50% 100%;filter:blur(240px);opacity:0}to{transform:translateY(0) scaleY(1) scaleX(1);transform-origin:50% 50%;filter:blur(0);opacity:1}}@keyframes slideOutBlurredTop{0%{transform:translateY(0) scaleY(1) scaleX(1);transform-origin:50% 0%;filter:blur(0);opacity:1}to{transform:translateY(-1000px) scaleY(2) scaleX(.2);transform-origin:50% 0%;filter:blur(240px);opacity:0}}@keyframes slideOutBlurredBottom{0%{transform:translateY(0) scaleY(1) scaleX(1);transform-origin:50% 50%;filter:blur(0);opacity:1}to{transform:translateY(1000px) scaleY(2) scaleX(.2);transform-origin:50% 100%;filter:blur(240px);opacity:0}}@keyframes slideOutBlurredLeft{0%{transform:translate(0) scaleY(1) scaleX(1);transform-origin:50% 50%;filter:blur(0);opacity:1}to{transform:translate(-1000px) scaleX(2) scaleY(.2);transform-origin:100% 50%;filter:blur(40px);opacity:0}}@keyframes slideOutBlurredRight{0%{transform:translate(0) scaleY(1) scaleX(1);transform-origin:50% 50%;filter:blur(0);opacity:1}to{transform:translate(1000px) scaleX(2) scaleY(.2);transform-origin:0% 50%;filter:blur(40px);opacity:0}}.Vue-Toastification__slideBlurred-enter-active.top-left,.Vue-Toastification__slideBlurred-enter-active.bottom-left{animation-name:slideInBlurredLeft}.Vue-Toastification__slideBlurred-enter-active.top-right,.Vue-Toastification__slideBlurred-enter-active.bottom-right{animation-name:slideInBlurredRight}.Vue-Toastification__slideBlurred-enter-active.top-center{animation-name:slideInBlurredTop}.Vue-Toastification__slideBlurred-enter-active.bottom-center{animation-name:slideInBlurredBottom}.Vue-Toastification__slideBlurred-leave-active:not(.disable-transition).top-left,.Vue-Toastification__slideBlurred-leave-active:not(.disable-transition).bottom-left{animation-name:slideOutBlurredLeft}.Vue-Toastification__slideBlurred-leave-active:not(.disable-transition).top-right,.Vue-Toastification__slideBlurred-leave-active:not(.disable-transition).bottom-right{animation-name:slideOutBlurredRight}.Vue-Toastification__slideBlurred-leave-active:not(.disable-transition).top-center{animation-name:slideOutBlurredTop}.Vue-Toastification__slideBlurred-leave-active:not(.disable-transition).bottom-center{animation-name:slideOutBlurredBottom}.Vue-Toastification__slideBlurred-leave-active,.Vue-Toastification__slideBlurred-enter-active{animation-duration:.75s;animation-fill-mode:both}.Vue-Toastification__slideBlurred-move{transition-timing-function:ease-in-out;transition-property:all;transition-duration:.4s}.itg.gld.is-fetching:after{grid-column:1/-1;display:flex;align-items:center;justify-content:center;margin:0 auto 864px;width:30px;height:30px;line-height:30px;content:"\u231B";animation:spin ease-in-out 1s infinite}.gldown{display:flex}.archive-button{display:flex;justify-content:center;align-items:center;flex-shrink:0;position:relative;top:-6px;margin-left:4px;width:24px;height:24px;border-radius:9999px;background-color:#5fa9cf;box-shadow:#0000003d 0 3px 5px;cursor:pointer}@keyframes spin{0%{rotate:0}to{rotate:360deg}}.popup{position:absolute!important;padding:20px;text-align:center;background-color:var(--bg-color);border:white solid 3px;border-radius:20px;z-index:100;transition:opacity .3s}.popup a{text-decoration:underline}div#gd5{float:unset;width:auto}.is-ready:after{content:" \u2714\uFE0F"}.is-fetching{font-size:0;pointer-events:none;text-decoration:none}.is-fetching:after{content:"\u231B";display:inline-block;font-size:8px;line-height:8px;animation:spin ease-in-out 1s infinite}input[name=dltype]+.is-fetching{position:relative}input[name=dltype]+.is-fetching:after{position:absolute;top:0;left:50%;font-size:12px;line-height:27px}input[name=dltype]+.is-fetching input{color:transparent}.is-finished{font-size:0;pointer-events:none;text-decoration:none}.is-finished:after{content:"\u2714\uFE0F";display:inline-block;font-size:8px;line-height:8px}.page-elevator[data-v-c3f8cb4a]{display:flex;flex-direction:column;gap:10px;width:40px;opacity:1}.page-elevator__input[data-v-c3f8cb4a]{display:flex;margin:0;padding:0;width:100%;height:30px;text-align:center;border:#777 solid 1px;box-sizing:border-box}.page-elevator__slash[data-v-c3f8cb4a]{line-height:100%}:fullscreen .page-elevator[data-v-c3f8cb4a]{opacity:0}:fullscreen .page-elevator[data-v-c3f8cb4a]:hover{opacity:1}#pane_images .mimg{width:min-content!important;min-width:unset;max-height:calc(var(--image-size) + 24px)!important}#pane_images .mimg>a{-webkit-user-select:none;user-select:none}#pane_images .mimg>a>img{width:auto!important;max-height:var(--image-size);pointer-events:none}.image-resizer[data-v-19caf69f]{display:flex;flex-direction:column;gap:16px;width:40px}.image-resizer__button[data-v-19caf69f]{padding:0;width:100%;height:30px;text-align:center;background-color:transparent;border:#777 solid 1px;border-radius:5px;box-sizing:border-box;cursor:pointer}.image-resizer__button[data-v-19caf69f]:hover{background-color:#ffa50033}.image-resizer__button--active[data-v-19caf69f],.image-resizer__button--active[data-v-19caf69f]:hover{background-color:orange}.enhancer-features{position:absolute;top:0;bottom:0;right:0;display:flex;align-items:center;padding-right:5px;z-index:100;flex-direction:row-reverse;gap:16px;box-sizing:border-box}.enhancer-features__feature{padding:10px 5px;background:#7777;border-radius:10px;opacity:0;transition:opacity .3s ease;box-sizing:border-box}.enhancer-features__feature:hover{opacity:1}.switch[data-v-894c8e09]{position:relative;display:inline-block;width:50px;height:24px}.switch__input[data-v-894c8e09]{width:0;height:0;opacity:0}.switch__slider[data-v-894c8e09]{position:absolute;top:0;bottom:0;right:0;left:0;background-color:#ccc;border-radius:9999px;transition:.4s;cursor:pointer}.switch__slider[data-v-894c8e09]:before{position:absolute;top:2px;left:2px;height:calc(100% - 4px);aspect-ratio:1/1;background-color:#fff;border-radius:50%;transition:.4s;content:""}.switch__input:checked+.switch__slider[data-v-894c8e09]{background-color:#34353b}.switch__input:checked+.switch__slider[data-v-894c8e09]:before{transform:translate(26px)}.settings-panel-wrap{display:flex;justify-content:center;align-items:center}.settings-panel{box-sizing:border-box;position:relative;display:flex;flex-direction:column;row-gap:16px;margin:32px;padding:32px;max-width:1000px;max-height:calc(100vh - 64px);background-color:#34353b;border-radius:4px;color:#f1f1f1}.settings-panel__inner{overflow-y:auto;padding-right:16px;height:100%}.settings-panel__section{background-color:#4f535b;border-radius:4px}.settings-panel__section-name{margin:16px 32px;padding-top:16px;font-size:20px;text-align:left;line-height:100%}.settings-panel__close-button{position:absolute;top:4px;right:4px;padding:8px;cursor:pointer}.settings-panel__close-button svg{width:16px;height:16px}.settings-panel a{color:#ddd}.settings-panel hr{background:#f1f1f1}.settings-panel select{color:#f1f1f1;background-color:#34353b;outline:none}.settings{display:flex;flex-wrap:wrap;align-items:center;justify-content:start;padding:8px 16px;column-gap:8px}.settings__name{font-size:16px}.settings__notice{font-size:12px}.settings__intro{margin-left:60px;width:100%;font-size:14px;text-align:left}.actions{display:flex;align-items:center;justify-content:flex-end}.actions__button{padding:8px 16px;color:#fff;background-color:#4f535b;border:none;border-radius:4px;cursor:pointer}.vfm--fixed{position:fixed}.vfm--absolute{position:absolute}.vfm--inset{top:0;right:0;bottom:0;left:0}.vfm--overlay{z-index:-1;background-color:#00000080}.vfm--prevent-none{pointer-events:none}.vfm--prevent-auto{pointer-events:auto}.vfm--outline-none:focus{outline:none}@keyframes fade-in{0%{opacity:0}to{opacity:1}}@keyframes fade-out{0%{opacity:1}to{opacity:0}}.vfm-fade-enter-active{animation:fade-in .3s ease}.vfm-fade-leave-active{animation:fade-out .3s ease}.vfm-bounce-back{transition-property:transform;transition-duration:.3s}.vfm-slide-up-enter-active,.vfm-slide-up-leave-active,.vfm-slide-down-enter-active,.vfm-slide-down-leave-active{transition:transform .3s ease}.vfm-slide-down-enter-from,.vfm-slide-down-leave-to{transform:translateY(100vh)!important}.vfm-slide-up-enter-from,.vfm-slide-up-leave-to{transform:translateY(-100vh)!important}.vfm-slide-right-enter-active,.vfm-slide-right-leave-active,.vfm-slide-left-enter-active,.vfm-slide-left-leave-active{transition:transform .3s ease}.vfm-slide-right-enter-from,.vfm-slide-right-leave-to{transform:translate(100vw)!important}.vfm-slide-left-enter-from,.vfm-slide-left-leave-to{transform:translate(-100vw)!important}.vfm-swipe-banner-back,.vfm-swipe-banner-forward{position:fixed;top:0;bottom:0;width:27px;z-index:10}.vfm-swipe-banner-back{left:0}.vfm-swipe-banner-forward{right:0} ');
  30.  
  31. (function (vue) {
  32. 'use strict';
  33.  
  34. var __defProp = Object.defineProperty;
  35. var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
  36. var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
  37. var _a;
  38. function tryOnScopeDispose$1(fn) {
  39. if (vue.getCurrentScope()) {
  40. vue.onScopeDispose(fn);
  41. return true;
  42. }
  43. return false;
  44. }
  45. function toValue$1(r) {
  46. return typeof r === "function" ? r() : vue.unref(r);
  47. }
  48. const isClient = typeof window !== "undefined" && typeof document !== "undefined";
  49. typeof WorkerGlobalScope !== "undefined" && globalThis instanceof WorkerGlobalScope;
  50. const notNullish = (val) => val != null;
  51. const toString = Object.prototype.toString;
  52. const isObject$2 = (val) => toString.call(val) === "[object Object]";
  53. const noop = () => {
  54. };
  55. function createFilterWrapper(filter, fn) {
  56. function wrapper(...args) {
  57. return new Promise((resolve, reject) => {
  58. Promise.resolve(filter(() => fn.apply(this, args), { fn, thisArg: this, args })).then(resolve).catch(reject);
  59. });
  60. }
  61. return wrapper;
  62. }
  63. const bypassFilter = (invoke2) => {
  64. return invoke2();
  65. };
  66. function pausableFilter(extendFilter = bypassFilter) {
  67. const isActive = vue.ref(true);
  68. function pause() {
  69. isActive.value = false;
  70. }
  71. function resume() {
  72. isActive.value = true;
  73. }
  74. const eventFilter = (...args) => {
  75. if (isActive.value)
  76. extendFilter(...args);
  77. };
  78. return { isActive: vue.readonly(isActive), pause, resume, eventFilter };
  79. }
  80. function objectEntries(obj) {
  81. return Object.entries(obj);
  82. }
  83. function getLifeCycleTarget(target) {
  84. return vue.getCurrentInstance();
  85. }
  86. function watchWithFilter(source, cb, options = {}) {
  87. const {
  88. eventFilter = bypassFilter,
  89. ...watchOptions
  90. } = options;
  91. return vue.watch(
  92. source,
  93. createFilterWrapper(
  94. eventFilter,
  95. cb
  96. ),
  97. watchOptions
  98. );
  99. }
  100. function watchPausable(source, cb, options = {}) {
  101. const {
  102. eventFilter: filter,
  103. ...watchOptions
  104. } = options;
  105. const { eventFilter, pause, resume, isActive } = pausableFilter(filter);
  106. const stop = watchWithFilter(
  107. source,
  108. cb,
  109. {
  110. ...watchOptions,
  111. eventFilter
  112. }
  113. );
  114. return { stop, pause, resume, isActive };
  115. }
  116. function tryOnMounted(fn, sync = true, target) {
  117. const instance = getLifeCycleTarget();
  118. if (instance)
  119. vue.onMounted(fn, target);
  120. else if (sync)
  121. fn();
  122. else
  123. vue.nextTick(fn);
  124. }
  125. const defaultWindow = isClient ? window : void 0;
  126. const defaultDocument = isClient ? window.document : void 0;
  127. function unrefElement$1(elRef) {
  128. var _a2;
  129. const plain = toValue$1(elRef);
  130. return (_a2 = plain == null ? void 0 : plain.$el) != null ? _a2 : plain;
  131. }
  132. function useEventListener(...args) {
  133. let target;
  134. let events2;
  135. let listeners;
  136. let options;
  137. if (typeof args[0] === "string" || Array.isArray(args[0])) {
  138. [events2, listeners, options] = args;
  139. target = defaultWindow;
  140. } else {
  141. [target, events2, listeners, options] = args;
  142. }
  143. if (!target)
  144. return noop;
  145. if (!Array.isArray(events2))
  146. events2 = [events2];
  147. if (!Array.isArray(listeners))
  148. listeners = [listeners];
  149. const cleanups = [];
  150. const cleanup = () => {
  151. cleanups.forEach((fn) => fn());
  152. cleanups.length = 0;
  153. };
  154. const register = (el, event, listener, options2) => {
  155. el.addEventListener(event, listener, options2);
  156. return () => el.removeEventListener(event, listener, options2);
  157. };
  158. const stopWatch = vue.watch(
  159. () => [unrefElement$1(target), toValue$1(options)],
  160. ([el, options2]) => {
  161. cleanup();
  162. if (!el)
  163. return;
  164. const optionsClone = isObject$2(options2) ? { ...options2 } : options2;
  165. cleanups.push(
  166. ...events2.flatMap((event) => {
  167. return listeners.map((listener) => register(el, event, listener, optionsClone));
  168. })
  169. );
  170. },
  171. { immediate: true, flush: "post" }
  172. );
  173. const stop = () => {
  174. stopWatch();
  175. cleanup();
  176. };
  177. tryOnScopeDispose$1(stop);
  178. return stop;
  179. }
  180. function useMounted() {
  181. const isMounted = vue.ref(false);
  182. const instance = vue.getCurrentInstance();
  183. if (instance) {
  184. vue.onMounted(() => {
  185. isMounted.value = true;
  186. }, instance);
  187. }
  188. return isMounted;
  189. }
  190. function useSupported(callback) {
  191. const isMounted = useMounted();
  192. return vue.computed(() => {
  193. isMounted.value;
  194. return Boolean(callback());
  195. });
  196. }
  197. function useMutationObserver(target, callback, options = {}) {
  198. const { window: window2 = defaultWindow, ...mutationOptions } = options;
  199. let observer;
  200. const isSupported = useSupported(() => window2 && "MutationObserver" in window2);
  201. const cleanup = () => {
  202. if (observer) {
  203. observer.disconnect();
  204. observer = void 0;
  205. }
  206. };
  207. const targets = vue.computed(() => {
  208. const value = toValue$1(target);
  209. const items = (Array.isArray(value) ? value : [value]).map(unrefElement$1).filter(notNullish);
  210. return new Set(items);
  211. });
  212. const stopWatch = vue.watch(
  213. () => targets.value,
  214. (targets2) => {
  215. cleanup();
  216. if (isSupported.value && targets2.size) {
  217. observer = new MutationObserver(callback);
  218. targets2.forEach((el) => observer.observe(el, mutationOptions));
  219. }
  220. },
  221. { immediate: true, flush: "post" }
  222. );
  223. const takeRecords = () => {
  224. return observer == null ? void 0 : observer.takeRecords();
  225. };
  226. const stop = () => {
  227. stopWatch();
  228. cleanup();
  229. };
  230. tryOnScopeDispose$1(stop);
  231. return {
  232. isSupported,
  233. stop,
  234. takeRecords
  235. };
  236. }
  237. const WRITABLE_PROPERTIES = [
  238. "hash",
  239. "host",
  240. "hostname",
  241. "href",
  242. "pathname",
  243. "port",
  244. "protocol",
  245. "search"
  246. ];
  247. function useBrowserLocation(options = {}) {
  248. const { window: window2 = defaultWindow } = options;
  249. const refs = Object.fromEntries(
  250. WRITABLE_PROPERTIES.map((key) => [key, vue.ref()])
  251. );
  252. for (const [key, ref2] of objectEntries(refs)) {
  253. vue.watch(ref2, (value) => {
  254. if (!(window2 == null ? void 0 : window2.location) || window2.location[key] === value)
  255. return;
  256. window2.location[key] = value;
  257. });
  258. }
  259. const buildState = (trigger) => {
  260. var _a2;
  261. const { state: state2, length } = (window2 == null ? void 0 : window2.history) || {};
  262. const { origin } = (window2 == null ? void 0 : window2.location) || {};
  263. for (const key of WRITABLE_PROPERTIES)
  264. refs[key].value = (_a2 = window2 == null ? void 0 : window2.location) == null ? void 0 : _a2[key];
  265. return vue.reactive({
  266. trigger,
  267. state: state2,
  268. length,
  269. origin,
  270. ...refs
  271. });
  272. };
  273. const state = vue.ref(buildState("load"));
  274. if (window2) {
  275. useEventListener(window2, "popstate", () => state.value = buildState("popstate"), { passive: true });
  276. useEventListener(window2, "hashchange", () => state.value = buildState("hashchange"), { passive: true });
  277. }
  278. return state;
  279. }
  280. const _global = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
  281. const globalKey = "__vueuse_ssr_handlers__";
  282. const handlers = /* @__PURE__ */ getHandlers();
  283. function getHandlers() {
  284. if (!(globalKey in _global))
  285. _global[globalKey] = _global[globalKey] || {};
  286. return _global[globalKey];
  287. }
  288. function getSSRHandler(key, fallback) {
  289. return handlers[key] || fallback;
  290. }
  291. function guessSerializerType(rawInit) {
  292. return rawInit == null ? "any" : rawInit instanceof Set ? "set" : rawInit instanceof Map ? "map" : rawInit instanceof Date ? "date" : typeof rawInit === "boolean" ? "boolean" : typeof rawInit === "string" ? "string" : typeof rawInit === "object" ? "object" : !Number.isNaN(rawInit) ? "number" : "any";
  293. }
  294. const StorageSerializers = {
  295. boolean: {
  296. read: (v) => v === "true",
  297. write: (v) => String(v)
  298. },
  299. object: {
  300. read: (v) => JSON.parse(v),
  301. write: (v) => JSON.stringify(v)
  302. },
  303. number: {
  304. read: (v) => Number.parseFloat(v),
  305. write: (v) => String(v)
  306. },
  307. any: {
  308. read: (v) => v,
  309. write: (v) => String(v)
  310. },
  311. string: {
  312. read: (v) => v,
  313. write: (v) => String(v)
  314. },
  315. map: {
  316. read: (v) => new Map(JSON.parse(v)),
  317. write: (v) => JSON.stringify(Array.from(v.entries()))
  318. },
  319. set: {
  320. read: (v) => new Set(JSON.parse(v)),
  321. write: (v) => JSON.stringify(Array.from(v))
  322. },
  323. date: {
  324. read: (v) => new Date(v),
  325. write: (v) => v.toISOString()
  326. }
  327. };
  328. const customStorageEventName = "vueuse-storage";
  329. function useStorage(key, defaults2, storage, options = {}) {
  330. var _a2;
  331. const {
  332. flush = "pre",
  333. deep = true,
  334. listenToStorageChanges = true,
  335. writeDefaults = true,
  336. mergeDefaults = false,
  337. shallow,
  338. window: window2 = defaultWindow,
  339. eventFilter,
  340. onError = (e) => {
  341. console.error(e);
  342. },
  343. initOnMounted
  344. } = options;
  345. const data = (shallow ? vue.shallowRef : vue.ref)(defaults2);
  346. if (!storage) {
  347. try {
  348. storage = getSSRHandler("getDefaultStorage", () => {
  349. var _a22;
  350. return (_a22 = defaultWindow) == null ? void 0 : _a22.localStorage;
  351. })();
  352. } catch (e) {
  353. onError(e);
  354. }
  355. }
  356. if (!storage)
  357. return data;
  358. const rawInit = toValue$1(defaults2);
  359. const type = guessSerializerType(rawInit);
  360. const serializer = (_a2 = options.serializer) != null ? _a2 : StorageSerializers[type];
  361. const { pause: pauseWatch, resume: resumeWatch } = watchPausable(
  362. data,
  363. () => write(data.value),
  364. { flush, deep, eventFilter }
  365. );
  366. if (window2 && listenToStorageChanges) {
  367. tryOnMounted(() => {
  368. if (storage instanceof Storage)
  369. useEventListener(window2, "storage", update);
  370. else
  371. useEventListener(window2, customStorageEventName, updateFromCustomEvent);
  372. if (initOnMounted)
  373. update();
  374. });
  375. }
  376. if (!initOnMounted)
  377. update();
  378. function dispatchWriteEvent(oldValue, newValue) {
  379. if (window2) {
  380. const payload = {
  381. key,
  382. oldValue,
  383. newValue,
  384. storageArea: storage
  385. };
  386. window2.dispatchEvent(storage instanceof Storage ? new StorageEvent("storage", payload) : new CustomEvent(customStorageEventName, {
  387. detail: payload
  388. }));
  389. }
  390. }
  391. function write(v) {
  392. try {
  393. const oldValue = storage.getItem(key);
  394. if (v == null) {
  395. dispatchWriteEvent(oldValue, null);
  396. storage.removeItem(key);
  397. } else {
  398. const serialized = serializer.write(v);
  399. if (oldValue !== serialized) {
  400. storage.setItem(key, serialized);
  401. dispatchWriteEvent(oldValue, serialized);
  402. }
  403. }
  404. } catch (e) {
  405. onError(e);
  406. }
  407. }
  408. function read(event) {
  409. const rawValue = event ? event.newValue : storage.getItem(key);
  410. if (rawValue == null) {
  411. if (writeDefaults && rawInit != null)
  412. storage.setItem(key, serializer.write(rawInit));
  413. return rawInit;
  414. } else if (!event && mergeDefaults) {
  415. const value = serializer.read(rawValue);
  416. if (typeof mergeDefaults === "function")
  417. return mergeDefaults(value, rawInit);
  418. else if (type === "object" && !Array.isArray(value))
  419. return { ...rawInit, ...value };
  420. return value;
  421. } else if (typeof rawValue !== "string") {
  422. return rawValue;
  423. } else {
  424. return serializer.read(rawValue);
  425. }
  426. }
  427. function update(event) {
  428. if (event && event.storageArea !== storage)
  429. return;
  430. if (event && event.key == null) {
  431. data.value = rawInit;
  432. return;
  433. }
  434. if (event && event.key !== key)
  435. return;
  436. pauseWatch();
  437. try {
  438. if ((event == null ? void 0 : event.newValue) !== serializer.write(data.value))
  439. data.value = read(event);
  440. } catch (e) {
  441. onError(e);
  442. } finally {
  443. if (event)
  444. vue.nextTick(resumeWatch);
  445. else
  446. resumeWatch();
  447. }
  448. }
  449. function updateFromCustomEvent(event) {
  450. update(event.detail);
  451. }
  452. return data;
  453. }
  454. function useResizeObserver(target, callback, options = {}) {
  455. const { window: window2 = defaultWindow, ...observerOptions } = options;
  456. let observer;
  457. const isSupported = useSupported(() => window2 && "ResizeObserver" in window2);
  458. const cleanup = () => {
  459. if (observer) {
  460. observer.disconnect();
  461. observer = void 0;
  462. }
  463. };
  464. const targets = vue.computed(() => {
  465. const _targets = toValue$1(target);
  466. return Array.isArray(_targets) ? _targets.map((el) => unrefElement$1(el)) : [unrefElement$1(_targets)];
  467. });
  468. const stopWatch = vue.watch(
  469. targets,
  470. (els) => {
  471. cleanup();
  472. if (isSupported.value && window2) {
  473. observer = new ResizeObserver(callback);
  474. for (const _el of els) {
  475. if (_el)
  476. observer.observe(_el, observerOptions);
  477. }
  478. }
  479. },
  480. { immediate: true, flush: "post" }
  481. );
  482. const stop = () => {
  483. cleanup();
  484. stopWatch();
  485. };
  486. tryOnScopeDispose$1(stop);
  487. return {
  488. isSupported,
  489. stop
  490. };
  491. }
  492. function useElementBounding(target, options = {}) {
  493. const {
  494. reset = true,
  495. windowResize = true,
  496. windowScroll = true,
  497. immediate = true,
  498. updateTiming = "sync"
  499. } = options;
  500. const height = vue.ref(0);
  501. const bottom = vue.ref(0);
  502. const left = vue.ref(0);
  503. const right = vue.ref(0);
  504. const top = vue.ref(0);
  505. const width = vue.ref(0);
  506. const x = vue.ref(0);
  507. const y = vue.ref(0);
  508. function recalculate() {
  509. const el = unrefElement$1(target);
  510. if (!el) {
  511. if (reset) {
  512. height.value = 0;
  513. bottom.value = 0;
  514. left.value = 0;
  515. right.value = 0;
  516. top.value = 0;
  517. width.value = 0;
  518. x.value = 0;
  519. y.value = 0;
  520. }
  521. return;
  522. }
  523. const rect = el.getBoundingClientRect();
  524. height.value = rect.height;
  525. bottom.value = rect.bottom;
  526. left.value = rect.left;
  527. right.value = rect.right;
  528. top.value = rect.top;
  529. width.value = rect.width;
  530. x.value = rect.x;
  531. y.value = rect.y;
  532. }
  533. function update() {
  534. if (updateTiming === "sync")
  535. recalculate();
  536. else if (updateTiming === "next-frame")
  537. requestAnimationFrame(() => recalculate());
  538. }
  539. useResizeObserver(target, update);
  540. vue.watch(() => unrefElement$1(target), (ele) => !ele && update());
  541. useMutationObserver(target, update, {
  542. attributeFilter: ["style", "class"]
  543. });
  544. if (windowScroll)
  545. useEventListener("scroll", update, { capture: true, passive: true });
  546. if (windowResize)
  547. useEventListener("resize", update, { passive: true });
  548. tryOnMounted(() => {
  549. if (immediate)
  550. update();
  551. });
  552. return {
  553. height,
  554. bottom,
  555. left,
  556. right,
  557. top,
  558. width,
  559. x,
  560. y,
  561. update
  562. };
  563. }
  564. const eventHandlers = [
  565. "fullscreenchange",
  566. "webkitfullscreenchange",
  567. "webkitendfullscreen",
  568. "mozfullscreenchange",
  569. "MSFullscreenChange"
  570. ];
  571. function useFullscreen(target, options = {}) {
  572. const {
  573. document: document2 = defaultDocument,
  574. autoExit = false
  575. } = options;
  576. const targetRef = vue.computed(() => {
  577. var _a2;
  578. return (_a2 = unrefElement$1(target)) != null ? _a2 : document2 == null ? void 0 : document2.querySelector("html");
  579. });
  580. const isFullscreen = vue.ref(false);
  581. const requestMethod = vue.computed(() => {
  582. return [
  583. "requestFullscreen",
  584. "webkitRequestFullscreen",
  585. "webkitEnterFullscreen",
  586. "webkitEnterFullScreen",
  587. "webkitRequestFullScreen",
  588. "mozRequestFullScreen",
  589. "msRequestFullscreen"
  590. ].find((m) => document2 && m in document2 || targetRef.value && m in targetRef.value);
  591. });
  592. const exitMethod = vue.computed(() => {
  593. return [
  594. "exitFullscreen",
  595. "webkitExitFullscreen",
  596. "webkitExitFullScreen",
  597. "webkitCancelFullScreen",
  598. "mozCancelFullScreen",
  599. "msExitFullscreen"
  600. ].find((m) => document2 && m in document2 || targetRef.value && m in targetRef.value);
  601. });
  602. const fullscreenEnabled = vue.computed(() => {
  603. return [
  604. "fullScreen",
  605. "webkitIsFullScreen",
  606. "webkitDisplayingFullscreen",
  607. "mozFullScreen",
  608. "msFullscreenElement"
  609. ].find((m) => document2 && m in document2 || targetRef.value && m in targetRef.value);
  610. });
  611. const fullscreenElementMethod = [
  612. "fullscreenElement",
  613. "webkitFullscreenElement",
  614. "mozFullScreenElement",
  615. "msFullscreenElement"
  616. ].find((m) => document2 && m in document2);
  617. const isSupported = useSupported(() => targetRef.value && document2 && requestMethod.value !== void 0 && exitMethod.value !== void 0 && fullscreenEnabled.value !== void 0);
  618. const isCurrentElementFullScreen = () => {
  619. if (fullscreenElementMethod)
  620. return (document2 == null ? void 0 : document2[fullscreenElementMethod]) === targetRef.value;
  621. return false;
  622. };
  623. const isElementFullScreen = () => {
  624. if (fullscreenEnabled.value) {
  625. if (document2 && document2[fullscreenEnabled.value] != null) {
  626. return document2[fullscreenEnabled.value];
  627. } else {
  628. const target2 = targetRef.value;
  629. if ((target2 == null ? void 0 : target2[fullscreenEnabled.value]) != null) {
  630. return Boolean(target2[fullscreenEnabled.value]);
  631. }
  632. }
  633. }
  634. return false;
  635. };
  636. async function exit() {
  637. if (!isSupported.value || !isFullscreen.value)
  638. return;
  639. if (exitMethod.value) {
  640. if ((document2 == null ? void 0 : document2[exitMethod.value]) != null) {
  641. await document2[exitMethod.value]();
  642. } else {
  643. const target2 = targetRef.value;
  644. if ((target2 == null ? void 0 : target2[exitMethod.value]) != null)
  645. await target2[exitMethod.value]();
  646. }
  647. }
  648. isFullscreen.value = false;
  649. }
  650. async function enter() {
  651. if (!isSupported.value || isFullscreen.value)
  652. return;
  653. if (isElementFullScreen())
  654. await exit();
  655. const target2 = targetRef.value;
  656. if (requestMethod.value && (target2 == null ? void 0 : target2[requestMethod.value]) != null) {
  657. await target2[requestMethod.value]();
  658. isFullscreen.value = true;
  659. }
  660. }
  661. async function toggle() {
  662. await (isFullscreen.value ? exit() : enter());
  663. }
  664. const handlerCallback = () => {
  665. const isElementFullScreenValue = isElementFullScreen();
  666. if (!isElementFullScreenValue || isElementFullScreenValue && isCurrentElementFullScreen())
  667. isFullscreen.value = isElementFullScreenValue;
  668. };
  669. useEventListener(document2, eventHandlers, handlerCallback, false);
  670. useEventListener(() => unrefElement$1(targetRef), eventHandlers, handlerCallback, false);
  671. if (autoExit)
  672. tryOnScopeDispose$1(exit);
  673. return {
  674. isSupported,
  675. isFullscreen,
  676. enter,
  677. exit,
  678. toggle
  679. };
  680. }
  681. function tryOnScopeDispose(fn) {
  682. if (vue.getCurrentScope()) {
  683. vue.onScopeDispose(fn);
  684. return true;
  685. }
  686. return false;
  687. }
  688. function toValue(r) {
  689. return typeof r === "function" ? r() : vue.unref(r);
  690. }
  691. typeof WorkerGlobalScope !== "undefined" && globalThis instanceof WorkerGlobalScope;
  692. function unrefElement(elRef) {
  693. var _a2;
  694. const plain = toValue(elRef);
  695. return (_a2 = plain == null ? void 0 : plain.$el) != null ? _a2 : plain;
  696. }
  697. /*!
  698. * tabbable 6.2.0
  699. * @license MIT, https://github.com/focus-trap/tabbable/blob/master/LICENSE
  700. */
  701. var candidateSelectors = ["input:not([inert])", "select:not([inert])", "textarea:not([inert])", "a[href]:not([inert])", "button:not([inert])", "[tabindex]:not(slot):not([inert])", "audio[controls]:not([inert])", "video[controls]:not([inert])", '[contenteditable]:not([contenteditable="false"]):not([inert])', "details>summary:first-of-type:not([inert])", "details:not([inert])"];
  702. var candidateSelector = /* @__PURE__ */ candidateSelectors.join(",");
  703. var NoElement = typeof Element === "undefined";
  704. var matches = NoElement ? function() {
  705. } : Element.prototype.matches || Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
  706. var getRootNode = !NoElement && Element.prototype.getRootNode ? function(element) {
  707. var _element$getRootNode;
  708. return element === null || element === void 0 ? void 0 : (_element$getRootNode = element.getRootNode) === null || _element$getRootNode === void 0 ? void 0 : _element$getRootNode.call(element);
  709. } : function(element) {
  710. return element === null || element === void 0 ? void 0 : element.ownerDocument;
  711. };
  712. var isInert = function isInert2(node, lookUp) {
  713. var _node$getAttribute;
  714. if (lookUp === void 0) {
  715. lookUp = true;
  716. }
  717. var inertAtt = node === null || node === void 0 ? void 0 : (_node$getAttribute = node.getAttribute) === null || _node$getAttribute === void 0 ? void 0 : _node$getAttribute.call(node, "inert");
  718. var inert = inertAtt === "" || inertAtt === "true";
  719. var result = inert || lookUp && node && isInert2(node.parentNode);
  720. return result;
  721. };
  722. var isContentEditable = function isContentEditable2(node) {
  723. var _node$getAttribute2;
  724. var attValue = node === null || node === void 0 ? void 0 : (_node$getAttribute2 = node.getAttribute) === null || _node$getAttribute2 === void 0 ? void 0 : _node$getAttribute2.call(node, "contenteditable");
  725. return attValue === "" || attValue === "true";
  726. };
  727. var getCandidates = function getCandidates2(el, includeContainer, filter) {
  728. if (isInert(el)) {
  729. return [];
  730. }
  731. var candidates = Array.prototype.slice.apply(el.querySelectorAll(candidateSelector));
  732. if (includeContainer && matches.call(el, candidateSelector)) {
  733. candidates.unshift(el);
  734. }
  735. candidates = candidates.filter(filter);
  736. return candidates;
  737. };
  738. var getCandidatesIteratively = function getCandidatesIteratively2(elements, includeContainer, options) {
  739. var candidates = [];
  740. var elementsToCheck = Array.from(elements);
  741. while (elementsToCheck.length) {
  742. var element = elementsToCheck.shift();
  743. if (isInert(element, false)) {
  744. continue;
  745. }
  746. if (element.tagName === "SLOT") {
  747. var assigned = element.assignedElements();
  748. var content = assigned.length ? assigned : element.children;
  749. var nestedCandidates = getCandidatesIteratively2(content, true, options);
  750. if (options.flatten) {
  751. candidates.push.apply(candidates, nestedCandidates);
  752. } else {
  753. candidates.push({
  754. scopeParent: element,
  755. candidates: nestedCandidates
  756. });
  757. }
  758. } else {
  759. var validCandidate = matches.call(element, candidateSelector);
  760. if (validCandidate && options.filter(element) && (includeContainer || !elements.includes(element))) {
  761. candidates.push(element);
  762. }
  763. var shadowRoot = element.shadowRoot || // check for an undisclosed shadow
  764. typeof options.getShadowRoot === "function" && options.getShadowRoot(element);
  765. var validShadowRoot = !isInert(shadowRoot, false) && (!options.shadowRootFilter || options.shadowRootFilter(element));
  766. if (shadowRoot && validShadowRoot) {
  767. var _nestedCandidates = getCandidatesIteratively2(shadowRoot === true ? element.children : shadowRoot.children, true, options);
  768. if (options.flatten) {
  769. candidates.push.apply(candidates, _nestedCandidates);
  770. } else {
  771. candidates.push({
  772. scopeParent: element,
  773. candidates: _nestedCandidates
  774. });
  775. }
  776. } else {
  777. elementsToCheck.unshift.apply(elementsToCheck, element.children);
  778. }
  779. }
  780. }
  781. return candidates;
  782. };
  783. var hasTabIndex = function hasTabIndex2(node) {
  784. return !isNaN(parseInt(node.getAttribute("tabindex"), 10));
  785. };
  786. var getTabIndex = function getTabIndex2(node) {
  787. if (!node) {
  788. throw new Error("No node provided");
  789. }
  790. if (node.tabIndex < 0) {
  791. if ((/^(AUDIO|VIDEO|DETAILS)$/.test(node.tagName) || isContentEditable(node)) && !hasTabIndex(node)) {
  792. return 0;
  793. }
  794. }
  795. return node.tabIndex;
  796. };
  797. var getSortOrderTabIndex = function getSortOrderTabIndex2(node, isScope) {
  798. var tabIndex = getTabIndex(node);
  799. if (tabIndex < 0 && isScope && !hasTabIndex(node)) {
  800. return 0;
  801. }
  802. return tabIndex;
  803. };
  804. var sortOrderedTabbables = function sortOrderedTabbables2(a, b) {
  805. return a.tabIndex === b.tabIndex ? a.documentOrder - b.documentOrder : a.tabIndex - b.tabIndex;
  806. };
  807. var isInput = function isInput2(node) {
  808. return node.tagName === "INPUT";
  809. };
  810. var isHiddenInput = function isHiddenInput2(node) {
  811. return isInput(node) && node.type === "hidden";
  812. };
  813. var isDetailsWithSummary = function isDetailsWithSummary2(node) {
  814. var r = node.tagName === "DETAILS" && Array.prototype.slice.apply(node.children).some(function(child) {
  815. return child.tagName === "SUMMARY";
  816. });
  817. return r;
  818. };
  819. var getCheckedRadio = function getCheckedRadio2(nodes, form) {
  820. for (var i = 0; i < nodes.length; i++) {
  821. if (nodes[i].checked && nodes[i].form === form) {
  822. return nodes[i];
  823. }
  824. }
  825. };
  826. var isTabbableRadio = function isTabbableRadio2(node) {
  827. if (!node.name) {
  828. return true;
  829. }
  830. var radioScope = node.form || getRootNode(node);
  831. var queryRadios = function queryRadios2(name) {
  832. return radioScope.querySelectorAll('input[type="radio"][name="' + name + '"]');
  833. };
  834. var radioSet;
  835. if (typeof window !== "undefined" && typeof window.CSS !== "undefined" && typeof window.CSS.escape === "function") {
  836. radioSet = queryRadios(window.CSS.escape(node.name));
  837. } else {
  838. try {
  839. radioSet = queryRadios(node.name);
  840. } catch (err) {
  841. console.error("Looks like you have a radio button with a name attribute containing invalid CSS selector characters and need the CSS.escape polyfill: %s", err.message);
  842. return false;
  843. }
  844. }
  845. var checked = getCheckedRadio(radioSet, node.form);
  846. return !checked || checked === node;
  847. };
  848. var isRadio = function isRadio2(node) {
  849. return isInput(node) && node.type === "radio";
  850. };
  851. var isNonTabbableRadio = function isNonTabbableRadio2(node) {
  852. return isRadio(node) && !isTabbableRadio(node);
  853. };
  854. var isNodeAttached = function isNodeAttached2(node) {
  855. var _nodeRoot;
  856. var nodeRoot = node && getRootNode(node);
  857. var nodeRootHost = (_nodeRoot = nodeRoot) === null || _nodeRoot === void 0 ? void 0 : _nodeRoot.host;
  858. var attached = false;
  859. if (nodeRoot && nodeRoot !== node) {
  860. var _nodeRootHost, _nodeRootHost$ownerDo, _node$ownerDocument;
  861. attached = !!((_nodeRootHost = nodeRootHost) !== null && _nodeRootHost !== void 0 && (_nodeRootHost$ownerDo = _nodeRootHost.ownerDocument) !== null && _nodeRootHost$ownerDo !== void 0 && _nodeRootHost$ownerDo.contains(nodeRootHost) || node !== null && node !== void 0 && (_node$ownerDocument = node.ownerDocument) !== null && _node$ownerDocument !== void 0 && _node$ownerDocument.contains(node));
  862. while (!attached && nodeRootHost) {
  863. var _nodeRoot2, _nodeRootHost2, _nodeRootHost2$ownerD;
  864. nodeRoot = getRootNode(nodeRootHost);
  865. nodeRootHost = (_nodeRoot2 = nodeRoot) === null || _nodeRoot2 === void 0 ? void 0 : _nodeRoot2.host;
  866. attached = !!((_nodeRootHost2 = nodeRootHost) !== null && _nodeRootHost2 !== void 0 && (_nodeRootHost2$ownerD = _nodeRootHost2.ownerDocument) !== null && _nodeRootHost2$ownerD !== void 0 && _nodeRootHost2$ownerD.contains(nodeRootHost));
  867. }
  868. }
  869. return attached;
  870. };
  871. var isZeroArea = function isZeroArea2(node) {
  872. var _node$getBoundingClie = node.getBoundingClientRect(), width = _node$getBoundingClie.width, height = _node$getBoundingClie.height;
  873. return width === 0 && height === 0;
  874. };
  875. var isHidden = function isHidden2(node, _ref) {
  876. var displayCheck = _ref.displayCheck, getShadowRoot = _ref.getShadowRoot;
  877. if (getComputedStyle(node).visibility === "hidden") {
  878. return true;
  879. }
  880. var isDirectSummary = matches.call(node, "details>summary:first-of-type");
  881. var nodeUnderDetails = isDirectSummary ? node.parentElement : node;
  882. if (matches.call(nodeUnderDetails, "details:not([open]) *")) {
  883. return true;
  884. }
  885. if (!displayCheck || displayCheck === "full" || displayCheck === "legacy-full") {
  886. if (typeof getShadowRoot === "function") {
  887. var originalNode = node;
  888. while (node) {
  889. var parentElement = node.parentElement;
  890. var rootNode = getRootNode(node);
  891. if (parentElement && !parentElement.shadowRoot && getShadowRoot(parentElement) === true) {
  892. return isZeroArea(node);
  893. } else if (node.assignedSlot) {
  894. node = node.assignedSlot;
  895. } else if (!parentElement && rootNode !== node.ownerDocument) {
  896. node = rootNode.host;
  897. } else {
  898. node = parentElement;
  899. }
  900. }
  901. node = originalNode;
  902. }
  903. if (isNodeAttached(node)) {
  904. return !node.getClientRects().length;
  905. }
  906. if (displayCheck !== "legacy-full") {
  907. return true;
  908. }
  909. } else if (displayCheck === "non-zero-area") {
  910. return isZeroArea(node);
  911. }
  912. return false;
  913. };
  914. var isDisabledFromFieldset = function isDisabledFromFieldset2(node) {
  915. if (/^(INPUT|BUTTON|SELECT|TEXTAREA)$/.test(node.tagName)) {
  916. var parentNode = node.parentElement;
  917. while (parentNode) {
  918. if (parentNode.tagName === "FIELDSET" && parentNode.disabled) {
  919. for (var i = 0; i < parentNode.children.length; i++) {
  920. var child = parentNode.children.item(i);
  921. if (child.tagName === "LEGEND") {
  922. return matches.call(parentNode, "fieldset[disabled] *") ? true : !child.contains(node);
  923. }
  924. }
  925. return true;
  926. }
  927. parentNode = parentNode.parentElement;
  928. }
  929. }
  930. return false;
  931. };
  932. var isNodeMatchingSelectorFocusable = function isNodeMatchingSelectorFocusable2(options, node) {
  933. if (node.disabled || // we must do an inert look up to filter out any elements inside an inert ancestor
  934. // because we're limited in the type of selectors we can use in JSDom (see related
  935. // note related to `candidateSelectors`)
  936. isInert(node) || isHiddenInput(node) || isHidden(node, options) || // For a details element with a summary, the summary element gets the focus
  937. isDetailsWithSummary(node) || isDisabledFromFieldset(node)) {
  938. return false;
  939. }
  940. return true;
  941. };
  942. var isNodeMatchingSelectorTabbable = function isNodeMatchingSelectorTabbable2(options, node) {
  943. if (isNonTabbableRadio(node) || getTabIndex(node) < 0 || !isNodeMatchingSelectorFocusable(options, node)) {
  944. return false;
  945. }
  946. return true;
  947. };
  948. var isValidShadowRootTabbable = function isValidShadowRootTabbable2(shadowHostNode) {
  949. var tabIndex = parseInt(shadowHostNode.getAttribute("tabindex"), 10);
  950. if (isNaN(tabIndex) || tabIndex >= 0) {
  951. return true;
  952. }
  953. return false;
  954. };
  955. var sortByOrder = function sortByOrder2(candidates) {
  956. var regularTabbables = [];
  957. var orderedTabbables = [];
  958. candidates.forEach(function(item, i) {
  959. var isScope = !!item.scopeParent;
  960. var element = isScope ? item.scopeParent : item;
  961. var candidateTabindex = getSortOrderTabIndex(element, isScope);
  962. var elements = isScope ? sortByOrder2(item.candidates) : element;
  963. if (candidateTabindex === 0) {
  964. isScope ? regularTabbables.push.apply(regularTabbables, elements) : regularTabbables.push(element);
  965. } else {
  966. orderedTabbables.push({
  967. documentOrder: i,
  968. tabIndex: candidateTabindex,
  969. item,
  970. isScope,
  971. content: elements
  972. });
  973. }
  974. });
  975. return orderedTabbables.sort(sortOrderedTabbables).reduce(function(acc, sortable) {
  976. sortable.isScope ? acc.push.apply(acc, sortable.content) : acc.push(sortable.content);
  977. return acc;
  978. }, []).concat(regularTabbables);
  979. };
  980. var tabbable = function tabbable2(container, options) {
  981. options = options || {};
  982. var candidates;
  983. if (options.getShadowRoot) {
  984. candidates = getCandidatesIteratively([container], options.includeContainer, {
  985. filter: isNodeMatchingSelectorTabbable.bind(null, options),
  986. flatten: false,
  987. getShadowRoot: options.getShadowRoot,
  988. shadowRootFilter: isValidShadowRootTabbable
  989. });
  990. } else {
  991. candidates = getCandidates(container, options.includeContainer, isNodeMatchingSelectorTabbable.bind(null, options));
  992. }
  993. return sortByOrder(candidates);
  994. };
  995. var focusable = function focusable2(container, options) {
  996. options = options || {};
  997. var candidates;
  998. if (options.getShadowRoot) {
  999. candidates = getCandidatesIteratively([container], options.includeContainer, {
  1000. filter: isNodeMatchingSelectorFocusable.bind(null, options),
  1001. flatten: true,
  1002. getShadowRoot: options.getShadowRoot
  1003. });
  1004. } else {
  1005. candidates = getCandidates(container, options.includeContainer, isNodeMatchingSelectorFocusable.bind(null, options));
  1006. }
  1007. return candidates;
  1008. };
  1009. var isTabbable = function isTabbable2(node, options) {
  1010. options = options || {};
  1011. if (!node) {
  1012. throw new Error("No node provided");
  1013. }
  1014. if (matches.call(node, candidateSelector) === false) {
  1015. return false;
  1016. }
  1017. return isNodeMatchingSelectorTabbable(options, node);
  1018. };
  1019. var focusableCandidateSelector = /* @__PURE__ */ candidateSelectors.concat("iframe").join(",");
  1020. var isFocusable = function isFocusable2(node, options) {
  1021. options = options || {};
  1022. if (!node) {
  1023. throw new Error("No node provided");
  1024. }
  1025. if (matches.call(node, focusableCandidateSelector) === false) {
  1026. return false;
  1027. }
  1028. return isNodeMatchingSelectorFocusable(options, node);
  1029. };
  1030. /*!
  1031. * focus-trap 7.5.4
  1032. * @license MIT, https://github.com/focus-trap/focus-trap/blob/master/LICENSE
  1033. */
  1034. function ownKeys(e, r) {
  1035. var t = Object.keys(e);
  1036. if (Object.getOwnPropertySymbols) {
  1037. var o = Object.getOwnPropertySymbols(e);
  1038. r && (o = o.filter(function(r2) {
  1039. return Object.getOwnPropertyDescriptor(e, r2).enumerable;
  1040. })), t.push.apply(t, o);
  1041. }
  1042. return t;
  1043. }
  1044. function _objectSpread2(e) {
  1045. for (var r = 1; r < arguments.length; r++) {
  1046. var t = null != arguments[r] ? arguments[r] : {};
  1047. r % 2 ? ownKeys(Object(t), true).forEach(function(r2) {
  1048. _defineProperty(e, r2, t[r2]);
  1049. }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function(r2) {
  1050. Object.defineProperty(e, r2, Object.getOwnPropertyDescriptor(t, r2));
  1051. });
  1052. }
  1053. return e;
  1054. }
  1055. function _defineProperty(obj, key, value) {
  1056. key = _toPropertyKey(key);
  1057. if (key in obj) {
  1058. Object.defineProperty(obj, key, {
  1059. value,
  1060. enumerable: true,
  1061. configurable: true,
  1062. writable: true
  1063. });
  1064. } else {
  1065. obj[key] = value;
  1066. }
  1067. return obj;
  1068. }
  1069. function _toPrimitive(input, hint) {
  1070. if (typeof input !== "object" || input === null) return input;
  1071. var prim = input[Symbol.toPrimitive];
  1072. if (prim !== void 0) {
  1073. var res = prim.call(input, hint || "default");
  1074. if (typeof res !== "object") return res;
  1075. throw new TypeError("@@toPrimitive must return a primitive value.");
  1076. }
  1077. return (hint === "string" ? String : Number)(input);
  1078. }
  1079. function _toPropertyKey(arg) {
  1080. var key = _toPrimitive(arg, "string");
  1081. return typeof key === "symbol" ? key : String(key);
  1082. }
  1083. var activeFocusTraps = {
  1084. activateTrap: function activateTrap(trapStack, trap) {
  1085. if (trapStack.length > 0) {
  1086. var activeTrap = trapStack[trapStack.length - 1];
  1087. if (activeTrap !== trap) {
  1088. activeTrap.pause();
  1089. }
  1090. }
  1091. var trapIndex = trapStack.indexOf(trap);
  1092. if (trapIndex === -1) {
  1093. trapStack.push(trap);
  1094. } else {
  1095. trapStack.splice(trapIndex, 1);
  1096. trapStack.push(trap);
  1097. }
  1098. },
  1099. deactivateTrap: function deactivateTrap(trapStack, trap) {
  1100. var trapIndex = trapStack.indexOf(trap);
  1101. if (trapIndex !== -1) {
  1102. trapStack.splice(trapIndex, 1);
  1103. }
  1104. if (trapStack.length > 0) {
  1105. trapStack[trapStack.length - 1].unpause();
  1106. }
  1107. }
  1108. };
  1109. var isSelectableInput = function isSelectableInput2(node) {
  1110. return node.tagName && node.tagName.toLowerCase() === "input" && typeof node.select === "function";
  1111. };
  1112. var isEscapeEvent = function isEscapeEvent2(e) {
  1113. return (e === null || e === void 0 ? void 0 : e.key) === "Escape" || (e === null || e === void 0 ? void 0 : e.key) === "Esc" || (e === null || e === void 0 ? void 0 : e.keyCode) === 27;
  1114. };
  1115. var isTabEvent = function isTabEvent2(e) {
  1116. return (e === null || e === void 0 ? void 0 : e.key) === "Tab" || (e === null || e === void 0 ? void 0 : e.keyCode) === 9;
  1117. };
  1118. var isKeyForward = function isKeyForward2(e) {
  1119. return isTabEvent(e) && !e.shiftKey;
  1120. };
  1121. var isKeyBackward = function isKeyBackward2(e) {
  1122. return isTabEvent(e) && e.shiftKey;
  1123. };
  1124. var delay$1 = function delay(fn) {
  1125. return setTimeout(fn, 0);
  1126. };
  1127. var findIndex = function findIndex2(arr, fn) {
  1128. var idx = -1;
  1129. arr.every(function(value, i) {
  1130. if (fn(value)) {
  1131. idx = i;
  1132. return false;
  1133. }
  1134. return true;
  1135. });
  1136. return idx;
  1137. };
  1138. var valueOrHandler = function valueOrHandler2(value) {
  1139. for (var _len = arguments.length, params = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
  1140. params[_key - 1] = arguments[_key];
  1141. }
  1142. return typeof value === "function" ? value.apply(void 0, params) : value;
  1143. };
  1144. var getActualTarget = function getActualTarget2(event) {
  1145. return event.target.shadowRoot && typeof event.composedPath === "function" ? event.composedPath()[0] : event.target;
  1146. };
  1147. var internalTrapStack = [];
  1148. var createFocusTrap = function createFocusTrap2(elements, userOptions) {
  1149. var doc = (userOptions === null || userOptions === void 0 ? void 0 : userOptions.document) || document;
  1150. var trapStack = (userOptions === null || userOptions === void 0 ? void 0 : userOptions.trapStack) || internalTrapStack;
  1151. var config = _objectSpread2({
  1152. returnFocusOnDeactivate: true,
  1153. escapeDeactivates: true,
  1154. delayInitialFocus: true,
  1155. isKeyForward,
  1156. isKeyBackward
  1157. }, userOptions);
  1158. var state = {
  1159. // containers given to createFocusTrap()
  1160. // @type {Array<HTMLElement>}
  1161. containers: [],
  1162. // list of objects identifying tabbable nodes in `containers` in the trap
  1163. // NOTE: it's possible that a group has no tabbable nodes if nodes get removed while the trap
  1164. // is active, but the trap should never get to a state where there isn't at least one group
  1165. // with at least one tabbable node in it (that would lead to an error condition that would
  1166. // result in an error being thrown)
  1167. // @type {Array<{
  1168. // container: HTMLElement,
  1169. // tabbableNodes: Array<HTMLElement>, // empty if none
  1170. // focusableNodes: Array<HTMLElement>, // empty if none
  1171. // posTabIndexesFound: boolean,
  1172. // firstTabbableNode: HTMLElement|undefined,
  1173. // lastTabbableNode: HTMLElement|undefined,
  1174. // firstDomTabbableNode: HTMLElement|undefined,
  1175. // lastDomTabbableNode: HTMLElement|undefined,
  1176. // nextTabbableNode: (node: HTMLElement, forward: boolean) => HTMLElement|undefined
  1177. // }>}
  1178. containerGroups: [],
  1179. // same order/length as `containers` list
  1180. // references to objects in `containerGroups`, but only those that actually have
  1181. // tabbable nodes in them
  1182. // NOTE: same order as `containers` and `containerGroups`, but __not necessarily__
  1183. // the same length
  1184. tabbableGroups: [],
  1185. nodeFocusedBeforeActivation: null,
  1186. mostRecentlyFocusedNode: null,
  1187. active: false,
  1188. paused: false,
  1189. // timer ID for when delayInitialFocus is true and initial focus in this trap
  1190. // has been delayed during activation
  1191. delayInitialFocusTimer: void 0,
  1192. // the most recent KeyboardEvent for the configured nav key (typically [SHIFT+]TAB), if any
  1193. recentNavEvent: void 0
  1194. };
  1195. var trap;
  1196. var getOption = function getOption2(configOverrideOptions, optionName, configOptionName) {
  1197. return configOverrideOptions && configOverrideOptions[optionName] !== void 0 ? configOverrideOptions[optionName] : config[configOptionName || optionName];
  1198. };
  1199. var findContainerIndex = function findContainerIndex2(element, event) {
  1200. var composedPath = typeof (event === null || event === void 0 ? void 0 : event.composedPath) === "function" ? event.composedPath() : void 0;
  1201. return state.containerGroups.findIndex(function(_ref) {
  1202. var container = _ref.container, tabbableNodes = _ref.tabbableNodes;
  1203. return container.contains(element) || // fall back to explicit tabbable search which will take into consideration any
  1204. // web components if the `tabbableOptions.getShadowRoot` option was used for
  1205. // the trap, enabling shadow DOM support in tabbable (`Node.contains()` doesn't
  1206. // look inside web components even if open)
  1207. (composedPath === null || composedPath === void 0 ? void 0 : composedPath.includes(container)) || tabbableNodes.find(function(node) {
  1208. return node === element;
  1209. });
  1210. });
  1211. };
  1212. var getNodeForOption = function getNodeForOption2(optionName) {
  1213. var optionValue = config[optionName];
  1214. if (typeof optionValue === "function") {
  1215. for (var _len2 = arguments.length, params = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
  1216. params[_key2 - 1] = arguments[_key2];
  1217. }
  1218. optionValue = optionValue.apply(void 0, params);
  1219. }
  1220. if (optionValue === true) {
  1221. optionValue = void 0;
  1222. }
  1223. if (!optionValue) {
  1224. if (optionValue === void 0 || optionValue === false) {
  1225. return optionValue;
  1226. }
  1227. throw new Error("`".concat(optionName, "` was specified but was not a node, or did not return a node"));
  1228. }
  1229. var node = optionValue;
  1230. if (typeof optionValue === "string") {
  1231. node = doc.querySelector(optionValue);
  1232. if (!node) {
  1233. throw new Error("`".concat(optionName, "` as selector refers to no known node"));
  1234. }
  1235. }
  1236. return node;
  1237. };
  1238. var getInitialFocusNode = function getInitialFocusNode2() {
  1239. var node = getNodeForOption("initialFocus");
  1240. if (node === false) {
  1241. return false;
  1242. }
  1243. if (node === void 0 || !isFocusable(node, config.tabbableOptions)) {
  1244. if (findContainerIndex(doc.activeElement) >= 0) {
  1245. node = doc.activeElement;
  1246. } else {
  1247. var firstTabbableGroup = state.tabbableGroups[0];
  1248. var firstTabbableNode = firstTabbableGroup && firstTabbableGroup.firstTabbableNode;
  1249. node = firstTabbableNode || getNodeForOption("fallbackFocus");
  1250. }
  1251. }
  1252. if (!node) {
  1253. throw new Error("Your focus-trap needs to have at least one focusable element");
  1254. }
  1255. return node;
  1256. };
  1257. var updateTabbableNodes = function updateTabbableNodes2() {
  1258. state.containerGroups = state.containers.map(function(container) {
  1259. var tabbableNodes = tabbable(container, config.tabbableOptions);
  1260. var focusableNodes = focusable(container, config.tabbableOptions);
  1261. var firstTabbableNode = tabbableNodes.length > 0 ? tabbableNodes[0] : void 0;
  1262. var lastTabbableNode = tabbableNodes.length > 0 ? tabbableNodes[tabbableNodes.length - 1] : void 0;
  1263. var firstDomTabbableNode = focusableNodes.find(function(node) {
  1264. return isTabbable(node);
  1265. });
  1266. var lastDomTabbableNode = focusableNodes.slice().reverse().find(function(node) {
  1267. return isTabbable(node);
  1268. });
  1269. var posTabIndexesFound = !!tabbableNodes.find(function(node) {
  1270. return getTabIndex(node) > 0;
  1271. });
  1272. return {
  1273. container,
  1274. tabbableNodes,
  1275. focusableNodes,
  1276. /** True if at least one node with positive `tabindex` was found in this container. */
  1277. posTabIndexesFound,
  1278. /** First tabbable node in container, __tabindex__ order; `undefined` if none. */
  1279. firstTabbableNode,
  1280. /** Last tabbable node in container, __tabindex__ order; `undefined` if none. */
  1281. lastTabbableNode,
  1282. // NOTE: DOM order is NOT NECESSARILY "document position" order, but figuring that out
  1283. // would require more than just https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition
  1284. // because that API doesn't work with Shadow DOM as well as it should (@see
  1285. // https://github.com/whatwg/dom/issues/320) and since this first/last is only needed, so far,
  1286. // to address an edge case related to positive tabindex support, this seems like a much easier,
  1287. // "close enough most of the time" alternative for positive tabindexes which should generally
  1288. // be avoided anyway...
  1289. /** First tabbable node in container, __DOM__ order; `undefined` if none. */
  1290. firstDomTabbableNode,
  1291. /** Last tabbable node in container, __DOM__ order; `undefined` if none. */
  1292. lastDomTabbableNode,
  1293. /**
  1294. * Finds the __tabbable__ node that follows the given node in the specified direction,
  1295. * in this container, if any.
  1296. * @param {HTMLElement} node
  1297. * @param {boolean} [forward] True if going in forward tab order; false if going
  1298. * in reverse.
  1299. * @returns {HTMLElement|undefined} The next tabbable node, if any.
  1300. */
  1301. nextTabbableNode: function nextTabbableNode(node) {
  1302. var forward = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : true;
  1303. var nodeIdx = tabbableNodes.indexOf(node);
  1304. if (nodeIdx < 0) {
  1305. if (forward) {
  1306. return focusableNodes.slice(focusableNodes.indexOf(node) + 1).find(function(el) {
  1307. return isTabbable(el);
  1308. });
  1309. }
  1310. return focusableNodes.slice(0, focusableNodes.indexOf(node)).reverse().find(function(el) {
  1311. return isTabbable(el);
  1312. });
  1313. }
  1314. return tabbableNodes[nodeIdx + (forward ? 1 : -1)];
  1315. }
  1316. };
  1317. });
  1318. state.tabbableGroups = state.containerGroups.filter(function(group) {
  1319. return group.tabbableNodes.length > 0;
  1320. });
  1321. if (state.tabbableGroups.length <= 0 && !getNodeForOption("fallbackFocus")) {
  1322. throw new Error("Your focus-trap must have at least one container with at least one tabbable node in it at all times");
  1323. }
  1324. if (state.containerGroups.find(function(g) {
  1325. return g.posTabIndexesFound;
  1326. }) && state.containerGroups.length > 1) {
  1327. throw new Error("At least one node with a positive tabindex was found in one of your focus-trap's multiple containers. Positive tabindexes are only supported in single-container focus-traps.");
  1328. }
  1329. };
  1330. var getActiveElement = function getActiveElement2(el) {
  1331. var activeElement = el.activeElement;
  1332. if (!activeElement) {
  1333. return;
  1334. }
  1335. if (activeElement.shadowRoot && activeElement.shadowRoot.activeElement !== null) {
  1336. return getActiveElement2(activeElement.shadowRoot);
  1337. }
  1338. return activeElement;
  1339. };
  1340. var tryFocus = function tryFocus2(node) {
  1341. if (node === false) {
  1342. return;
  1343. }
  1344. if (node === getActiveElement(document)) {
  1345. return;
  1346. }
  1347. if (!node || !node.focus) {
  1348. tryFocus2(getInitialFocusNode());
  1349. return;
  1350. }
  1351. node.focus({
  1352. preventScroll: !!config.preventScroll
  1353. });
  1354. state.mostRecentlyFocusedNode = node;
  1355. if (isSelectableInput(node)) {
  1356. node.select();
  1357. }
  1358. };
  1359. var getReturnFocusNode = function getReturnFocusNode2(previousActiveElement) {
  1360. var node = getNodeForOption("setReturnFocus", previousActiveElement);
  1361. return node ? node : node === false ? false : previousActiveElement;
  1362. };
  1363. var findNextNavNode = function findNextNavNode2(_ref2) {
  1364. var target = _ref2.target, event = _ref2.event, _ref2$isBackward = _ref2.isBackward, isBackward = _ref2$isBackward === void 0 ? false : _ref2$isBackward;
  1365. target = target || getActualTarget(event);
  1366. updateTabbableNodes();
  1367. var destinationNode = null;
  1368. if (state.tabbableGroups.length > 0) {
  1369. var containerIndex = findContainerIndex(target, event);
  1370. var containerGroup = containerIndex >= 0 ? state.containerGroups[containerIndex] : void 0;
  1371. if (containerIndex < 0) {
  1372. if (isBackward) {
  1373. destinationNode = state.tabbableGroups[state.tabbableGroups.length - 1].lastTabbableNode;
  1374. } else {
  1375. destinationNode = state.tabbableGroups[0].firstTabbableNode;
  1376. }
  1377. } else if (isBackward) {
  1378. var startOfGroupIndex = findIndex(state.tabbableGroups, function(_ref3) {
  1379. var firstTabbableNode = _ref3.firstTabbableNode;
  1380. return target === firstTabbableNode;
  1381. });
  1382. if (startOfGroupIndex < 0 && (containerGroup.container === target || isFocusable(target, config.tabbableOptions) && !isTabbable(target, config.tabbableOptions) && !containerGroup.nextTabbableNode(target, false))) {
  1383. startOfGroupIndex = containerIndex;
  1384. }
  1385. if (startOfGroupIndex >= 0) {
  1386. var destinationGroupIndex = startOfGroupIndex === 0 ? state.tabbableGroups.length - 1 : startOfGroupIndex - 1;
  1387. var destinationGroup = state.tabbableGroups[destinationGroupIndex];
  1388. destinationNode = getTabIndex(target) >= 0 ? destinationGroup.lastTabbableNode : destinationGroup.lastDomTabbableNode;
  1389. } else if (!isTabEvent(event)) {
  1390. destinationNode = containerGroup.nextTabbableNode(target, false);
  1391. }
  1392. } else {
  1393. var lastOfGroupIndex = findIndex(state.tabbableGroups, function(_ref4) {
  1394. var lastTabbableNode = _ref4.lastTabbableNode;
  1395. return target === lastTabbableNode;
  1396. });
  1397. if (lastOfGroupIndex < 0 && (containerGroup.container === target || isFocusable(target, config.tabbableOptions) && !isTabbable(target, config.tabbableOptions) && !containerGroup.nextTabbableNode(target))) {
  1398. lastOfGroupIndex = containerIndex;
  1399. }
  1400. if (lastOfGroupIndex >= 0) {
  1401. var _destinationGroupIndex = lastOfGroupIndex === state.tabbableGroups.length - 1 ? 0 : lastOfGroupIndex + 1;
  1402. var _destinationGroup = state.tabbableGroups[_destinationGroupIndex];
  1403. destinationNode = getTabIndex(target) >= 0 ? _destinationGroup.firstTabbableNode : _destinationGroup.firstDomTabbableNode;
  1404. } else if (!isTabEvent(event)) {
  1405. destinationNode = containerGroup.nextTabbableNode(target);
  1406. }
  1407. }
  1408. } else {
  1409. destinationNode = getNodeForOption("fallbackFocus");
  1410. }
  1411. return destinationNode;
  1412. };
  1413. var checkPointerDown = function checkPointerDown2(e) {
  1414. var target = getActualTarget(e);
  1415. if (findContainerIndex(target, e) >= 0) {
  1416. return;
  1417. }
  1418. if (valueOrHandler(config.clickOutsideDeactivates, e)) {
  1419. trap.deactivate({
  1420. // NOTE: by setting `returnFocus: false`, deactivate() will do nothing,
  1421. // which will result in the outside click setting focus to the node
  1422. // that was clicked (and if not focusable, to "nothing"); by setting
  1423. // `returnFocus: true`, we'll attempt to re-focus the node originally-focused
  1424. // on activation (or the configured `setReturnFocus` node), whether the
  1425. // outside click was on a focusable node or not
  1426. returnFocus: config.returnFocusOnDeactivate
  1427. });
  1428. return;
  1429. }
  1430. if (valueOrHandler(config.allowOutsideClick, e)) {
  1431. return;
  1432. }
  1433. e.preventDefault();
  1434. };
  1435. var checkFocusIn = function checkFocusIn2(event) {
  1436. var target = getActualTarget(event);
  1437. var targetContained = findContainerIndex(target, event) >= 0;
  1438. if (targetContained || target instanceof Document) {
  1439. if (targetContained) {
  1440. state.mostRecentlyFocusedNode = target;
  1441. }
  1442. } else {
  1443. event.stopImmediatePropagation();
  1444. var nextNode;
  1445. var navAcrossContainers = true;
  1446. if (state.mostRecentlyFocusedNode) {
  1447. if (getTabIndex(state.mostRecentlyFocusedNode) > 0) {
  1448. var mruContainerIdx = findContainerIndex(state.mostRecentlyFocusedNode);
  1449. var tabbableNodes = state.containerGroups[mruContainerIdx].tabbableNodes;
  1450. if (tabbableNodes.length > 0) {
  1451. var mruTabIdx = tabbableNodes.findIndex(function(node) {
  1452. return node === state.mostRecentlyFocusedNode;
  1453. });
  1454. if (mruTabIdx >= 0) {
  1455. if (config.isKeyForward(state.recentNavEvent)) {
  1456. if (mruTabIdx + 1 < tabbableNodes.length) {
  1457. nextNode = tabbableNodes[mruTabIdx + 1];
  1458. navAcrossContainers = false;
  1459. }
  1460. } else {
  1461. if (mruTabIdx - 1 >= 0) {
  1462. nextNode = tabbableNodes[mruTabIdx - 1];
  1463. navAcrossContainers = false;
  1464. }
  1465. }
  1466. }
  1467. }
  1468. } else {
  1469. if (!state.containerGroups.some(function(g) {
  1470. return g.tabbableNodes.some(function(n) {
  1471. return getTabIndex(n) > 0;
  1472. });
  1473. })) {
  1474. navAcrossContainers = false;
  1475. }
  1476. }
  1477. } else {
  1478. navAcrossContainers = false;
  1479. }
  1480. if (navAcrossContainers) {
  1481. nextNode = findNextNavNode({
  1482. // move FROM the MRU node, not event-related node (which will be the node that is
  1483. // outside the trap causing the focus escape we're trying to fix)
  1484. target: state.mostRecentlyFocusedNode,
  1485. isBackward: config.isKeyBackward(state.recentNavEvent)
  1486. });
  1487. }
  1488. if (nextNode) {
  1489. tryFocus(nextNode);
  1490. } else {
  1491. tryFocus(state.mostRecentlyFocusedNode || getInitialFocusNode());
  1492. }
  1493. }
  1494. state.recentNavEvent = void 0;
  1495. };
  1496. var checkKeyNav = function checkKeyNav2(event) {
  1497. var isBackward = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : false;
  1498. state.recentNavEvent = event;
  1499. var destinationNode = findNextNavNode({
  1500. event,
  1501. isBackward
  1502. });
  1503. if (destinationNode) {
  1504. if (isTabEvent(event)) {
  1505. event.preventDefault();
  1506. }
  1507. tryFocus(destinationNode);
  1508. }
  1509. };
  1510. var checkKey = function checkKey2(event) {
  1511. if (isEscapeEvent(event) && valueOrHandler(config.escapeDeactivates, event) !== false) {
  1512. event.preventDefault();
  1513. trap.deactivate();
  1514. return;
  1515. }
  1516. if (config.isKeyForward(event) || config.isKeyBackward(event)) {
  1517. checkKeyNav(event, config.isKeyBackward(event));
  1518. }
  1519. };
  1520. var checkClick = function checkClick2(e) {
  1521. var target = getActualTarget(e);
  1522. if (findContainerIndex(target, e) >= 0) {
  1523. return;
  1524. }
  1525. if (valueOrHandler(config.clickOutsideDeactivates, e)) {
  1526. return;
  1527. }
  1528. if (valueOrHandler(config.allowOutsideClick, e)) {
  1529. return;
  1530. }
  1531. e.preventDefault();
  1532. e.stopImmediatePropagation();
  1533. };
  1534. var addListeners = function addListeners2() {
  1535. if (!state.active) {
  1536. return;
  1537. }
  1538. activeFocusTraps.activateTrap(trapStack, trap);
  1539. state.delayInitialFocusTimer = config.delayInitialFocus ? delay$1(function() {
  1540. tryFocus(getInitialFocusNode());
  1541. }) : tryFocus(getInitialFocusNode());
  1542. doc.addEventListener("focusin", checkFocusIn, true);
  1543. doc.addEventListener("mousedown", checkPointerDown, {
  1544. capture: true,
  1545. passive: false
  1546. });
  1547. doc.addEventListener("touchstart", checkPointerDown, {
  1548. capture: true,
  1549. passive: false
  1550. });
  1551. doc.addEventListener("click", checkClick, {
  1552. capture: true,
  1553. passive: false
  1554. });
  1555. doc.addEventListener("keydown", checkKey, {
  1556. capture: true,
  1557. passive: false
  1558. });
  1559. return trap;
  1560. };
  1561. var removeListeners = function removeListeners2() {
  1562. if (!state.active) {
  1563. return;
  1564. }
  1565. doc.removeEventListener("focusin", checkFocusIn, true);
  1566. doc.removeEventListener("mousedown", checkPointerDown, true);
  1567. doc.removeEventListener("touchstart", checkPointerDown, true);
  1568. doc.removeEventListener("click", checkClick, true);
  1569. doc.removeEventListener("keydown", checkKey, true);
  1570. return trap;
  1571. };
  1572. var checkDomRemoval = function checkDomRemoval2(mutations) {
  1573. var isFocusedNodeRemoved = mutations.some(function(mutation) {
  1574. var removedNodes = Array.from(mutation.removedNodes);
  1575. return removedNodes.some(function(node) {
  1576. return node === state.mostRecentlyFocusedNode;
  1577. });
  1578. });
  1579. if (isFocusedNodeRemoved) {
  1580. tryFocus(getInitialFocusNode());
  1581. }
  1582. };
  1583. var mutationObserver = typeof window !== "undefined" && "MutationObserver" in window ? new MutationObserver(checkDomRemoval) : void 0;
  1584. var updateObservedNodes = function updateObservedNodes2() {
  1585. if (!mutationObserver) {
  1586. return;
  1587. }
  1588. mutationObserver.disconnect();
  1589. if (state.active && !state.paused) {
  1590. state.containers.map(function(container) {
  1591. mutationObserver.observe(container, {
  1592. subtree: true,
  1593. childList: true
  1594. });
  1595. });
  1596. }
  1597. };
  1598. trap = {
  1599. get active() {
  1600. return state.active;
  1601. },
  1602. get paused() {
  1603. return state.paused;
  1604. },
  1605. activate: function activate(activateOptions) {
  1606. if (state.active) {
  1607. return this;
  1608. }
  1609. var onActivate = getOption(activateOptions, "onActivate");
  1610. var onPostActivate = getOption(activateOptions, "onPostActivate");
  1611. var checkCanFocusTrap = getOption(activateOptions, "checkCanFocusTrap");
  1612. if (!checkCanFocusTrap) {
  1613. updateTabbableNodes();
  1614. }
  1615. state.active = true;
  1616. state.paused = false;
  1617. state.nodeFocusedBeforeActivation = doc.activeElement;
  1618. onActivate === null || onActivate === void 0 || onActivate();
  1619. var finishActivation = function finishActivation2() {
  1620. if (checkCanFocusTrap) {
  1621. updateTabbableNodes();
  1622. }
  1623. addListeners();
  1624. updateObservedNodes();
  1625. onPostActivate === null || onPostActivate === void 0 || onPostActivate();
  1626. };
  1627. if (checkCanFocusTrap) {
  1628. checkCanFocusTrap(state.containers.concat()).then(finishActivation, finishActivation);
  1629. return this;
  1630. }
  1631. finishActivation();
  1632. return this;
  1633. },
  1634. deactivate: function deactivate(deactivateOptions) {
  1635. if (!state.active) {
  1636. return this;
  1637. }
  1638. var options = _objectSpread2({
  1639. onDeactivate: config.onDeactivate,
  1640. onPostDeactivate: config.onPostDeactivate,
  1641. checkCanReturnFocus: config.checkCanReturnFocus
  1642. }, deactivateOptions);
  1643. clearTimeout(state.delayInitialFocusTimer);
  1644. state.delayInitialFocusTimer = void 0;
  1645. removeListeners();
  1646. state.active = false;
  1647. state.paused = false;
  1648. updateObservedNodes();
  1649. activeFocusTraps.deactivateTrap(trapStack, trap);
  1650. var onDeactivate = getOption(options, "onDeactivate");
  1651. var onPostDeactivate = getOption(options, "onPostDeactivate");
  1652. var checkCanReturnFocus = getOption(options, "checkCanReturnFocus");
  1653. var returnFocus = getOption(options, "returnFocus", "returnFocusOnDeactivate");
  1654. onDeactivate === null || onDeactivate === void 0 || onDeactivate();
  1655. var finishDeactivation = function finishDeactivation2() {
  1656. delay$1(function() {
  1657. if (returnFocus) {
  1658. tryFocus(getReturnFocusNode(state.nodeFocusedBeforeActivation));
  1659. }
  1660. onPostDeactivate === null || onPostDeactivate === void 0 || onPostDeactivate();
  1661. });
  1662. };
  1663. if (returnFocus && checkCanReturnFocus) {
  1664. checkCanReturnFocus(getReturnFocusNode(state.nodeFocusedBeforeActivation)).then(finishDeactivation, finishDeactivation);
  1665. return this;
  1666. }
  1667. finishDeactivation();
  1668. return this;
  1669. },
  1670. pause: function pause(pauseOptions) {
  1671. if (state.paused || !state.active) {
  1672. return this;
  1673. }
  1674. var onPause = getOption(pauseOptions, "onPause");
  1675. var onPostPause = getOption(pauseOptions, "onPostPause");
  1676. state.paused = true;
  1677. onPause === null || onPause === void 0 || onPause();
  1678. removeListeners();
  1679. updateObservedNodes();
  1680. onPostPause === null || onPostPause === void 0 || onPostPause();
  1681. return this;
  1682. },
  1683. unpause: function unpause(unpauseOptions) {
  1684. if (!state.paused || !state.active) {
  1685. return this;
  1686. }
  1687. var onUnpause = getOption(unpauseOptions, "onUnpause");
  1688. var onPostUnpause = getOption(unpauseOptions, "onPostUnpause");
  1689. state.paused = false;
  1690. onUnpause === null || onUnpause === void 0 || onUnpause();
  1691. updateTabbableNodes();
  1692. addListeners();
  1693. updateObservedNodes();
  1694. onPostUnpause === null || onPostUnpause === void 0 || onPostUnpause();
  1695. return this;
  1696. },
  1697. updateContainerElements: function updateContainerElements(containerElements) {
  1698. var elementsAsArray = [].concat(containerElements).filter(Boolean);
  1699. state.containers = elementsAsArray.map(function(element) {
  1700. return typeof element === "string" ? doc.querySelector(element) : element;
  1701. });
  1702. if (state.active) {
  1703. updateTabbableNodes();
  1704. }
  1705. updateObservedNodes();
  1706. return this;
  1707. }
  1708. };
  1709. trap.updateContainerElements(elements);
  1710. return trap;
  1711. };
  1712. function useFocusTrap(target, options = {}) {
  1713. let trap;
  1714. const { immediate, ...focusTrapOptions } = options;
  1715. const hasFocus = vue.ref(false);
  1716. const isPaused = vue.ref(false);
  1717. const activate = (opts) => trap && trap.activate(opts);
  1718. const deactivate = (opts) => trap && trap.deactivate(opts);
  1719. const pause = () => {
  1720. if (trap) {
  1721. trap.pause();
  1722. isPaused.value = true;
  1723. }
  1724. };
  1725. const unpause = () => {
  1726. if (trap) {
  1727. trap.unpause();
  1728. isPaused.value = false;
  1729. }
  1730. };
  1731. vue.watch(
  1732. () => unrefElement(target),
  1733. (el) => {
  1734. if (!el)
  1735. return;
  1736. trap = createFocusTrap(el, {
  1737. ...focusTrapOptions,
  1738. onActivate() {
  1739. hasFocus.value = true;
  1740. if (options.onActivate)
  1741. options.onActivate();
  1742. },
  1743. onDeactivate() {
  1744. hasFocus.value = false;
  1745. if (options.onDeactivate)
  1746. options.onDeactivate();
  1747. }
  1748. });
  1749. if (immediate)
  1750. activate();
  1751. },
  1752. { flush: "post" }
  1753. );
  1754. tryOnScopeDispose(() => deactivate());
  1755. return {
  1756. hasFocus,
  1757. isPaused,
  1758. activate,
  1759. deactivate,
  1760. pause,
  1761. unpause
  1762. };
  1763. }
  1764. const uo = (e) => (...o) => {
  1765. e && (e == null || e(...o), e = null);
  1766. }, q = () => {
  1767. };
  1768. function oe(e, o, l) {
  1769. return e > l ? l : e < o ? o : e;
  1770. }
  1771. function fe(e, o) {
  1772. var s;
  1773. const l = ((s = $(e, o)) == null ? void 0 : s[0]) || o;
  1774. e.push(l);
  1775. }
  1776. function $(e, o) {
  1777. const l = e.indexOf(o);
  1778. if (l !== -1)
  1779. return e.splice(l, 1);
  1780. }
  1781. const co = {
  1782. /**
  1783. * @description Set `null | false` to disable teleport.
  1784. * @default `'body'`
  1785. * @example
  1786. * ```js
  1787. * teleportTo: '#modals'
  1788. * ```
  1789. */
  1790. teleportTo: {
  1791. type: [String, null, Boolean, Object],
  1792. default: "body"
  1793. },
  1794. /**
  1795. * @description An uniq name for the open/close a modal via vfm.open/vfm.close APIs.
  1796. * @default `undefined`
  1797. * @example Symbol: `Symbol('MyModal')`
  1798. * @example String: `'AUniqString'`
  1799. * @example Number: `300`
  1800. */
  1801. modalId: {
  1802. type: [String, Number, Symbol],
  1803. default: void 0
  1804. },
  1805. /**
  1806. * @description Display the modal or not.
  1807. * @default `undefined`
  1808. * @example
  1809. * ```js
  1810. * const showModal = ref(false)
  1811. * v-model="showModal"
  1812. * ```
  1813. */
  1814. modelValue: {
  1815. type: Boolean,
  1816. default: void 0
  1817. },
  1818. /**
  1819. * @description Render the modal via `if` or `show`.
  1820. * @default `'if'`
  1821. * @example
  1822. * ```js
  1823. * displayDirective: 'if'
  1824. * ```
  1825. * @example
  1826. * ```js
  1827. * displayDirective: 'show'
  1828. * ```
  1829. */
  1830. displayDirective: {
  1831. type: String,
  1832. default: "if",
  1833. validator: (e) => ["if", "show", "visible"].includes(e)
  1834. },
  1835. /**
  1836. * @description Hide the overlay or not.
  1837. * @default `undefined`
  1838. * @example
  1839. * ```js
  1840. * hideOverlay="true"
  1841. * ```
  1842. */
  1843. hideOverlay: {
  1844. type: Boolean,
  1845. default: void 0
  1846. },
  1847. /**
  1848. * @description Customize the overlay behavior.
  1849. */
  1850. overlayBehavior: {
  1851. type: String,
  1852. default: "auto",
  1853. validator: (e) => ["auto", "persist"].includes(e)
  1854. },
  1855. /**
  1856. * @description Customize the overlay transition.
  1857. * @default `undefined`
  1858. */
  1859. overlayTransition: {
  1860. type: [String, Object],
  1861. default: void 0
  1862. },
  1863. /**
  1864. * @description Customize the content transition.
  1865. * @default `undefined`
  1866. */
  1867. contentTransition: {
  1868. type: [String, Object],
  1869. default: void 0
  1870. },
  1871. /**
  1872. * @description Bind class to vfm__overlay.
  1873. * @default `undefined`
  1874. */
  1875. overlayClass: {
  1876. type: void 0,
  1877. default: void 0
  1878. },
  1879. /**
  1880. * @description Bind class to vfm__content.
  1881. * @default `undefined`
  1882. */
  1883. contentClass: {
  1884. type: void 0,
  1885. default: void 0
  1886. },
  1887. /**
  1888. * @description Bind style to vfm__overlay.
  1889. * @default `undefined`
  1890. */
  1891. overlayStyle: {
  1892. type: [String, Object, Array],
  1893. default: void 0
  1894. },
  1895. /**
  1896. * @description Bind style to vfm__content.
  1897. * @default `undefined`
  1898. */
  1899. contentStyle: {
  1900. type: [String, Object, Array],
  1901. default: void 0
  1902. },
  1903. /**
  1904. * @description Is it allow to close the modal by clicking the overlay.
  1905. * @default `true`
  1906. */
  1907. clickToClose: {
  1908. type: Boolean,
  1909. default: true
  1910. },
  1911. /**
  1912. * @description Is it allow to close the modal by keypress `esc`.
  1913. * @default `true`
  1914. */
  1915. escToClose: {
  1916. type: Boolean,
  1917. default: true
  1918. },
  1919. /**
  1920. * @description Is it allow to click outside of the vfm__content when the modal is opened
  1921. * @default `'non-interactive'`
  1922. */
  1923. background: {
  1924. type: String,
  1925. default: "non-interactive",
  1926. validator: (e) => ["interactive", "non-interactive"].includes(e)
  1927. },
  1928. /**
  1929. * @description
  1930. * * Use `{ disabled: true }` to disable the focusTrap.
  1931. * * Checkout the createOptions type here https://github.com/focus-trap/focus-trap for more.
  1932. * @default `{ allowOutsideClick: true }`
  1933. */
  1934. focusTrap: {
  1935. type: [Boolean, Object],
  1936. default: () => ({
  1937. allowOutsideClick: true
  1938. })
  1939. },
  1940. /**
  1941. * @description Lock body scroll or not when the modal is opened.
  1942. * @default `true`
  1943. */
  1944. lockScroll: {
  1945. type: Boolean,
  1946. default: true
  1947. },
  1948. /**
  1949. * @description Creates a padding-right when scroll is locked to prevent the page from jumping
  1950. * @default `true`
  1951. */
  1952. reserveScrollBarGap: {
  1953. type: Boolean,
  1954. default: true
  1955. },
  1956. /**
  1957. * @description Define how to increase the zIndex when there are nested modals
  1958. * @default `({ index }) => 1000 + 2 * index`
  1959. */
  1960. zIndexFn: {
  1961. type: Function,
  1962. default: ({ index: e }) => 1e3 + 2 * e
  1963. },
  1964. /**
  1965. * @description The direction of swiping to close the modal
  1966. * @default `none`
  1967. * @example
  1968. * Set swipeToClose="none" to disable swiping to close
  1969. * ```js
  1970. * swipeToClose="none"
  1971. * ```
  1972. */
  1973. swipeToClose: {
  1974. type: String,
  1975. default: "none",
  1976. validator: (e) => ["none", "up", "right", "down", "left"].includes(e)
  1977. },
  1978. /**
  1979. * @description Threshold for swipe to close
  1980. * @default `0`
  1981. */
  1982. threshold: {
  1983. type: Number,
  1984. default: 0
  1985. },
  1986. /**
  1987. * @description If set `:showSwipeBanner="true"`, only allow clicking `swipe-banner` slot to swipe to close
  1988. * @default `undefined`
  1989. * @example
  1990. * ```js
  1991. * swipeToClose="right"
  1992. * :showSwipeBanner="true"
  1993. * ```
  1994. * ```html
  1995. * <VueFinalModal
  1996. * ...
  1997. * swipeToClose="right"
  1998. * :showSwipeBanner="true"
  1999. * >
  2000. * <template #swipe-banner>
  2001. * <div style="position: absolute; height: 100%; top: 0; left: 0; width: 10px;" />
  2002. * </template>
  2003. * ...modal content
  2004. * </VueFinalModal>
  2005. * ```
  2006. */
  2007. showSwipeBanner: {
  2008. type: Boolean,
  2009. default: void 0
  2010. },
  2011. /**
  2012. * @description When set `:preventNavigationGestures="true"`, there will be two invisible bars for prevent navigation gestures including swiping back/forward on mobile webkit. For example: Safari mobile.
  2013. * @default `undefined`
  2014. * @example
  2015. * Set preventNavigationGestures="true" to prevent Safari navigation gestures including swiping back/forward.
  2016. * ```js
  2017. * :preventNavigationGestures="true"
  2018. * ```
  2019. */
  2020. preventNavigationGestures: {
  2021. type: Boolean,
  2022. default: void 0
  2023. }
  2024. };
  2025. function Oe(e = false) {
  2026. const o = vue.ref(e), l = vue.ref(o.value ? 0 : void 0);
  2027. return [o, l, {
  2028. beforeEnter() {
  2029. l.value = 1;
  2030. },
  2031. afterEnter() {
  2032. l.value = 0;
  2033. },
  2034. beforeLeave() {
  2035. l.value = 3;
  2036. },
  2037. afterLeave() {
  2038. l.value = 2;
  2039. }
  2040. }];
  2041. }
  2042. function fo(e, o) {
  2043. const { modelValueLocal: l, onEntering: s, onEnter: u, onLeaving: c, onLeave: a } = o, n = vue.ref(l.value), [t, r, m] = Oe(n.value), [f, M, S] = Oe(n.value), V = vue.computed(() => typeof e.contentTransition == "string" ? { name: e.contentTransition, appear: true } : { appear: true, ...e.contentTransition }), O = vue.computed(() => typeof e.overlayTransition == "string" ? { name: e.overlayTransition, appear: true } : { appear: true, ...e.overlayTransition }), E = vue.computed(
  2044. () => (e.hideOverlay || M.value === 2) && r.value === 2
  2045. /* Leave */
  2046. );
  2047. vue.watch(
  2048. E,
  2049. (k) => {
  2050. k && (n.value = false);
  2051. }
  2052. ), vue.watch(r, (k) => {
  2053. if (k === 1) {
  2054. if (!n.value)
  2055. return;
  2056. s == null || s();
  2057. } else if (k === 0) {
  2058. if (!n.value)
  2059. return;
  2060. u == null || u();
  2061. } else
  2062. k === 3 ? c == null || c() : k === 2 && (a == null || a());
  2063. });
  2064. async function w() {
  2065. n.value = true, await vue.nextTick(), t.value = true, f.value = true;
  2066. }
  2067. function D() {
  2068. t.value = false, f.value = false;
  2069. }
  2070. return {
  2071. visible: n,
  2072. contentVisible: t,
  2073. contentListeners: m,
  2074. contentTransition: V,
  2075. overlayVisible: f,
  2076. overlayListeners: S,
  2077. overlayTransition: O,
  2078. enterTransition: w,
  2079. leaveTransition: D
  2080. };
  2081. }
  2082. function vo(e, o, l) {
  2083. const { vfmRootEl: s, vfmContentEl: u, visible: c, modelValueLocal: a } = l, n = vue.ref();
  2084. function t() {
  2085. c.value && e.escToClose && (a.value = false);
  2086. }
  2087. function r(f) {
  2088. n.value = f == null ? void 0 : f.target;
  2089. }
  2090. function m() {
  2091. var f;
  2092. n.value === s.value && (e.clickToClose ? a.value = false : ((f = u.value) == null || f.focus(), o("clickOutside")));
  2093. }
  2094. return {
  2095. onEsc: t,
  2096. onMouseupRoot: m,
  2097. onMousedown: r
  2098. };
  2099. }
  2100. function po(e, o, l) {
  2101. let s = false;
  2102. const { open: u, close: c } = l, a = vue.ref(false), n = {
  2103. get value() {
  2104. return a.value;
  2105. },
  2106. set value(r) {
  2107. t(r);
  2108. }
  2109. };
  2110. function t(r) {
  2111. (r ? u() : c()) ? (a.value = r, r !== e.modelValue && o("update:modelValue", r)) : (s = true, o("update:modelValue", !r), vue.nextTick(() => {
  2112. s = false;
  2113. }));
  2114. }
  2115. return vue.watch(() => e.modelValue, (r) => {
  2116. s || (n.value = !!r);
  2117. }), {
  2118. modelValueLocal: n
  2119. };
  2120. }
  2121. function yo(e, o) {
  2122. if (e.focusTrap === false)
  2123. return {
  2124. focus() {
  2125. },
  2126. blur() {
  2127. }
  2128. };
  2129. const { focusEl: l } = o, { hasFocus: s, activate: u, deactivate: c } = useFocusTrap(l, e.focusTrap);
  2130. function a() {
  2131. requestAnimationFrame(() => {
  2132. u();
  2133. });
  2134. }
  2135. function n() {
  2136. s.value && c();
  2137. }
  2138. return { focus: a, blur: n };
  2139. }
  2140. let be = false;
  2141. if (typeof window < "u") {
  2142. const e = {
  2143. get passive() {
  2144. be = true;
  2145. }
  2146. };
  2147. window.addEventListener("testPassive", null, e), window.removeEventListener("testPassive", null, e);
  2148. }
  2149. const He = typeof window < "u" && window.navigator && window.navigator.platform && (/iP(ad|hone|od)/.test(window.navigator.platform) || window.navigator.platform === "MacIntel" && window.navigator.maxTouchPoints > 1);
  2150. let j = [], le = false, ne = 0, je = -1, W, X;
  2151. const ho = (e) => {
  2152. if (!e || e.nodeType !== Node.ELEMENT_NODE)
  2153. return false;
  2154. const o = window.getComputedStyle(e);
  2155. return ["auto", "scroll"].includes(o.overflowY) && e.scrollHeight > e.clientHeight;
  2156. }, mo = (e, o) => !(e.scrollTop === 0 && o < 0 || e.scrollTop + e.clientHeight + o >= e.scrollHeight && o > 0), wo = (e) => {
  2157. const o = [];
  2158. for (; e; ) {
  2159. if (o.push(e), e.classList.contains("vfm"))
  2160. return o;
  2161. e = e.parentElement;
  2162. }
  2163. return o;
  2164. }, bo = (e, o) => {
  2165. let l = false;
  2166. return wo(e).forEach((u) => {
  2167. ho(u) && mo(u, o) && (l = true);
  2168. }), l;
  2169. }, Ne = (e) => j.some(() => bo(e, -ne)), se = (e) => {
  2170. const o = e || window.event;
  2171. return Ne(o.target) || o.touches.length > 1 ? true : (o.preventDefault && o.preventDefault(), false);
  2172. }, To = (e) => {
  2173. if (X === void 0) {
  2174. const o = !!e && e.reserveScrollBarGap === true, l = window.innerWidth - document.documentElement.clientWidth;
  2175. if (o && l > 0) {
  2176. const s = parseInt(getComputedStyle(document.body).getPropertyValue("padding-right"), 10);
  2177. X = document.body.style.paddingRight, document.body.style.paddingRight = `${s + l}px`;
  2178. }
  2179. }
  2180. W === void 0 && (W = document.body.style.overflow, document.body.style.overflow = "hidden");
  2181. }, So = () => {
  2182. X !== void 0 && (document.body.style.paddingRight = X, X = void 0), W !== void 0 && (document.body.style.overflow = W, W = void 0);
  2183. }, Mo = (e) => e ? e.scrollHeight - e.scrollTop <= e.clientHeight : false, go = (e, o) => (ne = e.targetTouches[0].clientY - je, Ne(e.target) ? false : o && o.scrollTop === 0 && ne > 0 || Mo(o) && ne < 0 ? se(e) : (e.stopPropagation(), true)), Co = (e, o) => {
  2184. if (!e) {
  2185. console.error(
  2186. "disableBodyScroll unsuccessful - targetElement must be provided when calling disableBodyScroll on IOS devices."
  2187. );
  2188. return;
  2189. }
  2190. if (j.some((s) => s.targetElement === e))
  2191. return;
  2192. const l = {
  2193. targetElement: e,
  2194. options: o || {}
  2195. };
  2196. j = [...j, l], He ? (e.ontouchstart = (s) => {
  2197. s.targetTouches.length === 1 && (je = s.targetTouches[0].clientY);
  2198. }, e.ontouchmove = (s) => {
  2199. s.targetTouches.length === 1 && go(s, e);
  2200. }, le || (document.addEventListener("touchmove", se, be ? { passive: false } : void 0), le = true)) : To(o);
  2201. }, ko = (e) => {
  2202. if (!e) {
  2203. console.error(
  2204. "enableBodyScroll unsuccessful - targetElement must be provided when calling enableBodyScroll on IOS devices."
  2205. );
  2206. return;
  2207. }
  2208. j = j.filter((o) => o.targetElement !== e), He ? (e.ontouchstart = null, e.ontouchmove = null, le && j.length === 0 && (document.removeEventListener("touchmove", se, be ? { passive: false } : void 0), le = false)) : j.length || So();
  2209. };
  2210. function Vo(e, o) {
  2211. const { lockScrollEl: l, modelValueLocal: s } = o;
  2212. let u;
  2213. vue.watch(l, (n) => {
  2214. n && (u = n);
  2215. }, { immediate: true }), vue.watch(() => e.lockScroll, (n) => {
  2216. n ? a() : c();
  2217. }), vue.onBeforeUnmount(() => {
  2218. c();
  2219. });
  2220. function c() {
  2221. u && ko(u);
  2222. }
  2223. function a() {
  2224. s.value && e.lockScroll && u && Co(u, {
  2225. reserveScrollBarGap: e.reserveScrollBarGap,
  2226. allowTouchMove: (n) => {
  2227. for (; n && n !== document.body; ) {
  2228. if (n.getAttribute("vfm-scroll-lock-ignore") !== null)
  2229. return true;
  2230. n = n.parentElement;
  2231. }
  2232. return false;
  2233. }
  2234. });
  2235. }
  2236. return {
  2237. enableBodyScroll: c,
  2238. disableBodyScroll: a
  2239. };
  2240. }
  2241. function Eo(e) {
  2242. const o = vue.ref();
  2243. function l(u) {
  2244. var c;
  2245. o.value = (c = e.zIndexFn) == null ? void 0 : c.call(e, { index: u <= -1 ? 0 : u });
  2246. }
  2247. function s() {
  2248. o.value = void 0;
  2249. }
  2250. return {
  2251. zIndex: o,
  2252. refreshZIndex: l,
  2253. resetZIndex: s
  2254. };
  2255. }
  2256. const ve = {
  2257. beforeMount(e, { value: o }, { transition: l }) {
  2258. e._vov = e.style.visibility === "hidden" ? "" : e.style.visibility, l && o ? l.beforeEnter(e) : G(e, o);
  2259. },
  2260. mounted(e, { value: o }, { transition: l }) {
  2261. l && o && l.enter(e);
  2262. },
  2263. updated(e, { value: o, oldValue: l }, { transition: s }) {
  2264. !o != !l && (s ? o ? (s.beforeEnter(e), G(e, true), s.enter(e)) : s.leave(e, () => {
  2265. G(e, false);
  2266. }) : G(e, o));
  2267. },
  2268. beforeUnmount(e, { value: o }) {
  2269. G(e, o);
  2270. }
  2271. };
  2272. function G(e, o) {
  2273. e.style.visibility = o ? e._vov : "hidden";
  2274. }
  2275. const De = (e) => {
  2276. if (e instanceof MouseEvent) {
  2277. const { clientX: o, clientY: l } = e;
  2278. return { x: o, y: l };
  2279. } else {
  2280. const { clientX: o, clientY: l } = e.targetTouches[0];
  2281. return { x: o, y: l };
  2282. }
  2283. };
  2284. function Bo(e) {
  2285. if (!e)
  2286. return false;
  2287. let o = false;
  2288. const l = {
  2289. get passive() {
  2290. return o = true, false;
  2291. }
  2292. };
  2293. return e.addEventListener("x", q, l), e.removeEventListener("x", q), o;
  2294. }
  2295. function Oo(e, {
  2296. threshold: o = 0,
  2297. onSwipeStart: l,
  2298. onSwipe: s,
  2299. onSwipeEnd: u,
  2300. passive: c = true
  2301. }) {
  2302. const a = vue.reactive({ x: 0, y: 0 }), n = vue.reactive({ x: 0, y: 0 }), t = vue.computed(() => a.x - n.x), r = vue.computed(() => a.y - n.y), { max: m, abs: f } = Math, M = vue.computed(
  2303. () => m(f(t.value), f(r.value)) >= o
  2304. ), S = vue.ref(false), V = vue.computed(() => M.value ? f(t.value) > f(r.value) ? t.value > 0 ? "left" : "right" : r.value > 0 ? "up" : "down" : "none"), O = (p, h) => {
  2305. a.x = p, a.y = h;
  2306. }, E = (p, h) => {
  2307. n.x = p, n.y = h;
  2308. };
  2309. let w, D;
  2310. function k(p) {
  2311. w.capture && !w.passive && p.preventDefault();
  2312. const { x: h, y: R } = De(p);
  2313. O(h, R), E(h, R), l == null || l(p), D = [
  2314. useEventListener(e, "mousemove", P, w),
  2315. useEventListener(e, "touchmove", P, w),
  2316. useEventListener(e, "mouseup", i, w),
  2317. useEventListener(e, "touchend", i, w),
  2318. useEventListener(e, "touchcancel", i, w)
  2319. ];
  2320. }
  2321. function P(p) {
  2322. const { x: h, y: R } = De(p);
  2323. E(h, R), !S.value && M.value && (S.value = true), S.value && (s == null || s(p));
  2324. }
  2325. function i(p) {
  2326. S.value && (u == null || u(p, V.value)), S.value = false, D.forEach((h) => h());
  2327. }
  2328. let b = [];
  2329. return vue.onMounted(() => {
  2330. const p = Bo(window == null ? void 0 : window.document);
  2331. c ? w = p ? { passive: true } : { capture: false } : w = p ? { passive: false, capture: true } : { capture: true }, b = [
  2332. useEventListener(e, "mousedown", k, w),
  2333. useEventListener(e, "touchstart", k, w)
  2334. ];
  2335. }), {
  2336. isSwiping: S,
  2337. direction: V,
  2338. coordsStart: a,
  2339. coordsEnd: n,
  2340. lengthX: t,
  2341. lengthY: r,
  2342. stop: () => {
  2343. b.forEach((p) => p()), D.forEach((p) => p());
  2344. }
  2345. };
  2346. }
  2347. function Do(e, o) {
  2348. const { vfmContentEl: l, modelValueLocal: s } = o, u = 0.1, c = 300, a = vue.ref(), n = vue.computed(() => {
  2349. if (!(e.swipeToClose === void 0 || e.swipeToClose === "none"))
  2350. return e.showSwipeBanner ? a.value : l.value;
  2351. }), t = vue.ref(0), r = vue.ref(true);
  2352. let m = q, f = true, M, S = false;
  2353. const { lengthX: V, lengthY: O, direction: E, isSwiping: w } = Oo(n, {
  2354. threshold: e.threshold,
  2355. onSwipeStart(i) {
  2356. m = useEventListener(document, "selectionchange", () => {
  2357. var b;
  2358. r.value = (b = window.getSelection()) == null ? void 0 : b.isCollapsed;
  2359. }), M = (/* @__PURE__ */ new Date()).getTime(), S = P(i == null ? void 0 : i.target);
  2360. },
  2361. onSwipe() {
  2362. var i, b, L, p;
  2363. if (S && r.value && E.value === e.swipeToClose) {
  2364. if (E.value === "up") {
  2365. const h = oe(Math.abs(O.value || 0), 0, ((i = n.value) == null ? void 0 : i.offsetHeight) || 0) - (e.threshold || 0);
  2366. t.value = h;
  2367. } else if (E.value === "down") {
  2368. const h = oe(Math.abs(O.value || 0), 0, ((b = n.value) == null ? void 0 : b.offsetHeight) || 0) - (e.threshold || 0);
  2369. t.value = -h;
  2370. } else if (E.value === "right") {
  2371. const h = oe(Math.abs(V.value || 0), 0, ((L = n.value) == null ? void 0 : L.offsetWidth) || 0) - (e.threshold || 0);
  2372. t.value = -h;
  2373. } else if (E.value === "left") {
  2374. const h = oe(Math.abs(V.value || 0), 0, ((p = n.value) == null ? void 0 : p.offsetWidth) || 0) - (e.threshold || 0);
  2375. t.value = h;
  2376. }
  2377. }
  2378. },
  2379. onSwipeEnd(i, b) {
  2380. if (m(), !r.value) {
  2381. r.value = true;
  2382. return;
  2383. }
  2384. const L = (/* @__PURE__ */ new Date()).getTime(), p = b === e.swipeToClose, h = (() => {
  2385. var J, Q;
  2386. if (b === "up" || b === "down")
  2387. return Math.abs((O == null ? void 0 : O.value) || 0) > u * (((J = n.value) == null ? void 0 : J.offsetHeight) || 0);
  2388. if (b === "left" || b === "right")
  2389. return Math.abs((V == null ? void 0 : V.value) || 0) > u * (((Q = n.value) == null ? void 0 : Q.offsetWidth) || 0);
  2390. })(), R = L - M <= c;
  2391. if (f && S && p && (h || R)) {
  2392. s.value = false;
  2393. return;
  2394. }
  2395. t.value = 0;
  2396. }
  2397. }), D = vue.computed(() => {
  2398. if (e.swipeToClose === "none")
  2399. return;
  2400. const i = (() => {
  2401. switch (e.swipeToClose) {
  2402. case "up":
  2403. case "down":
  2404. return "translateY";
  2405. case "left":
  2406. case "right":
  2407. return "translateX";
  2408. }
  2409. })();
  2410. return {
  2411. class: { "vfm-bounce-back": !w.value },
  2412. style: { transform: `${i}(${-t.value}px)` }
  2413. };
  2414. });
  2415. vue.watch(
  2416. () => r.value,
  2417. (i) => {
  2418. i || (t.value = 0);
  2419. }
  2420. ), vue.watch(
  2421. () => s.value,
  2422. (i) => {
  2423. i && (t.value = 0);
  2424. }
  2425. ), vue.watch(
  2426. () => t.value,
  2427. (i, b) => {
  2428. switch (e.swipeToClose) {
  2429. case "down":
  2430. case "right":
  2431. f = i < b;
  2432. break;
  2433. case "up":
  2434. case "left":
  2435. f = i > b;
  2436. break;
  2437. }
  2438. }
  2439. );
  2440. function k(i) {
  2441. e.preventNavigationGestures && i.preventDefault();
  2442. }
  2443. function P(i) {
  2444. const b = i == null ? void 0 : i.tagName;
  2445. if (!b || ["INPUT", "TEXTAREA"].includes(b))
  2446. return false;
  2447. const L = (() => {
  2448. switch (e.swipeToClose) {
  2449. case "up":
  2450. return (i == null ? void 0 : i.scrollTop) + (i == null ? void 0 : i.clientHeight) === (i == null ? void 0 : i.scrollHeight);
  2451. case "left":
  2452. return (i == null ? void 0 : i.scrollLeft) + (i == null ? void 0 : i.clientWidth) === (i == null ? void 0 : i.scrollWidth);
  2453. case "down":
  2454. return (i == null ? void 0 : i.scrollTop) === 0;
  2455. case "right":
  2456. return (i == null ? void 0 : i.scrollLeft) === 0;
  2457. default:
  2458. return false;
  2459. }
  2460. })();
  2461. return i === n.value ? L : L && P(i == null ? void 0 : i.parentElement);
  2462. }
  2463. return {
  2464. vfmContentEl: l,
  2465. swipeBannerEl: a,
  2466. bindSwipe: D,
  2467. onTouchStartSwipeBanner: k
  2468. };
  2469. }
  2470. const Ye = Symbol("vfm");
  2471. let H;
  2472. const Lo = (e) => H = e, Po = {
  2473. install: q,
  2474. modals: [],
  2475. openedModals: [],
  2476. openedModalOverlays: [],
  2477. dynamicModals: [],
  2478. modalsContainers: vue.ref([]),
  2479. get: () => {
  2480. },
  2481. toggle: () => {
  2482. },
  2483. open: () => {
  2484. },
  2485. close: () => {
  2486. },
  2487. closeAll: () => Promise.allSettled([])
  2488. }, Ao = () => vue.getCurrentInstance() && vue.inject(Ye, Po) || H;
  2489. function zo() {
  2490. const e = vue.shallowReactive([]), o = vue.shallowReactive([]), l = vue.shallowReactive([]), s = vue.shallowReactive([]), u = vue.ref([]), c = vue.markRaw({
  2491. install(a) {
  2492. a.provide(Ye, c), a.config.globalProperties.$vfm = c;
  2493. },
  2494. modals: e,
  2495. openedModals: o,
  2496. openedModalOverlays: l,
  2497. dynamicModals: s,
  2498. modalsContainers: u,
  2499. get(a) {
  2500. return e.find((n) => {
  2501. var t, r;
  2502. return ((r = (t = Z(n)) == null ? void 0 : t.value.modalId) == null ? void 0 : r.value) === a;
  2503. });
  2504. },
  2505. toggle(a, n) {
  2506. var r;
  2507. const t = c.get(a);
  2508. return (r = Z(t)) == null ? void 0 : r.value.toggle(n);
  2509. },
  2510. open(a) {
  2511. return c.toggle(a, true);
  2512. },
  2513. close(a) {
  2514. return c.toggle(a, false);
  2515. },
  2516. closeAll() {
  2517. return Promise.allSettled(
  2518. o.reduce((a, n) => {
  2519. const t = Z(n), r = t == null ? void 0 : t.value.toggle(false);
  2520. return r && a.push(r), a;
  2521. }, [])
  2522. );
  2523. }
  2524. });
  2525. return Lo(c), c;
  2526. }
  2527. function Z(e) {
  2528. var o;
  2529. return (o = e == null ? void 0 : e.exposed) == null ? void 0 : o.modalExposed;
  2530. }
  2531. const Io = vue.defineComponent({ inheritAttrs: false }), Ro = /* @__PURE__ */ vue.defineComponent({
  2532. ...Io,
  2533. __name: "VueFinalModal",
  2534. props: co,
  2535. emits: ["update:modelValue", "beforeOpen", "opened", "beforeClose", "closed", "clickOutside"],
  2536. setup(e, { expose: o, emit: l }) {
  2537. const s = e, u = l, c = vue.useAttrs(), a = vue.getCurrentInstance(), { modals: n, openedModals: t, openedModalOverlays: r } = K(), m = vue.ref(), f = vue.ref(), { focus: M, blur: S } = yo(s, { focusEl: m }), { zIndex: V, refreshZIndex: O, resetZIndex: E } = Eo(s), { modelValueLocal: w } = po(s, u, { open: We, close: Xe }), { enableBodyScroll: D, disableBodyScroll: k } = Vo(s, {
  2538. lockScrollEl: m,
  2539. modelValueLocal: w
  2540. });
  2541. let P = q;
  2542. const {
  2543. visible: i,
  2544. contentVisible: b,
  2545. contentListeners: L,
  2546. contentTransition: p,
  2547. overlayVisible: h,
  2548. overlayListeners: R,
  2549. overlayTransition: J,
  2550. enterTransition: Q,
  2551. leaveTransition: xe
  2552. } = fo(s, {
  2553. modelValueLocal: w,
  2554. onEntering() {
  2555. vue.nextTick(() => {
  2556. k(), M();
  2557. });
  2558. },
  2559. onEnter() {
  2560. u("opened"), P("opened");
  2561. },
  2562. onLeave() {
  2563. $(t, a), E(), D(), u("closed"), P("closed");
  2564. }
  2565. }), { onEsc: ze, onMouseupRoot: Ge, onMousedown: Te } = vo(s, u, { vfmRootEl: m, vfmContentEl: f, visible: i, modelValueLocal: w }), {
  2566. swipeBannerEl: $e,
  2567. bindSwipe: Ue,
  2568. onTouchStartSwipeBanner: Se
  2569. } = Do(s, { vfmContentEl: f, modelValueLocal: w }), Me = vue.computed(() => a ? t.indexOf(a) : -1);
  2570. vue.watch([() => s.zIndexFn, Me], () => {
  2571. i.value && O(Me.value);
  2572. }), vue.onMounted(() => {
  2573. fe(n, a);
  2574. }), s.modelValue && (w.value = true);
  2575. function We() {
  2576. let d = false;
  2577. return u("beforeOpen", { stop: () => d = true }), d ? false : (fe(t, a), fe(r, a), ie(), Q(), true);
  2578. }
  2579. function Xe() {
  2580. let d = false;
  2581. return u("beforeClose", { stop: () => d = true }), d ? false : ($(r, a), ie(), S(), xe(), true);
  2582. }
  2583. function Ze() {
  2584. w.value = false;
  2585. }
  2586. vue.onBeforeUnmount(() => {
  2587. D(), $(n, a), $(t, a), S(), ie();
  2588. });
  2589. async function ie() {
  2590. await vue.nextTick();
  2591. const d = r.filter((y) => {
  2592. var A;
  2593. const T = Z(y);
  2594. return (T == null ? void 0 : T.value.overlayBehavior.value) === "auto" && !((A = T == null ? void 0 : T.value.hideOverlay) != null && A.value);
  2595. });
  2596. d.forEach((y, T) => {
  2597. const A = Z(y);
  2598. A != null && A.value && (A.value.overlayVisible.value = T === d.length - 1);
  2599. });
  2600. }
  2601. const Ke = vue.toRef(() => s.modalId), ge = vue.toRef(() => s.hideOverlay), qe = vue.toRef(() => s.overlayBehavior), Je = vue.computed(() => ({
  2602. modalId: Ke,
  2603. hideOverlay: ge,
  2604. overlayBehavior: qe,
  2605. overlayVisible: h,
  2606. toggle(d) {
  2607. return new Promise((y) => {
  2608. P = uo((A) => y(A));
  2609. const T = typeof d == "boolean" ? d : !w.value;
  2610. w.value = T;
  2611. });
  2612. }
  2613. }));
  2614. return o({
  2615. modalExposed: Je
  2616. }), (d, y) => (vue.openBlock(), vue.createBlock(vue.Teleport, {
  2617. to: d.teleportTo ? d.teleportTo : void 0,
  2618. disabled: !d.teleportTo
  2619. }, [
  2620. d.displayDirective !== "if" || vue.unref(i) ? vue.withDirectives((vue.openBlock(), vue.createElementBlock("div", vue.mergeProps({ key: 0 }, vue.unref(c), {
  2621. ref_key: "vfmRootEl",
  2622. ref: m,
  2623. class: ["vfm vfm--fixed vfm--inset", { "vfm--prevent-none": d.background === "interactive" }],
  2624. style: { zIndex: vue.unref(V) },
  2625. role: "dialog",
  2626. "aria-modal": "true",
  2627. onKeydown: y[7] || (y[7] = vue.withKeys(() => vue.unref(ze)(), ["esc"])),
  2628. onMouseup: y[8] || (y[8] = vue.withModifiers(() => vue.unref(Ge)(), ["self"])),
  2629. onMousedown: y[9] || (y[9] = vue.withModifiers((T) => vue.unref(Te)(T), ["self"]))
  2630. }), [
  2631. ge.value ? vue.createCommentVNode("", true) : (vue.openBlock(), vue.createBlock(vue.Transition, vue.mergeProps({ key: 0 }, vue.unref(J), vue.toHandlers(vue.unref(R))), {
  2632. default: vue.withCtx(() => [
  2633. d.displayDirective !== "if" || vue.unref(h) ? vue.withDirectives((vue.openBlock(), vue.createElementBlock("div", {
  2634. key: 0,
  2635. class: vue.normalizeClass(["vfm__overlay vfm--overlay vfm--absolute vfm--inset vfm--prevent-none", d.overlayClass]),
  2636. style: vue.normalizeStyle(d.overlayStyle),
  2637. "aria-hidden": "true"
  2638. }, null, 6)), [
  2639. [vue.vShow, d.displayDirective !== "show" || vue.unref(h)],
  2640. [vue.unref(ve), d.displayDirective !== "visible" || vue.unref(h)]
  2641. ]) : vue.createCommentVNode("", true)
  2642. ]),
  2643. _: 1
  2644. }, 16)),
  2645. vue.createVNode(vue.Transition, vue.mergeProps(vue.unref(p), vue.toHandlers(vue.unref(L))), {
  2646. default: vue.withCtx(() => [
  2647. d.displayDirective !== "if" || vue.unref(b) ? vue.withDirectives((vue.openBlock(), vue.createElementBlock("div", vue.mergeProps({
  2648. key: 0,
  2649. ref_key: "vfmContentEl",
  2650. ref: f,
  2651. class: ["vfm__content vfm--outline-none", [d.contentClass, { "vfm--prevent-auto": d.background === "interactive" }]],
  2652. style: d.contentStyle,
  2653. tabindex: "0"
  2654. }, vue.unref(Ue), {
  2655. onMousedown: y[6] || (y[6] = () => vue.unref(Te)())
  2656. }), [
  2657. vue.renderSlot(d.$slots, "default", vue.normalizeProps(vue.guardReactiveProps({ close: Ze }))),
  2658. d.showSwipeBanner ? (vue.openBlock(), vue.createElementBlock("div", {
  2659. key: 0,
  2660. ref_key: "swipeBannerEl",
  2661. ref: $e,
  2662. class: "vfm-swipe-banner-container",
  2663. onTouchstart: y[2] || (y[2] = (T) => vue.unref(Se)(T))
  2664. }, [
  2665. vue.renderSlot(d.$slots, "swipe-banner", {}, () => [
  2666. vue.createElementVNode("div", {
  2667. class: "vfm-swipe-banner-back",
  2668. onTouchstart: y[0] || (y[0] = (T) => d.swipeToClose === "left" && T.preventDefault())
  2669. }, null, 32),
  2670. vue.createElementVNode("div", {
  2671. class: "vfm-swipe-banner-forward",
  2672. onTouchstart: y[1] || (y[1] = (T) => d.swipeToClose === "right" && T.preventDefault())
  2673. }, null, 32)
  2674. ])
  2675. ], 544)) : !d.showSwipeBanner && d.preventNavigationGestures ? (vue.openBlock(), vue.createElementBlock("div", {
  2676. key: 1,
  2677. class: "vfm-swipe-banner-container",
  2678. onTouchstart: y[5] || (y[5] = (T) => vue.unref(Se)(T))
  2679. }, [
  2680. vue.createElementVNode("div", {
  2681. class: "vfm-swipe-banner-back",
  2682. onTouchstart: y[3] || (y[3] = (T) => d.swipeToClose === "left" && T.preventDefault())
  2683. }, null, 32),
  2684. vue.createElementVNode("div", {
  2685. class: "vfm-swipe-banner-forward",
  2686. onTouchstart: y[4] || (y[4] = (T) => d.swipeToClose === "right" && T.preventDefault())
  2687. }, null, 32)
  2688. ], 32)) : vue.createCommentVNode("", true)
  2689. ], 16)), [
  2690. [vue.vShow, d.displayDirective !== "show" || vue.unref(b)],
  2691. [vue.unref(ve), d.displayDirective !== "visible" || vue.unref(b)]
  2692. ]) : vue.createCommentVNode("", true)
  2693. ]),
  2694. _: 3
  2695. }, 16)
  2696. ], 16)), [
  2697. [vue.vShow, d.displayDirective !== "show" || vue.unref(i)],
  2698. [vue.unref(ve), d.displayDirective !== "visible" || vue.unref(i)]
  2699. ]) : vue.createCommentVNode("", true)
  2700. ], 8, ["to", "disabled"]));
  2701. }
  2702. });
  2703. function K() {
  2704. const e = Ao();
  2705. if (!e)
  2706. throw new Error(
  2707. `[Vue Final Modal]: getActiveVfm was called with no active Vfm. Did you forget to install vfm?
  2708. const vfm = createVfm()
  2709. app.use(vfm)
  2710. This will fail in production.`
  2711. );
  2712. return e;
  2713. }
  2714. var __defProp2 = Object.defineProperty;
  2715. var __getOwnPropSymbols = Object.getOwnPropertySymbols;
  2716. var __hasOwnProp = Object.prototype.hasOwnProperty;
  2717. var __propIsEnum = Object.prototype.propertyIsEnumerable;
  2718. var __defNormalProp2 = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
  2719. var __spreadValues = (a, b) => {
  2720. for (var prop in b || (b = {}))
  2721. if (__hasOwnProp.call(b, prop))
  2722. __defNormalProp2(a, prop, b[prop]);
  2723. if (__getOwnPropSymbols)
  2724. for (var prop of __getOwnPropSymbols(b)) {
  2725. if (__propIsEnum.call(b, prop))
  2726. __defNormalProp2(a, prop, b[prop]);
  2727. }
  2728. return a;
  2729. };
  2730. var isFunction = (value) => typeof value === "function";
  2731. var isString = (value) => typeof value === "string";
  2732. var isNonEmptyString = (value) => isString(value) && value.trim().length > 0;
  2733. var isNumber = (value) => typeof value === "number";
  2734. var isUndefined = (value) => typeof value === "undefined";
  2735. var isObject$1 = (value) => typeof value === "object" && value !== null;
  2736. var isJSX = (obj) => hasProp(obj, "tag") && isNonEmptyString(obj.tag);
  2737. var isTouchEvent = (event) => window.TouchEvent && event instanceof TouchEvent;
  2738. var isToastComponent = (obj) => hasProp(obj, "component") && isToastContent(obj.component);
  2739. var isVueComponent = (c) => isFunction(c) || isObject$1(c);
  2740. var isToastContent = (obj) => !isUndefined(obj) && (isString(obj) || isVueComponent(obj) || isToastComponent(obj));
  2741. var isDOMRect = (obj) => isObject$1(obj) && ["height", "width", "right", "left", "top", "bottom"].every((p) => isNumber(obj[p]));
  2742. var hasProp = (obj, propKey) => (isObject$1(obj) || isFunction(obj)) && propKey in obj;
  2743. var getId = /* @__PURE__ */ ((i) => () => i++)(0);
  2744. function getX(event) {
  2745. return isTouchEvent(event) ? event.targetTouches[0].clientX : event.clientX;
  2746. }
  2747. function getY(event) {
  2748. return isTouchEvent(event) ? event.targetTouches[0].clientY : event.clientY;
  2749. }
  2750. var removeElement = (el) => {
  2751. if (!isUndefined(el.remove)) {
  2752. el.remove();
  2753. } else if (el.parentNode) {
  2754. el.parentNode.removeChild(el);
  2755. }
  2756. };
  2757. var getVueComponentFromObj = (obj) => {
  2758. if (isToastComponent(obj)) {
  2759. return getVueComponentFromObj(obj.component);
  2760. }
  2761. if (isJSX(obj)) {
  2762. return vue.defineComponent({
  2763. render() {
  2764. return obj;
  2765. }
  2766. });
  2767. }
  2768. return typeof obj === "string" ? obj : vue.toRaw(vue.unref(obj));
  2769. };
  2770. var normalizeToastComponent = (obj) => {
  2771. if (typeof obj === "string") {
  2772. return obj;
  2773. }
  2774. const props = hasProp(obj, "props") && isObject$1(obj.props) ? obj.props : {};
  2775. const listeners = hasProp(obj, "listeners") && isObject$1(obj.listeners) ? obj.listeners : {};
  2776. return { component: getVueComponentFromObj(obj), props, listeners };
  2777. };
  2778. var isBrowser = () => typeof window !== "undefined";
  2779. var EventBus = class {
  2780. constructor() {
  2781. this.allHandlers = {};
  2782. }
  2783. getHandlers(eventType) {
  2784. return this.allHandlers[eventType] || [];
  2785. }
  2786. on(eventType, handler) {
  2787. const handlers2 = this.getHandlers(eventType);
  2788. handlers2.push(handler);
  2789. this.allHandlers[eventType] = handlers2;
  2790. }
  2791. off(eventType, handler) {
  2792. const handlers2 = this.getHandlers(eventType);
  2793. handlers2.splice(handlers2.indexOf(handler) >>> 0, 1);
  2794. }
  2795. emit(eventType, event) {
  2796. const handlers2 = this.getHandlers(eventType);
  2797. handlers2.forEach((handler) => handler(event));
  2798. }
  2799. };
  2800. var isEventBusInterface = (e) => ["on", "off", "emit"].every((f) => hasProp(e, f) && isFunction(e[f]));
  2801. var TYPE;
  2802. (function(TYPE2) {
  2803. TYPE2["SUCCESS"] = "success";
  2804. TYPE2["ERROR"] = "error";
  2805. TYPE2["WARNING"] = "warning";
  2806. TYPE2["INFO"] = "info";
  2807. TYPE2["DEFAULT"] = "default";
  2808. })(TYPE || (TYPE = {}));
  2809. var POSITION;
  2810. (function(POSITION2) {
  2811. POSITION2["TOP_LEFT"] = "top-left";
  2812. POSITION2["TOP_CENTER"] = "top-center";
  2813. POSITION2["TOP_RIGHT"] = "top-right";
  2814. POSITION2["BOTTOM_LEFT"] = "bottom-left";
  2815. POSITION2["BOTTOM_CENTER"] = "bottom-center";
  2816. POSITION2["BOTTOM_RIGHT"] = "bottom-right";
  2817. })(POSITION || (POSITION = {}));
  2818. var EVENTS;
  2819. (function(EVENTS2) {
  2820. EVENTS2["ADD"] = "add";
  2821. EVENTS2["DISMISS"] = "dismiss";
  2822. EVENTS2["UPDATE"] = "update";
  2823. EVENTS2["CLEAR"] = "clear";
  2824. EVENTS2["UPDATE_DEFAULTS"] = "update_defaults";
  2825. })(EVENTS || (EVENTS = {}));
  2826. var VT_NAMESPACE = "Vue-Toastification";
  2827. var COMMON = {
  2828. type: {
  2829. type: String,
  2830. default: TYPE.DEFAULT
  2831. },
  2832. classNames: {
  2833. type: [String, Array],
  2834. default: () => []
  2835. },
  2836. trueBoolean: {
  2837. type: Boolean,
  2838. default: true
  2839. }
  2840. };
  2841. var ICON = {
  2842. type: COMMON.type,
  2843. customIcon: {
  2844. type: [String, Boolean, Object, Function],
  2845. default: true
  2846. }
  2847. };
  2848. var CLOSE_BUTTON = {
  2849. component: {
  2850. type: [String, Object, Function, Boolean],
  2851. default: "button"
  2852. },
  2853. classNames: COMMON.classNames,
  2854. showOnHover: {
  2855. type: Boolean,
  2856. default: false
  2857. },
  2858. ariaLabel: {
  2859. type: String,
  2860. default: "close"
  2861. }
  2862. };
  2863. var PROGRESS_BAR = {
  2864. timeout: {
  2865. type: [Number, Boolean],
  2866. default: 5e3
  2867. },
  2868. hideProgressBar: {
  2869. type: Boolean,
  2870. default: false
  2871. },
  2872. isRunning: {
  2873. type: Boolean,
  2874. default: false
  2875. }
  2876. };
  2877. var TRANSITION = {
  2878. transition: {
  2879. type: [Object, String],
  2880. default: `${VT_NAMESPACE}__bounce`
  2881. }
  2882. };
  2883. var CORE_TOAST = {
  2884. position: {
  2885. type: String,
  2886. default: POSITION.TOP_RIGHT
  2887. },
  2888. draggable: COMMON.trueBoolean,
  2889. draggablePercent: {
  2890. type: Number,
  2891. default: 0.6
  2892. },
  2893. pauseOnFocusLoss: COMMON.trueBoolean,
  2894. pauseOnHover: COMMON.trueBoolean,
  2895. closeOnClick: COMMON.trueBoolean,
  2896. timeout: PROGRESS_BAR.timeout,
  2897. hideProgressBar: PROGRESS_BAR.hideProgressBar,
  2898. toastClassName: COMMON.classNames,
  2899. bodyClassName: COMMON.classNames,
  2900. icon: ICON.customIcon,
  2901. closeButton: CLOSE_BUTTON.component,
  2902. closeButtonClassName: CLOSE_BUTTON.classNames,
  2903. showCloseButtonOnHover: CLOSE_BUTTON.showOnHover,
  2904. accessibility: {
  2905. type: Object,
  2906. default: () => ({
  2907. toastRole: "alert",
  2908. closeButtonLabel: "close"
  2909. })
  2910. },
  2911. rtl: {
  2912. type: Boolean,
  2913. default: false
  2914. },
  2915. eventBus: {
  2916. type: Object,
  2917. required: false,
  2918. default: () => new EventBus()
  2919. }
  2920. };
  2921. var TOAST = {
  2922. id: {
  2923. type: [String, Number],
  2924. required: true,
  2925. default: 0
  2926. },
  2927. type: COMMON.type,
  2928. content: {
  2929. type: [String, Object, Function],
  2930. required: true,
  2931. default: ""
  2932. },
  2933. onClick: {
  2934. type: Function,
  2935. default: void 0
  2936. },
  2937. onClose: {
  2938. type: Function,
  2939. default: void 0
  2940. }
  2941. };
  2942. var CONTAINER = {
  2943. container: {
  2944. type: [
  2945. Object,
  2946. Function
  2947. ],
  2948. default: () => document.body
  2949. },
  2950. newestOnTop: COMMON.trueBoolean,
  2951. maxToasts: {
  2952. type: Number,
  2953. default: 20
  2954. },
  2955. transition: TRANSITION.transition,
  2956. toastDefaults: Object,
  2957. filterBeforeCreate: {
  2958. type: Function,
  2959. default: (toast2) => toast2
  2960. },
  2961. filterToasts: {
  2962. type: Function,
  2963. default: (toasts) => toasts
  2964. },
  2965. containerClassName: COMMON.classNames,
  2966. onMounted: Function,
  2967. shareAppContext: [Boolean, Object]
  2968. };
  2969. var propValidators_default = {
  2970. CORE_TOAST,
  2971. TOAST,
  2972. CONTAINER,
  2973. PROGRESS_BAR,
  2974. ICON,
  2975. TRANSITION,
  2976. CLOSE_BUTTON
  2977. };
  2978. var VtProgressBar_default = vue.defineComponent({
  2979. name: "VtProgressBar",
  2980. props: propValidators_default.PROGRESS_BAR,
  2981. data() {
  2982. return {
  2983. hasClass: true
  2984. };
  2985. },
  2986. computed: {
  2987. style() {
  2988. return {
  2989. animationDuration: `${this.timeout}ms`,
  2990. animationPlayState: this.isRunning ? "running" : "paused",
  2991. opacity: this.hideProgressBar ? 0 : 1
  2992. };
  2993. },
  2994. cpClass() {
  2995. return this.hasClass ? `${VT_NAMESPACE}__progress-bar` : "";
  2996. }
  2997. },
  2998. watch: {
  2999. timeout() {
  3000. this.hasClass = false;
  3001. this.$nextTick(() => this.hasClass = true);
  3002. }
  3003. },
  3004. mounted() {
  3005. this.$el.addEventListener("animationend", this.animationEnded);
  3006. },
  3007. beforeUnmount() {
  3008. this.$el.removeEventListener("animationend", this.animationEnded);
  3009. },
  3010. methods: {
  3011. animationEnded() {
  3012. this.$emit("close-toast");
  3013. }
  3014. }
  3015. });
  3016. function render(_ctx, _cache) {
  3017. return vue.openBlock(), vue.createElementBlock("div", {
  3018. style: vue.normalizeStyle(_ctx.style),
  3019. class: vue.normalizeClass(_ctx.cpClass)
  3020. }, null, 6);
  3021. }
  3022. VtProgressBar_default.render = render;
  3023. var VtProgressBar_default2 = VtProgressBar_default;
  3024. var VtCloseButton_default = vue.defineComponent({
  3025. name: "VtCloseButton",
  3026. props: propValidators_default.CLOSE_BUTTON,
  3027. computed: {
  3028. buttonComponent() {
  3029. if (this.component !== false) {
  3030. return getVueComponentFromObj(this.component);
  3031. }
  3032. return "button";
  3033. },
  3034. classes() {
  3035. const classes = [`${VT_NAMESPACE}__close-button`];
  3036. if (this.showOnHover) {
  3037. classes.push("show-on-hover");
  3038. }
  3039. return classes.concat(this.classNames);
  3040. }
  3041. }
  3042. });
  3043. var _hoisted_1$8 = /* @__PURE__ */ vue.createTextVNode(" × ");
  3044. function render2(_ctx, _cache) {
  3045. return vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(_ctx.buttonComponent), vue.mergeProps({
  3046. "aria-label": _ctx.ariaLabel,
  3047. class: _ctx.classes
  3048. }, _ctx.$attrs), {
  3049. default: vue.withCtx(() => [
  3050. _hoisted_1$8
  3051. ]),
  3052. _: 1
  3053. }, 16, ["aria-label", "class"]);
  3054. }
  3055. VtCloseButton_default.render = render2;
  3056. var VtCloseButton_default2 = VtCloseButton_default;
  3057. var VtSuccessIcon_default = {};
  3058. var _hoisted_12$1 = {
  3059. "aria-hidden": "true",
  3060. focusable: "false",
  3061. "data-prefix": "fas",
  3062. "data-icon": "check-circle",
  3063. class: "svg-inline--fa fa-check-circle fa-w-16",
  3064. role: "img",
  3065. xmlns: "http://www.w3.org/2000/svg",
  3066. viewBox: "0 0 512 512"
  3067. };
  3068. var _hoisted_2$4 = /* @__PURE__ */ vue.createElementVNode("path", {
  3069. fill: "currentColor",
  3070. d: "M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z"
  3071. }, null, -1);
  3072. var _hoisted_3$3 = [
  3073. _hoisted_2$4
  3074. ];
  3075. function render3(_ctx, _cache) {
  3076. return vue.openBlock(), vue.createElementBlock("svg", _hoisted_12$1, _hoisted_3$3);
  3077. }
  3078. VtSuccessIcon_default.render = render3;
  3079. var VtSuccessIcon_default2 = VtSuccessIcon_default;
  3080. var VtInfoIcon_default = {};
  3081. var _hoisted_13$1 = {
  3082. "aria-hidden": "true",
  3083. focusable: "false",
  3084. "data-prefix": "fas",
  3085. "data-icon": "info-circle",
  3086. class: "svg-inline--fa fa-info-circle fa-w-16",
  3087. role: "img",
  3088. xmlns: "http://www.w3.org/2000/svg",
  3089. viewBox: "0 0 512 512"
  3090. };
  3091. var _hoisted_22 = /* @__PURE__ */ vue.createElementVNode("path", {
  3092. fill: "currentColor",
  3093. d: "M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 110c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z"
  3094. }, null, -1);
  3095. var _hoisted_32 = [
  3096. _hoisted_22
  3097. ];
  3098. function render4(_ctx, _cache) {
  3099. return vue.openBlock(), vue.createElementBlock("svg", _hoisted_13$1, _hoisted_32);
  3100. }
  3101. VtInfoIcon_default.render = render4;
  3102. var VtInfoIcon_default2 = VtInfoIcon_default;
  3103. var VtWarningIcon_default = {};
  3104. var _hoisted_14$1 = {
  3105. "aria-hidden": "true",
  3106. focusable: "false",
  3107. "data-prefix": "fas",
  3108. "data-icon": "exclamation-circle",
  3109. class: "svg-inline--fa fa-exclamation-circle fa-w-16",
  3110. role: "img",
  3111. xmlns: "http://www.w3.org/2000/svg",
  3112. viewBox: "0 0 512 512"
  3113. };
  3114. var _hoisted_23 = /* @__PURE__ */ vue.createElementVNode("path", {
  3115. fill: "currentColor",
  3116. d: "M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"
  3117. }, null, -1);
  3118. var _hoisted_33 = [
  3119. _hoisted_23
  3120. ];
  3121. function render5(_ctx, _cache) {
  3122. return vue.openBlock(), vue.createElementBlock("svg", _hoisted_14$1, _hoisted_33);
  3123. }
  3124. VtWarningIcon_default.render = render5;
  3125. var VtWarningIcon_default2 = VtWarningIcon_default;
  3126. var VtErrorIcon_default = {};
  3127. var _hoisted_15$1 = {
  3128. "aria-hidden": "true",
  3129. focusable: "false",
  3130. "data-prefix": "fas",
  3131. "data-icon": "exclamation-triangle",
  3132. class: "svg-inline--fa fa-exclamation-triangle fa-w-18",
  3133. role: "img",
  3134. xmlns: "http://www.w3.org/2000/svg",
  3135. viewBox: "0 0 576 512"
  3136. };
  3137. var _hoisted_24 = /* @__PURE__ */ vue.createElementVNode("path", {
  3138. fill: "currentColor",
  3139. d: "M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"
  3140. }, null, -1);
  3141. var _hoisted_34 = [
  3142. _hoisted_24
  3143. ];
  3144. function render6(_ctx, _cache) {
  3145. return vue.openBlock(), vue.createElementBlock("svg", _hoisted_15$1, _hoisted_34);
  3146. }
  3147. VtErrorIcon_default.render = render6;
  3148. var VtErrorIcon_default2 = VtErrorIcon_default;
  3149. var VtIcon_default = vue.defineComponent({
  3150. name: "VtIcon",
  3151. props: propValidators_default.ICON,
  3152. computed: {
  3153. customIconChildren() {
  3154. return hasProp(this.customIcon, "iconChildren") ? this.trimValue(this.customIcon.iconChildren) : "";
  3155. },
  3156. customIconClass() {
  3157. if (isString(this.customIcon)) {
  3158. return this.trimValue(this.customIcon);
  3159. } else if (hasProp(this.customIcon, "iconClass")) {
  3160. return this.trimValue(this.customIcon.iconClass);
  3161. }
  3162. return "";
  3163. },
  3164. customIconTag() {
  3165. if (hasProp(this.customIcon, "iconTag")) {
  3166. return this.trimValue(this.customIcon.iconTag, "i");
  3167. }
  3168. return "i";
  3169. },
  3170. hasCustomIcon() {
  3171. return this.customIconClass.length > 0;
  3172. },
  3173. component() {
  3174. if (this.hasCustomIcon) {
  3175. return this.customIconTag;
  3176. }
  3177. if (isToastContent(this.customIcon)) {
  3178. return getVueComponentFromObj(this.customIcon);
  3179. }
  3180. return this.iconTypeComponent;
  3181. },
  3182. iconTypeComponent() {
  3183. const types = {
  3184. [TYPE.DEFAULT]: VtInfoIcon_default2,
  3185. [TYPE.INFO]: VtInfoIcon_default2,
  3186. [TYPE.SUCCESS]: VtSuccessIcon_default2,
  3187. [TYPE.ERROR]: VtErrorIcon_default2,
  3188. [TYPE.WARNING]: VtWarningIcon_default2
  3189. };
  3190. return types[this.type];
  3191. },
  3192. iconClasses() {
  3193. const classes = [`${VT_NAMESPACE}__icon`];
  3194. if (this.hasCustomIcon) {
  3195. return classes.concat(this.customIconClass);
  3196. }
  3197. return classes;
  3198. }
  3199. },
  3200. methods: {
  3201. trimValue(value, empty = "") {
  3202. return isNonEmptyString(value) ? value.trim() : empty;
  3203. }
  3204. }
  3205. });
  3206. function render7(_ctx, _cache) {
  3207. return vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(_ctx.component), {
  3208. class: vue.normalizeClass(_ctx.iconClasses)
  3209. }, {
  3210. default: vue.withCtx(() => [
  3211. vue.createTextVNode(vue.toDisplayString(_ctx.customIconChildren), 1)
  3212. ]),
  3213. _: 1
  3214. }, 8, ["class"]);
  3215. }
  3216. VtIcon_default.render = render7;
  3217. var VtIcon_default2 = VtIcon_default;
  3218. var VtToast_default = vue.defineComponent({
  3219. name: "VtToast",
  3220. components: { ProgressBar: VtProgressBar_default2, CloseButton: VtCloseButton_default2, Icon: VtIcon_default2 },
  3221. inheritAttrs: false,
  3222. props: Object.assign({}, propValidators_default.CORE_TOAST, propValidators_default.TOAST),
  3223. data() {
  3224. const data = {
  3225. isRunning: true,
  3226. disableTransitions: false,
  3227. beingDragged: false,
  3228. dragStart: 0,
  3229. dragPos: { x: 0, y: 0 },
  3230. dragRect: {}
  3231. };
  3232. return data;
  3233. },
  3234. computed: {
  3235. classes() {
  3236. const classes = [
  3237. `${VT_NAMESPACE}__toast`,
  3238. `${VT_NAMESPACE}__toast--${this.type}`,
  3239. `${this.position}`
  3240. ].concat(this.toastClassName);
  3241. if (this.disableTransitions) {
  3242. classes.push("disable-transition");
  3243. }
  3244. if (this.rtl) {
  3245. classes.push(`${VT_NAMESPACE}__toast--rtl`);
  3246. }
  3247. return classes;
  3248. },
  3249. bodyClasses() {
  3250. const classes = [
  3251. `${VT_NAMESPACE}__toast-${isString(this.content) ? "body" : "component-body"}`
  3252. ].concat(this.bodyClassName);
  3253. return classes;
  3254. },
  3255. draggableStyle() {
  3256. if (this.dragStart === this.dragPos.x) {
  3257. return {};
  3258. } else if (this.beingDragged) {
  3259. return {
  3260. transform: `translateX(${this.dragDelta}px)`,
  3261. opacity: 1 - Math.abs(this.dragDelta / this.removalDistance)
  3262. };
  3263. } else {
  3264. return {
  3265. transition: "transform 0.2s, opacity 0.2s",
  3266. transform: "translateX(0)",
  3267. opacity: 1
  3268. };
  3269. }
  3270. },
  3271. dragDelta() {
  3272. return this.beingDragged ? this.dragPos.x - this.dragStart : 0;
  3273. },
  3274. removalDistance() {
  3275. if (isDOMRect(this.dragRect)) {
  3276. return (this.dragRect.right - this.dragRect.left) * this.draggablePercent;
  3277. }
  3278. return 0;
  3279. }
  3280. },
  3281. mounted() {
  3282. if (this.draggable) {
  3283. this.draggableSetup();
  3284. }
  3285. if (this.pauseOnFocusLoss) {
  3286. this.focusSetup();
  3287. }
  3288. },
  3289. beforeUnmount() {
  3290. if (this.draggable) {
  3291. this.draggableCleanup();
  3292. }
  3293. if (this.pauseOnFocusLoss) {
  3294. this.focusCleanup();
  3295. }
  3296. },
  3297. methods: {
  3298. hasProp,
  3299. getVueComponentFromObj,
  3300. closeToast() {
  3301. this.eventBus.emit(EVENTS.DISMISS, this.id);
  3302. },
  3303. clickHandler() {
  3304. if (this.onClick) {
  3305. this.onClick(this.closeToast);
  3306. }
  3307. if (this.closeOnClick) {
  3308. if (!this.beingDragged || this.dragStart === this.dragPos.x) {
  3309. this.closeToast();
  3310. }
  3311. }
  3312. },
  3313. timeoutHandler() {
  3314. this.closeToast();
  3315. },
  3316. hoverPause() {
  3317. if (this.pauseOnHover) {
  3318. this.isRunning = false;
  3319. }
  3320. },
  3321. hoverPlay() {
  3322. if (this.pauseOnHover) {
  3323. this.isRunning = true;
  3324. }
  3325. },
  3326. focusPause() {
  3327. this.isRunning = false;
  3328. },
  3329. focusPlay() {
  3330. this.isRunning = true;
  3331. },
  3332. focusSetup() {
  3333. addEventListener("blur", this.focusPause);
  3334. addEventListener("focus", this.focusPlay);
  3335. },
  3336. focusCleanup() {
  3337. removeEventListener("blur", this.focusPause);
  3338. removeEventListener("focus", this.focusPlay);
  3339. },
  3340. draggableSetup() {
  3341. const element = this.$el;
  3342. element.addEventListener("touchstart", this.onDragStart, {
  3343. passive: true
  3344. });
  3345. element.addEventListener("mousedown", this.onDragStart);
  3346. addEventListener("touchmove", this.onDragMove, { passive: false });
  3347. addEventListener("mousemove", this.onDragMove);
  3348. addEventListener("touchend", this.onDragEnd);
  3349. addEventListener("mouseup", this.onDragEnd);
  3350. },
  3351. draggableCleanup() {
  3352. const element = this.$el;
  3353. element.removeEventListener("touchstart", this.onDragStart);
  3354. element.removeEventListener("mousedown", this.onDragStart);
  3355. removeEventListener("touchmove", this.onDragMove);
  3356. removeEventListener("mousemove", this.onDragMove);
  3357. removeEventListener("touchend", this.onDragEnd);
  3358. removeEventListener("mouseup", this.onDragEnd);
  3359. },
  3360. onDragStart(event) {
  3361. this.beingDragged = true;
  3362. this.dragPos = { x: getX(event), y: getY(event) };
  3363. this.dragStart = getX(event);
  3364. this.dragRect = this.$el.getBoundingClientRect();
  3365. },
  3366. onDragMove(event) {
  3367. if (this.beingDragged) {
  3368. event.preventDefault();
  3369. if (this.isRunning) {
  3370. this.isRunning = false;
  3371. }
  3372. this.dragPos = { x: getX(event), y: getY(event) };
  3373. }
  3374. },
  3375. onDragEnd() {
  3376. if (this.beingDragged) {
  3377. if (Math.abs(this.dragDelta) >= this.removalDistance) {
  3378. this.disableTransitions = true;
  3379. this.$nextTick(() => this.closeToast());
  3380. } else {
  3381. setTimeout(() => {
  3382. this.beingDragged = false;
  3383. if (isDOMRect(this.dragRect) && this.pauseOnHover && this.dragRect.bottom >= this.dragPos.y && this.dragPos.y >= this.dragRect.top && this.dragRect.left <= this.dragPos.x && this.dragPos.x <= this.dragRect.right) {
  3384. this.isRunning = false;
  3385. } else {
  3386. this.isRunning = true;
  3387. }
  3388. });
  3389. }
  3390. }
  3391. }
  3392. }
  3393. });
  3394. var _hoisted_16$1 = ["role"];
  3395. function render8(_ctx, _cache) {
  3396. const _component_Icon = vue.resolveComponent("Icon");
  3397. const _component_CloseButton = vue.resolveComponent("CloseButton");
  3398. const _component_ProgressBar = vue.resolveComponent("ProgressBar");
  3399. return vue.openBlock(), vue.createElementBlock("div", {
  3400. class: vue.normalizeClass(_ctx.classes),
  3401. style: vue.normalizeStyle(_ctx.draggableStyle),
  3402. onClick: _cache[0] || (_cache[0] = (...args) => _ctx.clickHandler && _ctx.clickHandler(...args)),
  3403. onMouseenter: _cache[1] || (_cache[1] = (...args) => _ctx.hoverPause && _ctx.hoverPause(...args)),
  3404. onMouseleave: _cache[2] || (_cache[2] = (...args) => _ctx.hoverPlay && _ctx.hoverPlay(...args))
  3405. }, [
  3406. _ctx.icon ? (vue.openBlock(), vue.createBlock(_component_Icon, {
  3407. key: 0,
  3408. "custom-icon": _ctx.icon,
  3409. type: _ctx.type
  3410. }, null, 8, ["custom-icon", "type"])) : vue.createCommentVNode("v-if", true),
  3411. vue.createElementVNode("div", {
  3412. role: _ctx.accessibility.toastRole || "alert",
  3413. class: vue.normalizeClass(_ctx.bodyClasses)
  3414. }, [
  3415. typeof _ctx.content === "string" ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 0 }, [
  3416. vue.createTextVNode(vue.toDisplayString(_ctx.content), 1)
  3417. ], 2112)) : (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(_ctx.getVueComponentFromObj(_ctx.content)), vue.mergeProps({
  3418. key: 1,
  3419. "toast-id": _ctx.id
  3420. }, _ctx.hasProp(_ctx.content, "props") ? _ctx.content.props : {}, vue.toHandlers(_ctx.hasProp(_ctx.content, "listeners") ? _ctx.content.listeners : {}), { onCloseToast: _ctx.closeToast }), null, 16, ["toast-id", "onCloseToast"]))
  3421. ], 10, _hoisted_16$1),
  3422. !!_ctx.closeButton ? (vue.openBlock(), vue.createBlock(_component_CloseButton, {
  3423. key: 1,
  3424. component: _ctx.closeButton,
  3425. "class-names": _ctx.closeButtonClassName,
  3426. "show-on-hover": _ctx.showCloseButtonOnHover,
  3427. "aria-label": _ctx.accessibility.closeButtonLabel,
  3428. onClick: vue.withModifiers(_ctx.closeToast, ["stop"])
  3429. }, null, 8, ["component", "class-names", "show-on-hover", "aria-label", "onClick"])) : vue.createCommentVNode("v-if", true),
  3430. _ctx.timeout ? (vue.openBlock(), vue.createBlock(_component_ProgressBar, {
  3431. key: 2,
  3432. "is-running": _ctx.isRunning,
  3433. "hide-progress-bar": _ctx.hideProgressBar,
  3434. timeout: _ctx.timeout,
  3435. onCloseToast: _ctx.timeoutHandler
  3436. }, null, 8, ["is-running", "hide-progress-bar", "timeout", "onCloseToast"])) : vue.createCommentVNode("v-if", true)
  3437. ], 38);
  3438. }
  3439. VtToast_default.render = render8;
  3440. var VtToast_default2 = VtToast_default;
  3441. var VtTransition_default = vue.defineComponent({
  3442. name: "VtTransition",
  3443. props: propValidators_default.TRANSITION,
  3444. emits: ["leave"],
  3445. methods: {
  3446. hasProp,
  3447. leave(el) {
  3448. if (el instanceof HTMLElement) {
  3449. el.style.left = el.offsetLeft + "px";
  3450. el.style.top = el.offsetTop + "px";
  3451. el.style.width = getComputedStyle(el).width;
  3452. el.style.position = "absolute";
  3453. }
  3454. }
  3455. }
  3456. });
  3457. function render9(_ctx, _cache) {
  3458. return vue.openBlock(), vue.createBlock(vue.TransitionGroup, {
  3459. tag: "div",
  3460. "enter-active-class": _ctx.transition.enter ? _ctx.transition.enter : `${_ctx.transition}-enter-active`,
  3461. "move-class": _ctx.transition.move ? _ctx.transition.move : `${_ctx.transition}-move`,
  3462. "leave-active-class": _ctx.transition.leave ? _ctx.transition.leave : `${_ctx.transition}-leave-active`,
  3463. onLeave: _ctx.leave
  3464. }, {
  3465. default: vue.withCtx(() => [
  3466. vue.renderSlot(_ctx.$slots, "default")
  3467. ]),
  3468. _: 3
  3469. }, 8, ["enter-active-class", "move-class", "leave-active-class", "onLeave"]);
  3470. }
  3471. VtTransition_default.render = render9;
  3472. var VtTransition_default2 = VtTransition_default;
  3473. var VtToastContainer_default = vue.defineComponent({
  3474. name: "VueToastification",
  3475. devtools: {
  3476. hide: true
  3477. },
  3478. components: { Toast: VtToast_default2, VtTransition: VtTransition_default2 },
  3479. props: Object.assign({}, propValidators_default.CORE_TOAST, propValidators_default.CONTAINER, propValidators_default.TRANSITION),
  3480. data() {
  3481. const data = {
  3482. count: 0,
  3483. positions: Object.values(POSITION),
  3484. toasts: {},
  3485. defaults: {}
  3486. };
  3487. return data;
  3488. },
  3489. computed: {
  3490. toastArray() {
  3491. return Object.values(this.toasts);
  3492. },
  3493. filteredToasts() {
  3494. return this.defaults.filterToasts(this.toastArray);
  3495. }
  3496. },
  3497. beforeMount() {
  3498. const events = this.eventBus;
  3499. events.on(EVENTS.ADD, this.addToast);
  3500. events.on(EVENTS.CLEAR, this.clearToasts);
  3501. events.on(EVENTS.DISMISS, this.dismissToast);
  3502. events.on(EVENTS.UPDATE, this.updateToast);
  3503. events.on(EVENTS.UPDATE_DEFAULTS, this.updateDefaults);
  3504. this.defaults = this.$props;
  3505. },
  3506. mounted() {
  3507. this.setup(this.container);
  3508. },
  3509. methods: {
  3510. async setup(container) {
  3511. if (isFunction(container)) {
  3512. container = await container();
  3513. }
  3514. removeElement(this.$el);
  3515. container.appendChild(this.$el);
  3516. },
  3517. setToast(props) {
  3518. if (!isUndefined(props.id)) {
  3519. this.toasts[props.id] = props;
  3520. }
  3521. },
  3522. addToast(params) {
  3523. params.content = normalizeToastComponent(params.content);
  3524. const props = Object.assign({}, this.defaults, params.type && this.defaults.toastDefaults && this.defaults.toastDefaults[params.type], params);
  3525. const toast2 = this.defaults.filterBeforeCreate(props, this.toastArray);
  3526. toast2 && this.setToast(toast2);
  3527. },
  3528. dismissToast(id) {
  3529. const toast2 = this.toasts[id];
  3530. if (!isUndefined(toast2) && !isUndefined(toast2.onClose)) {
  3531. toast2.onClose();
  3532. }
  3533. delete this.toasts[id];
  3534. },
  3535. clearToasts() {
  3536. Object.keys(this.toasts).forEach((id) => {
  3537. this.dismissToast(id);
  3538. });
  3539. },
  3540. getPositionToasts(position) {
  3541. const toasts = this.filteredToasts.filter((toast2) => toast2.position === position).slice(0, this.defaults.maxToasts);
  3542. return this.defaults.newestOnTop ? toasts.reverse() : toasts;
  3543. },
  3544. updateDefaults(update) {
  3545. if (!isUndefined(update.container)) {
  3546. this.setup(update.container);
  3547. }
  3548. this.defaults = Object.assign({}, this.defaults, update);
  3549. },
  3550. updateToast({
  3551. id,
  3552. options,
  3553. create
  3554. }) {
  3555. if (this.toasts[id]) {
  3556. if (options.timeout && options.timeout === this.toasts[id].timeout) {
  3557. options.timeout++;
  3558. }
  3559. this.setToast(Object.assign({}, this.toasts[id], options));
  3560. } else if (create) {
  3561. this.addToast(Object.assign({}, { id }, options));
  3562. }
  3563. },
  3564. getClasses(position) {
  3565. const classes = [`${VT_NAMESPACE}__container`, position];
  3566. return classes.concat(this.defaults.containerClassName);
  3567. }
  3568. }
  3569. });
  3570. function render10(_ctx, _cache) {
  3571. const _component_Toast = vue.resolveComponent("Toast");
  3572. const _component_VtTransition = vue.resolveComponent("VtTransition");
  3573. return vue.openBlock(), vue.createElementBlock("div", null, [
  3574. (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.positions, (pos) => {
  3575. return vue.openBlock(), vue.createElementBlock("div", { key: pos }, [
  3576. vue.createVNode(_component_VtTransition, {
  3577. transition: _ctx.defaults.transition,
  3578. class: vue.normalizeClass(_ctx.getClasses(pos))
  3579. }, {
  3580. default: vue.withCtx(() => [
  3581. (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.getPositionToasts(pos), (toast2) => {
  3582. return vue.openBlock(), vue.createBlock(_component_Toast, vue.mergeProps({
  3583. key: toast2.id
  3584. }, toast2), null, 16);
  3585. }), 128))
  3586. ]),
  3587. _: 2
  3588. }, 1032, ["transition", "class"])
  3589. ]);
  3590. }), 128))
  3591. ]);
  3592. }
  3593. VtToastContainer_default.render = render10;
  3594. var VtToastContainer_default2 = VtToastContainer_default;
  3595. var buildInterface = (globalOptions = {}, mountContainer = true) => {
  3596. const events = globalOptions.eventBus = globalOptions.eventBus || new EventBus();
  3597. if (mountContainer) {
  3598. vue.nextTick(() => {
  3599. const app2 = vue.createApp(VtToastContainer_default2, __spreadValues({}, globalOptions));
  3600. const component = app2.mount(document.createElement("div"));
  3601. const onMounted2 = globalOptions.onMounted;
  3602. if (!isUndefined(onMounted2)) {
  3603. onMounted2(component, app2);
  3604. }
  3605. if (globalOptions.shareAppContext) {
  3606. const baseApp = globalOptions.shareAppContext;
  3607. if (baseApp === true) {
  3608. console.warn(`[${VT_NAMESPACE}] App to share context with was not provided.`);
  3609. } else {
  3610. app2._context.components = baseApp._context.components;
  3611. app2._context.directives = baseApp._context.directives;
  3612. app2._context.mixins = baseApp._context.mixins;
  3613. app2._context.provides = baseApp._context.provides;
  3614. app2.config.globalProperties = baseApp.config.globalProperties;
  3615. }
  3616. }
  3617. });
  3618. }
  3619. const toast2 = (content, options) => {
  3620. const props = Object.assign({}, { id: getId(), type: TYPE.DEFAULT }, options, {
  3621. content
  3622. });
  3623. events.emit(EVENTS.ADD, props);
  3624. return props.id;
  3625. };
  3626. toast2.clear = () => events.emit(EVENTS.CLEAR, void 0);
  3627. toast2.updateDefaults = (update) => {
  3628. events.emit(EVENTS.UPDATE_DEFAULTS, update);
  3629. };
  3630. toast2.dismiss = (id) => {
  3631. events.emit(EVENTS.DISMISS, id);
  3632. };
  3633. function updateToast(id, { content, options }, create = false) {
  3634. const opt = Object.assign({}, options, { content });
  3635. events.emit(EVENTS.UPDATE, {
  3636. id,
  3637. options: opt,
  3638. create
  3639. });
  3640. }
  3641. toast2.update = updateToast;
  3642. toast2.success = (content, options) => toast2(content, Object.assign({}, options, { type: TYPE.SUCCESS }));
  3643. toast2.info = (content, options) => toast2(content, Object.assign({}, options, { type: TYPE.INFO }));
  3644. toast2.error = (content, options) => toast2(content, Object.assign({}, options, { type: TYPE.ERROR }));
  3645. toast2.warning = (content, options) => toast2(content, Object.assign({}, options, { type: TYPE.WARNING }));
  3646. return toast2;
  3647. };
  3648. var createMockToastInterface = () => {
  3649. const toast2 = () => console.warn(`[${VT_NAMESPACE}] This plugin does not support SSR!`);
  3650. return new Proxy(toast2, {
  3651. get() {
  3652. return toast2;
  3653. }
  3654. });
  3655. };
  3656. function createToastInterface(optionsOrEventBus) {
  3657. if (!isBrowser()) {
  3658. return createMockToastInterface();
  3659. }
  3660. if (isEventBusInterface(optionsOrEventBus)) {
  3661. return buildInterface({ eventBus: optionsOrEventBus }, false);
  3662. }
  3663. return buildInterface(optionsOrEventBus, true);
  3664. }
  3665. var toastInjectionKey = Symbol("VueToastification");
  3666. var globalEventBus = new EventBus();
  3667. var VueToastificationPlugin = (App, options) => {
  3668. if ((options == null ? void 0 : options.shareAppContext) === true) {
  3669. options.shareAppContext = App;
  3670. }
  3671. const inter = createToastInterface(__spreadValues({
  3672. eventBus: globalEventBus
  3673. }, options));
  3674. App.provide(toastInjectionKey, inter);
  3675. };
  3676. var useToast = (eventBus) => {
  3677. const toast2 = vue.getCurrentInstance() ? vue.inject(toastInjectionKey, void 0) : void 0;
  3678. return toast2 ? toast2 : createToastInterface(globalEventBus);
  3679. };
  3680. var src_default = VueToastificationPlugin;
  3681. var _GM = /* @__PURE__ */ (() => typeof GM != "undefined" ? GM : void 0)();
  3682. var _GM_addStyle = /* @__PURE__ */ (() => typeof GM_addStyle != "undefined" ? GM_addStyle : void 0)();
  3683. var _GM_addValueChangeListener = /* @__PURE__ */ (() => typeof GM_addValueChangeListener != "undefined" ? GM_addValueChangeListener : void 0)();
  3684. var _GM_getValue = /* @__PURE__ */ (() => typeof GM_getValue != "undefined" ? GM_getValue : void 0)();
  3685. var _GM_setValue = /* @__PURE__ */ (() => typeof GM_setValue != "undefined" ? GM_setValue : void 0)();
  3686. var _unsafeWindow = /* @__PURE__ */ (() => typeof unsafeWindow != "undefined" ? unsafeWindow : void 0)();
  3687. var GMKey = /* @__PURE__ */ ((GMKey2) => {
  3688. GMKey2["InfiniteScroll"] = "InfiniteScroll";
  3689. GMKey2["ScrollByRow"] = "ScrollByRow";
  3690. GMKey2["ArchiveButton"] = "archiveButton";
  3691. GMKey2["Highlight"] = "Highlight";
  3692. GMKey2["BetterPopup"] = "BetterPopup";
  3693. GMKey2["QuickDownloadMethod"] = "QuickDownloadMethod";
  3694. GMKey2["LoadAllGalleryImages"] = "LoadAllGalleryImages";
  3695. GMKey2["MultipageViewerEnhancer"] = "MultipageViewerEnhancer";
  3696. GMKey2["AutoRedirect"] = "AutoRedirect";
  3697. GMKey2["PreventImageRemoval"] = "PreventImageRemoval";
  3698. GMKey2["ShowJapaneseTitle"] = "ShowJapaneseTitle";
  3699. return GMKey2;
  3700. })(GMKey || {});
  3701. var DownloadMethod = /* @__PURE__ */ ((DownloadMethod2) => {
  3702. DownloadMethod2["Manual"] = "Manual";
  3703. DownloadMethod2["HaH_Original"] = "download Original Resolution with H@H";
  3704. DownloadMethod2["HaH_2400"] = "download 2400x Resolution with H@H";
  3705. DownloadMethod2["Direct_Origin"] = "download Original Resolution directly";
  3706. DownloadMethod2["Direct_Resample"] = "download Resample Resolution directly";
  3707. return DownloadMethod2;
  3708. })(DownloadMethod || {});
  3709. class GMVariable {
  3710. constructor(key, defaultValue) {
  3711. __publicField(this, "_key");
  3712. __publicField(this, "_value");
  3713. this._key = key;
  3714. this._value = defaultValue;
  3715. }
  3716. get value() {
  3717. return this._value;
  3718. }
  3719. set value(value) {
  3720. this._value = value;
  3721. _GM.setValue(this._key, this._value);
  3722. }
  3723. async initialize() {
  3724. this._value = await _GM.getValue(this._key, this._value);
  3725. }
  3726. }
  3727. const infiniteScrollSwitch = vue.reactive(new GMVariable(GMKey.InfiniteScroll, true));
  3728. const archiveButtonSwitch = vue.reactive(new GMVariable(GMKey.ArchiveButton, true));
  3729. const highlightSwitch = vue.reactive(new GMVariable(GMKey.Highlight, true));
  3730. const scrollByRowSwitch = vue.reactive(new GMVariable(GMKey.ScrollByRow, true));
  3731. const betterPopupSwitch = vue.reactive(new GMVariable(GMKey.BetterPopup, true));
  3732. const quickDownloadMethod = vue.reactive(new GMVariable(GMKey.QuickDownloadMethod, DownloadMethod.Manual));
  3733. const loadAllGalleryImagesSwitch = vue.reactive(new GMVariable(GMKey.LoadAllGalleryImages, true));
  3734. const multipageViewerEnhancerSwitch = vue.reactive(new GMVariable(GMKey.MultipageViewerEnhancer, true));
  3735. const autoRedirectSwitch = vue.reactive(new GMVariable(GMKey.AutoRedirect, false));
  3736. const preventImageRemovalSwitch = vue.reactive(new GMVariable(GMKey.PreventImageRemoval, false));
  3737. const showJapaneseTitle = vue.reactive(new GMVariable(GMKey.ShowJapaneseTitle, true));
  3738. async function initializeMonkeySwitches() {
  3739. await Promise.all([
  3740. infiniteScrollSwitch.initialize(),
  3741. archiveButtonSwitch.initialize(),
  3742. highlightSwitch.initialize(),
  3743. scrollByRowSwitch.initialize(),
  3744. betterPopupSwitch.initialize(),
  3745. quickDownloadMethod.initialize(),
  3746. loadAllGalleryImagesSwitch.initialize(),
  3747. multipageViewerEnhancerSwitch.initialize(),
  3748. preventImageRemovalSwitch.initialize(),
  3749. autoRedirectSwitch.initialize(),
  3750. showJapaneseTitle.initialize()
  3751. ]);
  3752. }
  3753. function delay2(ms) {
  3754. return new Promise((resolve) => setTimeout(resolve, ms));
  3755. }
  3756. function getElement(selector, root2 = document) {
  3757. return root2.querySelector(selector);
  3758. }
  3759. function getElements(selector, root2 = document) {
  3760. return root2.querySelectorAll(selector);
  3761. }
  3762. async function getDoc(url, options) {
  3763. const response = await fetch(url, options);
  3764. const html = await response.text();
  3765. return new DOMParser().parseFromString(html, "text/html");
  3766. }
  3767. function scrollElement(element, { offset, absolute }) {
  3768. if (offset) {
  3769. element.scrollTop += offset;
  3770. return;
  3771. }
  3772. if (absolute) {
  3773. element.scrollTop = absolute;
  3774. }
  3775. }
  3776. function useWheelStep({
  3777. containerSelector,
  3778. itemsSelector
  3779. }) {
  3780. const container = getElement(containerSelector);
  3781. if (!container) {
  3782. console.warn(`container not found. selector: ${containerSelector}`);
  3783. return;
  3784. }
  3785. let firstItemOfRows = getFirstItemOfRows(itemsSelector, container);
  3786. if (firstItemOfRows.length === 0) {
  3787. console.warn(`item not found. selector: ${itemsSelector}`);
  3788. return;
  3789. }
  3790. const mutationObserver = new MutationObserver(() => {
  3791. firstItemOfRows = getFirstItemOfRows(itemsSelector, container);
  3792. });
  3793. mutationObserver.observe(container, {
  3794. childList: true,
  3795. characterData: true
  3796. });
  3797. setContainerWheelEvent();
  3798. function setContainerWheelEvent() {
  3799. if (!container) {
  3800. return;
  3801. }
  3802. container.addEventListener("mousewheel", (event) => {
  3803. if (!firstItemOfRows) {
  3804. return;
  3805. }
  3806. const firstVisibleItemIndex = firstItemOfRows.findIndex((item) => Math.floor(item.getBoundingClientRect().bottom) > 0);
  3807. const firstVisibleItem = firstItemOfRows[firstVisibleItemIndex];
  3808. const boundingTop = Math.floor(firstVisibleItem.getBoundingClientRect().top);
  3809. let nextIndex = firstVisibleItemIndex;
  3810. if (Math.sign(event.deltaY) === 1 && boundingTop <= 0) {
  3811. nextIndex++;
  3812. } else if (Math.sign(event.deltaY) === -1 && boundingTop >= -1) {
  3813. nextIndex--;
  3814. }
  3815. if (nextIndex >= 0 && nextIndex < firstItemOfRows.length) {
  3816. event.preventDefault();
  3817. event.stopPropagation();
  3818. firstItemOfRows[nextIndex].scrollIntoView();
  3819. }
  3820. });
  3821. }
  3822. }
  3823. function getFirstItemOfRows(selector, parent) {
  3824. const item = getElement(selector, parent);
  3825. if (!item) {
  3826. return [];
  3827. }
  3828. if (parent.clientWidth === 0 || parent.clientWidth === 0) {
  3829. console.warn(`container width is 0, do nothing. container: ${parent}`);
  3830. return [];
  3831. }
  3832. if (item.clientWidth === 0) {
  3833. console.warn(`item width is 0, do nothing. item: ${item}`);
  3834. return [];
  3835. }
  3836. const itemsPerRow = Math.floor(parent.clientWidth / item.clientWidth);
  3837. const firstItemOfRows = getElements(`${selector}:nth-child(${itemsPerRow}n + 1)`, parent);
  3838. if (!firstItemOfRows) {
  3839. return [];
  3840. }
  3841. return [...firstItemOfRows];
  3842. }
  3843. class Logger {
  3844. constructor(feature, scope) {
  3845. __publicField(this, "_feature");
  3846. __publicField(this, "_featureStyle");
  3847. __publicField(this, "_scope");
  3848. __publicField(this, "_scopeStyle");
  3849. this._feature = feature;
  3850. this._scope = scope;
  3851. this._featureStyle = "background: #777; border-radius: 5px;";
  3852. this._scopeStyle = "background: #555; border-radius: 5px;";
  3853. }
  3854. set scope(scope) {
  3855. this._scope = scope;
  3856. }
  3857. get prefix() {
  3858. let prefix = `%c ${this._feature} `;
  3859. if (this._scope) {
  3860. prefix += `%c ${this._scope} `;
  3861. }
  3862. return prefix;
  3863. }
  3864. get style() {
  3865. const style = [this._featureStyle];
  3866. if (this._scope) {
  3867. style.push(this._scopeStyle);
  3868. }
  3869. return style;
  3870. }
  3871. log(message) {
  3872. console.log(
  3873. this.prefix,
  3874. ...this.style,
  3875. message
  3876. );
  3877. }
  3878. error(message, error) {
  3879. console.error(
  3880. this.prefix,
  3881. ...this.style,
  3882. message,
  3883. error
  3884. );
  3885. }
  3886. }
  3887. class LoggerScopeDecorator {
  3888. constructor(baseLogger2, scope) {
  3889. __publicField(this, "_logger");
  3890. this._logger = baseLogger2;
  3891. this._logger.scope = scope;
  3892. }
  3893. log(message) {
  3894. this._logger.log(message);
  3895. }
  3896. error(message, error) {
  3897. this._logger.error(message, error);
  3898. }
  3899. }
  3900. function useGalleryElements() {
  3901. const infoDiv = getElement(".gm");
  3902. const archiveLinkAnchor = getElement("#gd5 > p:nth-child(2) a");
  3903. const torrentLinkAnchor = getElement("#gd5 > p:nth-child(3) a");
  3904. const favoritesLinkAnchor = getElement("#favoritelink");
  3905. const favoritesLinkDiv = getElement("#gdf");
  3906. return {
  3907. infoDiv,
  3908. archiveLinkAnchor,
  3909. torrentLinkAnchor,
  3910. favoritesLinkAnchor,
  3911. favoritesLinkDiv
  3912. };
  3913. }
  3914. const torrentInnerHtml = vue.ref("");
  3915. const archiveInnerHtml = vue.ref("");
  3916. const favoriteInnerHtml = vue.ref("");
  3917. function useFetchPopups() {
  3918. const {
  3919. archiveLinkAnchor,
  3920. torrentLinkAnchor
  3921. } = useGalleryElements();
  3922. function getInnerHTMLs() {
  3923. return {
  3924. torrentInnerHtml,
  3925. archiveInnerHtml,
  3926. favoriteInnerHtml
  3927. };
  3928. }
  3929. async function preloadLinks() {
  3930. [
  3931. archiveInnerHtml.value,
  3932. torrentInnerHtml.value,
  3933. favoriteInnerHtml.value
  3934. ] = await Promise.all([
  3935. fetchArchive(),
  3936. fetchTorrents(),
  3937. fetchFavorites()
  3938. ]);
  3939. }
  3940. async function fetchTorrents() {
  3941. const logger = new LoggerScopeDecorator(new Logger("Preload Links"), "Torrent");
  3942. logger.log("Start");
  3943. const link = getDownloadLink(torrentLinkAnchor);
  3944. if (!link) {
  3945. logger.error("link not found.");
  3946. return "";
  3947. }
  3948. const doc = await getDoc(link);
  3949. const popupContent = getPopupContent(doc, "#torrentinfo > div:first-child");
  3950. if (!popupContent) {
  3951. logger.error("popup content not found.");
  3952. return "";
  3953. }
  3954. logger.log("End");
  3955. return popupContent.innerHTML;
  3956. }
  3957. async function fetchArchive(url) {
  3958. const logger = new LoggerScopeDecorator(new Logger("Preload Links"), "Archive");
  3959. logger.log("Start");
  3960. const link = url || getDownloadLink(archiveLinkAnchor);
  3961. if (!link) {
  3962. logger.error("link not found.");
  3963. return "";
  3964. }
  3965. const doc = await getDoc(link);
  3966. const popupContent = getPopupContent(doc, "#db");
  3967. if (!popupContent) {
  3968. logger.error("popup content not found.");
  3969. return "";
  3970. }
  3971. logger.log("End");
  3972. return popupContent.innerHTML;
  3973. }
  3974. async function fetchFavorites() {
  3975. const logger = new LoggerScopeDecorator(new Logger("Preload Links"), "Favorites");
  3976. logger.log("Start");
  3977. const link = getFavoritesLink();
  3978. if (!link) {
  3979. logger.error("link not found.");
  3980. return "";
  3981. }
  3982. const doc = await getDoc(link);
  3983. const popupContent = getPopupContent(doc, ".stuffbox");
  3984. if (!popupContent) {
  3985. logger.error("popup content not found.");
  3986. return "";
  3987. }
  3988. logger.log("End");
  3989. return popupContent.innerHTML;
  3990. }
  3991. function getDownloadLink(linkElement) {
  3992. var _a2;
  3993. const onClick = linkElement.getAttribute("onclick");
  3994. if (!onClick) {
  3995. return null;
  3996. }
  3997. return (_a2 = onClick.match(/(https:\/\/\S+)',\d+,\d+/)) == null ? void 0 : _a2[1];
  3998. }
  3999. function getPopupContent(doc, selector) {
  4000. const content = getElement(selector, doc);
  4001. if (!content) {
  4002. return null;
  4003. }
  4004. content.removeAttribute("style");
  4005. content.classList.add("popup");
  4006. return content;
  4007. }
  4008. function getFavoritesLink() {
  4009. return `${location.origin}/gallerypopups.php?gid=${getGID()}&t=${getGalleryVersion()}&act=addfav`;
  4010. }
  4011. function getGID() {
  4012. return location.pathname.split("/")[2];
  4013. }
  4014. function getGalleryVersion() {
  4015. return location.pathname.split("/")[3];
  4016. }
  4017. return {
  4018. getInnerHTMLs,
  4019. preloadLinks,
  4020. fetchTorrents,
  4021. fetchArchive,
  4022. fetchFavorites,
  4023. getDownloadLink,
  4024. getPopupContent,
  4025. getFavoritesLink,
  4026. getGID,
  4027. getGalleryVersion
  4028. };
  4029. }
  4030. function getAipUrl() {
  4031. if (_unsafeWindow.location.origin === "https://exhentai.org") {
  4032. return "https://exhentai.org/api.php";
  4033. } else {
  4034. return "https://api.e-hentai.org/api.php";
  4035. }
  4036. }
  4037. function getGalleryMetadataBody(id, token) {
  4038. return JSON.stringify({
  4039. "method": "gdata",
  4040. "gidlist": [
  4041. [id, token]
  4042. ],
  4043. "namespace": 1
  4044. });
  4045. }
  4046. function getGalleryIDandToken(pathname) {
  4047. var _a2;
  4048. const groups = (_a2 = pathname.match(/(mpv|g)\/(?<id>\d+)\/(?<token>\w+)/)) == null ? void 0 : _a2.groups;
  4049. if (!groups) {
  4050. return {
  4051. id: null,
  4052. token: null
  4053. };
  4054. }
  4055. return {
  4056. id: Number(groups.id),
  4057. token: groups.token
  4058. };
  4059. }
  4060. async function fetchGalleryData({ id, token }) {
  4061. const apiURL = getAipUrl();
  4062. return fetch(
  4063. apiURL,
  4064. {
  4065. method: "POST",
  4066. body: getGalleryMetadataBody(id, token)
  4067. }
  4068. ).then((response) => response.json());
  4069. }
  4070. async function changeTitleToJapanese() {
  4071. const { id, token } = getGalleryIDandToken(_unsafeWindow.location.pathname);
  4072. if (!id || !token) {
  4073. return;
  4074. }
  4075. const galleryData = await fetchGalleryData({
  4076. id,
  4077. token
  4078. });
  4079. if (galleryData) {
  4080. const japaneseTitle = galleryData.gmetadata[0].title_jpn;
  4081. if (japaneseTitle) {
  4082. document.title = japaneseTitle;
  4083. }
  4084. }
  4085. }
  4086. async function getArchiveLink(url) {
  4087. const { id, token } = getGalleryIDandToken(url);
  4088. if (!id || !token) {
  4089. return;
  4090. }
  4091. const galleryData = await fetchGalleryData({
  4092. id,
  4093. token
  4094. });
  4095. return `${_unsafeWindow.location.origin}/archiver.php?gid=${id}&token=${token}&or=${galleryData.gmetadata[0].archiver_key}`;
  4096. }
  4097. function useHighlight() {
  4098. const downloadedGalleriesIDs = _GM_getValue("downloaded-galleries-ids", []);
  4099. function setAsDownloaded(galleryID) {
  4100. if (!highlightSwitch.value) {
  4101. return;
  4102. }
  4103. highlight(galleryID);
  4104. downloadedGalleriesIDs.push(galleryID);
  4105. _GM_setValue("downloaded-galleries-ids", downloadedGalleriesIDs);
  4106. }
  4107. function highlight(galleryID) {
  4108. const galleryDiv = getElement(`div[gid="${galleryID}"]`);
  4109. if (galleryDiv) {
  4110. galleryDiv.style.backgroundColor = "black";
  4111. }
  4112. }
  4113. function highlightAll() {
  4114. if (!highlightSwitch.value) {
  4115. return;
  4116. }
  4117. downloadedGalleriesIDs.forEach(highlight);
  4118. _GM_addValueChangeListener("downloaded-galleries-ids", (_key, _oldValue, newValue) => {
  4119. newValue.forEach(highlight);
  4120. });
  4121. }
  4122. return {
  4123. highlightAll,
  4124. setAsDownloaded
  4125. };
  4126. }
  4127. const toast = useToast();
  4128. function useArchive() {
  4129. const { setAsDownloaded } = useHighlight();
  4130. function setHentaiAtHomeEvent() {
  4131. var _a2, _b, _c;
  4132. const logger = new Logger("Hentai At Home Event");
  4133. const hentaiAtHomeLinks = getElements(".popup--archive table td a");
  4134. if (!(hentaiAtHomeLinks == null ? void 0 : hentaiAtHomeLinks.length)) {
  4135. logger.error("hentai@Home Links not found.");
  4136. return;
  4137. }
  4138. const postUrl = (_a2 = getElement("#hathdl_form")) == null ? void 0 : _a2.getAttribute("action");
  4139. if (!postUrl) {
  4140. logger.error("postUrl not found.");
  4141. return;
  4142. }
  4143. for (const link of hentaiAtHomeLinks) {
  4144. const ORIGINAL_SIZE = "org";
  4145. const resolution = ((_c = (_b = link.getAttribute("onclick")) == null ? void 0 : _b.split("'")) == null ? void 0 : _c[1]) || ORIGINAL_SIZE;
  4146. link.removeAttribute("onclick");
  4147. link.addEventListener("click", async (event) => {
  4148. event.preventDefault();
  4149. link.classList.add("is-fetching");
  4150. const doc = await sendDownloadRequest(postUrl, resolution);
  4151. const response = getElement("#db", doc);
  4152. logger.log(response);
  4153. const parsedResponse = parseResponse(response, logger);
  4154. if (parsedResponse) {
  4155. link.classList.remove("is-fetching");
  4156. if (/download has been queued/.test(parsedResponse)) {
  4157. toast.success(parsedResponse);
  4158. link.classList.add("is-finished");
  4159. } else {
  4160. toast.error(parsedResponse);
  4161. }
  4162. }
  4163. const gid = Number(new URL(postUrl).searchParams.get("gid"));
  4164. setAsDownloaded(gid);
  4165. });
  4166. }
  4167. }
  4168. async function sendDownloadRequest(postUrl, resolution) {
  4169. const formData = new FormData();
  4170. formData.append("hathdl_xres", resolution);
  4171. const doc = await getDoc(postUrl, {
  4172. method: "POST",
  4173. body: formData
  4174. });
  4175. return doc;
  4176. }
  4177. function parseResponse(response, logger) {
  4178. if (!response) {
  4179. logger.error("Failed to get response.");
  4180. return null;
  4181. }
  4182. if (!response.innerHTML) {
  4183. logger.error("Failed to get response innerHTML.");
  4184. return null;
  4185. }
  4186. const result = response.innerHTML.match(new RegExp("(?<=<p>)(.*?)(?=<\\/p>)", "g"));
  4187. if (!result) {
  4188. logger.error("Failed to parse response.");
  4189. return null;
  4190. }
  4191. return result.join("\n").replace(/<strong>#\d+<\/strong>/, "");
  4192. }
  4193. function setDirectDownloadEvent() {
  4194. const logger = new Logger("Archive Event");
  4195. const downloadButtons = getElements('form input[name="dlcheck"]');
  4196. if (!downloadButtons) {
  4197. logger.error("archive download buttons not found.");
  4198. return;
  4199. }
  4200. for (const button of downloadButtons) {
  4201. button.addEventListener("click", async (event) => {
  4202. var _a2;
  4203. event.preventDefault();
  4204. const form = (_a2 = button == null ? void 0 : button.parentElement) == null ? void 0 : _a2.parentElement;
  4205. if (!form) {
  4206. logger.error("form not found.");
  4207. return;
  4208. }
  4209. const url = form.getAttribute("action");
  4210. if (!url) {
  4211. logger.error("url not found.");
  4212. return;
  4213. }
  4214. const resolution = button.getAttribute("value");
  4215. button.parentElement.classList.add("is-fetching");
  4216. await sendDownloadRequest2(url, resolution);
  4217. button.parentElement.classList.remove("is-fetching");
  4218. const gid = Number(new URL(url).searchParams.get("gid"));
  4219. setAsDownloaded(gid);
  4220. });
  4221. }
  4222. async function sendDownloadRequest2(url, resolution) {
  4223. const resolutionParams = resolution === "Download Original Archive" ? "dlcheck=Download Original Archive&dltype=org" : "dlcheck=Download Resample Archive&dltype=res";
  4224. const response = await fetch(url, {
  4225. method: "POST",
  4226. body: resolutionParams,
  4227. headers: new Headers({
  4228. "Content-Type": "application/x-www-form-urlencoded"
  4229. })
  4230. });
  4231. const html = await response.text();
  4232. if (!html.includes("Locating archive server and preparing file for download...")) {
  4233. toast.error("something went wrong. Open your console to see the response");
  4234. console.warn("Download failed, response HTML:", html);
  4235. return;
  4236. }
  4237. const matches2 = html.match(/document\.location = "(.*)"/);
  4238. if (!matches2 || (matches2 == null ? void 0 : matches2.length) !== 2) {
  4239. toast.error("something went wrong. Open your console to see the response");
  4240. console.warn("Download failed, response HTML:", html);
  4241. return;
  4242. }
  4243. const downloadLink = `${matches2[1]}?start=1`;
  4244. window.location.href = downloadLink;
  4245. }
  4246. }
  4247. const { getInnerHTMLs } = useFetchPopups();
  4248. const { archiveInnerHtml: archiveInnerHtml2 } = getInnerHTMLs();
  4249. function setCancelArchiveEvent() {
  4250. var _a2, _b;
  4251. const logger = new Logger("Archive Event");
  4252. const invalidateForm = getElement("#invalidate_form");
  4253. if (!invalidateForm) {
  4254. logger.log("no unlocked archive to invalidate.");
  4255. return;
  4256. }
  4257. const cancelButton = (_b = (_a2 = invalidateForm == null ? void 0 : invalidateForm.nextElementSibling) == null ? void 0 : _a2.children) == null ? void 0 : _b[2];
  4258. if (!cancelButton || cancelButton.innerHTML !== "cancel") {
  4259. logger.log("no unlocked archive to invalidate.");
  4260. return;
  4261. }
  4262. cancelButton.removeAttribute("onclick");
  4263. cancelButton.addEventListener("click", (event) => {
  4264. event.preventDefault();
  4265. cancelButton.innerHTML = "canceling...";
  4266. const url = invalidateForm.getAttribute("action");
  4267. fetch(url, {
  4268. method: "POST",
  4269. body: "invalidate_sessions=1",
  4270. headers: new Headers({
  4271. "Content-Type": "application/x-www-form-urlencoded"
  4272. })
  4273. }).then((res) => res.text()).then((text) => {
  4274. var _a3;
  4275. const html = new DOMParser().parseFromString(text, "text/html");
  4276. archiveInnerHtml2.value = (_a3 = getElement("#db", html)) == null ? void 0 : _a3.innerHTML;
  4277. setTimeout(() => {
  4278. setDirectDownloadEvent();
  4279. }, 0);
  4280. });
  4281. });
  4282. }
  4283. function quickDownload(popup) {
  4284. function getHaHDownloadLinkElement(downloadMethod) {
  4285. const indexMap = {
  4286. [DownloadMethod.HaH_Original]: 6,
  4287. [DownloadMethod.HaH_2400]: 5
  4288. };
  4289. const index = indexMap[downloadMethod];
  4290. return getElement(`td:nth-child(${index}) > p > a`, popup.value);
  4291. }
  4292. switch (quickDownloadMethod.value) {
  4293. case DownloadMethod.HaH_Original:
  4294. case DownloadMethod.HaH_2400: {
  4295. const downloadLinkElement = getHaHDownloadLinkElement(quickDownloadMethod.value);
  4296. if (downloadLinkElement) {
  4297. downloadLinkElement.click();
  4298. } else {
  4299. toast.warning(`Failed ${quickDownloadMethod.value}. The link might not exists.
  4300. Open popup`);
  4301. return false;
  4302. }
  4303. break;
  4304. }
  4305. case DownloadMethod.Direct_Origin:
  4306. getElement('input[value="Download Original Archive"]', popup.value).click();
  4307. break;
  4308. case DownloadMethod.Direct_Resample:
  4309. getElement('input[value="Download Resample Archive"]', popup.value).click();
  4310. break;
  4311. }
  4312. return true;
  4313. }
  4314. return {
  4315. setHentaiAtHomeEvent,
  4316. setDirectDownloadEvent,
  4317. setCancelArchiveEvent,
  4318. quickDownload
  4319. };
  4320. }
  4321. const _hoisted_1$7 = ["innerHTML"];
  4322. const _sfc_main$8 = /* @__PURE__ */ vue.defineComponent({
  4323. __name: "FrontPageEnhancer",
  4324. setup(__props) {
  4325. if (scrollByRowSwitch.value) {
  4326. useWheelStep({
  4327. containerSelector: ".itg.gld",
  4328. itemsSelector: ".gl1t"
  4329. });
  4330. }
  4331. if (infiniteScrollSwitch.value) {
  4332. useInfiniteScroll({
  4333. onFetched: appendArchiveButtons
  4334. });
  4335. }
  4336. function useInfiniteScroll({
  4337. onFetched = () => {
  4338. }
  4339. } = {}) {
  4340. var _a2, _b;
  4341. const galleryContainer = getElement(".itg.gld");
  4342. const bottomPagination = (_a2 = getElements(".searchnav")) == null ? void 0 : _a2[1];
  4343. let nextPageUrl = (_b = getElement("#dnext")) == null ? void 0 : _b.getAttribute("href");
  4344. let isFetching = false;
  4345. const intersectionObserver = new IntersectionObserver(async ([bottomPagination2]) => {
  4346. var _a3;
  4347. if (!bottomPagination2.isIntersecting || isFetching) {
  4348. return;
  4349. }
  4350. if (!nextPageUrl) {
  4351. return;
  4352. }
  4353. isFetching = true;
  4354. galleryContainer == null ? void 0 : galleryContainer.classList.add("is-fetching");
  4355. const doc = await getDoc(nextPageUrl);
  4356. const galleriesOfNextPage = getElements(".itg.gld > .gl1t", doc);
  4357. if (!galleriesOfNextPage) {
  4358. return;
  4359. }
  4360. galleryContainer == null ? void 0 : galleryContainer.append(...galleriesOfNextPage);
  4361. isFetching = false;
  4362. galleryContainer == null ? void 0 : galleryContainer.classList.remove("is-fetching");
  4363. nextPageUrl = (_a3 = getElement("#dnext", doc)) == null ? void 0 : _a3.getAttribute("href");
  4364. history.pushState(void 0, doc.title, nextPageUrl);
  4365. onFetched();
  4366. });
  4367. if (bottomPagination) {
  4368. intersectionObserver.observe(bottomPagination);
  4369. }
  4370. }
  4371. const { getInnerHTMLs, fetchArchive } = useFetchPopups();
  4372. const { archiveInnerHtml: archiveInnerHtml2 } = getInnerHTMLs();
  4373. const archivePopup = vue.ref();
  4374. const activeButton = vue.ref();
  4375. async function appendArchiveButtons() {
  4376. const galleries = getElements(".gl1t");
  4377. galleries == null ? void 0 : galleries.forEach((gallery) => {
  4378. if (getElement(".archive-button", gallery)) {
  4379. return;
  4380. }
  4381. const button = document.createElement("span");
  4382. button.classList.add("archive-button");
  4383. button.textContent = "A";
  4384. button.title = "Show Archive";
  4385. button.onclick = async () => {
  4386. isArchivePopupShow.value = !isArchivePopupShow.value;
  4387. archiveInnerHtml2.value = "Fetching...";
  4388. activeButton.value = button;
  4389. const link = getElement("a", gallery);
  4390. const archiveLink = await getArchiveLink(link.href);
  4391. archiveInnerHtml2.value = await fetchArchive(archiveLink);
  4392. setTimeout(() => {
  4393. setArchiveEvent();
  4394. }, 0);
  4395. };
  4396. const downloadDiv = getElement(".gldown", gallery);
  4397. downloadDiv == null ? void 0 : downloadDiv.appendChild(button);
  4398. });
  4399. }
  4400. const borderRect = useElementBounding(getElement(".itg.gld"));
  4401. const popupRect = useElementBounding(archivePopup);
  4402. const targetRect = useElementBounding(activeButton);
  4403. const archivePopupPosition = vue.computed(() => {
  4404. const top = Math.min(targetRect.bottom.value + 5, borderRect.bottom.value - popupRect.height.value);
  4405. let left = targetRect.left.value - popupRect.width.value / 2;
  4406. const right = left + popupRect.width.value;
  4407. if (left < borderRect.left.value) {
  4408. left = borderRect.left.value;
  4409. } else if (right > borderRect.right.value) {
  4410. left = borderRect.right.value - popupRect.width.value;
  4411. }
  4412. return {
  4413. top: `${top}px`,
  4414. left: `${left}px`,
  4415. // 防止 popup right 超出邊界時,瀏覽器自動 shrink popup
  4416. marginRight: "-9999px"
  4417. };
  4418. });
  4419. if (archiveButtonSwitch.value) {
  4420. appendArchiveButtons();
  4421. }
  4422. const modalOptions = vue.ref({
  4423. teleportTo: ".enhancer-container",
  4424. displayDirective: "show",
  4425. hideOverlay: true,
  4426. contentTransition: "vfm-fade",
  4427. lockScroll: false
  4428. });
  4429. const isArchivePopupShow = vue.ref(false);
  4430. const { setHentaiAtHomeEvent, setDirectDownloadEvent, setCancelArchiveEvent, quickDownload } = useArchive();
  4431. const isQuickDownload = vue.computed(() => quickDownloadMethod.value !== DownloadMethod.Manual);
  4432. function setArchiveEvent() {
  4433. setHentaiAtHomeEvent();
  4434. setDirectDownloadEvent();
  4435. setCancelArchiveEvent();
  4436. if (isQuickDownload.value) {
  4437. const succeed = quickDownload(archivePopup);
  4438. if (!succeed) {
  4439. isArchivePopupShow.value = true;
  4440. }
  4441. }
  4442. }
  4443. const { highlightAll } = useHighlight();
  4444. highlightAll();
  4445. return (_ctx, _cache) => {
  4446. return vue.openBlock(), vue.createBlock(vue.unref(Ro), vue.mergeProps({
  4447. modelValue: isArchivePopupShow.value,
  4448. "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => isArchivePopupShow.value = $event)
  4449. }, modalOptions.value), {
  4450. default: vue.withCtx(() => [
  4451. vue.createElementVNode("div", {
  4452. ref_key: "archivePopup",
  4453. ref: archivePopup,
  4454. class: "popup popup--archive",
  4455. style: vue.normalizeStyle(archivePopupPosition.value),
  4456. innerHTML: vue.unref(archiveInnerHtml2)
  4457. }, null, 12, _hoisted_1$7)
  4458. ]),
  4459. _: 1
  4460. }, 16, ["modelValue"]);
  4461. };
  4462. }
  4463. });
  4464. function usePositions() {
  4465. const { archiveLinkAnchor, torrentLinkAnchor, favoritesLinkAnchor, infoDiv } = useGalleryElements();
  4466. const archiveLinkRect = useElementBounding(archiveLinkAnchor);
  4467. const torrentLinkRect = useElementBounding(torrentLinkAnchor);
  4468. const favoriteLinkRect = useElementBounding(favoritesLinkAnchor);
  4469. function getDownloadPopupRight() {
  4470. return (document.documentElement.clientWidth - infoDiv.clientWidth) / 2;
  4471. }
  4472. return {
  4473. archive: vue.computed(() => ({
  4474. top: `${archiveLinkRect.bottom.value + 5}px`,
  4475. right: `${getDownloadPopupRight()}px`
  4476. })),
  4477. torrent: vue.computed(() => ({
  4478. top: `${torrentLinkRect.bottom.value + 5}px`,
  4479. right: `${getDownloadPopupRight()}px`
  4480. })),
  4481. favorite: vue.computed(() => ({
  4482. top: `${favoriteLinkRect.bottom.value + 5}px`,
  4483. right: `${favoriteLinkRect.left.value}px`
  4484. }))
  4485. };
  4486. }
  4487. const baseLogger = new Logger("Images");
  4488. async function fetchAllImages({ delayInMs = 3e3 }) {
  4489. const logger = new LoggerScopeDecorator(baseLogger, "Fetch All");
  4490. if (!isFirstPage()) {
  4491. logger.log("Not first page, do nothing");
  4492. return;
  4493. }
  4494. logger.log("Start");
  4495. const pageUrls = getPageUrls();
  4496. if (!pageUrls) {
  4497. logger.error("Page URLs not found.");
  4498. return;
  4499. }
  4500. if (pageUrls.length === 0) {
  4501. logger.log("Only one page, do nothing");
  4502. return;
  4503. }
  4504. for (const url of pageUrls) {
  4505. try {
  4506. await delay2(delayInMs);
  4507. logger.log(`fetching ${url}`);
  4508. const doc = await getDoc(url);
  4509. const imageElements = getImageElements(doc);
  4510. if (!imageElements) {
  4511. return;
  4512. }
  4513. appendImages(imageElements);
  4514. } catch (error) {
  4515. if (error instanceof Error) {
  4516. logger.error(`fetch ${url} failed`, error);
  4517. }
  4518. }
  4519. }
  4520. logger.log("Done");
  4521. function isFirstPage() {
  4522. var _a2;
  4523. return ((_a2 = getElement(".ptds")) == null ? void 0 : _a2.innerText) === "1";
  4524. }
  4525. function getImageElements(doc) {
  4526. return getElements("#gdt > a", doc);
  4527. }
  4528. function getPageUrls() {
  4529. const lastPageElement = getElement(".ptt td:nth-last-child(2) a");
  4530. if (!lastPageElement) {
  4531. logger.error("Get last page element failed");
  4532. return;
  4533. }
  4534. const pageCount2 = Number(lastPageElement.innerText);
  4535. if (pageCount2 === 1) {
  4536. return [];
  4537. }
  4538. const { href } = window.location;
  4539. return Array(pageCount2 - 1).fill("").map((_, index) => `${href}?p=${index + 1}`);
  4540. }
  4541. function appendImages(elements) {
  4542. var _a2;
  4543. (_a2 = getElement("#gdt")) == null ? void 0 : _a2.append(...elements);
  4544. }
  4545. }
  4546. function useFavorite(favoriteInnerHtml2) {
  4547. const { fetchFavorites, getFavoritesLink } = useFetchPopups();
  4548. function setRequestEvents(target, popup, isPopupShow) {
  4549. var _a2, _b;
  4550. const submitButton = (_a2 = popup.value) == null ? void 0 : _a2.querySelector("input[type=submit]");
  4551. submitButton == null ? void 0 : submitButton.addEventListener("click", async (event) => {
  4552. var _a3;
  4553. event.preventDefault();
  4554. const favoriteCategory = (_a3 = getElement("[name=favcat]:checked")) == null ? void 0 : _a3.value;
  4555. await setFavorite(favoriteCategory);
  4556. });
  4557. const categoryOptions = (_b = popup.value) == null ? void 0 : _b.querySelectorAll("#galpop .nosel > div");
  4558. if (categoryOptions == null ? void 0 : categoryOptions.length) {
  4559. for (const option of categoryOptions) {
  4560. option.addEventListener("dblclick", async (event) => {
  4561. var _a3;
  4562. event.preventDefault();
  4563. const category = (_a3 = option.querySelector("[name=favcat]")) == null ? void 0 : _a3.value;
  4564. await setFavorite(category);
  4565. });
  4566. }
  4567. }
  4568. _unsafeWindow.clicked_fav = () => null;
  4569. async function setFavorite(category) {
  4570. var _a3, _b2;
  4571. const formData = new FormData();
  4572. const favoriteNote = (_a3 = getElement("[name=favnote]")) == null ? void 0 : _a3.value;
  4573. const apply = category === "favdel" ? "Apply Changes" : "Add to Favorites";
  4574. formData.append("favcat", category);
  4575. formData.append("favnote", favoriteNote);
  4576. formData.append("apply", apply);
  4577. formData.append("update", "1");
  4578. const response = await fetch(getFavoritesLink(), {
  4579. method: "POST",
  4580. body: formData
  4581. });
  4582. const html = await response.text();
  4583. const originalScript = (_b2 = html.match(/(if\(window\.opener\.document\.getElementById\("favoritelink"\)).*/)) == null ? void 0 : _b2[0];
  4584. const script = originalScript == null ? void 0 : originalScript.replaceAll(".opener", "");
  4585. Function(script)();
  4586. isPopupShow.value = false;
  4587. favoriteInnerHtml2.value = await fetchFavorites();
  4588. await vue.nextTick();
  4589. setRequestEvents(target, popup, isPopupShow);
  4590. }
  4591. }
  4592. return {
  4593. setRequestEvents
  4594. };
  4595. }
  4596. function useTorrent() {
  4597. function downloadTorrent(popup) {
  4598. var _a2;
  4599. (_a2 = getElement("a", popup.value)) == null ? void 0 : _a2.click();
  4600. }
  4601. return {
  4602. downloadTorrent
  4603. };
  4604. }
  4605. const _hoisted_1$6 = ["innerHTML"];
  4606. const _hoisted_2$3 = ["innerHTML"];
  4607. const _hoisted_3$2 = ["innerHTML"];
  4608. const _sfc_main$7 = /* @__PURE__ */ vue.defineComponent({
  4609. __name: "GalleryEnhancer",
  4610. async setup(__props) {
  4611. let __temp, __restore;
  4612. if (loadAllGalleryImagesSwitch.value) {
  4613. fetchAllImages({ delayInMs: 1e3 });
  4614. }
  4615. if (scrollByRowSwitch.value) {
  4616. useWheelStep({
  4617. containerSelector: "#gdt",
  4618. itemsSelector: "a"
  4619. });
  4620. }
  4621. const modalOptions = vue.ref({
  4622. teleportTo: ".enhancer-container",
  4623. displayDirective: "show",
  4624. hideOverlay: true,
  4625. contentTransition: "vfm-fade",
  4626. lockScroll: false
  4627. });
  4628. const { archiveLinkAnchor, torrentLinkAnchor, favoritesLinkAnchor } = useGalleryElements();
  4629. const archivePopup = vue.ref();
  4630. const torrentPopup = vue.ref();
  4631. const favoritePopup = vue.ref();
  4632. const { getInnerHTMLs, preloadLinks } = useFetchPopups();
  4633. const {
  4634. archiveInnerHtml: archiveInnerHtml2,
  4635. torrentInnerHtml: torrentInnerHtml2,
  4636. favoriteInnerHtml: favoriteInnerHtml2
  4637. } = getInnerHTMLs();
  4638. const isArchivePopupShow = vue.ref(false);
  4639. const isTorrentPopupShow = vue.ref(false);
  4640. const isFavoritePopupShow = vue.ref(false);
  4641. const {
  4642. archive: archivePosition,
  4643. torrent: torrentPosition,
  4644. favorite: favoritePosition
  4645. } = usePositions();
  4646. const { setHentaiAtHomeEvent, setDirectDownloadEvent, setCancelArchiveEvent, quickDownload } = useArchive();
  4647. const { downloadTorrent } = useTorrent();
  4648. const { setRequestEvents } = useFavorite(favoriteInnerHtml2);
  4649. if (betterPopupSwitch.value) {
  4650. [__temp, __restore] = vue.withAsyncContext(() => preloadLinks()), await __temp, __restore();
  4651. setTimeout(() => {
  4652. setArchiveClickEvent();
  4653. setTorrentClickEvent();
  4654. setFavoriteClickEvent();
  4655. }, 0);
  4656. }
  4657. const isQuickDownload = vue.computed(() => quickDownloadMethod.value !== DownloadMethod.Manual);
  4658. function setArchiveClickEvent() {
  4659. setHentaiAtHomeEvent();
  4660. setDirectDownloadEvent();
  4661. setCancelArchiveEvent();
  4662. archiveLinkAnchor.addEventListener("click", (event) => {
  4663. event.preventDefault();
  4664. event.stopPropagation();
  4665. if (isQuickDownload.value) {
  4666. const succeed = quickDownload(archivePopup);
  4667. if (!succeed) {
  4668. isArchivePopupShow.value = true;
  4669. }
  4670. } else {
  4671. isArchivePopupShow.value = !isArchivePopupShow.value;
  4672. }
  4673. });
  4674. setReady(archiveLinkAnchor);
  4675. }
  4676. const { setAsDownloaded } = useHighlight();
  4677. function setTorrentClickEvent() {
  4678. setRequestEvents(archiveLinkAnchor, favoritePopup, isFavoritePopupShow);
  4679. const isOnlyOneTorrent = torrentLinkAnchor.innerText === "Torrent Download (1)";
  4680. const torrentDownloadLinks = getElements("a", torrentPopup.value);
  4681. if (torrentDownloadLinks == null ? void 0 : torrentDownloadLinks.length) {
  4682. torrentDownloadLinks == null ? void 0 : torrentDownloadLinks.forEach((link) => {
  4683. link.addEventListener("click", () => {
  4684. setAsDownloaded(_unsafeWindow.gid);
  4685. });
  4686. });
  4687. }
  4688. torrentLinkAnchor.addEventListener("click", (event) => {
  4689. event.preventDefault();
  4690. event.stopPropagation();
  4691. if (isOnlyOneTorrent) {
  4692. downloadTorrent(torrentPopup);
  4693. } else {
  4694. isTorrentPopupShow.value = !isTorrentPopupShow.value;
  4695. }
  4696. });
  4697. setReady(torrentLinkAnchor);
  4698. }
  4699. function setFavoriteClickEvent() {
  4700. favoritesLinkAnchor.addEventListener("click", (event) => {
  4701. event.preventDefault();
  4702. event.stopPropagation();
  4703. isFavoritePopupShow.value = !isFavoritePopupShow.value;
  4704. });
  4705. setReady(favoritesLinkAnchor);
  4706. }
  4707. function setReady(element) {
  4708. element.removeAttribute("onclick");
  4709. element.classList.add("is-ready");
  4710. }
  4711. vue.onMounted(() => {
  4712. _unsafeWindow.pop_ren = Function('popUp(popbase + "rename", window.innerWidth * 2 / 3, window.innerHeight * 2 / 3);');
  4713. });
  4714. return (_ctx, _cache) => {
  4715. return vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [
  4716. vue.createVNode(vue.unref(Ro), vue.mergeProps({
  4717. modelValue: isArchivePopupShow.value,
  4718. "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => isArchivePopupShow.value = $event)
  4719. }, modalOptions.value), {
  4720. default: vue.withCtx(() => [
  4721. vue.createElementVNode("div", {
  4722. ref_key: "archivePopup",
  4723. ref: archivePopup,
  4724. class: "popup popup--archive",
  4725. style: vue.normalizeStyle(vue.unref(archivePosition)),
  4726. innerHTML: vue.unref(archiveInnerHtml2)
  4727. }, null, 12, _hoisted_1$6)
  4728. ]),
  4729. _: 1
  4730. }, 16, ["modelValue"]),
  4731. vue.createVNode(vue.unref(Ro), vue.mergeProps({
  4732. modelValue: isTorrentPopupShow.value,
  4733. "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => isTorrentPopupShow.value = $event)
  4734. }, modalOptions.value), {
  4735. default: vue.withCtx(() => [
  4736. vue.createElementVNode("div", {
  4737. ref_key: "torrentPopup",
  4738. ref: torrentPopup,
  4739. class: "popup popup--torrent",
  4740. style: vue.normalizeStyle(vue.unref(torrentPosition)),
  4741. innerHTML: vue.unref(torrentInnerHtml2)
  4742. }, null, 12, _hoisted_2$3)
  4743. ]),
  4744. _: 1
  4745. }, 16, ["modelValue"]),
  4746. vue.createVNode(vue.unref(Ro), vue.mergeProps({
  4747. modelValue: isFavoritePopupShow.value,
  4748. "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => isFavoritePopupShow.value = $event)
  4749. }, modalOptions.value), {
  4750. default: vue.withCtx(() => [
  4751. vue.createElementVNode("div", {
  4752. ref_key: "favoritePopup",
  4753. ref: favoritePopup,
  4754. class: "popup",
  4755. style: vue.normalizeStyle(vue.unref(favoritePosition)),
  4756. innerHTML: vue.unref(favoriteInnerHtml2)
  4757. }, null, 12, _hoisted_3$2)
  4758. ]),
  4759. _: 1
  4760. }, 16, ["modelValue"])
  4761. ], 64);
  4762. };
  4763. }
  4764. });
  4765. function useMultiPageViewerElements() {
  4766. const paneImagesDiv2 = getElement("#pane_images");
  4767. const paneThumbsDiv2 = getElement("#pane_thumbs");
  4768. return {
  4769. paneImagesDiv: paneImagesDiv2,
  4770. paneThumbsDiv: paneThumbsDiv2
  4771. };
  4772. }
  4773. const { paneImagesDiv: paneImagesDiv$1 } = useMultiPageViewerElements();
  4774. const location$1 = useBrowserLocation();
  4775. const currentPage$1 = vue.ref(Number((_a = location$1.value.hash) == null ? void 0 : _a.replace("#page", "")) || 1);
  4776. function usePages() {
  4777. const pageCount2 = _unsafeWindow.pagecount;
  4778. function appendPageIndex() {
  4779. const imageContainers = getElements(".mimg");
  4780. const pageCount22 = imageContainers.length;
  4781. const mutationObserver = new MutationObserver(([mutation]) => {
  4782. const target = mutation.target;
  4783. const index = target.id.split("image_")[1];
  4784. const captionElement = getElement(".mbar > *:nth-child(3)", target);
  4785. const captionText = captionElement == null ? void 0 : captionElement.innerText;
  4786. if (!captionText || (captionText == null ? void 0 : captionText.includes(" / "))) {
  4787. return;
  4788. }
  4789. captionElement.innerText = `${captionText} - ${index} ${pageCount22}`;
  4790. });
  4791. const config = { attributes: true };
  4792. imageContainers.forEach((container) => {
  4793. mutationObserver.observe(container, config);
  4794. });
  4795. }
  4796. function goToNextPage2() {
  4797. goToPageByOffset2(1);
  4798. }
  4799. function goToPrevPage2() {
  4800. goToPageByOffset2(-1);
  4801. }
  4802. function goToCurrentPage() {
  4803. goToPage2(currentPage$1.value);
  4804. }
  4805. function goToPageByOffset2(offset) {
  4806. let index = currentPage$1.value + offset;
  4807. index = Math.min(index, pageCount2);
  4808. index = Math.max(index, 1);
  4809. goToPage2(index);
  4810. }
  4811. function goToPage2(index) {
  4812. currentPage$1.value = index;
  4813. const target = getElement(`#image_${index}`);
  4814. target.scrollIntoView();
  4815. }
  4816. function scrollToImageTop() {
  4817. getCurrentImage2().scrollIntoView();
  4818. }
  4819. function scrollToRelativePosition(relativeToViewport) {
  4820. const currentImage = getCurrentImage2();
  4821. const { height: imageHeight } = currentImage.getBoundingClientRect();
  4822. const top = currentImage.offsetTop + relativeToViewport * imageHeight - window.innerHeight / 2 - 1;
  4823. paneImagesDiv$1.scrollTo({ top });
  4824. }
  4825. function getRelativeToViewport2() {
  4826. const currentImage = getCurrentImage2();
  4827. if (!currentImage) {
  4828. return null;
  4829. }
  4830. const { top: imageTop, height: imageHeight } = currentImage.getBoundingClientRect();
  4831. return 1 - (imageHeight - 1 + imageTop - window.innerHeight / 2) / imageHeight;
  4832. }
  4833. function scrollToProperPosition2(relativeToViewport, currentSize) {
  4834. const currentImage = getCurrentImage2();
  4835. if (currentSize === 100) {
  4836. scrollToImageTop();
  4837. } else {
  4838. scrollToRelativePosition(relativeToViewport);
  4839. }
  4840. if (currentImage.getBoundingClientRect().top > 1) {
  4841. scrollToImageTop();
  4842. }
  4843. }
  4844. function changePageOnWheel(event) {
  4845. if (event.deltaY < 0) {
  4846. goToPrevPage2();
  4847. } else {
  4848. goToNextPage2();
  4849. }
  4850. }
  4851. function setPreloadImagesEvent() {
  4852. paneImagesDiv$1.onscroll = () => {
  4853. _unsafeWindow.preload_scroll_images();
  4854. };
  4855. }
  4856. function getCurrentImage2() {
  4857. return getElement(`img[id^=imgsrc_${currentPage$1.value}]`);
  4858. }
  4859. function syncCurrentImageOnScroll() {
  4860. const imageContainers = getElements(".mimg");
  4861. let firstIntersectingIndex = 1;
  4862. const observer = new IntersectionObserver((entries) => {
  4863. firstIntersectingIndex = Number(entries[0].target.id.replace("image_", ""));
  4864. });
  4865. imageContainers.forEach((container) => {
  4866. observer.observe(container);
  4867. });
  4868. paneImagesDiv$1.addEventListener("scroll", () => {
  4869. const visibleImageContainers = [];
  4870. for (let index = Math.max(firstIntersectingIndex - 1, 1); index < imageContainers.length; index++) {
  4871. const percentage = getVisiblePercentageInViewport(imageContainers[index - 1]);
  4872. if (percentage > 0) {
  4873. visibleImageContainers.push({
  4874. index,
  4875. percentage,
  4876. element: imageContainers[index]
  4877. });
  4878. }
  4879. }
  4880. if (visibleImageContainers.length === 0) {
  4881. return;
  4882. } else if (visibleImageContainers.length === 1) {
  4883. currentPage$1.value = visibleImageContainers[0].index;
  4884. } else {
  4885. visibleImageContainers.sort((elem1, elem2) => elem2.percentage - elem1.percentage);
  4886. const [largest, secondLargest] = visibleImageContainers;
  4887. if (largest.percentage / secondLargest.percentage >= 2) {
  4888. currentPage$1.value = largest.index;
  4889. }
  4890. }
  4891. });
  4892. }
  4893. function getVisiblePercentageInViewport(element) {
  4894. const viewportHeight = window.innerHeight;
  4895. const { top, bottom } = element.getBoundingClientRect();
  4896. if (top > viewportHeight || bottom < 0) {
  4897. return 0;
  4898. }
  4899. const visibleBottom = Math.min(viewportHeight, bottom);
  4900. const visibleTop = Math.max(top, 0);
  4901. return (visibleBottom - visibleTop) / viewportHeight;
  4902. }
  4903. return {
  4904. appendPageIndex,
  4905. pageCount: pageCount2,
  4906. currentPage: currentPage$1,
  4907. getCurrentImage: getCurrentImage2,
  4908. goToNextPage: goToNextPage2,
  4909. goToPrevPage: goToPrevPage2,
  4910. goToPageByOffset: goToPageByOffset2,
  4911. goToPage: goToPage2,
  4912. goToCurrentPage,
  4913. scrollToImageTop,
  4914. scrollToRelativePosition,
  4915. getRelativeToViewport: getRelativeToViewport2,
  4916. scrollToProperPosition: scrollToProperPosition2,
  4917. changePageOnWheel,
  4918. syncCurrentImageOnScroll,
  4919. setPreloadImagesEvent
  4920. };
  4921. }
  4922. var freeGlobal = typeof global == "object" && global && global.Object === Object && global;
  4923. var freeSelf = typeof self == "object" && self && self.Object === Object && self;
  4924. var root = freeGlobal || freeSelf || Function("return this")();
  4925. var Symbol$1 = root.Symbol;
  4926. var objectProto$1 = Object.prototype;
  4927. var hasOwnProperty = objectProto$1.hasOwnProperty;
  4928. var nativeObjectToString$1 = objectProto$1.toString;
  4929. var symToStringTag$1 = Symbol$1 ? Symbol$1.toStringTag : void 0;
  4930. function getRawTag(value) {
  4931. var isOwn = hasOwnProperty.call(value, symToStringTag$1), tag = value[symToStringTag$1];
  4932. try {
  4933. value[symToStringTag$1] = void 0;
  4934. var unmasked = true;
  4935. } catch (e) {
  4936. }
  4937. var result = nativeObjectToString$1.call(value);
  4938. if (unmasked) {
  4939. if (isOwn) {
  4940. value[symToStringTag$1] = tag;
  4941. } else {
  4942. delete value[symToStringTag$1];
  4943. }
  4944. }
  4945. return result;
  4946. }
  4947. var objectProto = Object.prototype;
  4948. var nativeObjectToString = objectProto.toString;
  4949. function objectToString(value) {
  4950. return nativeObjectToString.call(value);
  4951. }
  4952. var nullTag = "[object Null]", undefinedTag = "[object Undefined]";
  4953. var symToStringTag = Symbol$1 ? Symbol$1.toStringTag : void 0;
  4954. function baseGetTag(value) {
  4955. if (value == null) {
  4956. return value === void 0 ? undefinedTag : nullTag;
  4957. }
  4958. return symToStringTag && symToStringTag in Object(value) ? getRawTag(value) : objectToString(value);
  4959. }
  4960. function isObjectLike(value) {
  4961. return value != null && typeof value == "object";
  4962. }
  4963. var symbolTag = "[object Symbol]";
  4964. function isSymbol(value) {
  4965. return typeof value == "symbol" || isObjectLike(value) && baseGetTag(value) == symbolTag;
  4966. }
  4967. var reWhitespace = /\s/;
  4968. function trimmedEndIndex(string) {
  4969. var index = string.length;
  4970. while (index-- && reWhitespace.test(string.charAt(index))) {
  4971. }
  4972. return index;
  4973. }
  4974. var reTrimStart = /^\s+/;
  4975. function baseTrim(string) {
  4976. return string ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, "") : string;
  4977. }
  4978. function isObject(value) {
  4979. var type = typeof value;
  4980. return value != null && (type == "object" || type == "function");
  4981. }
  4982. var NAN = 0 / 0;
  4983. var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
  4984. var reIsBinary = /^0b[01]+$/i;
  4985. var reIsOctal = /^0o[0-7]+$/i;
  4986. var freeParseInt = parseInt;
  4987. function toNumber(value) {
  4988. if (typeof value == "number") {
  4989. return value;
  4990. }
  4991. if (isSymbol(value)) {
  4992. return NAN;
  4993. }
  4994. if (isObject(value)) {
  4995. var other = typeof value.valueOf == "function" ? value.valueOf() : value;
  4996. value = isObject(other) ? other + "" : other;
  4997. }
  4998. if (typeof value != "string") {
  4999. return value === 0 ? value : +value;
  5000. }
  5001. value = baseTrim(value);
  5002. var isBinary = reIsBinary.test(value);
  5003. return isBinary || reIsOctal.test(value) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : reIsBadHex.test(value) ? NAN : +value;
  5004. }
  5005. var now = function() {
  5006. return root.Date.now();
  5007. };
  5008. var FUNC_ERROR_TEXT = "Expected a function";
  5009. var nativeMax = Math.max, nativeMin = Math.min;
  5010. function debounce(func, wait, options) {
  5011. var lastArgs, lastThis, maxWait, result, timerId, lastCallTime, lastInvokeTime = 0, leading = false, maxing = false, trailing = true;
  5012. if (typeof func != "function") {
  5013. throw new TypeError(FUNC_ERROR_TEXT);
  5014. }
  5015. wait = toNumber(wait) || 0;
  5016. if (isObject(options)) {
  5017. leading = !!options.leading;
  5018. maxing = "maxWait" in options;
  5019. maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
  5020. trailing = "trailing" in options ? !!options.trailing : trailing;
  5021. }
  5022. function invokeFunc(time) {
  5023. var args = lastArgs, thisArg = lastThis;
  5024. lastArgs = lastThis = void 0;
  5025. lastInvokeTime = time;
  5026. result = func.apply(thisArg, args);
  5027. return result;
  5028. }
  5029. function leadingEdge(time) {
  5030. lastInvokeTime = time;
  5031. timerId = setTimeout(timerExpired, wait);
  5032. return leading ? invokeFunc(time) : result;
  5033. }
  5034. function remainingWait(time) {
  5035. var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime, timeWaiting = wait - timeSinceLastCall;
  5036. return maxing ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke) : timeWaiting;
  5037. }
  5038. function shouldInvoke(time) {
  5039. var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime;
  5040. return lastCallTime === void 0 || timeSinceLastCall >= wait || timeSinceLastCall < 0 || maxing && timeSinceLastInvoke >= maxWait;
  5041. }
  5042. function timerExpired() {
  5043. var time = now();
  5044. if (shouldInvoke(time)) {
  5045. return trailingEdge(time);
  5046. }
  5047. timerId = setTimeout(timerExpired, remainingWait(time));
  5048. }
  5049. function trailingEdge(time) {
  5050. timerId = void 0;
  5051. if (trailing && lastArgs) {
  5052. return invokeFunc(time);
  5053. }
  5054. lastArgs = lastThis = void 0;
  5055. return result;
  5056. }
  5057. function cancel() {
  5058. if (timerId !== void 0) {
  5059. clearTimeout(timerId);
  5060. }
  5061. lastInvokeTime = 0;
  5062. lastArgs = lastCallTime = lastThis = timerId = void 0;
  5063. }
  5064. function flush() {
  5065. return timerId === void 0 ? result : trailingEdge(now());
  5066. }
  5067. function debounced() {
  5068. var time = now(), isInvoking = shouldInvoke(time);
  5069. lastArgs = arguments;
  5070. lastThis = this;
  5071. lastCallTime = time;
  5072. if (isInvoking) {
  5073. if (timerId === void 0) {
  5074. return leadingEdge(lastCallTime);
  5075. }
  5076. if (maxing) {
  5077. clearTimeout(timerId);
  5078. timerId = setTimeout(timerExpired, wait);
  5079. return invokeFunc(lastCallTime);
  5080. }
  5081. }
  5082. if (timerId === void 0) {
  5083. timerId = setTimeout(timerExpired, wait);
  5084. }
  5085. return result;
  5086. }
  5087. debounced.cancel = cancel;
  5088. debounced.flush = flush;
  5089. return debounced;
  5090. }
  5091. const {
  5092. pageCount,
  5093. currentPage,
  5094. getCurrentImage,
  5095. goToPage,
  5096. goToPageByOffset,
  5097. goToNextPage,
  5098. goToPrevPage,
  5099. getRelativeToViewport,
  5100. scrollToProperPosition
  5101. } = usePages();
  5102. const {
  5103. paneImagesDiv,
  5104. paneThumbsDiv
  5105. } = useMultiPageViewerElements();
  5106. setReflowTrigger();
  5107. function setReflowTrigger() {
  5108. const observer = new ResizeObserver((entries) => {
  5109. for (const entry of entries) {
  5110. requestAnimationFrame(() => {
  5111. requestAnimationFrame(() => {
  5112. var _a2;
  5113. (_a2 = entry.target) == null ? void 0 : _a2.dispatchEvent(new CustomEvent("reflow"));
  5114. });
  5115. });
  5116. }
  5117. });
  5118. observer.observe(document.body);
  5119. }
  5120. function useEvents() {
  5121. function setKeyBoardEvent() {
  5122. document.onkeydown = null;
  5123. window.addEventListener("keydown", async (event) => {
  5124. const isCtrlPressed = event.ctrlKey;
  5125. if (isCtrlPressed) {
  5126. switch (event.code) {
  5127. case "ArrowLeft":
  5128. goToPageByOffset(-10);
  5129. break;
  5130. case "ArrowRight":
  5131. goToPageByOffset(10);
  5132. break;
  5133. }
  5134. } else {
  5135. const currentImage = getCurrentImage();
  5136. switch (event.code) {
  5137. case "Numpad8":
  5138. if (currentImage) {
  5139. scrollElement(paneImagesDiv, {
  5140. absolute: currentImage.offsetTop
  5141. });
  5142. }
  5143. break;
  5144. case "Numpad5":
  5145. if (currentImage) {
  5146. scrollElement(paneImagesDiv, {
  5147. absolute: currentImage.offsetTop + (currentImage.offsetHeight - window.innerHeight) / 2
  5148. });
  5149. }
  5150. break;
  5151. case "Numpad2":
  5152. if (currentImage) {
  5153. scrollElement(paneImagesDiv, {
  5154. absolute: currentImage.offsetTop + currentImage.offsetHeight - window.innerHeight
  5155. });
  5156. }
  5157. break;
  5158. case "ArrowUp":
  5159. scrollElement(paneImagesDiv, { offset: -50 });
  5160. break;
  5161. case "ArrowDown":
  5162. scrollElement(paneImagesDiv, { offset: 50 });
  5163. break;
  5164. case "ArrowLeft":
  5165. case "Numpad1":
  5166. case "Numpad4":
  5167. goToPrevPage();
  5168. break;
  5169. case "Backspace":
  5170. event.preventDefault();
  5171. goToPrevPage();
  5172. break;
  5173. case "ArrowRight":
  5174. case "Numpad3":
  5175. case "Numpad6":
  5176. case "Space":
  5177. goToNextPage();
  5178. break;
  5179. case "PageUp":
  5180. goToPageByOffset(-10);
  5181. break;
  5182. case "PageDown":
  5183. goToPageByOffset(10);
  5184. break;
  5185. case "Home":
  5186. goToPage(1);
  5187. break;
  5188. case "End":
  5189. goToPage(pageCount);
  5190. break;
  5191. case "KeyF":
  5192. case "Enter": {
  5193. toggleFullScreen();
  5194. break;
  5195. }
  5196. case "KeyR":
  5197. _unsafeWindow.action_reload(currentPage.value);
  5198. break;
  5199. case "Numpad7":
  5200. rotate(-90);
  5201. break;
  5202. case "Numpad9":
  5203. rotate(90);
  5204. break;
  5205. }
  5206. }
  5207. });
  5208. }
  5209. function setClickEvent() {
  5210. setChangePageClickEvent();
  5211. setFullscreenToggleEvent();
  5212. setThumbsClickEvent();
  5213. function setChangePageClickEvent() {
  5214. const config = {
  5215. click: goToNextPage,
  5216. contextmenu: goToPrevPage
  5217. };
  5218. for (const [event, action] of Object.entries(config)) {
  5219. paneImagesDiv.addEventListener(event, (event2) => {
  5220. const target = event2.target;
  5221. if (target.closest(".mbar")) {
  5222. return;
  5223. }
  5224. event2.preventDefault();
  5225. event2.stopPropagation();
  5226. action();
  5227. hideCursor(event2);
  5228. });
  5229. }
  5230. }
  5231. function setFullscreenToggleEvent() {
  5232. document.body.addEventListener("mousedown", (event) => {
  5233. if (event.button !== 1) {
  5234. return;
  5235. }
  5236. const target = event.target;
  5237. if (target.closest(".original-functions")) {
  5238. return;
  5239. }
  5240. document.body.addEventListener("mouseup", () => {
  5241. toggleFullScreen();
  5242. }, {
  5243. once: true
  5244. });
  5245. });
  5246. }
  5247. function setThumbsClickEvent() {
  5248. paneThumbsDiv.addEventListener("click", (event) => {
  5249. var _a2;
  5250. const index = Number(
  5251. (_a2 = event.target.closest("div")) == null ? void 0 : _a2.id.replace("thumb_", "")
  5252. );
  5253. currentPage.value = index;
  5254. });
  5255. }
  5256. }
  5257. function setShowCursorEvent() {
  5258. document.body.addEventListener("mousemove", (event) => {
  5259. if (!checkMouseDelta(event)) {
  5260. return;
  5261. }
  5262. showCursor();
  5263. });
  5264. }
  5265. function setHideCursorEvent() {
  5266. document.body.addEventListener("mousewheel", (event) => {
  5267. hideCursor(event);
  5268. }, true);
  5269. const debouncedHideCursor = debounce(hideCursor, 1e3);
  5270. document.body.addEventListener("mousemove", (event) => {
  5271. debouncedHideCursor(event);
  5272. }, true);
  5273. }
  5274. const prevMousePoint = {
  5275. x: 0,
  5276. y: 0
  5277. };
  5278. function checkMouseDelta({ clientX, clientY }) {
  5279. const threshold = 50;
  5280. return Math.abs(clientX - prevMousePoint.x) >= threshold || Math.abs(clientY - prevMousePoint.y) >= threshold;
  5281. }
  5282. function showCursor() {
  5283. document.body.classList.remove("hide-cursor");
  5284. }
  5285. function hideCursor({ clientX, clientY }) {
  5286. prevMousePoint.x = clientX;
  5287. prevMousePoint.y = clientY;
  5288. document.body.classList.add("hide-cursor");
  5289. }
  5290. function setShowThumbsEvent() {
  5291. document.addEventListener("mousemove", (event) => {
  5292. const threshold = 15;
  5293. const shouldShowThumbs = event.clientX < paneThumbsDiv.offsetWidth + threshold;
  5294. paneThumbsDiv.style.opacity = shouldShowThumbs ? "1" : "0";
  5295. });
  5296. }
  5297. const { toggle } = useFullscreen(document.body);
  5298. async function toggleFullScreen() {
  5299. const relativeToViewport = getRelativeToViewport();
  5300. const page = currentPage.value;
  5301. document.body.addEventListener("reflow", () => {
  5302. if (relativeToViewport) {
  5303. setTimeout(() => {
  5304. goToPage(page);
  5305. setTimeout(() => {
  5306. scrollToProperPosition(relativeToViewport);
  5307. }, 0);
  5308. }, 100);
  5309. }
  5310. }, {
  5311. once: true
  5312. });
  5313. await toggle();
  5314. }
  5315. function rotate(degree) {
  5316. const currentImage = getCurrentImage();
  5317. const currentDegree = Number(currentImage.style.rotate.replace("deg", ""));
  5318. const newDegree = (currentDegree + degree) % 360;
  5319. currentImage.style.rotate = `${newDegree}deg`;
  5320. if (newDegree % 180 == 0) {
  5321. currentImage.style.scale = "initial";
  5322. } else {
  5323. const { width, height } = currentImage.getBoundingClientRect();
  5324. currentImage.style.scale = (width / height).toString();
  5325. }
  5326. }
  5327. return {
  5328. setKeyBoardEvent,
  5329. setClickEvent,
  5330. setShowCursorEvent,
  5331. setHideCursorEvent,
  5332. setShowThumbsEvent
  5333. };
  5334. }
  5335. const _hoisted_1$5 = { class: "page-elevator" };
  5336. const _hoisted_2$2 = ["value"];
  5337. const _hoisted_3$1 = ["textContent"];
  5338. const _sfc_main$6 = /* @__PURE__ */ vue.defineComponent({
  5339. __name: "PageElevator",
  5340. setup(__props) {
  5341. const {
  5342. pageCount: pageCount2,
  5343. currentPage: currentPage2,
  5344. goToPage: goToPage2
  5345. } = usePages();
  5346. return (_ctx, _cache) => {
  5347. return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$5, [
  5348. vue.createElementVNode("input", {
  5349. type: "text",
  5350. class: "page-elevator__input",
  5351. value: vue.unref(currentPage2),
  5352. onKeydown: [
  5353. _cache[0] || (_cache[0] = vue.withModifiers(() => {
  5354. }, ["stop"])),
  5355. _cache[1] || (_cache[1] = vue.withKeys(($event) => vue.unref(goToPage2)(Number($event.target.value)), ["enter"]))
  5356. ]
  5357. }, null, 40, _hoisted_2$2),
  5358. _cache[2] || (_cache[2] = vue.createElementVNode("span", { class: "page-elevator__slash" }, "/", -1)),
  5359. vue.createElementVNode("span", {
  5360. textContent: vue.toDisplayString(vue.unref(pageCount2))
  5361. }, null, 8, _hoisted_3$1)
  5362. ]);
  5363. };
  5364. }
  5365. });
  5366. const _export_sfc = (sfc, props) => {
  5367. const target = sfc.__vccOpts || sfc;
  5368. for (const [key, val] of props) {
  5369. target[key] = val;
  5370. }
  5371. return target;
  5372. };
  5373. const PageElevator = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["__scopeId", "data-v-c3f8cb4a"]]);
  5374. const _hoisted_1$4 = { class: "image-resizer" };
  5375. const _hoisted_2$1 = ["onClick", "textContent"];
  5376. const _sfc_main$5 = /* @__PURE__ */ vue.defineComponent({
  5377. __name: "ImageResizer",
  5378. setup(__props) {
  5379. const {
  5380. goToCurrentPage,
  5381. getRelativeToViewport: getRelativeToViewport2,
  5382. scrollToProperPosition: scrollToProperPosition2
  5383. } = usePages();
  5384. const { paneImagesDiv: paneImagesDiv2 } = useMultiPageViewerElements();
  5385. const {
  5386. sizeList,
  5387. currentIndex,
  5388. setImageSize,
  5389. onResizerClick,
  5390. setResizeShortcuts
  5391. } = useImageResizer();
  5392. setResizeShortcuts();
  5393. setTimeout(() => {
  5394. setImageSize(currentIndex.value);
  5395. goToCurrentPage();
  5396. }, 0);
  5397. function useImageResizer() {
  5398. const sizeList2 = [100, 125, 150, 175, 200];
  5399. const storedIndex = useStorage("image-resizer-index", 0);
  5400. const currentIndex2 = vue.ref(storedIndex.value);
  5401. vue.watch(currentIndex2, (index) => {
  5402. storedIndex.value = index;
  5403. });
  5404. const currentSize = vue.computed(() => {
  5405. if (currentIndex2.value < 0) {
  5406. return void 0;
  5407. }
  5408. return sizeList2[currentIndex2.value];
  5409. });
  5410. function onResizerClick2(index) {
  5411. const relativeToViewport = getRelativeToViewport2();
  5412. if (index === currentIndex2.value) {
  5413. clearImageSize();
  5414. } else {
  5415. setImageSize2(index);
  5416. }
  5417. if (relativeToViewport) {
  5418. scrollToProperPosition2(relativeToViewport);
  5419. }
  5420. }
  5421. function setImageSize2(index) {
  5422. currentIndex2.value = index;
  5423. paneImagesDiv2.style.setProperty("--image-size", `${currentSize.value}vh`);
  5424. }
  5425. function clearImageSize() {
  5426. currentIndex2.value = -1;
  5427. paneImagesDiv2.style.removeProperty("--image-size");
  5428. }
  5429. function increaseImageSize() {
  5430. const index = Math.min(currentIndex2.value + 1, sizeList2.length - 1);
  5431. setImageSize2(index);
  5432. }
  5433. function decreaseImageSize() {
  5434. const index = currentIndex2.value === -1 ? sizeList2.length - 1 : Math.max(currentIndex2.value - 1, 0);
  5435. setImageSize2(index);
  5436. }
  5437. function setResizeShortcuts2() {
  5438. window.addEventListener("keydown", (event) => {
  5439. var _a2;
  5440. const relativeToViewport = getRelativeToViewport2();
  5441. const isCtrlPressed = event.ctrlKey;
  5442. if (isCtrlPressed) {
  5443. const regex = /Numpad(?<index>[1-5])/;
  5444. const matchResult = event.code.match(regex);
  5445. if (!matchResult) {
  5446. return;
  5447. }
  5448. const index = Number((_a2 = matchResult.groups) == null ? void 0 : _a2.index);
  5449. setImageSize2(index - 1);
  5450. } else {
  5451. switch (event.code) {
  5452. case "NumpadAdd":
  5453. increaseImageSize();
  5454. break;
  5455. case "NumpadSubtract":
  5456. decreaseImageSize();
  5457. break;
  5458. case "Numpad0":
  5459. if (currentIndex2.value === 0) {
  5460. clearImageSize();
  5461. } else {
  5462. setImageSize2(0);
  5463. }
  5464. break;
  5465. case "NumpadDecimal": {
  5466. const index = Math.floor(sizeList2.length / 2);
  5467. if (currentIndex2.value === index) {
  5468. clearImageSize();
  5469. } else {
  5470. setImageSize2(index);
  5471. }
  5472. break;
  5473. }
  5474. case "NumpadEnter":
  5475. clearImageSize();
  5476. break;
  5477. default:
  5478. return;
  5479. }
  5480. }
  5481. if (relativeToViewport) {
  5482. scrollToProperPosition2(relativeToViewport, currentSize.value);
  5483. }
  5484. });
  5485. }
  5486. return {
  5487. sizeList: sizeList2,
  5488. currentIndex: currentIndex2,
  5489. currentSize,
  5490. setImageSize: setImageSize2,
  5491. onResizerClick: onResizerClick2,
  5492. setResizeShortcuts: setResizeShortcuts2
  5493. };
  5494. }
  5495. return (_ctx, _cache) => {
  5496. return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$4, [
  5497. (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(vue.unref(sizeList), (size, index) => {
  5498. return vue.openBlock(), vue.createElementBlock("button", {
  5499. key: size,
  5500. class: vue.normalizeClass(["image-resizer__button", { "image-resizer__button--active": index === vue.unref(currentIndex) }]),
  5501. onClick: ($event) => vue.unref(onResizerClick)(index),
  5502. textContent: vue.toDisplayString(size)
  5503. }, null, 10, _hoisted_2$1);
  5504. }), 128))
  5505. ]);
  5506. };
  5507. }
  5508. });
  5509. const ImageResizer = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["__scopeId", "data-v-19caf69f"]]);
  5510. const _hoisted_1$3 = ["innerHTML"];
  5511. const _sfc_main$4 = /* @__PURE__ */ vue.defineComponent({
  5512. __name: "MultiPageViewerEnhancer",
  5513. setup(__props) {
  5514. const {
  5515. currentPage: currentPage2,
  5516. appendPageIndex,
  5517. changePageOnWheel,
  5518. setPreloadImagesEvent,
  5519. syncCurrentImageOnScroll
  5520. } = usePages();
  5521. const {
  5522. setKeyBoardEvent,
  5523. setClickEvent,
  5524. setShowCursorEvent,
  5525. setHideCursorEvent,
  5526. setShowThumbsEvent
  5527. } = useEvents();
  5528. appendPageIndex();
  5529. setPreloadImagesEvent();
  5530. syncCurrentImageOnScroll();
  5531. setKeyBoardEvent();
  5532. setClickEvent();
  5533. setShowCursorEvent();
  5534. setHideCursorEvent();
  5535. setShowThumbsEvent();
  5536. useWheelStep({
  5537. containerSelector: "#pane_thumbs",
  5538. itemsSelector: "[id^=thumb_]"
  5539. });
  5540. const exhentaiButtons = vue.ref("");
  5541. vue.onMounted(() => {
  5542. exhentaiButtons.value = replaceOriginalFunctions();
  5543. });
  5544. function replaceOriginalFunctions() {
  5545. var _a2;
  5546. const originalFunctions = getElement("#bar3");
  5547. const closeButton = originalFunctions.querySelector("img:first-child");
  5548. if (!closeButton) {
  5549. return "";
  5550. }
  5551. const link = document.createElement("a");
  5552. link.href = window.location.origin + window.location.pathname.replace("mpv", "g");
  5553. (_a2 = closeButton.parentNode) == null ? void 0 : _a2.insertBefore(link, closeButton);
  5554. link.append(closeButton);
  5555. return originalFunctions.innerHTML;
  5556. }
  5557. vue.onMounted(() => {
  5558. overrideGlobalCSS();
  5559. vue.watch(() => preventImageRemovalSwitch.value, (value) => {
  5560. if (!value) {
  5561. return;
  5562. }
  5563. _unsafeWindow.preload_generic = Function("a", "b", "c", `
  5564. var d = a.scrollTop;
  5565. a = d + a.offsetHeight;
  5566. for (var e = "image" == b, f = 1; f <= pagecount; f++) {
  5567. var g = document.getElementById(b + "_" + f)
  5568. , h = g.offsetTop
  5569. , k = h + g.offsetHeight;
  5570. if ("hidden" == g.style.visibility && k >= d && h <= a + c)
  5571. e ? load_image(f) : load_thumb(f),
  5572. g.style.visibility = "visible";
  5573. }
  5574. `);
  5575. }, { immediate: true });
  5576. vue.watch(currentPage2, (index) => {
  5577. var _a2;
  5578. (_a2 = getElement(`#thumb_${index}`)) == null ? void 0 : _a2.scrollIntoView({
  5579. block: "center"
  5580. });
  5581. });
  5582. });
  5583. function overrideGlobalCSS() {
  5584. _GM_addStyle(`
  5585. html,
  5586. body {
  5587. padding: 0;
  5588. width: 100% !important;
  5589. height: 100% !important;
  5590. }
  5591.  
  5592. div#bar3 {
  5593. display: none;
  5594. }
  5595.  
  5596. .hide-cursor,
  5597. .hide-cursor * {
  5598. cursor: none;
  5599. }
  5600.  
  5601. .original-functions {
  5602. position: absolute;
  5603. top: 0;
  5604. right: 0;
  5605. display: block;
  5606. width: 35px;
  5607. height: 270px;
  5608. opacity: 0;
  5609. transition: opacity 0.3s ease;
  5610.  
  5611. &:hover {
  5612. opacity: 1;
  5613. }
  5614.  
  5615. > img {
  5616. cursor: pointer;
  5617. }
  5618. }
  5619.  
  5620. #pane_images {
  5621. inset: 0 !important;
  5622. margin: auto;
  5623. }
  5624.  
  5625. #pane_thumbs {
  5626. display: block;
  5627. opacity: 0;
  5628. z-index: 1;
  5629. transition: opacity 0.3s;
  5630. }
  5631. `);
  5632. }
  5633. return (_ctx, _cache) => {
  5634. return vue.openBlock(), vue.createElementBlock("div", {
  5635. class: "enhancer-features",
  5636. onWheel: _cache[0] || (_cache[0] = vue.withModifiers(
  5637. //@ts-ignore
  5638. (...args) => vue.unref(changePageOnWheel) && vue.unref(changePageOnWheel)(...args),
  5639. ["stop"]
  5640. ))
  5641. }, [
  5642. vue.createVNode(PageElevator, { class: "enhancer-features__feature" }),
  5643. vue.createVNode(ImageResizer, { class: "enhancer-features__feature" }),
  5644. vue.createElementVNode("div", {
  5645. class: "original-functions",
  5646. innerHTML: exhentaiButtons.value
  5647. }, null, 8, _hoisted_1$3)
  5648. ], 32);
  5649. };
  5650. }
  5651. });
  5652. const _sfc_main$3 = {};
  5653. const _hoisted_1$2 = {
  5654. xmlns: "http://www.w3.org/2000/svg",
  5655. "xmlns:xlink": "http://www.w3.org/1999/xlink",
  5656. fill: "#FFF",
  5657. version: "1.1",
  5658. width: "800px",
  5659. height: "800px",
  5660. viewBox: "0 0 94.926 94.926",
  5661. "xml:space": "preserve"
  5662. };
  5663. function _sfc_render(_ctx, _cache) {
  5664. return vue.openBlock(), vue.createElementBlock("svg", _hoisted_1$2, _cache[0] || (_cache[0] = [
  5665. vue.createElementVNode("g", null, [
  5666. vue.createElementVNode("path", { d: "M55.931,47.463L94.306,9.09c0.826-0.827,0.826-2.167,0-2.994L88.833,0.62C88.436,0.224,87.896,0,87.335,0 c-0.562,0-1.101,0.224-1.498,0.62L47.463,38.994L9.089,0.62c-0.795-0.795-2.202-0.794-2.995,0L0.622,6.096 c-0.827,0.827-0.827,2.167,0,2.994l38.374,38.373L0.622,85.836c-0.827,0.827-0.827,2.167,0,2.994l5.473,5.476 c0.397,0.396,0.936,0.62,1.498,0.62s1.1-0.224,1.497-0.62l38.374-38.374l38.374,38.374c0.397,0.396,0.937,0.62,1.498,0.62 s1.101-0.224,1.498-0.62l5.473-5.476c0.826-0.827,0.826-2.167,0-2.994L55.931,47.463z" })
  5667. ], -1)
  5668. ]));
  5669. }
  5670. const CrossButton = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["render", _sfc_render]]);
  5671. const _hoisted_1$1 = { class: "switch" };
  5672. const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
  5673. __name: "ToggleSwitch",
  5674. props: {
  5675. modelValue: { type: Boolean }
  5676. },
  5677. emits: ["update:modelValue", "toggle"],
  5678. setup(__props, { emit: __emit }) {
  5679. const props = __props;
  5680. const emit = __emit;
  5681. const modelValueProxy = vue.computed({
  5682. get: () => props.modelValue,
  5683. set: (value) => {
  5684. emit("update:modelValue", value);
  5685. emit("toggle", value);
  5686. }
  5687. });
  5688. return (_ctx, _cache) => {
  5689. return vue.openBlock(), vue.createElementBlock("label", _hoisted_1$1, [
  5690. vue.withDirectives(vue.createElementVNode("input", {
  5691. "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => modelValueProxy.value = $event),
  5692. type: "checkbox",
  5693. class: "switch__input"
  5694. }, null, 512), [
  5695. [vue.vModelCheckbox, modelValueProxy.value]
  5696. ]),
  5697. _cache[1] || (_cache[1] = vue.createElementVNode("span", { class: "switch__slider" }, null, -1))
  5698. ]);
  5699. };
  5700. }
  5701. });
  5702. const ToggleSwitch = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-894c8e09"]]);
  5703. const _hoisted_1 = { class: "settings-panel__inner" };
  5704. const _hoisted_2 = { class: "settings-panel__section" };
  5705. const _hoisted_3 = { class: "settings" };
  5706. const _hoisted_4 = { class: "settings-panel__section" };
  5707. const _hoisted_5 = { class: "settings" };
  5708. const _hoisted_6 = { class: "settings" };
  5709. const _hoisted_7 = { class: "settings__intro" };
  5710. const _hoisted_8 = { class: "settings" };
  5711. const _hoisted_9 = { class: "settings-panel__section" };
  5712. const _hoisted_10 = { class: "settings" };
  5713. const _hoisted_11 = { class: "settings" };
  5714. const _hoisted_12 = { class: "settings" };
  5715. const _hoisted_13 = { class: "settings-panel__section" };
  5716. const _hoisted_14 = { class: "settings" };
  5717. const _hoisted_15 = { class: "settings" };
  5718. const _hoisted_16 = { class: "settings" };
  5719. const _hoisted_17 = { class: "settings" };
  5720. const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
  5721. __name: "SettingsPanel",
  5722. setup(__props) {
  5723. const isShow = vue.ref(false);
  5724. vue.onMounted(() => {
  5725. _GM.registerMenuCommand("Open settings panel", () => isShow.value = !isShow.value);
  5726. });
  5727. function reload() {
  5728. location.reload();
  5729. }
  5730. return (_ctx, _cache) => {
  5731. return vue.openBlock(), vue.createBlock(vue.unref(Ro), {
  5732. modelValue: isShow.value,
  5733. "onUpdate:modelValue": _cache[13] || (_cache[13] = ($event) => isShow.value = $event),
  5734. "overlay-transition": "vfm-fade",
  5735. class: "settings-panel-wrap",
  5736. "content-class": "settings-panel"
  5737. }, {
  5738. default: vue.withCtx(() => [
  5739. vue.createElementVNode("div", _hoisted_1, [
  5740. vue.createElementVNode("section", _hoisted_2, [
  5741. _cache[15] || (_cache[15] = vue.createElementVNode("h2", { class: "settings-panel__section-name" }, " Common ", -1)),
  5742. _cache[16] || (_cache[16] = vue.createElementVNode("hr", null, null, -1)),
  5743. vue.createElementVNode("div", _hoisted_3, [
  5744. vue.createVNode(ToggleSwitch, {
  5745. modelValue: vue.unref(showJapaneseTitle).value,
  5746. "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => vue.unref(showJapaneseTitle).value = $event)
  5747. }, null, 8, ["modelValue"]),
  5748. _cache[14] || (_cache[14] = vue.createElementVNode("h3", { class: "settings__name" }, " Change page title to Japanese (effect on browser/tab title) ", -1))
  5749. ])
  5750. ]),
  5751. vue.createElementVNode("section", _hoisted_4, [
  5752. _cache[23] || (_cache[23] = vue.createElementVNode("h2", { class: "settings-panel__section-name" }, " Gallery Enhancer ", -1)),
  5753. _cache[24] || (_cache[24] = vue.createElementVNode("hr", null, null, -1)),
  5754. vue.createElementVNode("div", _hoisted_5, [
  5755. vue.createVNode(ToggleSwitch, {
  5756. modelValue: vue.unref(scrollByRowSwitch).value,
  5757. "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => vue.unref(scrollByRowSwitch).value = $event)
  5758. }, null, 8, ["modelValue"]),
  5759. _cache[17] || (_cache[17] = vue.createElementVNode("h3", { class: "settings__name" }, " Scroll by Row ", -1)),
  5760. _cache[18] || (_cache[18] = vue.createElementVNode("span", { class: "settings__notice" }, ' *sync with "Front Page Enhancer - Scroll by Row" ', -1))
  5761. ]),
  5762. vue.createElementVNode("div", _hoisted_6, [
  5763. vue.createVNode(ToggleSwitch, {
  5764. modelValue: vue.unref(betterPopupSwitch).value,
  5765. "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => vue.unref(betterPopupSwitch).value = $event)
  5766. }, null, 8, ["modelValue"]),
  5767. _cache[21] || (_cache[21] = vue.createElementVNode("h3", { class: "settings__name" }, " Better Popup ", -1)),
  5768. vue.createElementVNode("div", _hoisted_7, [
  5769. _cache[19] || (_cache[19] = vue.createElementVNode("span", null, ' Action when clicking "Archive Download": ', -1)),
  5770. vue.withDirectives(vue.createElementVNode("select", {
  5771. "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => vue.unref(quickDownloadMethod).value = $event)
  5772. }, [
  5773. vue.createElementVNode("option", null, vue.toDisplayString(vue.unref(DownloadMethod).Manual), 1),
  5774. vue.createElementVNode("option", null, vue.toDisplayString(vue.unref(DownloadMethod).HaH_Original), 1),
  5775. vue.createElementVNode("option", null, vue.toDisplayString(vue.unref(DownloadMethod).HaH_2400), 1),
  5776. vue.createElementVNode("option", null, vue.toDisplayString(vue.unref(DownloadMethod).Direct_Origin), 1),
  5777. vue.createElementVNode("option", null, vue.toDisplayString(vue.unref(DownloadMethod).Direct_Resample), 1)
  5778. ], 512), [
  5779. [vue.vModelSelect, vue.unref(quickDownloadMethod).value]
  5780. ]),
  5781. _cache[20] || (_cache[20] = vue.createElementVNode("p", null, [
  5782. vue.createTextVNode(' *Notice: If you had changed the Archiver Settings, you have to change it back to "Manual Select, Manual Start (Default)" in the setting page: '),
  5783. vue.createElementVNode("a", {
  5784. target: "_blank",
  5785. href: "https://e-hentai.org/uconfig.php",
  5786. rel: "noreferrer noopener"
  5787. }, " e-hentai "),
  5788. vue.createTextVNode(" , "),
  5789. vue.createElementVNode("a", {
  5790. target: "_blank",
  5791. href: "https://exhentai.org/uconfig.php",
  5792. rel: "noreferrer noopener"
  5793. }, " exhentai ")
  5794. ], -1))
  5795. ])
  5796. ]),
  5797. vue.createElementVNode("div", _hoisted_8, [
  5798. vue.createVNode(ToggleSwitch, {
  5799. modelValue: vue.unref(loadAllGalleryImagesSwitch).value,
  5800. "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => vue.unref(loadAllGalleryImagesSwitch).value = $event)
  5801. }, null, 8, ["modelValue"]),
  5802. _cache[22] || (_cache[22] = vue.createElementVNode("h3", { class: "settings__name" }, " Load All Gallery Images ", -1))
  5803. ])
  5804. ]),
  5805. vue.createElementVNode("section", _hoisted_9, [
  5806. _cache[29] || (_cache[29] = vue.createElementVNode("h2", { class: "settings-panel__section-name" }, " Multi-Page Viewer Enhancer ", -1)),
  5807. _cache[30] || (_cache[30] = vue.createElementVNode("hr", null, null, -1)),
  5808. vue.createElementVNode("div", _hoisted_10, [
  5809. vue.createVNode(ToggleSwitch, {
  5810. modelValue: vue.unref(multipageViewerEnhancerSwitch).value,
  5811. "onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => vue.unref(multipageViewerEnhancerSwitch).value = $event)
  5812. }, null, 8, ["modelValue"]),
  5813. _cache[25] || (_cache[25] = vue.createElementVNode("h3", { class: "settings__name" }, " Multi-Page Viewer Enhancer ", -1))
  5814. ]),
  5815. vue.createElementVNode("div", _hoisted_11, [
  5816. vue.createVNode(ToggleSwitch, {
  5817. modelValue: vue.unref(preventImageRemovalSwitch).value,
  5818. "onUpdate:modelValue": _cache[6] || (_cache[6] = ($event) => vue.unref(preventImageRemovalSwitch).value = $event)
  5819. }, null, 8, ["modelValue"]),
  5820. _cache[26] || (_cache[26] = vue.createElementVNode("h3", { class: "settings__name" }, " Prevent Image Removal ", -1)),
  5821. _cache[27] || (_cache[27] = vue.createElementVNode("div", { class: "settings__intro" }, [
  5822. vue.createElementVNode("p", null, " The original script of exhentai would remove the images which are too far from your current scroll. "),
  5823. vue.createElementVNode("p", null, " So if you scroll back to the images that have been removed. It might be flashing because although your browser has cached the image but still have to re-render it. ")
  5824. ], -1))
  5825. ]),
  5826. vue.createElementVNode("div", _hoisted_12, [
  5827. vue.createVNode(ToggleSwitch, {
  5828. modelValue: vue.unref(autoRedirectSwitch).value,
  5829. "onUpdate:modelValue": _cache[7] || (_cache[7] = ($event) => vue.unref(autoRedirectSwitch).value = $event)
  5830. }, null, 8, ["modelValue"]),
  5831. _cache[28] || (_cache[28] = vue.createElementVNode("h3", { class: "settings__name" }, " Auto Redirect to Multi-Page Viewer ", -1))
  5832. ])
  5833. ]),
  5834. vue.createElementVNode("section", _hoisted_13, [
  5835. _cache[37] || (_cache[37] = vue.createElementVNode("h2", { class: "settings-panel__section-name" }, " Front Page Enhancer ", -1)),
  5836. _cache[38] || (_cache[38] = vue.createElementVNode("hr", null, null, -1)),
  5837. vue.createElementVNode("div", _hoisted_14, [
  5838. vue.createVNode(ToggleSwitch, {
  5839. modelValue: vue.unref(infiniteScrollSwitch).value,
  5840. "onUpdate:modelValue": _cache[8] || (_cache[8] = ($event) => vue.unref(infiniteScrollSwitch).value = $event)
  5841. }, null, 8, ["modelValue"]),
  5842. _cache[31] || (_cache[31] = vue.createElementVNode("h3", { class: "settings__name" }, " Infinite Scroll ", -1))
  5843. ]),
  5844. vue.createElementVNode("div", _hoisted_15, [
  5845. vue.createVNode(ToggleSwitch, {
  5846. modelValue: vue.unref(scrollByRowSwitch).value,
  5847. "onUpdate:modelValue": _cache[9] || (_cache[9] = ($event) => vue.unref(scrollByRowSwitch).value = $event)
  5848. }, null, 8, ["modelValue"]),
  5849. _cache[32] || (_cache[32] = vue.createElementVNode("h3", { class: "settings__name" }, " Scroll by Row ", -1)),
  5850. _cache[33] || (_cache[33] = vue.createElementVNode("span", { class: "settings__notice" }, ' *sync with "Gallery Enhancer - Scroll by Row" ', -1))
  5851. ]),
  5852. vue.createElementVNode("div", _hoisted_16, [
  5853. vue.createVNode(ToggleSwitch, {
  5854. modelValue: vue.unref(highlightSwitch).value,
  5855. "onUpdate:modelValue": _cache[10] || (_cache[10] = ($event) => vue.unref(highlightSwitch).value = $event)
  5856. }, null, 8, ["modelValue"]),
  5857. _cache[34] || (_cache[34] = vue.createElementVNode("h3", { class: "settings__name" }, " Highlight downloaded gallery ", -1)),
  5858. _cache[35] || (_cache[35] = vue.createElementVNode("div", { class: "settings__intro" }, " Set background color of downloaded Gallery color to black. ", -1))
  5859. ]),
  5860. vue.createElementVNode("div", _hoisted_17, [
  5861. vue.createVNode(ToggleSwitch, {
  5862. modelValue: vue.unref(archiveButtonSwitch).value,
  5863. "onUpdate:modelValue": _cache[11] || (_cache[11] = ($event) => vue.unref(archiveButtonSwitch).value = $event)
  5864. }, null, 8, ["modelValue"]),
  5865. _cache[36] || (_cache[36] = vue.createElementVNode("h3", { class: "settings__name" }, " Insert archiver buttons to galleries on the front page. ", -1))
  5866. ])
  5867. ])
  5868. ]),
  5869. vue.createElementVNode("span", {
  5870. class: "settings-panel__close-button",
  5871. onClick: _cache[12] || (_cache[12] = ($event) => isShow.value = false)
  5872. }, [
  5873. vue.createVNode(CrossButton)
  5874. ]),
  5875. vue.createElementVNode("div", { class: "actions" }, [
  5876. vue.createElementVNode("button", {
  5877. class: "actions__button",
  5878. onClick: reload
  5879. }, " Apply and Reload ")
  5880. ])
  5881. ]),
  5882. _: 1
  5883. }, 8, ["modelValue"]);
  5884. };
  5885. }
  5886. });
  5887. const _sfc_main = /* @__PURE__ */ vue.defineComponent({
  5888. __name: "App",
  5889. setup(__props) {
  5890. const { href } = window.location;
  5891. const { enhancer } = useEnhancer();
  5892. const { redirectIfSinglePageViewer } = useRedirect();
  5893. if (autoRedirectSwitch.value) {
  5894. redirectIfSinglePageViewer();
  5895. }
  5896. if (showJapaneseTitle.value) {
  5897. changeTitleToJapanese();
  5898. }
  5899. setCSS();
  5900. function useEnhancer() {
  5901. const enhancer2 = vue.computed(() => {
  5902. if (/https:\/\/e[-x]hentai\.org\/(watched|popular)?(\?.+)?$/.test(href) || /https:\/\/e[-x]hentai\.org\/(tag)\/\w+/.test(href)) {
  5903. return _sfc_main$8;
  5904. }
  5905. if (/https:\/\/e[-x]hentai\.org\/g\/\w+\/\w+/.test(href)) {
  5906. return _sfc_main$7;
  5907. }
  5908. if (multipageViewerEnhancerSwitch.value && /https:\/\/e[-x]hentai\.org\/mpv\/\w+\/\w+/.test(href)) {
  5909. return _sfc_main$4;
  5910. }
  5911. return null;
  5912. });
  5913. return {
  5914. enhancer: enhancer2
  5915. };
  5916. }
  5917. function useRedirect() {
  5918. function redirectIfSinglePageViewer2() {
  5919. const isSinglePageViewer = /https:\/\/e[-x]hentai\.org\/s\/\w+\/\w+/.test(href);
  5920. if (isSinglePageViewer) {
  5921. vue.onMounted(() => {
  5922. const page = location.pathname.split("-")[1];
  5923. const url = getElement(".sb > a").href.replace("/g/", "/mpv/");
  5924. location.href = `${url}#page${page}`;
  5925. });
  5926. }
  5927. }
  5928. return {
  5929. redirectIfSinglePageViewer: redirectIfSinglePageViewer2
  5930. };
  5931. }
  5932. function setCSS() {
  5933. document.documentElement.style.setProperty(
  5934. "--bg-color",
  5935. _unsafeWindow.location.origin === "https://exhentai.org" ? "#34353b" : "#E3E0D1"
  5936. );
  5937. }
  5938. return (_ctx, _cache) => {
  5939. return vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [
  5940. (vue.openBlock(), vue.createBlock(vue.Suspense, null, {
  5941. default: vue.withCtx(() => [
  5942. (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(vue.unref(enhancer))))
  5943. ]),
  5944. _: 1
  5945. })),
  5946. vue.createVNode(_sfc_main$1)
  5947. ], 64);
  5948. };
  5949. }
  5950. });
  5951. const app = vue.createApp(_sfc_main);
  5952. const vfm = zo();
  5953. app.use(vfm);
  5954. app.use(src_default, {
  5955. transition: "Vue-Toastification__fade",
  5956. maxToasts: 2,
  5957. newestOnTop: true,
  5958. pauseOnFocusLoss: true,
  5959. hideProgressBar: true,
  5960. closeButton: false
  5961. });
  5962. (async () => {
  5963. await initializeMonkeySwitches();
  5964. app.mount(
  5965. (() => {
  5966. const app2 = document.createElement("div");
  5967. app2.classList.add("enhancer-container");
  5968. document.body.append(app2);
  5969. return app2;
  5970. })()
  5971. );
  5972. })();
  5973.  
  5974. })(Vue);