diff --git a/.gitignore b/.gitignore index d9e2c18..811669a 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,7 @@ go.work.sum /data/*.db /data/*.db-shm /data/*.db-wal +/data/*.mmdb # Production config (keep .example, ignore real secrets) /config/config.yaml /config/config.local.yaml diff --git a/cmd/server.go b/cmd/server.go index ac8f6d2..4f79a67 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -6,6 +6,7 @@ import ( "fmt" "os" "os/signal" + "path/filepath" "syscall" "time" @@ -16,6 +17,7 @@ import ( "github.com/peterqiu0516/sub-store/internal/config" "github.com/peterqiu0516/sub-store/internal/database" + "github.com/peterqiu0516/sub-store/internal/geoip" "github.com/peterqiu0516/sub-store/internal/handler" "github.com/peterqiu0516/sub-store/internal/middleware" ) @@ -54,6 +56,24 @@ func RunServer(cfg *config.Config) error { return err } + // Ensure GeoIP database exists (download in background if missing) + mmdbPath := filepath.Join(filepath.Dir(cfg.Database.Path), "GeoLite2-City.mmdb") + geoip.SetMmdbPath(mmdbPath) + if _, err := os.Stat(mmdbPath); err != nil { + logrus.Info("GeoIP database not found, downloading in background...") + go func() { + if err := geoip.DownloadMmdb(mmdbPath); err != nil { + logrus.WithError(err).Warn("GeoIP download failed, name-based detection will be used as fallback") + } else { + logrus.Info("GeoIP database downloaded successfully") + // Reload the reader + geoip.SetMmdbPath(mmdbPath) + } + }() + } else { + logrus.Info("GeoIP database found") + } + return startFiber(cfg, db) } diff --git a/frontend/dist/assets/index-BkTyHILH.css b/frontend/dist/assets/index-BkTyHILH.css deleted file mode 100644 index 17a40f1..0000000 --- a/frontend/dist/assets/index-BkTyHILH.css +++ /dev/null @@ -1 +0,0 @@ -*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.inset-y-0{top:0;bottom:0}.bottom-4{bottom:1rem}.left-0{left:0}.right-4{right:1rem}.top-0{top:0}.z-30{z-index:30}.z-50{z-index:50}.z-\[60\]{z-index:60}.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-5{margin-bottom:1.25rem}.mb-6{margin-bottom:1.5rem}.ml-3{margin-left:.75rem}.ml-60{margin-left:15rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-4{margin-top:1rem}.mt-6{margin-top:1.5rem}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-2{height:.5rem}.max-h-32{max-height:8rem}.max-h-96{max-height:24rem}.max-h-\[85vh\]{max-height:85vh}.min-h-screen{min-height:100vh}.w-2{width:.5rem}.w-24{width:6rem}.w-28{width:7rem}.w-60{width:15rem}.w-full{width:100%}.min-w-0{min-width:0px}.max-w-2xl{max-width:42rem}.max-w-sm{max-width:24rem}.flex-1{flex:1 1 0%}.border-collapse{border-collapse:collapse}.cursor-pointer{cursor:pointer}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.375rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse))}.divide-gray-100>:not([hidden])~:not([hidden]){--tw-divide-opacity: 1;border-color:rgb(243 244 246 / var(--tw-divide-opacity, 1))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-l-2{border-left-width:2px}.border-t{border-top-width:1px}.border-gray-200{--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1))}.border-gray-300{--tw-border-opacity: 1;border-color:rgb(209 213 219 / var(--tw-border-opacity, 1))}.border-gray-700{--tw-border-opacity: 1;border-color:rgb(55 65 81 / var(--tw-border-opacity, 1))}.border-primary-500{--tw-border-opacity: 1;border-color:rgb(59 130 246 / var(--tw-border-opacity, 1))}.border-transparent{border-color:transparent}.bg-black\/40{background-color:#0006}.bg-blue-100{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1))}.bg-gray-100{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.bg-gray-50{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.bg-gray-600{--tw-bg-opacity: 1;background-color:rgb(75 85 99 / var(--tw-bg-opacity, 1))}.bg-gray-800{--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity, 1))}.bg-gray-900{--tw-bg-opacity: 1;background-color:rgb(17 24 39 / var(--tw-bg-opacity, 1))}.bg-green-100{--tw-bg-opacity: 1;background-color:rgb(220 252 231 / var(--tw-bg-opacity, 1))}.bg-green-500{--tw-bg-opacity: 1;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))}.bg-green-600{--tw-bg-opacity: 1;background-color:rgb(22 163 74 / var(--tw-bg-opacity, 1))}.bg-primary-50{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.bg-primary-500{--tw-bg-opacity: 1;background-color:rgb(59 130 246 / var(--tw-bg-opacity, 1))}.bg-primary-600{--tw-bg-opacity: 1;background-color:rgb(37 99 235 / var(--tw-bg-opacity, 1))}.bg-purple-100{--tw-bg-opacity: 1;background-color:rgb(243 232 255 / var(--tw-bg-opacity, 1))}.bg-red-100{--tw-bg-opacity: 1;background-color:rgb(254 226 226 / var(--tw-bg-opacity, 1))}.bg-red-500{--tw-bg-opacity: 1;background-color:rgb(239 68 68 / var(--tw-bg-opacity, 1))}.bg-red-600{--tw-bg-opacity: 1;background-color:rgb(220 38 38 / var(--tw-bg-opacity, 1))}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-5{padding-top:1.25rem;padding-bottom:1.25rem}.py-8{padding-top:2rem;padding-bottom:2rem}.text-left{text-align:left}.text-center{text-align:center}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-7xl{font-size:4.5rem;line-height:1}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.text-blue-600{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.text-blue-700{--tw-text-opacity: 1;color:rgb(29 78 216 / var(--tw-text-opacity, 1))}.text-gray-300{--tw-text-opacity: 1;color:rgb(209 213 219 / var(--tw-text-opacity, 1))}.text-gray-400{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.text-gray-500{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}.text-gray-600{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.text-gray-700{--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.text-gray-900{--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}.text-green-600{--tw-text-opacity: 1;color:rgb(22 163 74 / var(--tw-text-opacity, 1))}.text-green-700{--tw-text-opacity: 1;color:rgb(21 128 61 / var(--tw-text-opacity, 1))}.text-primary-600{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.text-primary-700{--tw-text-opacity: 1;color:rgb(29 78 216 / var(--tw-text-opacity, 1))}.text-purple-600{--tw-text-opacity: 1;color:rgb(147 51 234 / var(--tw-text-opacity, 1))}.text-purple-700{--tw-text-opacity: 1;color:rgb(126 34 206 / var(--tw-text-opacity, 1))}.text-red-500{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.text-red-600{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.text-red-700{--tw-text-opacity: 1;color:rgb(185 28 28 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-shadow{transition-property:box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:4px}::-webkit-scrollbar-thumb:hover{background:#94a3b8}.fade-enter-active,.fade-leave-active{transition:opacity .2s}.fade-enter-from,.fade-leave-to{opacity:0}.hover\:bg-blue-50:hover{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-100:hover{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-50:hover{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-700:hover{--tw-bg-opacity: 1;background-color:rgb(55 65 81 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-800\/50:hover{background-color:#1f293780}.hover\:bg-green-700:hover{--tw-bg-opacity: 1;background-color:rgb(21 128 61 / var(--tw-bg-opacity, 1))}.hover\:bg-primary-700:hover{--tw-bg-opacity: 1;background-color:rgb(29 78 216 / var(--tw-bg-opacity, 1))}.hover\:bg-red-50:hover{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.hover\:bg-red-700:hover{--tw-bg-opacity: 1;background-color:rgb(185 28 28 / var(--tw-bg-opacity, 1))}.hover\:text-gray-600:hover{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.hover\:underline:hover{text-decoration-line:underline}.hover\:shadow-md:hover{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-2:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-primary-500:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity, 1))}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:bg-gray-100:disabled{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.disabled\:opacity-60:disabled{opacity:.6}@media(min-width:1024px){.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}} diff --git a/frontend/dist/assets/index-CPGYuQco.js b/frontend/dist/assets/index-CPGYuQco.js deleted file mode 100644 index d1b09db..0000000 --- a/frontend/dist/assets/index-CPGYuQco.js +++ /dev/null @@ -1,37 +0,0 @@ -(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))s(r);new MutationObserver(r=>{for(const o of r)if(o.type==="childList")for(const i of o.addedNodes)i.tagName==="LINK"&&i.rel==="modulepreload"&&s(i)}).observe(document,{childList:!0,subtree:!0});function n(r){const o={};return r.integrity&&(o.integrity=r.integrity),r.referrerPolicy&&(o.referrerPolicy=r.referrerPolicy),r.crossOrigin==="use-credentials"?o.credentials="include":r.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function s(r){if(r.ep)return;r.ep=!0;const o=n(r);fetch(r.href,o)}})();/** -* @vue/shared v3.5.40 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/function Gr(e){const t=Object.create(null);for(const n of e.split(","))t[n]=1;return n=>n in t}const Ce={},yn=[],Ct=()=>{},sl=()=>!1,Fs=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),Ms=e=>e.startsWith("onUpdate:"),Ue=Object.assign,Jr=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},pc=Object.prototype.hasOwnProperty,we=(e,t)=>pc.call(e,t),ne=Array.isArray,bn=e=>ls(e)==="[object Map]",Pn=e=>ls(e)==="[object Set]",ko=e=>ls(e)==="[object Date]",le=e=>typeof e=="function",Te=e=>typeof e=="string",ht=e=>typeof e=="symbol",Ee=e=>e!==null&&typeof e=="object",rl=e=>(Ee(e)||le(e))&&le(e.then)&&le(e.catch),ol=Object.prototype.toString,ls=e=>ol.call(e),hc=e=>ls(e).slice(8,-1),il=e=>ls(e)==="[object Object]",Xr=e=>Te(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,jn=Gr(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Vs=e=>{const t=Object.create(null);return(n=>t[n]||(t[n]=e(n)))},mc=/-\w/g,et=Vs(e=>e.replace(mc,t=>t.slice(1).toUpperCase())),gc=/\B([A-Z])/g,Jt=Vs(e=>e.replace(gc,"-$1").toLowerCase()),Bs=Vs(e=>e.charAt(0).toUpperCase()+e.slice(1)),sr=Vs(e=>e?`on${Bs(e)}`:""),Rt=(e,t)=>!Object.is(e,t),xs=(e,...t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:s,value:n})},js=e=>{const t=parseFloat(e);return isNaN(t)?e:t},yc=e=>{const t=Te(e)?Number(e):NaN;return isNaN(t)?e:t};let $o;const Hs=()=>$o||($o=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function Yr(e){if(ne(e)){const t={};for(let n=0;n{if(n){const s=n.split(xc);s.length>1&&(t[s[0].trim()]=s[1].trim())}}),t}function je(e){let t="";if(Te(e))t=e;else if(ne(e))for(let n=0;nWt(n,t))}const cl=e=>!!(e&&e.__v_isRef===!0),H=e=>Te(e)?e:e==null?"":ne(e)||Ee(e)&&(e.toString===ol||!le(e.toString))?cl(e)?H(e.value):JSON.stringify(e,ul,2):String(e),ul=(e,t)=>cl(t)?ul(e,t.value):bn(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((n,[s,r],o)=>(n[rr(s,o)+" =>"]=r,n),{})}:Pn(t)?{[`Set(${t.size})`]:[...t.values()].map(n=>rr(n))}:ht(t)?rr(t):Ee(t)&&!ne(t)&&!il(t)?String(t):t,rr=(e,t="")=>{var n;return ht(e)?`Symbol(${(n=e.description)!=null?n:t})`:e};/** -* @vue/reactivity v3.5.40 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/let Ve;class fl{constructor(t=!1){this.detached=t,this._active=!0,this._on=0,this.effects=[],this.cleanups=[],this._isPaused=!1,this._warnOnRun=!0,this.__v_skip=!0,!t&&Ve&&(Ve.active?(this.parent=Ve,this.index=(Ve.scopes||(Ve.scopes=[])).push(this)-1):(this._active=!1,this._warnOnRun=!1))}get active(){return this._active}pause(){if(this._active){this._isPaused=!0;let t,n;if(this.scopes){const s=this.scopes.slice();for(t=0,n=s.length;t0&&--this._on===0){if(Ve===this)Ve=this.prevScope;else{let t=Ve;for(;t;){if(t.prevScope===this){t.prevScope=this.prevScope;break}t=t.prevScope}}this.prevScope=void 0}}stop(t){if(this._active){this._active=!1;let n,s;for(n=0,s=this.effects.length;n0)return;if(qn){let t=qn;for(qn=void 0;t;){const n=t.next;t.next=void 0,t.flags&=-9,t=n}}let e;for(;Hn;){let t=Hn;for(Hn=void 0;t;){const n=t.next;if(t.next=void 0,t.flags&=-9,t.flags&1)try{t.trigger()}catch(s){e||(e=s)}t=n}}if(e)throw e}function ml(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function gl(e){let t,n=e.depsTail,s=n;for(;s;){const r=s.prevDep;s.version===-1?(s===n&&(n=r),to(s),Ac(s)):t=s,s.dep.activeLink=s.prevActiveLink,s.prevActiveLink=void 0,s=r}e.deps=t,e.depsTail=n}function Rr(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&(yl(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function yl(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===Jn)||(e.globalVersion=Jn,!e.isSSR&&e.flags&128&&(!e.deps&&!e._dirty||!Rr(e))))return;e.flags|=2;const t=e.dep,n=Ae,s=ft;Ae=e,ft=!0;try{ml(e);const r=e.fn(e._value);(t.version===0||Rt(r,e._value))&&(e.flags|=128,e._value=r,t.version++)}catch(r){throw t.version++,r}finally{Ae=n,ft=s,gl(e),e.flags&=-3}}function to(e,t=!1){const{dep:n,prevSub:s,nextSub:r}=e;if(s&&(s.nextSub=r,e.prevSub=void 0),r&&(r.prevSub=s,e.nextSub=void 0),n.subs===e&&(n.subs=s,!s&&n.computed)){n.computed.flags&=-5;for(let o=n.computed.deps;o;o=o.nextDep)to(o,!0)}!t&&!--n.sc&&n.map&&n.map.delete(n.key)}function Ac(e){const{prevDep:t,nextDep:n}=e;t&&(t.nextDep=n,e.prevDep=void 0),n&&(n.prevDep=t,e.nextDep=void 0)}let ft=!0;const bl=[];function Ut(){bl.push(ft),ft=!1}function Ft(){const e=bl.pop();ft=e===void 0?!0:e}function Do(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const n=Ae;Ae=void 0;try{t()}finally{Ae=n}}}let Jn=0;class Oc{constructor(t,n){this.sub=t,this.dep=n,this.version=n.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}}class no{constructor(t){this.computed=t,this.version=0,this.activeLink=void 0,this.subs=void 0,this.map=void 0,this.key=void 0,this.sc=0,this.__v_skip=!0}track(t){if(!Ae||!ft||Ae===this.computed)return;let n=this.activeLink;if(n===void 0||n.sub!==Ae)n=this.activeLink=new Oc(Ae,this),Ae.deps?(n.prevDep=Ae.depsTail,Ae.depsTail.nextDep=n,Ae.depsTail=n):Ae.deps=Ae.depsTail=n,xl(n);else if(n.version===-1&&(n.version=this.version,n.nextDep)){const s=n.nextDep;s.prevDep=n.prevDep,n.prevDep&&(n.prevDep.nextDep=s),n.prevDep=Ae.depsTail,n.nextDep=void 0,Ae.depsTail.nextDep=n,Ae.depsTail=n,Ae.deps===n&&(Ae.deps=s)}return n}trigger(t){this.version++,Jn++,this.notify(t)}notify(t){Zr();try{for(let n=this.subs;n;n=n.prevSub)n.sub.notify()&&n.sub.dep.notify()}finally{eo()}}}function xl(e){if(e.dep.sc++,e.sub.flags&4){const t=e.dep.computed;if(t&&!e.dep.subs){t.flags|=20;for(let s=t.deps;s;s=s.nextDep)xl(s)}const n=e.dep.subs;n!==e&&(e.prevSub=n,n&&(n.nextSub=e)),e.dep.subs=e}}const Cr=new WeakMap,ln=Symbol(""),Ar=Symbol(""),Xn=Symbol("");function Ke(e,t,n){if(ft&&Ae){let s=Cr.get(e);s||Cr.set(e,s=new Map);let r=s.get(n);r||(s.set(n,r=new no),r.map=s,r.key=n),r.track()}}function kt(e,t,n,s,r,o){const i=Cr.get(e);if(!i){Jn++;return}const l=a=>{a&&a.trigger()};if(Zr(),t==="clear")i.forEach(l);else{const a=ne(e),u=a&&Xr(n);if(a&&n==="length"){const c=Number(s);i.forEach((f,h)=>{(h==="length"||h===Xn||!ht(h)&&h>=c)&&l(f)})}else switch((n!==void 0||i.has(void 0))&&l(i.get(n)),u&&l(i.get(Xn)),t){case"add":a?u&&l(i.get("length")):(l(i.get(ln)),bn(e)&&l(i.get(Ar)));break;case"delete":a||(l(i.get(ln)),bn(e)&&l(i.get(Ar)));break;case"set":bn(e)&&l(i.get(ln));break}}eo()}function pn(e){const t=xe(e);return t===e?t:(Ke(t,"iterate",Xn),lt(e)?t:t.map(mt))}function qs(e){return Ke(e=xe(e),"iterate",Xn),e}function Et(e,t){return Mt(e)?En(an(e)?mt(t):t):mt(t)}const Tc={__proto__:null,[Symbol.iterator](){return ir(this,Symbol.iterator,e=>Et(this,e))},concat(...e){return pn(this).concat(...e.map(t=>ne(t)?pn(t):t))},entries(){return ir(this,"entries",e=>(e[1]=Et(this,e[1]),e))},every(e,t){return Ot(this,"every",e,t,void 0,arguments)},filter(e,t){return Ot(this,"filter",e,t,n=>n.map(s=>Et(this,s)),arguments)},find(e,t){return Ot(this,"find",e,t,n=>Et(this,n),arguments)},findIndex(e,t){return Ot(this,"findIndex",e,t,void 0,arguments)},findLast(e,t){return Ot(this,"findLast",e,t,n=>Et(this,n),arguments)},findLastIndex(e,t){return Ot(this,"findLastIndex",e,t,void 0,arguments)},forEach(e,t){return Ot(this,"forEach",e,t,void 0,arguments)},includes(...e){return lr(this,"includes",e)},indexOf(...e){return lr(this,"indexOf",e)},join(e){return pn(this).join(e)},lastIndexOf(...e){return lr(this,"lastIndexOf",e)},map(e,t){return Ot(this,"map",e,t,void 0,arguments)},pop(){return $n(this,"pop")},push(...e){return $n(this,"push",e)},reduce(e,...t){return Lo(this,"reduce",e,t)},reduceRight(e,...t){return Lo(this,"reduceRight",e,t)},shift(){return $n(this,"shift")},some(e,t){return Ot(this,"some",e,t,void 0,arguments)},splice(...e){return $n(this,"splice",e)},toReversed(){return pn(this).toReversed()},toSorted(e){return pn(this).toSorted(e)},toSpliced(...e){return pn(this).toSpliced(...e)},unshift(...e){return $n(this,"unshift",e)},values(){return ir(this,"values",e=>Et(this,e))}};function ir(e,t,n){const s=qs(e),r=s[t]();return s!==e&&!lt(e)&&(r._next=r.next,r.next=()=>{const o=r._next();return o.done||(o.value=n(o.value)),o}),r}const Pc=Array.prototype;function Ot(e,t,n,s,r,o){const i=qs(e),l=i!==e&&!lt(e),a=i[t];if(a!==Pc[t]){const f=a.apply(e,o);return l?mt(f):f}let u=n;i!==e&&(l?u=function(f,h){return n.call(this,Et(e,f),h,e)}:n.length>2&&(u=function(f,h){return n.call(this,f,h,e)}));const c=a.call(i,u,s);return l&&r?r(c):c}function Lo(e,t,n,s){const r=qs(e),o=r!==e&&!lt(e);let i=n,l=!1;r!==e&&(o?(l=s.length===0,i=function(u,c,f){return l&&(l=!1,u=Et(e,u)),n.call(this,u,Et(e,c),f,e)}):n.length>3&&(i=function(u,c,f){return n.call(this,u,c,f,e)}));const a=r[t](i,...s);return l?Et(e,a):a}function lr(e,t,n){const s=xe(e);Ke(s,"iterate",Xn);const r=s[t](...n);return(r===-1||r===!1)&&oo(n[0])?(n[0]=xe(n[0]),s[t](...n)):r}function $n(e,t,n=[]){Ut(),Zr();const s=xe(e)[t].apply(e,n);return eo(),Ft(),s}const Nc=Gr("__proto__,__v_isRef,__isVue"),vl=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(ht));function Ic(e){ht(e)||(e=String(e));const t=xe(this);return Ke(t,"has",e),t.hasOwnProperty(e)}class _l{constructor(t=!1,n=!1){this._isReadonly=t,this._isShallow=n}get(t,n,s){if(n==="__v_skip")return t.__v_skip;const r=this._isReadonly,o=this._isShallow;if(n==="__v_isReactive")return!r;if(n==="__v_isReadonly")return r;if(n==="__v_isShallow")return o;if(n==="__v_raw")return s===(r?o?jc:Rl:o?Sl:El).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(s)?t:void 0;const i=ne(t);if(!r){let a;if(i&&(a=Tc[n]))return a;if(n==="hasOwnProperty")return Ic}const l=Reflect.get(t,n,Ge(t)?t:s);if((ht(n)?vl.has(n):Nc(n))||(r||Ke(t,"get",n),o))return l;if(Ge(l)){const a=i&&Xr(n)?l:l.value;return r&&Ee(a)?Tr(a):a}return Ee(l)?r?Tr(l):At(l):l}}class wl extends _l{constructor(t=!1){super(!1,t)}set(t,n,s,r){let o=t[n];const i=ne(t)&&Xr(n);if(!this._isShallow){const u=Mt(o);if(!lt(s)&&!Mt(s)&&(o=xe(o),s=xe(s)),!i&&Ge(o)&&!Ge(s))return u||(o.value=s),!0}const l=i?Number(n)e,hs=e=>Reflect.getPrototypeOf(e);function Uc(e,t,n){return function(...s){const r=this.__v_raw,o=xe(r),i=bn(o),l=e==="entries"||e===Symbol.iterator&&i,a=e==="keys"&&i,u=r[e](...s),c=n?Or:t?En:mt;return!t&&Ke(o,"iterate",a?Ar:ln),Ue(Object.create(u),{next(){const{value:f,done:h}=u.next();return h?{value:f,done:h}:{value:l?[c(f[0]),c(f[1])]:c(f),done:h}}})}}function ms(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function Fc(e,t){const n={get(r){const o=this.__v_raw,i=xe(o),l=xe(r);e||(Rt(r,l)&&Ke(i,"get",r),Ke(i,"get",l));const{has:a}=hs(i),u=t?Or:e?En:mt;if(a.call(i,r))return u(o.get(r));if(a.call(i,l))return u(o.get(l));o!==i&&o.get(r)},get size(){const r=this.__v_raw;return!e&&Ke(xe(r),"iterate",ln),r.size},has(r){const o=this.__v_raw,i=xe(o),l=xe(r);return e||(Rt(r,l)&&Ke(i,"has",r),Ke(i,"has",l)),r===l?o.has(r):o.has(r)||o.has(l)},forEach(r,o){const i=this,l=i.__v_raw,a=xe(l),u=t?Or:e?En:mt;return!e&&Ke(a,"iterate",ln),l.forEach((c,f)=>r.call(o,u(c),u(f),i))}};return Ue(n,e?{add:ms("add"),set:ms("set"),delete:ms("delete"),clear:ms("clear")}:{add(r){const o=xe(this),i=hs(o),l=xe(r),a=!t&&!lt(r)&&!Mt(r)?l:r;return i.has.call(o,a)||Rt(r,a)&&i.has.call(o,r)||Rt(l,a)&&i.has.call(o,l)||(o.add(a),kt(o,"add",a,a)),this},set(r,o){!t&&!lt(o)&&!Mt(o)&&(o=xe(o));const i=xe(this),{has:l,get:a}=hs(i);let u=l.call(i,r);u||(r=xe(r),u=l.call(i,r));const c=a.call(i,r);return i.set(r,o),u?Rt(o,c)&&kt(i,"set",r,o):kt(i,"add",r,o),this},delete(r){const o=xe(this),{has:i,get:l}=hs(o);let a=i.call(o,r);a||(r=xe(r),a=i.call(o,r)),l&&l.call(o,r);const u=o.delete(r);return a&&kt(o,"delete",r,void 0),u},clear(){const r=xe(this),o=r.size!==0,i=r.clear();return o&&kt(r,"clear",void 0,void 0),i}}),["keys","values","entries",Symbol.iterator].forEach(r=>{n[r]=Uc(r,e,t)}),n}function so(e,t){const n=Fc(e,t);return(s,r,o)=>r==="__v_isReactive"?!e:r==="__v_isReadonly"?e:r==="__v_raw"?s:Reflect.get(we(n,r)&&r in s?n:s,r,o)}const Mc={get:so(!1,!1)},Vc={get:so(!1,!0)},Bc={get:so(!0,!1)};const El=new WeakMap,Sl=new WeakMap,Rl=new WeakMap,jc=new WeakMap;function Hc(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function At(e){return Mt(e)?e:ro(e,!1,$c,Mc,El)}function Cl(e){return ro(e,!1,Lc,Vc,Sl)}function Tr(e){return ro(e,!0,Dc,Bc,Rl)}function ro(e,t,n,s,r){if(!Ee(e)||e.__v_raw&&!(t&&e.__v_isReactive)||e.__v_skip||!Object.isExtensible(e))return e;const o=r.get(e);if(o)return o;const i=Hc(hc(e));if(i===0)return e;const l=new Proxy(e,i===2?s:n);return r.set(e,l),l}function an(e){return Mt(e)?an(e.__v_raw):!!(e&&e.__v_isReactive)}function Mt(e){return!!(e&&e.__v_isReadonly)}function lt(e){return!!(e&&e.__v_isShallow)}function oo(e){return e?!!e.__v_raw:!1}function xe(e){const t=e&&e.__v_raw;return t?xe(t):e}function Al(e){return!we(e,"__v_skip")&&Object.isExtensible(e)&&ll(e,"__v_skip",!0),e}const mt=e=>Ee(e)?At(e):e,En=e=>Ee(e)?Tr(e):e;function Ge(e){return e?e.__v_isRef===!0:!1}function Z(e){return Ol(e,!1)}function qc(e){return Ol(e,!0)}function Ol(e,t){return Ge(e)?e:new Kc(e,t)}class Kc{constructor(t,n){this.dep=new no,this.__v_isRef=!0,this.__v_isShallow=!1,this._rawValue=n?t:xe(t),this._value=n?t:mt(t),this.__v_isShallow=n}get value(){return this.dep.track(),this._value}set value(t){const n=this._rawValue,s=this.__v_isShallow||lt(t)||Mt(t);t=s?t:xe(t),Rt(t,n)&&(this._rawValue=t,this._value=s?t:mt(t),this.dep.trigger())}}function xn(e){return Ge(e)?e.value:e}const Wc={get:(e,t,n)=>t==="__v_raw"?e:xn(Reflect.get(e,t,n)),set:(e,t,n,s)=>{const r=e[t];return Ge(r)&&!Ge(n)?(r.value=n,!0):Reflect.set(e,t,n,s)}};function Tl(e){return an(e)?e:new Proxy(e,Wc)}class zc{constructor(t,n,s){this.fn=t,this.setter=n,this._value=void 0,this.dep=new no(this),this.__v_isRef=!0,this.deps=void 0,this.depsTail=void 0,this.flags=16,this.globalVersion=Jn-1,this.next=void 0,this.effect=this,this.__v_isReadonly=!n,this.isSSR=s}notify(){if(this.flags|=16,!(this.flags&8)&&Ae!==this)return hl(this,!0),!0}get value(){const t=this.dep.track();return yl(this),t&&(t.version=this.dep.version),this._value}set value(t){this.setter&&this.setter(t)}}function Gc(e,t,n=!1){let s,r;return le(e)?s=e:(s=e.get,r=e.set),new zc(s,r,n)}const gs={},Cs=new WeakMap;let tn;function Jc(e,t=!1,n=tn){if(n){let s=Cs.get(n);s||Cs.set(n,s=[]),s.push(e)}}function Xc(e,t,n=Ce){const{immediate:s,deep:r,once:o,scheduler:i,augmentJob:l,call:a}=n,u=R=>r?R:lt(R)||r===!1||r===0?$t(R,1):$t(R);let c,f,h,m,S=!1,C=!1;if(Ge(e)?(f=()=>e.value,S=lt(e)):an(e)?(f=()=>u(e),S=!0):ne(e)?(C=!0,S=e.some(R=>an(R)||lt(R)),f=()=>e.map(R=>{if(Ge(R))return R.value;if(an(R))return u(R);if(le(R))return a?a(R,2):R()})):le(e)?t?f=a?()=>a(e,2):e:f=()=>{if(h){Ut();try{h()}finally{Ft()}}const R=tn;tn=c;try{return a?a(e,3,[m]):e(m)}finally{tn=R}}:f=Ct,t&&r){const R=f,O=r===!0?1/0:r;f=()=>$t(R(),O)}const P=Cc(),v=()=>{c.stop(),P&&P.active&&Jr(P.effects,c)};if(o&&t){const R=t;t=(...O)=>{const $=R(...O);return v(),$}}let x=C?new Array(e.length).fill(gs):gs;const A=R=>{if(!(!(c.flags&1)||!c.dirty&&!R))if(t){const O=c.run();if(R||r||S||(C?O.some(($,U)=>Rt($,x[U])):Rt(O,x))){h&&h();const $=tn;tn=c;try{const U=[O,x===gs?void 0:C&&x[0]===gs?[]:x,m];x=O,a?a(t,3,U):t(...U)}finally{tn=$}}}else c.run()};return l&&l(A),c=new dl(f),c.scheduler=i?()=>i(A,!1):A,m=R=>Jc(R,!1,c),h=c.onStop=()=>{const R=Cs.get(c);if(R){if(a)a(R,4);else for(const O of R)O();Cs.delete(c)}},t?s?A(!0):x=c.run():i?i(A.bind(null,!0),!0):c.run(),v.pause=c.pause.bind(c),v.resume=c.resume.bind(c),v.stop=v,v}function $t(e,t=1/0,n){if(t<=0||!Ee(e)||e.__v_skip||(n=n||new Map,(n.get(e)||0)>=t))return e;if(n.set(e,t),t--,Ge(e))$t(e.value,t,n);else if(ne(e))for(let s=0;s{$t(s,t,n)});else if(il(e)){for(const s in e)$t(e[s],t,n);for(const s of Object.getOwnPropertySymbols(e))Object.prototype.propertyIsEnumerable.call(e,s)&&$t(e[s],t,n)}return e}/** -* @vue/runtime-core v3.5.40 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/function as(e,t,n,s){try{return s?e(...s):e()}catch(r){Ks(r,t,n)}}function ct(e,t,n,s){if(le(e)){const r=as(e,t,n,s);return r&&rl(r)&&r.catch(o=>{Ks(o,t,n)}),r}if(ne(e)){const r=[];for(let o=0;o>>1,r=Ze[s],o=Yn(r);o=Yn(n)?Ze.push(e):Ze.splice(Qc(t),0,e),e.flags|=1,Nl()}}function Nl(){As||(As=Pl.then(kl))}function Zc(e){ne(e)?vn.push(...e):qt&&e.id===-1?qt.splice(mn+1,0,e):e.flags&1||(vn.push(e),e.flags|=1),Nl()}function Uo(e,t,n=wt+1){for(;nYn(n)-Yn(s));if(vn.length=0,qt){qt.push(...t);return}for(qt=t,mn=0;mne.id==null?e.flags&2?-1:1/0:e.id;function kl(e){try{for(wt=0;wt{s._d&&Ns(-1);const o=Os(t),i=Lt.length;let l;try{l=e(...r)}finally{for(let a=Lt.length;a>i;a--)fo();Os(o),s._d&&Ns(1)}return l};return s._n=!0,s._c=!0,s._d=!0,s}function me(e,t){if(He===null)return e;const n=Xs(He),s=e.dirs||(e.dirs=[]);for(let r=0;r1)return n&&le(t)?t.call(s&&s.proxy):t}}const eu=Symbol.for("v-scx"),tu=()=>pt(eu);function _s(e,t,n){return Dl(e,t,n)}function Dl(e,t,n=Ce){const{immediate:s,deep:r,flush:o,once:i}=n,l=Ue({},n),a=t&&s||!t&&o!=="post";let u;if(ns){if(o==="sync"){const m=tu();u=m.__watcherHandles||(m.__watcherHandles=[])}else if(!a){const m=()=>{};return m.stop=Ct,m.resume=Ct,m.pause=Ct,m}}const c=ze;l.call=(m,S,C)=>ct(m,c,S,C);let f=!1;o==="post"?l.scheduler=m=>{Ye(m,c&&c.suspense)}:o!=="sync"&&(f=!0,l.scheduler=(m,S)=>{S?m():lo(m)}),l.augmentJob=m=>{t&&(m.flags|=4),f&&(m.flags|=2,c&&(m.id=c.uid,m.i=c))};const h=Xc(e,t,l);return ns&&(u?u.push(h):a&&h()),h}function nu(e,t,n){const s=this.proxy,r=Te(e)?e.includes(".")?Ll(s,e):()=>s[e]:e.bind(s,s);let o;le(t)?o=t:(o=t.handler,n=t);const i=cs(this),l=Dl(r,o.bind(s),n);return i(),l}function Ll(e,t){const n=t.split(".");return()=>{let s=e;for(let r=0;re.__isTeleport,nn=e=>e&&(e.disabled||e.disabled===""),su=e=>e&&(e.defer||e.defer===""),Fo=e=>typeof SVGElement<"u"&&e instanceof SVGElement,Mo=e=>typeof MathMLElement=="function"&&e instanceof MathMLElement,Pr=(e,t)=>{const n=e&&e.to;return Te(n)?t?t(n):null:n},ru={name:"Teleport",__isTeleport:!0,process(e,t,n,s,r,o,i,l,a,u){const{mc:c,pc:f,pbc:h,o:{insert:m,querySelector:S,createText:C,createComment:P,parentNode:v}}=u,x=nn(t.props);let{dynamicChildren:A}=t;const R=(U,ae,Y)=>{U.shapeFlag&16&&c(U.children,ae,Y,r,o,i,l,a)},O=(U=t)=>{const ae=nn(U.props),Y=U.target=Pr(U.props,S),se=Nr(Y,U,C,m);Y&&(i!=="svg"&&Fo(Y)?i="svg":i!=="mathml"&&Mo(Y)&&(i="mathml"),r&&r.isCE&&(r.ce._teleportTargets||(r.ce._teleportTargets=new Set)).add(Y),ae||(R(U,Y,se),Mn(U,!1)))},$=U=>{const ae=()=>{if(Ht.get(U)===ae){if(Ht.delete(U),nn(U.props)){const Y=v(U.el)||n;R(U,Y,U.anchor),Mn(U,!0)}O(U)}};Ht.set(U,ae),Ye(ae,o)};if(e==null){const U=t.el=C(""),ae=t.anchor=C("");if(m(U,n,s),m(ae,n,s),su(t.props)||o&&o.pendingBranch){$(t);return}x&&(R(t,n,ae),Mn(t,!0)),O()}else{t.el=e.el;const U=t.anchor=e.anchor,ae=Ht.get(e);if(ae){ae.flags|=8,Ht.delete(e),$(t);return}t.targetStart=e.targetStart;const Y=t.target=e.target,se=t.targetAnchor=e.targetAnchor,oe=nn(e.props),W=oe?n:Y,ce=oe?U:se;if(i==="svg"||Fo(Y)?i="svg":(i==="mathml"||Mo(Y))&&(i="mathml"),A?(h(e.dynamicChildren,A,W,r,o,i,l),uo(e,t,!0)):a||f(e,t,W,ce,r,o,i,l,!1),x)oe?t.props&&e.props&&t.props.to!==e.props.to&&(t.props.to=e.props.to):ys(t,n,U,u,1);else if((t.props&&t.props.to)!==(e.props&&e.props.to)){const fe=Pr(t.props,S);fe&&(t.target=fe,ys(t,fe,null,u,0))}else oe&&ys(t,Y,se,u,1);Mn(t,x)}},remove(e,t,n,{um:s,o:{remove:r}},o){const{shapeFlag:i,children:l,anchor:a,targetStart:u,targetAnchor:c,target:f,props:h}=e,m=nn(h),S=o||!m,C=Ht.get(e);if(C&&(C.flags|=8,Ht.delete(e)),f&&(r(u),r(c)),o&&r(a),!C&&(m||f)&&i&16)for(let P=0;P{e.isMounted=!0}),Gl(()=>{e.isUnmounting=!0}),e}const ot=[Function,Array],Vl={mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:ot,onEnter:ot,onAfterEnter:ot,onEnterCancelled:ot,onBeforeLeave:ot,onLeave:ot,onAfterLeave:ot,onLeaveCancelled:ot,onBeforeAppear:ot,onAppear:ot,onAfterAppear:ot,onAppearCancelled:ot},Bl=e=>{const t=e.subTree;return t.component?Bl(t.component):t},lu={name:"BaseTransition",props:Vl,setup(e,{slots:t}){const n=ba(),s=iu();return()=>{const r=t.default&&ql(t.default(),!0),o=r&&r.length?jl(r):n.subTree?pe():void 0;if(!o)return;const i=xe(e),{mode:l}=i;if(s.isLeaving)return ar(o);const a=Vo(o);if(!a)return ar(o);let u=Ir(a,i,s,n,f=>u=f);a.type!==We&&Qn(a,u);let c=n.subTree&&Vo(n.subTree);if(c&&c.type!==We&&!sn(c,a)&&Bl(n).type!==We){let f=Ir(c,i,s,n);if(Qn(c,f),l==="out-in"&&a.type!==We)return s.isLeaving=!0,f.afterLeave=()=>{s.isLeaving=!1,n.job.flags&8||n.update(),delete f.afterLeave,c=void 0},ar(o);l==="in-out"&&a.type!==We?f.delayLeave=(h,m,S)=>{const C=Hl(s,c);C[String(c.key)]=c,h[it]=()=>{m(),h[it]=void 0,delete u.delayedLeave,c=void 0},u.delayedLeave=()=>{S(),delete u.delayedLeave,c=void 0}}:c=void 0}else c&&(c=void 0);return o}}};function jl(e){let t=e[0];if(e.length>1){for(const n of e)if(n.type!==We){t=n;break}}return t}const au=lu;function Hl(e,t){const{leavingVNodes:n}=e;let s=n.get(t.type);return s||(s=Object.create(null),n.set(t.type,s)),s}function Ir(e,t,n,s,r){const{appear:o,mode:i,persisted:l=!1,onBeforeEnter:a,onEnter:u,onAfterEnter:c,onEnterCancelled:f,onBeforeLeave:h,onLeave:m,onAfterLeave:S,onLeaveCancelled:C,onBeforeAppear:P,onAppear:v,onAfterAppear:x,onAppearCancelled:A}=t,R=String(e.key),O=Hl(n,e),$=(Y,se)=>{Y&&ct(Y,s,9,se)},U=(Y,se)=>{const oe=se[1];$(Y,se),ne(Y)?Y.every(W=>W.length<=1)&&oe():Y.length<=1&&oe()},ae={mode:i,persisted:l,beforeEnter(Y){let se=a;if(!n.isMounted)if(o)se=P||a;else return;Y[it]&&Y[it](!0);const oe=O[R];oe&&sn(e,oe)&&oe.el[it]&&oe.el[it](),$(se,[Y])},enter(Y){if(O[R]===e)return;let se=u,oe=c,W=f;if(!n.isMounted)if(o)se=v||u,oe=x||c,W=A||f;else return;let ce=!1;Y[Dn]=Pe=>{ce||(ce=!0,Pe?$(W,[Y]):$(oe,[Y]),ae.delayedLeave&&ae.delayedLeave(),Y[Dn]=void 0)};const fe=Y[Dn].bind(null,!1);se?U(se,[Y,fe]):fe()},leave(Y,se){const oe=String(e.key);if(Y[Dn]&&Y[Dn](!0),n.isUnmounting)return se();$(h,[Y]);let W=!1;Y[it]=fe=>{W||(W=!0,se(),fe?$(C,[Y]):$(S,[Y]),Y[it]=void 0,O[oe]===e&&delete O[oe])};const ce=Y[it].bind(null,!1);O[oe]=e,m?U(m,[Y,ce]):ce()},clone(Y){const se=Ir(Y,t,n,s,r);return r&&r(se),se}};return ae}function ar(e){if(Ws(e))return e=zt(e),e.children=null,e}function Vo(e){if(!Ws(e))return Fl(e.type)&&e.children?jl(e.children):e;if(e.component)return e.component.subTree;const{shapeFlag:t,children:n}=e;if(n){if(t&16)return n[0];if(t&32&&le(n.default))return n.default()}}function Qn(e,t){e.shapeFlag&6&&e.component?(e.transition=t,Qn(e.component.subTree,t)):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function ql(e,t=!1,n){let s=[],r=0;for(let o=0;o1)for(let o=0;oKn(C,t&&(ne(t)?t[P]:t),n,s,r));return}if(_n(s)&&!r){s.shapeFlag&512&&s.type.__asyncResolved&&s.component.subTree.component&&Kn(e,t,n,s.component.subTree);return}const o=s.shapeFlag&4?Xs(s.component):s.el,i=r?null:o,{i:l,r:a}=e,u=t&&t.r,c=l.refs===Ce?l.refs={}:l.refs,f=l.setupState,h=xe(f),m=f===Ce?sl:C=>Bo(c,C)?!1:we(h,C),S=(C,P)=>!(P&&Bo(c,P));if(u!=null&&u!==a){if(jo(t),Te(u))c[u]=null,m(u)&&(f[u]=null);else if(Ge(u)){const C=t;S(u,C.k)&&(u.value=null),C.k&&(c[C.k]=null)}}if(le(a))as(a,l,12,[i,c]);else{const C=Te(a),P=Ge(a);if(C||P){const v=()=>{if(e.f){const x=C?m(a)?f[a]:c[a]:S()||!e.k?a.value:c[e.k];if(r)ne(x)&&Jr(x,o);else if(ne(x))x.includes(o)||x.push(o);else if(C)c[a]=[o],m(a)&&(f[a]=c[a]);else{const A=[o];S(a,e.k)&&(a.value=A),e.k&&(c[e.k]=A)}}else C?(c[a]=i,m(a)&&(f[a]=i)):P&&(S(a,e.k)&&(a.value=i),e.k&&(c[e.k]=i))};if(i){const x=()=>{v(),Ts.delete(e)};x.id=-1,Ts.set(e,x),Ye(x,n)}else jo(e),v()}}}function jo(e){const t=Ts.get(e);t&&(t.flags|=8,Ts.delete(e))}Hs().requestIdleCallback;Hs().cancelIdleCallback;const _n=e=>!!e.type.__asyncLoader,Ws=e=>e.type.__isKeepAlive;function cu(e,t){zl(e,"a",t)}function uu(e,t){zl(e,"da",t)}function zl(e,t,n=ze){const s=e.__wdc||(e.__wdc=()=>{let r=n;for(;r;){if(r.isDeactivated)return;r=r.parent}return e()});if(zs(t,s,n),n){let r=n.parent;for(;r&&r.parent;)Ws(r.parent.vnode)&&fu(s,t,n,r),r=r.parent}}function fu(e,t,n,s){const r=zs(t,e,s,!0);Jl(()=>{Jr(s[t],r)},n)}function zs(e,t,n=ze,s=!1){if(n){const r=n[e]||(n[e]=[]),o=t.__weh||(t.__weh=(...i)=>{Ut();const l=cs(n),a=ct(t,n,e,i);return l(),Ft(),a});return s?r.unshift(o):r.push(o),o}}const Vt=e=>(t,n=ze)=>{(!ns||e==="sp")&&zs(e,(...s)=>t(...s),n)},du=Vt("bm"),Xt=Vt("m"),pu=Vt("bu"),hu=Vt("u"),Gl=Vt("bum"),Jl=Vt("um"),mu=Vt("sp"),gu=Vt("rtg"),yu=Vt("rtc");function bu(e,t=ze){zs("ec",e,t)}const Xl="components";function kr(e,t){return Ql(Xl,e,!0,t)||e}const Yl=Symbol.for("v-ndc");function xu(e){return Te(e)?Ql(Xl,e,!1)||e:e||Yl}function Ql(e,t,n=!0,s=!1){const r=He||ze;if(r){const o=r.type;{const l=nf(o,!1);if(l&&(l===t||l===et(t)||l===Bs(et(t))))return o}const i=Ho(r[e]||o[e],t)||Ho(r.appContext[e],t);return!i&&s?o:i}}function Ho(e,t){return e&&(e[t]||e[et(t)]||e[Bs(et(t))])}function Fe(e,t,n,s){let r;const o=n,i=ne(e);if(i||Te(e)){const l=i&&an(e);let a=!1,u=!1;l&&(a=!lt(e),u=Mt(e),e=qs(e)),r=new Array(e.length);for(let c=0,f=e.length;ct(l,a,void 0,o));else{const l=Object.keys(e);r=new Array(l.length);for(let a=0,u=l.length;a0;return t!=="default"&&(u.name=t),F(),un(ve,null,[Oe("slot",u,s)],c?-2:64)}let i=e[t];i&&i._c&&(i._d=!1);const l=Lt.length;F();let a;try{const u=i&&Zl(i(n)),c=n.key||o||u&&u.key;a=un(ve,{key:(c&&!ht(c)?c:`_${t}`)+(!u&&s?"_fb":"")},u||(s?s():[]),u&&e._===1?64:-2)}catch(u){for(let c=Lt.length;c>l;c--)fo();throw u}finally{i&&i._c&&(i._d=!0)}return a.scopeId&&(a.slotScopeIds=[a.scopeId+"-s"]),a}function Zl(e){return e.some(t=>es(t)?!(t.type===We||t.type===ve&&!Zl(t.children)):!0)?e:null}const $r=e=>e?xa(e)?Xs(e):$r(e.parent):null,Wn=Ue(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>$r(e.parent),$root:e=>$r(e.root),$host:e=>e.ce,$emit:e=>e.emit,$options:e=>ta(e),$forceUpdate:e=>e.f||(e.f=()=>{lo(e.update)}),$nextTick:e=>e.n||(e.n=io.bind(e.proxy)),$watch:e=>nu.bind(e)}),cr=(e,t)=>e!==Ce&&!e.__isScriptSetup&&we(e,t),vu={get({_:e},t){if(t==="__v_skip")return!0;const{ctx:n,setupState:s,data:r,props:o,accessCache:i,type:l,appContext:a}=e;if(t[0]!=="$"){const h=i[t];if(h!==void 0)switch(h){case 1:return s[t];case 2:return r[t];case 4:return n[t];case 3:return o[t]}else{if(cr(s,t))return i[t]=1,s[t];if(r!==Ce&&we(r,t))return i[t]=2,r[t];if(we(o,t))return i[t]=3,o[t];if(n!==Ce&&we(n,t))return i[t]=4,n[t];Dr&&(i[t]=0)}}const u=Wn[t];let c,f;if(u)return t==="$attrs"&&Ke(e.attrs,"get",""),u(e);if((c=l.__cssModules)&&(c=c[t]))return c;if(n!==Ce&&we(n,t))return i[t]=4,n[t];if(f=a.config.globalProperties,we(f,t))return f[t]},set({_:e},t,n){const{data:s,setupState:r,ctx:o}=e;return cr(r,t)?(r[t]=n,!0):s!==Ce&&we(s,t)?(s[t]=n,!0):we(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(o[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:s,appContext:r,props:o,type:i}},l){let a;return!!(n[l]||e!==Ce&&l[0]!=="$"&&we(e,l)||cr(t,l)||we(o,l)||we(s,l)||we(Wn,l)||we(r.config.globalProperties,l)||(a=i.__cssModules)&&a[l])},defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:we(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}};function Ko(e){return ne(e)?e.reduce((t,n)=>(t[n]=null,t),{}):e}let Dr=!0;function _u(e){const t=ta(e),n=e.proxy,s=e.ctx;Dr=!1,t.beforeCreate&&Wo(t.beforeCreate,e,"bc");const{data:r,computed:o,methods:i,watch:l,provide:a,inject:u,created:c,beforeMount:f,mounted:h,beforeUpdate:m,updated:S,activated:C,deactivated:P,beforeDestroy:v,beforeUnmount:x,destroyed:A,unmounted:R,render:O,renderTracked:$,renderTriggered:U,errorCaptured:ae,serverPrefetch:Y,expose:se,inheritAttrs:oe,components:W,directives:ce,filters:fe}=t;if(u&&wu(u,s,null),i)for(const D in i){const I=i[D];le(I)&&(s[D]=I.bind(n))}if(r){const D=r.call(n,n);Ee(D)&&(e.data=At(D))}if(Dr=!0,o)for(const D in o){const I=o[D],J=le(I)?I.bind(n,n):le(I.get)?I.get.bind(n,n):Ct,ue=!le(I)&&le(I.set)?I.set.bind(n):Ct,re=tt({get:J,set:ue});Object.defineProperty(s,D,{enumerable:!0,configurable:!0,get:()=>re.value,set:de=>re.value=de})}if(l)for(const D in l)ea(l[D],s,n,D);if(a){const D=le(a)?a.call(n):a;Reflect.ownKeys(D).forEach(I=>{vs(I,D[I])})}c&&Wo(c,e,"c");function be(D,I){ne(I)?I.forEach(J=>D(J.bind(n))):I&&D(I.bind(n))}if(be(du,f),be(Xt,h),be(pu,m),be(hu,S),be(cu,C),be(uu,P),be(bu,ae),be(yu,$),be(gu,U),be(Gl,x),be(Jl,R),be(mu,Y),ne(se))if(se.length){const D=e.exposed||(e.exposed={});se.forEach(I=>{Object.defineProperty(D,I,{get:()=>n[I],set:J=>n[I]=J,enumerable:!0})})}else e.exposed||(e.exposed={});O&&e.render===Ct&&(e.render=O),oe!=null&&(e.inheritAttrs=oe),W&&(e.components=W),ce&&(e.directives=ce),Y&&Wl(e)}function wu(e,t,n=Ct){ne(e)&&(e=Lr(e));for(const s in e){const r=e[s];let o;Ee(r)?"default"in r?o=pt(r.from||s,r.default,!0):o=pt(r.from||s):o=pt(r),Ge(o)?Object.defineProperty(t,s,{enumerable:!0,configurable:!0,get:()=>o.value,set:i=>o.value=i}):t[s]=o}}function Wo(e,t,n){ct(ne(e)?e.map(s=>s.bind(t.proxy)):e.bind(t.proxy),t,n)}function ea(e,t,n,s){let r=s.includes(".")?Ll(n,s):()=>n[s];if(Te(e)){const o=t[e];le(o)&&_s(r,o)}else if(le(e))_s(r,e.bind(n));else if(Ee(e))if(ne(e))e.forEach(o=>ea(o,t,n,s));else{const o=le(e.handler)?e.handler.bind(n):t[e.handler];le(o)&&_s(r,o,e)}}function ta(e){const t=e.type,{mixins:n,extends:s}=t,{mixins:r,optionsCache:o,config:{optionMergeStrategies:i}}=e.appContext,l=o.get(t);let a;return l?a=l:!r.length&&!n&&!s?a=t:(a={},r.length&&r.forEach(u=>Ps(a,u,i,!0)),Ps(a,t,i)),Ee(t)&&o.set(t,a),a}function Ps(e,t,n,s=!1){const{mixins:r,extends:o}=t;o&&Ps(e,o,n,!0),r&&r.forEach(i=>Ps(e,i,n,!0));for(const i in t)if(!(s&&i==="expose")){const l=Eu[i]||n&&n[i];e[i]=l?l(e[i],t[i]):t[i]}return e}const Eu={data:zo,props:Go,emits:Go,methods:Vn,computed:Vn,beforeCreate:Xe,created:Xe,beforeMount:Xe,mounted:Xe,beforeUpdate:Xe,updated:Xe,beforeDestroy:Xe,beforeUnmount:Xe,destroyed:Xe,unmounted:Xe,activated:Xe,deactivated:Xe,errorCaptured:Xe,serverPrefetch:Xe,components:Vn,directives:Vn,watch:Ru,provide:zo,inject:Su};function zo(e,t){return t?e?function(){return Ue(le(e)?e.call(this,this):e,le(t)?t.call(this,this):t)}:t:e}function Su(e,t){return Vn(Lr(e),Lr(t))}function Lr(e){if(ne(e)){const t={};for(let n=0;nt==="modelValue"||t==="model-value"?e.modelModifiers:e[`${t}Modifiers`]||e[`${et(t)}Modifiers`]||e[`${Jt(t)}Modifiers`];function Tu(e,t,...n){if(e.isUnmounted)return;const s=e.vnode.props||Ce;let r=n;const o=t.startsWith("update:"),i=o&&Ou(s,t.slice(7));i&&(i.trim&&(r=n.map(c=>Te(c)?c.trim():c)),i.number&&(r=n.map(js)));let l,a=s[l=sr(t)]||s[l=sr(et(t))];!a&&o&&(a=s[l=sr(Jt(t))]),a&&ct(a,e,6,r);const u=s[l+"Once"];if(u){if(!e.emitted)e.emitted={};else if(e.emitted[l])return;e.emitted[l]=!0,ct(u,e,6,r)}}const Pu=new WeakMap;function sa(e,t,n=!1){const s=n?Pu:t.emitsCache,r=s.get(e);if(r!==void 0)return r;const o=e.emits;let i={},l=!1;if(!le(e)){const a=u=>{const c=sa(u,t,!0);c&&(l=!0,Ue(i,c))};!n&&t.mixins.length&&t.mixins.forEach(a),e.extends&&a(e.extends),e.mixins&&e.mixins.forEach(a)}return!o&&!l?(Ee(e)&&s.set(e,null),null):(ne(o)?o.forEach(a=>i[a]=null):Ue(i,o),Ee(e)&&s.set(e,i),i)}function Gs(e,t){return!e||!Fs(t)?!1:(t=t.slice(2),t=t==="Once"?t:t.replace(/Once$/,""),we(e,t[0].toLowerCase()+t.slice(1))||we(e,Jt(t))||we(e,t))}function Jo(e){const{type:t,vnode:n,proxy:s,withProxy:r,propsOptions:[o],slots:i,attrs:l,emit:a,render:u,renderCache:c,props:f,data:h,setupState:m,ctx:S,inheritAttrs:C}=e,P=Os(e);let v,x;try{if(n.shapeFlag&4){const R=r||s,O=R;v=St(u.call(O,R,c,f,m,h,S)),x=l}else{const R=t;v=St(R.length>1?R(f,{attrs:l,slots:i,emit:a}):R(f,null)),x=t.props?l:Nu(l)}}catch(R){Lt.length=0,Ks(R,e,1),v=Oe(We)}let A=v;if(x&&C!==!1){const R=Object.keys(x),{shapeFlag:O}=A;R.length&&O&7&&(o&&R.some(Ms)&&(x=Iu(x,o)),A=zt(A,x,!1,!0))}return n.dirs&&(A=zt(A,null,!1,!0),A.dirs=A.dirs?A.dirs.concat(n.dirs):n.dirs),n.transition&&Qn(A,n.transition),v=A,Os(P),v}const Nu=e=>{let t;for(const n in e)(n==="class"||n==="style"||Fs(n))&&((t||(t={}))[n]=e[n]);return t},Iu=(e,t)=>{const n={};for(const s in e)(!Ms(s)||!(s.slice(9)in t))&&(n[s]=e[s]);return n};function ku(e,t,n){const{props:s,children:r,component:o}=e,{props:i,children:l,patchFlag:a}=t,u=o.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&a>=0){if(a&1024)return!0;if(a&16)return s?Xo(s,i,u):!!i;if(a&8){const c=t.dynamicProps;for(let f=0;fObject.create(oa),la=e=>Object.getPrototypeOf(e)===oa;function Du(e,t,n,s=!1){const r={},o=ia();e.propsDefaults=Object.create(null),aa(e,t,r,o);for(const i in e.propsOptions[0])i in r||(r[i]=void 0);n?e.props=s?r:Cl(r):e.type.props?e.props=r:e.props=o,e.attrs=o}function Lu(e,t,n,s){const{props:r,attrs:o,vnode:{patchFlag:i}}=e,l=xe(r),[a]=e.propsOptions;let u=!1;if((s||i>0)&&!(i&16)){if(i&8){const c=e.vnode.dynamicProps;for(let f=0;f{a=!0;const[h,m]=ca(f,t,!0);Ue(i,h),m&&l.push(...m)};!n&&t.mixins.length&&t.mixins.forEach(c),e.extends&&c(e.extends),e.mixins&&e.mixins.forEach(c)}if(!o&&!a)return Ee(e)&&s.set(e,yn),yn;if(ne(o))for(let c=0;ce==="_"||e==="_ctx"||e==="$stable",co=e=>ne(e)?e.map(St):[St(e)],Fu=(e,t,n)=>{if(t._n)return t;const s=dt((...r)=>co(t(...r)),n);return s._c=!1,s},ua=(e,t,n)=>{const s=e._ctx;for(const r in e){if(ao(r))continue;const o=e[r];if(le(o))t[r]=Fu(r,o,s);else if(o!=null){const i=co(o);t[r]=()=>i}}},fa=(e,t)=>{const n=co(t);e.slots.default=()=>n},da=(e,t,n)=>{for(const s in t)(n||!ao(s))&&(e[s]=t[s])},Mu=(e,t,n)=>{const s=e.slots=ia();if(e.vnode.shapeFlag&32){const r=t._;r?(da(s,t,n),n&&ll(s,"_",r,!0)):ua(t,s)}else t&&fa(e,t)},Vu=(e,t,n)=>{const{vnode:s,slots:r}=e;let o=!0,i=Ce;if(s.shapeFlag&32){const l=t._;l?n&&l===1?o=!1:da(r,t,n):(o=!t.$stable,ua(t,r)),i=t}else t&&(fa(e,t),i={default:1});if(o)for(const l in r)!ao(l)&&i[l]==null&&delete r[l]},Ye=Ku;function Bu(e){return ju(e)}function ju(e,t){const n=Hs();n.__VUE__=!0;const{insert:s,remove:r,patchProp:o,createElement:i,createText:l,createComment:a,setText:u,setElementText:c,parentNode:f,nextSibling:h,setScopeId:m=Ct,insertStaticContent:S}=e,C=(p,g,_,N=null,E=null,T=null,K=void 0,j=null,q=!!g.dynamicChildren)=>{if(p===g)return;p&&!sn(p,g)&&(N=y(p),de(p,E,T,!0),p=null),g.patchFlag===-2&&(q=!1,g.dynamicChildren=null);const{type:L,ref:ee,shapeFlag:G}=g;switch(L){case Js:P(p,g,_,N);break;case We:v(p,g,_,N);break;case fr:p==null&&x(g,_,N,K);break;case ve:W(p,g,_,N,E,T,K,j,q);break;default:G&1?O(p,g,_,N,E,T,K,j,q):G&6?ce(p,g,_,N,E,T,K,j,q):(G&64||G&128)&&L.process(p,g,_,N,E,T,K,j,q,X)}ee!=null&&E?Kn(ee,p&&p.ref,T,g||p,!g):ee==null&&p&&p.ref!=null&&Kn(p.ref,null,T,p,!0)},P=(p,g,_,N)=>{if(p==null)s(g.el=l(g.children),_,N);else{const E=g.el=p.el;g.children!==p.children&&u(E,g.children)}},v=(p,g,_,N)=>{p==null?s(g.el=a(g.children||""),_,N):g.el=p.el},x=(p,g,_,N)=>{[p.el,p.anchor]=S(p.children,g,_,N,p.el,p.anchor)},A=({el:p,anchor:g},_,N)=>{let E;for(;p&&p!==g;)E=h(p),s(p,_,N),p=E;s(g,_,N)},R=({el:p,anchor:g})=>{let _;for(;p&&p!==g;)_=h(p),r(p),p=_;r(g)},O=(p,g,_,N,E,T,K,j,q)=>{if(g.type==="svg"?K="svg":g.type==="math"&&(K="mathml"),p==null)$(g,_,N,E,T,K,j,q);else{const L=p.el&&p.el._isVueCE?p.el:null;try{L&&L._beginPatch(),Y(p,g,E,T,K,j,q)}finally{L&&L._endPatch()}}},$=(p,g,_,N,E,T,K,j)=>{let q,L;const{props:ee,shapeFlag:G,transition:te,dirs:ie}=p;if(q=p.el=i(p.type,T,ee&&ee.is,ee),G&8?c(q,p.children):G&16&&ae(p.children,q,null,N,E,ur(p,T),K,j),ie&&Yt(p,null,N,"created"),U(q,p,p.scopeId,K,N),ee){for(const Re in ee)Re!=="value"&&!jn(Re)&&o(q,Re,null,ee[Re],T,N);"value"in ee&&o(q,"value",null,ee.value,T),(L=ee.onVnodeBeforeMount)&&_t(L,N,p)}ie&&Yt(p,null,N,"beforeMount");const he=Hu(E,te);he&&te.beforeEnter(q),s(q,g,_),((L=ee&&ee.onVnodeMounted)||he||ie)&&Ye(()=>{try{L&&_t(L,N,p),he&&te.enter(q),ie&&Yt(p,null,N,"mounted")}finally{}},E)},U=(p,g,_,N,E)=>{if(_&&m(p,_),N)for(let T=0;T{for(let L=q;L{const j=g.el=p.el;let{patchFlag:q,dynamicChildren:L,dirs:ee}=g;q|=p.patchFlag&16;const G=p.props||Ce,te=g.props||Ce;let ie;if(_&&Qt(_,!1),(ie=te.onVnodeBeforeUpdate)&&_t(ie,_,g,p),ee&&Yt(g,p,_,"beforeUpdate"),_&&Qt(_,!0),L&&(!p.dynamicChildren||p.dynamicChildren.length!==L.length)&&(q=0,K=!1,L=null),(G.innerHTML&&te.innerHTML==null||G.textContent&&te.textContent==null)&&c(j,""),L?se(p.dynamicChildren,L,j,_,N,ur(g,E),T):K||I(p,g,j,null,_,N,ur(g,E),T,!1),q>0){if(q&16)oe(j,G,te,_,E);else if(q&2&&G.class!==te.class&&o(j,"class",null,te.class,E),q&4&&o(j,"style",G.style,te.style,E),q&8){const he=g.dynamicProps;for(let Re=0;Re{ie&&_t(ie,_,g,p),ee&&Yt(g,p,_,"updated")},N)},se=(p,g,_,N,E,T,K)=>{for(let j=0;j{if(g!==_){if(g!==Ce)for(const T in g)!jn(T)&&!(T in _)&&o(p,T,g[T],null,E,N);for(const T in _){if(jn(T))continue;const K=_[T],j=g[T];K!==j&&T!=="value"&&o(p,T,j,K,E,N)}"value"in _&&o(p,"value",g.value,_.value,E)}},W=(p,g,_,N,E,T,K,j,q)=>{const L=g.el=p?p.el:l(""),ee=g.anchor=p?p.anchor:l("");let{patchFlag:G,dynamicChildren:te,slotScopeIds:ie}=g;ie&&(j=j?j.concat(ie):ie),p==null?(s(L,_,N),s(ee,_,N),ae(g.children||[],_,ee,E,T,K,j,q)):G>0&&G&64&&te&&p.dynamicChildren&&p.dynamicChildren.length===te.length?(se(p.dynamicChildren,te,_,E,T,K,j),(g.key!=null||E&&g===E.subTree)&&uo(p,g,!0)):I(p,g,_,ee,E,T,K,j,q)},ce=(p,g,_,N,E,T,K,j,q)=>{g.slotScopeIds=j,p==null?g.shapeFlag&512?E.ctx.activate(g,_,N,K,q):fe(g,_,N,E,T,K,q):Pe(p,g,q)},fe=(p,g,_,N,E,T,K)=>{const j=p.component=Yu(p,N,E);if(Ws(p)&&(j.ctx.renderer=X),Qu(j,!1,K),j.asyncDep){if(E&&E.registerDep(j,be,K),!p.el){const q=j.subTree=Oe(We);v(null,q,g,_),p.placeholder=q.el}}else be(j,p,g,_,E,T,K)},Pe=(p,g,_)=>{const N=g.component=p.component;if(ku(p,g,_))if(N.asyncDep&&!N.asyncResolved){D(N,g,_);return}else N.next=g,N.update();else g.el=p.el,N.vnode=g},be=(p,g,_,N,E,T,K)=>{const j=()=>{if(p.isMounted){let{next:G,bu:te,u:ie,parent:he,vnode:Re}=p;{const xt=pa(p);if(xt){G&&(G.el=Re.el,D(p,G,K)),xt.asyncDep.then(()=>{Ye(()=>{p.isUnmounted||L()},E)});return}}let Se=G,$e;Qt(p,!1),G?(G.el=Re.el,D(p,G,K)):G=Re,te&&xs(te),($e=G.props&&G.props.onVnodeBeforeUpdate)&&_t($e,he,G,Re),Qt(p,!0);const Me=Jo(p),bt=p.subTree;p.subTree=Me,C(bt,Me,f(bt.el),y(bt),p,E,T),G.el=Me.el,Se===null&&$u(p,Me.el),ie&&Ye(ie,E),($e=G.props&&G.props.onVnodeUpdated)&&Ye(()=>_t($e,he,G,Re),E)}else{let G;const{el:te,props:ie}=g,{bm:he,m:Re,parent:Se,root:$e,type:Me}=p,bt=_n(g);Qt(p,!1),he&&xs(he),!bt&&(G=ie&&ie.onVnodeBeforeMount)&&_t(G,Se,g),Qt(p,!0);{$e.ce&&$e.ce._hasShadowRoot()&&$e.ce._injectChildStyle(Me,p.parent?p.parent.type:void 0);const xt=p.subTree=Jo(p);C(null,xt,_,N,p,E,T),g.el=xt.el}if(Re&&Ye(Re,E),!bt&&(G=ie&&ie.onVnodeMounted)){const xt=g;Ye(()=>_t(G,Se,xt),E)}(g.shapeFlag&256||Se&&_n(Se.vnode)&&Se.vnode.shapeFlag&256)&&p.a&&Ye(p.a,E),p.isMounted=!0,g=_=N=null}};p.scope.on();const q=p.effect=new dl(j);p.scope.off();const L=p.update=q.run.bind(q),ee=p.job=q.runIfDirty.bind(q);ee.i=p,ee.id=p.uid,q.scheduler=()=>lo(ee),Qt(p,!0),L()},D=(p,g,_)=>{g.component=p;const N=p.vnode.props;p.vnode=g,p.next=null,Lu(p,g.props,N,_),Vu(p,g.children,_),Ut(),Uo(p),Ft()},I=(p,g,_,N,E,T,K,j,q=!1)=>{const L=p&&p.children,ee=p?p.shapeFlag:0,G=g.children,{patchFlag:te,shapeFlag:ie}=g;if(te>0){if(te&128){ue(L,G,_,N,E,T,K,j,q);return}else if(te&256){J(L,G,_,N,E,T,K,j,q);return}}ie&8?(ee&16&&w(L,E,T),G!==L&&c(_,G)):ee&16?ie&16?ue(L,G,_,N,E,T,K,j,q):w(L,E,T,!0):(ee&8&&c(_,""),ie&16&&ae(G,_,N,E,T,K,j,q))},J=(p,g,_,N,E,T,K,j,q)=>{p=p||yn,g=g||yn;const L=p.length,ee=g.length,G=Math.min(L,ee);let te;for(te=0;teee?w(p,E,T,!0,!1,G):ae(g,_,N,E,T,K,j,q,G)},ue=(p,g,_,N,E,T,K,j,q)=>{let L=0;const ee=g.length;let G=p.length-1,te=ee-1;for(;L<=G&&L<=te;){const ie=p[L],he=g[L]=q?It(g[L]):St(g[L]);if(sn(ie,he))C(ie,he,_,null,E,T,K,j,q);else break;L++}for(;L<=G&&L<=te;){const ie=p[G],he=g[te]=q?It(g[te]):St(g[te]);if(sn(ie,he))C(ie,he,_,null,E,T,K,j,q);else break;G--,te--}if(L>G){if(L<=te){const ie=te+1,he=iete)for(;L<=G;)de(p[L],E,T,!0),L++;else{const ie=L,he=L,Re=new Map;for(L=he;L<=te;L++){const st=g[L]=q?It(g[L]):St(g[L]);st.key!=null&&Re.set(st.key,L)}let Se,$e=0;const Me=te-he+1;let bt=!1,xt=0;const kn=new Array(Me);for(L=0;L=Me){de(st,E,T,!0);continue}let vt;if(st.key!=null)vt=Re.get(st.key);else for(Se=he;Se<=te;Se++)if(kn[Se-he]===0&&sn(st,g[Se])){vt=Se;break}vt===void 0?de(st,E,T,!0):(kn[vt-he]=L+1,vt>=xt?xt=vt:bt=!0,C(st,g[vt],_,null,E,T,K,j,q),$e++)}const Po=bt?qu(kn):yn;for(Se=Po.length-1,L=Me-1;L>=0;L--){const st=he+L,vt=g[st],No=g[st+1],Io=st+1{const{el:T,type:K,transition:j,children:q,shapeFlag:L}=p;if(L&6){re(p.component.subTree,g,_,N);return}if(L&128){p.suspense.move(g,_,N);return}if(L&64){K.move(p,g,_,X);return}if(K===ve){s(T,g,_);for(let G=0;Gj.enter(T),E));else{const{leave:G,delayLeave:te,afterLeave:ie}=j,he=()=>{p.ctx.isUnmounted?r(T):s(T,g,_)},Re=()=>{const Se=T._isLeaving||!!T[it];T._isLeaving&&T[it](!0),j.persisted&&!Se?he():G(T,()=>{he(),ie&&ie()})};te?te(T,he,Re):Re()}else s(T,g,_)},de=(p,g,_,N=!1,E=!1)=>{const{type:T,props:K,ref:j,children:q,dynamicChildren:L,shapeFlag:ee,patchFlag:G,dirs:te,cacheIndex:ie,memo:he}=p;if(G===-2&&(E=!1),j!=null&&(Ut(),Kn(j,null,_,p,!0),Ft()),ie!=null&&(g.renderCache[ie]=void 0),ee&256){g.ctx.deactivate(p);return}const Re=ee&1&&te,Se=!_n(p);let $e;if(Se&&($e=K&&K.onVnodeBeforeUnmount)&&_t($e,g,p),ee&6)k(p.component,_,N);else{if(ee&128){p.suspense.unmount(_,N);return}Re&&Yt(p,null,g,"beforeUnmount"),ee&64?p.type.remove(p,g,_,X,N):L&&!L.hasOnce&&(T!==ve||G>0&&G&64)?w(L,g,_,!1,!0):(T===ve&&G&384||!E&&ee&16)&&w(q,g,_),N&&Ne(p)}const Me=he!=null&&ie==null;(Se&&($e=K&&K.onVnodeUnmounted)||Re||Me)&&Ye(()=>{$e&&_t($e,g,p),Re&&Yt(p,null,g,"unmounted"),Me&&(p.el=null)},_)},Ne=p=>{const{type:g,el:_,anchor:N,transition:E}=p;if(g===ve){ge(_,N);return}if(g===fr){R(p);return}const T=()=>{r(_),E&&!E.persisted&&E.afterLeave&&E.afterLeave()};if(p.shapeFlag&1&&E&&!E.persisted){const{leave:K,delayLeave:j}=E,q=()=>K(_,T);j?j(p.el,T,q):q()}else T()},ge=(p,g)=>{let _;for(;p!==g;)_=h(p),r(p),p=_;r(g)},k=(p,g,_)=>{const{bum:N,scope:E,job:T,subTree:K,um:j,m:q,a:L}=p;Qo(q),Qo(L),N&&xs(N),E.stop(),T&&(T.flags|=8,de(K,p,g,_)),j&&Ye(j,g),Ye(()=>{p.isUnmounted=!0},g)},w=(p,g,_,N=!1,E=!1,T=0)=>{for(let K=T;K{if(p.shapeFlag&6)return y(p.component.subTree);if(p.shapeFlag&128)return p.suspense.next();const g=h(p.anchor||p.el),_=g&&g[Ul];return _?h(_):g};let V=!1;const M=(p,g,_)=>{let N;p==null?g._vnode&&(de(g._vnode,null,null,!0),N=g._vnode.component):C(g._vnode||null,p,g,null,null,null,_),g._vnode=p,V||(V=!0,Uo(N),Il(),V=!1)},X={p:C,um:de,m:re,r:Ne,mt:fe,mc:ae,pc:I,pbc:se,n:y,o:e};return{render:M,hydrate:void 0,createApp:Au(M)}}function ur({type:e,props:t},n){return n==="svg"&&e==="foreignObject"||n==="mathml"&&e==="annotation-xml"&&t&&t.encoding&&t.encoding.includes("html")?void 0:n}function Qt({effect:e,job:t},n){n?(e.flags|=32,t.flags|=4):(e.flags&=-33,t.flags&=-5)}function Hu(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function uo(e,t,n=!1){const s=e.children,r=t.children;if(ne(s)&&ne(r))for(let o=0;o>1,e[n[l]]0&&(t[s]=n[o-1]),n[o]=s)}}for(o=n.length,i=n[o-1];o-- >0;)n[o]=i,i=t[i];return n}function pa(e){const t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:pa(t)}function Qo(e){if(e)for(let t=0;te.__isSuspense;function Ku(e,t){t&&t.pendingBranch?ne(e)?t.effects.push(...e):t.effects.push(e):Zc(e)}const ve=Symbol.for("v-fgt"),Js=Symbol.for("v-txt"),We=Symbol.for("v-cmt"),fr=Symbol.for("v-stc"),Lt=[];let rt=null;function F(e=!1){Lt.push(rt=e?null:[])}function fo(){Lt.pop(),rt=Lt[Lt.length-1]||null}let Zn=1;function Ns(e,t=!1){Zn+=e,e<0&&rt&&t&&(rt.hasOnce=!0)}function ga(e){return e.dynamicChildren=Zn>0?rt||yn:null,fo(),Zn>0&&rt&&rt.push(e),e}function B(e,t,n,s,r,o){return ga(d(e,t,n,s,r,o,!0))}function un(e,t,n,s,r){return ga(Oe(e,t,n,s,r,!0))}function es(e){return e?e.__v_isVNode===!0:!1}function sn(e,t){return e.type===t.type&&e.key===t.key}const ya=({key:e})=>e??null,ws=({ref:e,ref_key:t,ref_for:n})=>(typeof e=="number"&&(e=""+e),e!=null?Te(e)||Ge(e)||le(e)?{i:He,r:e,k:t,f:!!n}:e:null);function d(e,t=null,n=null,s=0,r=null,o=e===ve?0:1,i=!1,l=!1){const a={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&ya(t),ref:t&&ws(t),scopeId:$l,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetStart:null,targetAnchor:null,staticCount:0,shapeFlag:o,patchFlag:s,dynamicProps:r,dynamicChildren:null,appContext:null,ctx:He};return l?(Is(a,n),o&128&&e.normalize(a)):n&&(a.shapeFlag|=Te(n)?8:16),Zn>0&&!i&&rt&&(a.patchFlag>0||o&6)&&a.patchFlag!==32&&rt.push(a),a}const Oe=Wu;function Wu(e,t=null,n=null,s=0,r=null,o=!1){if((!e||e===Yl)&&(e=We),es(e)){const l=zt(e,t,!0);return n&&Is(l,n),Zn>0&&!o&&rt&&(l.shapeFlag&6?rt[rt.indexOf(e)]=l:rt.push(l)),l.patchFlag=-2,l}if(sf(e)&&(e=e.__vccOpts),t){t=zu(t);let{class:l,style:a}=t;l&&!Te(l)&&(t.class=je(l)),Ee(a)&&(oo(a)&&!ne(a)&&(a=Ue({},a)),t.style=Yr(a))}const i=Te(e)?1:ma(e)?128:Fl(e)?64:Ee(e)?4:le(e)?2:0;return d(e,t,n,s,r,i,o,!0)}function zu(e){return e?oo(e)||la(e)?Ue({},e):e:null}function zt(e,t,n=!1,s=!1){const{props:r,ref:o,patchFlag:i,children:l,transition:a}=e,u=t?Gu(r||{},t):r,c={__v_isVNode:!0,__v_skip:!0,type:e.type,props:u,key:u&&ya(u),ref:t&&t.ref?n&&o?ne(o)?o.concat(ws(t)):[o,ws(t)]:ws(t):o,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:l,target:e.target,targetStart:e.targetStart,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==ve?i===-1?16:i|16:i,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:a,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&zt(e.ssContent),ssFallback:e.ssFallback&&zt(e.ssFallback),placeholder:e.placeholder,el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce};return a&&s&&Qn(c,a.clone(c)),c}function ts(e=" ",t=0){return Oe(Js,null,e,t)}function pe(e="",t=!1){return t?(F(),un(We,null,e)):Oe(We,null,e)}function St(e){return e==null||typeof e=="boolean"?Oe(We):ne(e)?Oe(ve,null,e.slice()):es(e)?It(e):Oe(Js,null,String(e))}function It(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:zt(e)}function Is(e,t){let n=0;const{shapeFlag:s}=e;if(t==null)t=null;else if(ne(t))n=16;else if(typeof t=="object")if(s&65){const r=t.default;r&&(r._c&&(r._d=!1),Is(e,r()),r._c&&(r._d=!0));return}else{n=32;const r=t._;!r&&!la(t)?t._ctx=He:r===3&&He&&(He.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else if(le(t)){if(s&65){Is(e,{default:t});return}t={default:t,_ctx:He},n=32}else t=String(t),s&64?(n=16,t=[ts(t)]):n=8;e.children=t,e.shapeFlag|=n}function Gu(...e){const t={};for(let n=0;nze||He;let ks,Fr;{const e=Hs(),t=(n,s)=>{let r;return(r=e[n])||(r=e[n]=[]),r.push(s),o=>{r.length>1?r.forEach(i=>i(o)):r[0](o)}};ks=t("__VUE_INSTANCE_SETTERS__",n=>ze=n),Fr=t("__VUE_SSR_SETTERS__",n=>ns=n)}const cs=e=>{const t=ze;return ks(e),e.scope.on(),()=>{e.scope.off(),ks(t)}},Zo=()=>{ze&&ze.scope.off(),ks(null)};function xa(e){return e.vnode.shapeFlag&4}let ns=!1;function Qu(e,t=!1,n=!1){t&&Fr(t);const{props:s,children:r}=e.vnode,o=xa(e);Du(e,s,o,t),Mu(e,r,n||t);const i=o?Zu(e,t):void 0;return t&&Fr(!1),i}function Zu(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=new Proxy(e.ctx,vu);const{setup:s}=n;if(s){Ut();const r=e.setupContext=s.length>1?tf(e):null,o=cs(e),i=as(s,e,0,[e.props,r]),l=rl(i);if(Ft(),o(),(l||e.sp)&&!_n(e)&&Wl(e),l){if(i.then(Zo,Zo),t)return i.then(a=>{ei(e,a)}).catch(a=>{Ks(a,e,0)});e.asyncDep=i}else ei(e,i)}else va(e)}function ei(e,t,n){le(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:Ee(t)&&(e.setupState=Tl(t)),va(e)}function va(e,t,n){const s=e.type;e.render||(e.render=s.render||Ct);{const r=cs(e);Ut();try{_u(e)}finally{Ft(),r()}}}const ef={get(e,t){return Ke(e,"get",""),e[t]}};function tf(e){const t=n=>{e.exposed=n||{}};return{attrs:new Proxy(e.attrs,ef),slots:e.slots,emit:e.emit,expose:t}}function Xs(e){return e.exposed?e.exposeProxy||(e.exposeProxy=new Proxy(Tl(Al(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in Wn)return Wn[n](e)},has(t,n){return n in t||n in Wn}})):e.proxy}function nf(e,t=!0){return le(e)?e.displayName||e.name:e.name||t&&e.__name}function sf(e){return le(e)&&"__vccOpts"in e}const tt=(e,t)=>Gc(e,t,ns);function po(e,t,n){try{Ns(-1);const s=arguments.length;return s===2?Ee(t)&&!ne(t)?es(t)?Oe(e,null,[t]):Oe(e,t):Oe(e,null,t):(s>3?n=Array.prototype.slice.call(arguments,2):s===3&&es(n)&&(n=[n]),Oe(e,t,n))}finally{Ns(1)}}const rf="3.5.40";/** -* @vue/runtime-dom v3.5.40 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/let Mr;const ti=typeof window<"u"&&window.trustedTypes;if(ti)try{Mr=ti.createPolicy("vue",{createHTML:e=>e})}catch{}const _a=Mr?e=>Mr.createHTML(e):e=>e,of="http://www.w3.org/2000/svg",lf="http://www.w3.org/1998/Math/MathML",Nt=typeof document<"u"?document:null,ni=Nt&&Nt.createElement("template"),af={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,s)=>{const r=t==="svg"?Nt.createElementNS(of,e):t==="mathml"?Nt.createElementNS(lf,e):n?Nt.createElement(e,{is:n}):Nt.createElement(e);return e==="select"&&s&&s.multiple!=null&&r.setAttribute("multiple",s.multiple),r},createText:e=>Nt.createTextNode(e),createComment:e=>Nt.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>Nt.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,s,r,o){const i=n?n.previousSibling:t.lastChild;if(r&&(r===o||r.nextSibling))for(;t.insertBefore(r.cloneNode(!0),n),!(r===o||!(r=r.nextSibling)););else{ni.innerHTML=_a(s==="svg"?`${e}`:s==="mathml"?`${e}`:e);const l=ni.content;if(s==="svg"||s==="mathml"){const a=l.firstChild;for(;a.firstChild;)l.appendChild(a.firstChild);l.removeChild(a)}t.insertBefore(l,n)}return[i?i.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},Bt="transition",Ln="animation",ss=Symbol("_vtc"),wa={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String},cf=Ue({},Vl,wa),uf=e=>(e.displayName="Transition",e.props=cf,e),ff=uf((e,{slots:t})=>po(au,df(e),t)),Zt=(e,t=[])=>{ne(e)?e.forEach(n=>n(...t)):e&&e(...t)},si=e=>e?ne(e)?e.some(t=>t.length>1):e.length>1:!1;function df(e){const t={};for(const W in e)W in wa||(t[W]=e[W]);if(e.css===!1)return t;const{name:n="v",type:s,duration:r,enterFromClass:o=`${n}-enter-from`,enterActiveClass:i=`${n}-enter-active`,enterToClass:l=`${n}-enter-to`,appearFromClass:a=o,appearActiveClass:u=i,appearToClass:c=l,leaveFromClass:f=`${n}-leave-from`,leaveActiveClass:h=`${n}-leave-active`,leaveToClass:m=`${n}-leave-to`}=e,S=pf(r),C=S&&S[0],P=S&&S[1],{onBeforeEnter:v,onEnter:x,onEnterCancelled:A,onLeave:R,onLeaveCancelled:O,onBeforeAppear:$=v,onAppear:U=x,onAppearCancelled:ae=A}=t,Y=(W,ce,fe,Pe)=>{W._enterCancelled=Pe,en(W,ce?c:l),en(W,ce?u:i),fe&&fe()},se=(W,ce)=>{W._isLeaving=!1,en(W,f),en(W,m),en(W,h),ce&&ce()},oe=W=>(ce,fe)=>{const Pe=W?U:x,be=()=>Y(ce,W,fe);Zt(Pe,[ce,be]),ri(()=>{en(ce,W?a:o),Tt(ce,W?c:l),si(Pe)||oi(ce,s,C,be)})};return Ue(t,{onBeforeEnter(W){Zt(v,[W]),Tt(W,o),Tt(W,i)},onBeforeAppear(W){Zt($,[W]),Tt(W,a),Tt(W,u)},onEnter:oe(!1),onAppear:oe(!0),onLeave(W,ce){W._isLeaving=!0;const fe=()=>se(W,ce);Tt(W,f),W._enterCancelled?(Tt(W,h),ai(W)):(ai(W),Tt(W,h)),ri(()=>{W._isLeaving&&(en(W,f),Tt(W,m),si(R)||oi(W,s,P,fe))}),Zt(R,[W,fe])},onEnterCancelled(W){Y(W,!1,void 0,!0),Zt(A,[W])},onAppearCancelled(W){Y(W,!0,void 0,!0),Zt(ae,[W])},onLeaveCancelled(W){se(W),Zt(O,[W])}})}function pf(e){if(e==null)return null;if(Ee(e))return[dr(e.enter),dr(e.leave)];{const t=dr(e);return[t,t]}}function dr(e){return yc(e)}function Tt(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e[ss]||(e[ss]=new Set)).add(t)}function en(e,t){t.split(/\s+/).forEach(s=>s&&e.classList.remove(s));const n=e[ss];n&&(n.delete(t),n.size||(e[ss]=void 0))}function ri(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let hf=0;function oi(e,t,n,s){const r=e._endId=++hf,o=()=>{r===e._endId&&s()};if(n!=null)return setTimeout(o,n);const{type:i,timeout:l,propCount:a}=mf(e,t);if(!i)return s();const u=i+"end";let c=0;const f=()=>{e.removeEventListener(u,h),o()},h=m=>{m.target===e&&++c>=a&&f()};setTimeout(()=>{c(n[S]||"").split(", "),r=s(`${Bt}Delay`),o=s(`${Bt}Duration`),i=ii(r,o),l=s(`${Ln}Delay`),a=s(`${Ln}Duration`),u=ii(l,a);let c=null,f=0,h=0;t===Bt?i>0&&(c=Bt,f=i,h=o.length):t===Ln?u>0&&(c=Ln,f=u,h=a.length):(f=Math.max(i,u),c=f>0?i>u?Bt:Ln:null,h=c?c===Bt?o.length:a.length:0);const m=c===Bt&&/\b(?:transform|all)(?:,|$)/.test(s(`${Bt}Property`).toString());return{type:c,timeout:f,propCount:h,hasTransform:m}}function ii(e,t){for(;e.lengthli(n)+li(e[s])))}function li(e){return e==="auto"?0:Number(e.slice(0,-1).replace(",","."))*1e3}function ai(e){return(e?e.ownerDocument:document).body.offsetHeight}function gf(e,t,n){const s=e[ss];s&&(t=(t?[t,...s]:[...s]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}const ci=Symbol("_vod"),yf=Symbol("_vsh"),bf=Symbol(""),xf=/(?:^|;)\s*display\s*:/;function vf(e,t,n){const s=e.style,r=Te(n);let o=!1;if(n&&!r){if(t)if(Te(t))for(const i of t.split(";")){const l=i.slice(0,i.indexOf(":")).trim();n[l]==null&&Bn(s,l,"")}else for(const i in t)n[i]==null&&Bn(s,i,"");for(const i in n){i==="display"&&(o=!0);const l=n[i];l!=null?wf(e,i,!Te(t)&&t?t[i]:void 0,l)||Bn(s,i,l):Bn(s,i,"")}}else if(r){if(t!==n){const i=s[bf];i&&(n+=";"+i),s.cssText=n,o=xf.test(n)}}else t&&e.removeAttribute("style");ci in e&&(e[ci]=o?s.display:"",e[yf]&&(s.display="none"))}const ui=/\s*!important$/;function Bn(e,t,n){if(ne(n))n.forEach(s=>Bn(e,t,s));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const s=_f(e,t);ui.test(n)?e.setProperty(Jt(s),n.replace(ui,""),"important"):e[s]=n}}const fi=["Webkit","Moz","ms"],pr={};function _f(e,t){const n=pr[t];if(n)return n;let s=et(t);if(s!=="filter"&&s in e)return pr[t]=s;s=Bs(s);for(let r=0;rhr||(Of.then(()=>hr=0),hr=Date.now());function Pf(e,t){const n=s=>{if(!s._vts)s._vts=Date.now();else if(s._vts<=n.attached)return;const r=n.value;if(ne(r)){const o=s.stopImmediatePropagation;s.stopImmediatePropagation=()=>{o.call(s),s._stopped=!0};const i=r.slice(),l=[s];for(let a=0;ae.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,Nf=(e,t,n,s,r,o)=>{const i=r==="svg";t==="class"?gf(e,s,i):t==="style"?vf(e,n,s):Fs(t)?Ms(t)||Sf(e,t,n,s,o):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):If(e,t,s,i))?(hi(e,t,s),!e.tagName.includes("-")&&(t==="value"||t==="checked"||t==="selected")&&pi(e,t,s,i,o,t!=="value")):e._isVueCE&&(kf(e,t)||e._def.__asyncLoader&&(/[A-Z]/.test(t)||!Te(s)))?hi(e,et(t),s,o,t):(t==="true-value"?e._trueValue=s:t==="false-value"&&(e._falseValue=s),pi(e,t,s,i))};function If(e,t,n,s){if(s)return!!(t==="innerHTML"||t==="textContent"||t in e&&gi(t)&&le(n));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="autocorrect"||t==="sandbox"&&e.tagName==="IFRAME"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const r=e.tagName;if(r==="IMG"||r==="VIDEO"||r==="CANVAS"||r==="SOURCE")return!1}return gi(t)&&Te(n)?!1:t in e}function kf(e,t){const n=e._def.props;if(!n)return!1;const s=et(t);return Array.isArray(n)?n.some(r=>et(r)===s):Object.keys(n).some(r=>et(r)===s)}const Gt=e=>{const t=e.props["onUpdate:modelValue"]||!1;return ne(t)?n=>xs(t,n):t};function $f(e){e.target.composing=!0}function yi(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const at=Symbol("_assign");function bi(e,t,n){return t&&(e=e.trim()),n&&(e=js(e)),e}const De={created(e,{modifiers:{lazy:t,trim:n,number:s}},r){e[at]=Gt(r);const o=s||r.props&&r.props.type==="number";Dt(e,t?"change":"input",i=>{i.target.composing||e[at](bi(e.value,n,o))}),(n||o)&&Dt(e,"change",()=>{e.value=bi(e.value,n,o)}),t||(Dt(e,"compositionstart",$f),Dt(e,"compositionend",yi),Dt(e,"change",yi))},mounted(e,{value:t}){e.value=t??""},beforeUpdate(e,{value:t,oldValue:n,modifiers:{lazy:s,trim:r,number:o}},i){if(e[at]=Gt(i),e.composing)return;const l=(o||e.type==="number")&&!/^0\d/.test(e.value)?js(e.value):e.value,a=t??"";if(l===a)return;const u=e.getRootNode();(u instanceof Document||u instanceof ShadowRoot)&&u.activeElement===e&&e.type!=="range"&&(s&&t===n||r&&e.value.trim()===a)||(e.value=a)}},zn={deep:!0,created(e,t,n){e[at]=Gt(n),Dt(e,"change",()=>{const s=e._modelValue,r=Rn(e),o=e.checked,i=e[at];if(ne(s)){const l=Qr(s,r),a=l!==-1;if(o&&!a)i(s.concat(r));else if(!o&&a){const u=[...s];u.splice(l,1),i(u)}}else if(Pn(s)){const l=new Set(s);o?l.add(r):l.delete(r),i(l)}else i(Ea(e,o))})},mounted:xi,beforeUpdate(e,t,n){e[at]=Gt(n),xi(e,t,n)}};function xi(e,{value:t,oldValue:n},s){e._modelValue=t;let r;if(ne(t))r=Qr(t,s.props.value)>-1;else if(Pn(t))r=t.has(s.props.value);else{if(t===n)return;r=Wt(t,Ea(e,!0))}e.checked!==r&&(e.checked=r)}const vi={created(e,{value:t},n){e.checked=Wt(t,n.props.value),e[at]=Gt(n),Dt(e,"change",()=>{e[at](Rn(e))})},beforeUpdate(e,{value:t,oldValue:n},s){e[at]=Gt(s),t!==n&&(e.checked=Wt(t,s.props.value))}},Sn={deep:!0,created(e,{value:t,modifiers:{number:n}},s){e._modelValue=t,Dt(e,"change",()=>{const r=Array.prototype.filter.call(e.options,o=>o.selected).map(o=>n?js(Rn(o)):Rn(o));e[at](e.multiple?Pn(e._modelValue)?new Set(r):r:r[0]),e._assigning=!0,io(()=>{e._assigning=!1})}),e[at]=Gt(s)},mounted(e,{value:t}){_i(e,t)},beforeUpdate(e,{value:t},n){e._modelValue=t,e[at]=Gt(n)},updated(e,{value:t}){e._assigning||_i(e,t)}};function _i(e,t){const n=e.multiple,s=ne(t);if(!(n&&!s&&!Pn(t))){for(let r=0,o=e.options.length;rString(u)===String(l)):i.selected=Qr(t,l)>-1}else i.selected=t.has(l);else if(Wt(Rn(i),t)){e.selectedIndex!==r&&(e.selectedIndex=r);return}}!n&&e.selectedIndex!==-1&&(e.selectedIndex=-1)}}function Rn(e){return"_value"in e?e._value:e.value}function Ea(e,t){const n=t?"_trueValue":"_falseValue";return n in e?e[n]:t}const Df=["ctrl","shift","alt","meta"],Lf={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>"button"in e&&e.button!==0,middle:e=>"button"in e&&e.button!==1,right:e=>"button"in e&&e.button!==2,exact:(e,t)=>Df.some(n=>e[`${n}Key`]&&!t.includes(n))},ut=(e,t)=>{if(!e)return e;const n=e._withMods||(e._withMods={}),s=t.join(".");return n[s]||(n[s]=((r,...o)=>{for(let i=0;i{const n=e._withKeys||(e._withKeys={}),s=t.join(".");return n[s]||(n[s]=(r=>{if(!("key"in r))return;const o=Jt(r.key);if(t.some(i=>i===o||Uf[i]===o))return e(r)}))},Mf=Ue({patchProp:Nf},af);let wi;function Vf(){return wi||(wi=Bu(Mf))}const Bf=((...e)=>{const t=Vf().createApp(...e),{mount:n}=t;return t.mount=s=>{const r=Hf(s);if(!r)return;const o=t._component;!le(o)&&!o.render&&!o.template&&(o.template=r.innerHTML),r.nodeType===1&&(r.textContent="");const i=n(r,!1,jf(r));return r instanceof Element&&(r.removeAttribute("v-cloak"),r.setAttribute("data-v-app","")),i},t});function jf(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function Hf(e){return Te(e)?document.querySelector(e):e}/*! - * pinia v2.3.1 - * (c) 2025 Eduardo San Martin Morote - * @license MIT - */const qf=Symbol();var Ei;(function(e){e.direct="direct",e.patchObject="patch object",e.patchFunction="patch function"})(Ei||(Ei={}));function Kf(){const e=Rc(!0),t=e.run(()=>Z({}));let n=[],s=[];const r=Al({install(o){r._a=o,o.provide(qf,r),o.config.globalProperties.$pinia=r,s.forEach(i=>n.push(i)),s=[]},use(o){return this._a?n.push(o):s.push(o),this},_p:n,_a:null,_e:e,_s:new Map,state:t});return r}const Wf={__name:"App",setup(e){return(t,n)=>{const s=kr("router-view");return F(),un(s,null,{default:dt(({Component:r})=>[Oe(ff,{name:"fade",mode:"out-in"},{default:dt(()=>[(F(),un(xu(r)))]),_:2},1024)]),_:1})}}};/*! - * vue-router v4.6.4 - * (c) 2025 Eduardo San Martin Morote - * @license MIT - */const gn=typeof document<"u";function Sa(e){return typeof e=="object"||"displayName"in e||"props"in e||"__vccOpts"in e}function zf(e){return e.__esModule||e[Symbol.toStringTag]==="Module"||e.default&&Sa(e.default)}const _e=Object.assign;function mr(e,t){const n={};for(const s in t){const r=t[s];n[s]=gt(r)?r.map(e):e(r)}return n}const Gn=()=>{},gt=Array.isArray;function Si(e,t){const n={};for(const s in e)n[s]=s in t?t[s]:e[s];return n}const Ra=/#/g,Gf=/&/g,Jf=/\//g,Xf=/=/g,Yf=/\?/g,Ca=/\+/g,Qf=/%5B/g,Zf=/%5D/g,Aa=/%5E/g,ed=/%60/g,Oa=/%7B/g,td=/%7C/g,Ta=/%7D/g,nd=/%20/g;function ho(e){return e==null?"":encodeURI(""+e).replace(td,"|").replace(Qf,"[").replace(Zf,"]")}function sd(e){return ho(e).replace(Oa,"{").replace(Ta,"}").replace(Aa,"^")}function Vr(e){return ho(e).replace(Ca,"%2B").replace(nd,"+").replace(Ra,"%23").replace(Gf,"%26").replace(ed,"`").replace(Oa,"{").replace(Ta,"}").replace(Aa,"^")}function rd(e){return Vr(e).replace(Xf,"%3D")}function od(e){return ho(e).replace(Ra,"%23").replace(Yf,"%3F")}function id(e){return od(e).replace(Jf,"%2F")}function rs(e){if(e==null)return null;try{return decodeURIComponent(""+e)}catch{}return""+e}const ld=/\/$/,ad=e=>e.replace(ld,"");function gr(e,t,n="/"){let s,r={},o="",i="";const l=t.indexOf("#");let a=t.indexOf("?");return a=l>=0&&a>l?-1:a,a>=0&&(s=t.slice(0,a),o=t.slice(a,l>0?l:t.length),r=e(o.slice(1))),l>=0&&(s=s||t.slice(0,l),i=t.slice(l,t.length)),s=dd(s??t,n),{fullPath:s+o+i,path:s,query:r,hash:rs(i)}}function cd(e,t){const n=t.query?e(t.query):"";return t.path+(n&&"?")+n+(t.hash||"")}function Ri(e,t){return!t||!e.toLowerCase().startsWith(t.toLowerCase())?e:e.slice(t.length)||"/"}function ud(e,t,n){const s=t.matched.length-1,r=n.matched.length-1;return s>-1&&s===r&&Cn(t.matched[s],n.matched[r])&&Pa(t.params,n.params)&&e(t.query)===e(n.query)&&t.hash===n.hash}function Cn(e,t){return(e.aliasOf||e)===(t.aliasOf||t)}function Pa(e,t){if(Object.keys(e).length!==Object.keys(t).length)return!1;for(var n in e)if(!fd(e[n],t[n]))return!1;return!0}function fd(e,t){return gt(e)?Ci(e,t):gt(t)?Ci(t,e):(e==null?void 0:e.valueOf())===(t==null?void 0:t.valueOf())}function Ci(e,t){return gt(t)?e.length===t.length&&e.every((n,s)=>n===t[s]):e.length===1&&e[0]===t}function dd(e,t){if(e.startsWith("/"))return e;if(!e)return t;const n=t.split("/"),s=e.split("/"),r=s[s.length-1];(r===".."||r===".")&&s.push("");let o=n.length-1,i,l;for(i=0;i1&&o--;else break;return n.slice(0,o).join("/")+"/"+s.slice(i).join("/")}const jt={path:"/",name:void 0,params:{},query:{},hash:"",fullPath:"/",matched:[],meta:{},redirectedFrom:void 0};let Br=(function(e){return e.pop="pop",e.push="push",e})({}),yr=(function(e){return e.back="back",e.forward="forward",e.unknown="",e})({});function pd(e){if(!e)if(gn){const t=document.querySelector("base");e=t&&t.getAttribute("href")||"/",e=e.replace(/^\w+:\/\/[^\/]+/,"")}else e="/";return e[0]!=="/"&&e[0]!=="#"&&(e="/"+e),ad(e)}const hd=/^[^#]+#/;function md(e,t){return e.replace(hd,"#")+t}function gd(e,t){const n=document.documentElement.getBoundingClientRect(),s=e.getBoundingClientRect();return{behavior:t.behavior,left:s.left-n.left-(t.left||0),top:s.top-n.top-(t.top||0)}}const Ys=()=>({left:window.scrollX,top:window.scrollY});function yd(e){let t;if("el"in e){const n=e.el,s=typeof n=="string"&&n.startsWith("#"),r=typeof n=="string"?s?document.getElementById(n.slice(1)):document.querySelector(n):n;if(!r)return;t=gd(r,e)}else t=e;"scrollBehavior"in document.documentElement.style?window.scrollTo(t):window.scrollTo(t.left!=null?t.left:window.scrollX,t.top!=null?t.top:window.scrollY)}function Ai(e,t){return(history.state?history.state.position-t:-1)+e}const jr=new Map;function bd(e,t){jr.set(e,t)}function xd(e){const t=jr.get(e);return jr.delete(e),t}function vd(e){return typeof e=="string"||e&&typeof e=="object"}function Na(e){return typeof e=="string"||typeof e=="symbol"}let Ie=(function(e){return e[e.MATCHER_NOT_FOUND=1]="MATCHER_NOT_FOUND",e[e.NAVIGATION_GUARD_REDIRECT=2]="NAVIGATION_GUARD_REDIRECT",e[e.NAVIGATION_ABORTED=4]="NAVIGATION_ABORTED",e[e.NAVIGATION_CANCELLED=8]="NAVIGATION_CANCELLED",e[e.NAVIGATION_DUPLICATED=16]="NAVIGATION_DUPLICATED",e})({});const Ia=Symbol("");Ie.MATCHER_NOT_FOUND+"",Ie.NAVIGATION_GUARD_REDIRECT+"",Ie.NAVIGATION_ABORTED+"",Ie.NAVIGATION_CANCELLED+"",Ie.NAVIGATION_DUPLICATED+"";function An(e,t){return _e(new Error,{type:e,[Ia]:!0},t)}function Pt(e,t){return e instanceof Error&&Ia in e&&(t==null||!!(e.type&t))}const _d=["params","query","hash"];function wd(e){if(typeof e=="string")return e;if(e.path!=null)return e.path;const t={};for(const n of _d)n in e&&(t[n]=e[n]);return JSON.stringify(t,null,2)}function Ed(e){const t={};if(e===""||e==="?")return t;const n=(e[0]==="?"?e.slice(1):e).split("&");for(let s=0;sr&&Vr(r)):[s&&Vr(s)]).forEach(r=>{r!==void 0&&(t+=(t.length?"&":"")+n,r!=null&&(t+="="+r))})}return t}function Sd(e){const t={};for(const n in e){const s=e[n];s!==void 0&&(t[n]=gt(s)?s.map(r=>r==null?null:""+r):s==null?s:""+s)}return t}const Rd=Symbol(""),Ti=Symbol(""),Qs=Symbol(""),mo=Symbol(""),Hr=Symbol("");function Un(){let e=[];function t(s){return e.push(s),()=>{const r=e.indexOf(s);r>-1&&e.splice(r,1)}}function n(){e=[]}return{add:t,list:()=>e.slice(),reset:n}}function Kt(e,t,n,s,r,o=i=>i()){const i=s&&(s.enterCallbacks[r]=s.enterCallbacks[r]||[]);return()=>new Promise((l,a)=>{const u=h=>{h===!1?a(An(Ie.NAVIGATION_ABORTED,{from:n,to:t})):h instanceof Error?a(h):vd(h)?a(An(Ie.NAVIGATION_GUARD_REDIRECT,{from:t,to:h})):(i&&s.enterCallbacks[r]===i&&typeof h=="function"&&i.push(h),l())},c=o(()=>e.call(s&&s.instances[r],t,n,u));let f=Promise.resolve(c);e.length<3&&(f=f.then(u)),f.catch(h=>a(h))})}function br(e,t,n,s,r=o=>o()){const o=[];for(const i of e)for(const l in i.components){let a=i.components[l];if(!(t!=="beforeRouteEnter"&&!i.instances[l]))if(Sa(a)){const u=(a.__vccOpts||a)[t];u&&o.push(Kt(u,n,s,i,l,r))}else{let u=a();o.push(()=>u.then(c=>{if(!c)throw new Error(`Couldn't resolve component "${l}" at "${i.path}"`);const f=zf(c)?c.default:c;i.mods[l]=c,i.components[l]=f;const h=(f.__vccOpts||f)[t];return h&&Kt(h,n,s,i,l,r)()}))}}return o}function Cd(e,t){const n=[],s=[],r=[],o=Math.max(t.matched.length,e.matched.length);for(let i=0;iCn(u,l))?s.push(l):n.push(l));const a=e.matched[i];a&&(t.matched.find(u=>Cn(u,a))||r.push(a))}return[n,s,r]}/*! - * vue-router v4.6.4 - * (c) 2025 Eduardo San Martin Morote - * @license MIT - */let Ad=()=>location.protocol+"//"+location.host;function ka(e,t){const{pathname:n,search:s,hash:r}=t,o=e.indexOf("#");if(o>-1){let i=r.includes(e.slice(o))?e.slice(o).length:1,l=r.slice(i);return l[0]!=="/"&&(l="/"+l),Ri(l,"")}return Ri(n,e)+s+r}function Od(e,t,n,s){let r=[],o=[],i=null;const l=({state:h})=>{const m=ka(e,location),S=n.value,C=t.value;let P=0;if(h){if(n.value=m,t.value=h,i&&i===S){i=null;return}P=C?h.position-C.position:0}else s(m);r.forEach(v=>{v(n.value,S,{delta:P,type:Br.pop,direction:P?P>0?yr.forward:yr.back:yr.unknown})})};function a(){i=n.value}function u(h){r.push(h);const m=()=>{const S=r.indexOf(h);S>-1&&r.splice(S,1)};return o.push(m),m}function c(){if(document.visibilityState==="hidden"){const{history:h}=window;if(!h.state)return;h.replaceState(_e({},h.state,{scroll:Ys()}),"")}}function f(){for(const h of o)h();o=[],window.removeEventListener("popstate",l),window.removeEventListener("pagehide",c),document.removeEventListener("visibilitychange",c)}return window.addEventListener("popstate",l),window.addEventListener("pagehide",c),document.addEventListener("visibilitychange",c),{pauseListeners:a,listen:u,destroy:f}}function Pi(e,t,n,s=!1,r=!1){return{back:e,current:t,forward:n,replaced:s,position:window.history.length,scroll:r?Ys():null}}function Td(e){const{history:t,location:n}=window,s={value:ka(e,n)},r={value:t.state};r.value||o(s.value,{back:null,current:s.value,forward:null,position:t.length-1,replaced:!0,scroll:null},!0);function o(a,u,c){const f=e.indexOf("#"),h=f>-1?(n.host&&document.querySelector("base")?e:e.slice(f))+a:Ad()+e+a;try{t[c?"replaceState":"pushState"](u,"",h),r.value=u}catch(m){console.error(m),n[c?"replace":"assign"](h)}}function i(a,u){o(a,_e({},t.state,Pi(r.value.back,a,r.value.forward,!0),u,{position:r.value.position}),!0),s.value=a}function l(a,u){const c=_e({},r.value,t.state,{forward:a,scroll:Ys()});o(c.current,c,!0),o(a,_e({},Pi(s.value,a,null),{position:c.position+1},u),!1),s.value=a}return{location:s,state:r,push:l,replace:i}}function Pd(e){e=pd(e);const t=Td(e),n=Od(e,t.state,t.location,t.replace);function s(o,i=!0){i||n.pauseListeners(),history.go(o)}const r=_e({location:"",base:e,go:s,createHref:md.bind(null,e)},t,n);return Object.defineProperty(r,"location",{enumerable:!0,get:()=>t.location.value}),Object.defineProperty(r,"state",{enumerable:!0,get:()=>t.state.value}),r}let rn=(function(e){return e[e.Static=0]="Static",e[e.Param=1]="Param",e[e.Group=2]="Group",e})({});var Le=(function(e){return e[e.Static=0]="Static",e[e.Param=1]="Param",e[e.ParamRegExp=2]="ParamRegExp",e[e.ParamRegExpEnd=3]="ParamRegExpEnd",e[e.EscapeNext=4]="EscapeNext",e})(Le||{});const Nd={type:rn.Static,value:""},Id=/[a-zA-Z0-9_]/;function kd(e){if(!e)return[[]];if(e==="/")return[[Nd]];if(!e.startsWith("/"))throw new Error(`Invalid path "${e}"`);function t(m){throw new Error(`ERR (${n})/"${u}": ${m}`)}let n=Le.Static,s=n;const r=[];let o;function i(){o&&r.push(o),o=[]}let l=0,a,u="",c="";function f(){u&&(n===Le.Static?o.push({type:rn.Static,value:u}):n===Le.Param||n===Le.ParamRegExp||n===Le.ParamRegExpEnd?(o.length>1&&(a==="*"||a==="+")&&t(`A repeatable param (${u}) must be alone in its segment. eg: '/:ids+.`),o.push({type:rn.Param,value:u,regexp:c,repeatable:a==="*"||a==="+",optional:a==="*"||a==="?"})):t("Invalid state to consume buffer"),u="")}function h(){u+=a}for(;lt.length?t.length===1&&t[0]===Qe.Static+Qe.Segment?1:-1:0}function $a(e,t){let n=0;const s=e.score,r=t.score;for(;n0&&t[t.length-1]<0}const Fd={strict:!1,end:!0,sensitive:!1};function Md(e,t,n){const s=Ld(kd(e.path),n),r=_e(s,{record:e,parent:t,children:[],alias:[]});return t&&!r.record.aliasOf==!t.record.aliasOf&&t.children.push(r),r}function Vd(e,t){const n=[],s=new Map;t=Si(Fd,t);function r(f){return s.get(f)}function o(f,h,m){const S=!m,C=$i(f);C.aliasOf=m&&m.record;const P=Si(t,f),v=[C];if("alias"in f){const R=typeof f.alias=="string"?[f.alias]:f.alias;for(const O of R)v.push($i(_e({},C,{components:m?m.record.components:C.components,path:O,aliasOf:m?m.record:C})))}let x,A;for(const R of v){const{path:O}=R;if(h&&O[0]!=="/"){const $=h.record.path,U=$[$.length-1]==="/"?"":"/";R.path=h.record.path+(O&&U+O)}if(x=Md(R,h,P),m?m.alias.push(x):(A=A||x,A!==x&&A.alias.push(x),S&&f.name&&!Di(x)&&i(f.name)),Da(x)&&a(x),C.children){const $=C.children;for(let U=0;U<$.length;U++)o($[U],x,m&&m.children[U])}m=m||x}return A?()=>{i(A)}:Gn}function i(f){if(Na(f)){const h=s.get(f);h&&(s.delete(f),n.splice(n.indexOf(h),1),h.children.forEach(i),h.alias.forEach(i))}else{const h=n.indexOf(f);h>-1&&(n.splice(h,1),f.record.name&&s.delete(f.record.name),f.children.forEach(i),f.alias.forEach(i))}}function l(){return n}function a(f){const h=Hd(f,n);n.splice(h,0,f),f.record.name&&!Di(f)&&s.set(f.record.name,f)}function u(f,h){let m,S={},C,P;if("name"in f&&f.name){if(m=s.get(f.name),!m)throw An(Ie.MATCHER_NOT_FOUND,{location:f});P=m.record.name,S=_e(ki(h.params,m.keys.filter(A=>!A.optional).concat(m.parent?m.parent.keys.filter(A=>A.optional):[]).map(A=>A.name)),f.params&&ki(f.params,m.keys.map(A=>A.name))),C=m.stringify(S)}else if(f.path!=null)C=f.path,m=n.find(A=>A.re.test(C)),m&&(S=m.parse(C),P=m.record.name);else{if(m=h.name?s.get(h.name):n.find(A=>A.re.test(h.path)),!m)throw An(Ie.MATCHER_NOT_FOUND,{location:f,currentLocation:h});P=m.record.name,S=_e({},h.params,f.params),C=m.stringify(S)}const v=[];let x=m;for(;x;)v.unshift(x.record),x=x.parent;return{name:P,path:C,params:S,matched:v,meta:jd(v)}}e.forEach(f=>o(f));function c(){n.length=0,s.clear()}return{addRoute:o,resolve:u,removeRoute:i,clearRoutes:c,getRoutes:l,getRecordMatcher:r}}function ki(e,t){const n={};for(const s of t)s in e&&(n[s]=e[s]);return n}function $i(e){const t={path:e.path,redirect:e.redirect,name:e.name,meta:e.meta||{},aliasOf:e.aliasOf,beforeEnter:e.beforeEnter,props:Bd(e),children:e.children||[],instances:{},leaveGuards:new Set,updateGuards:new Set,enterCallbacks:{},components:"components"in e?e.components||null:e.component&&{default:e.component}};return Object.defineProperty(t,"mods",{value:{}}),t}function Bd(e){const t={},n=e.props||!1;if("component"in e)t.default=n;else for(const s in e.components)t[s]=typeof n=="object"?n[s]:n;return t}function Di(e){for(;e;){if(e.record.aliasOf)return!0;e=e.parent}return!1}function jd(e){return e.reduce((t,n)=>_e(t,n.meta),{})}function Hd(e,t){let n=0,s=t.length;for(;n!==s;){const o=n+s>>1;$a(e,t[o])<0?s=o:n=o+1}const r=qd(e);return r&&(s=t.lastIndexOf(r,s-1)),s}function qd(e){let t=e;for(;t=t.parent;)if(Da(t)&&$a(e,t)===0)return t}function Da({record:e}){return!!(e.name||e.components&&Object.keys(e.components).length||e.redirect)}function Li(e){const t=pt(Qs),n=pt(mo),s=tt(()=>{const a=xn(e.to);return t.resolve(a)}),r=tt(()=>{const{matched:a}=s.value,{length:u}=a,c=a[u-1],f=n.matched;if(!c||!f.length)return-1;const h=f.findIndex(Cn.bind(null,c));if(h>-1)return h;const m=Ui(a[u-2]);return u>1&&Ui(c)===m&&f[f.length-1].path!==m?f.findIndex(Cn.bind(null,a[u-2])):h}),o=tt(()=>r.value>-1&&Jd(n.params,s.value.params)),i=tt(()=>r.value>-1&&r.value===n.matched.length-1&&Pa(n.params,s.value.params));function l(a={}){if(Gd(a)){const u=t[xn(e.replace)?"replace":"push"](xn(e.to)).catch(Gn);return e.viewTransition&&typeof document<"u"&&"startViewTransition"in document&&document.startViewTransition(()=>u),u}return Promise.resolve()}return{route:s,href:tt(()=>s.value.href),isActive:o,isExactActive:i,navigate:l}}function Kd(e){return e.length===1?e[0]:e}const Wd=Kl({name:"RouterLink",compatConfig:{MODE:3},props:{to:{type:[String,Object],required:!0},replace:Boolean,activeClass:String,exactActiveClass:String,custom:Boolean,ariaCurrentValue:{type:String,default:"page"},viewTransition:Boolean},useLink:Li,setup(e,{slots:t}){const n=At(Li(e)),{options:s}=pt(Qs),r=tt(()=>({[Fi(e.activeClass,s.linkActiveClass,"router-link-active")]:n.isActive,[Fi(e.exactActiveClass,s.linkExactActiveClass,"router-link-exact-active")]:n.isExactActive}));return()=>{const o=t.default&&Kd(t.default(n));return e.custom?o:po("a",{"aria-current":n.isExactActive?e.ariaCurrentValue:null,href:n.href,onClick:n.navigate,class:r.value},o)}}}),zd=Wd;function Gd(e){if(!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)&&!e.defaultPrevented&&!(e.button!==void 0&&e.button!==0)){if(e.currentTarget&&e.currentTarget.getAttribute){const t=e.currentTarget.getAttribute("target");if(/\b_blank\b/i.test(t))return}return e.preventDefault&&e.preventDefault(),!0}}function Jd(e,t){for(const n in t){const s=t[n],r=e[n];if(typeof s=="string"){if(s!==r)return!1}else if(!gt(r)||r.length!==s.length||s.some((o,i)=>o.valueOf()!==r[i].valueOf()))return!1}return!0}function Ui(e){return e?e.aliasOf?e.aliasOf.path:e.path:""}const Fi=(e,t,n)=>e??t??n,Xd=Kl({name:"RouterView",inheritAttrs:!1,props:{name:{type:String,default:"default"},route:Object},compatConfig:{MODE:3},setup(e,{attrs:t,slots:n}){const s=pt(Hr),r=tt(()=>e.route||s.value),o=pt(Ti,0),i=tt(()=>{let u=xn(o);const{matched:c}=r.value;let f;for(;(f=c[u])&&!f.components;)u++;return u}),l=tt(()=>r.value.matched[i.value]);vs(Ti,tt(()=>i.value+1)),vs(Rd,l),vs(Hr,r);const a=Z();return _s(()=>[a.value,l.value,e.name],([u,c,f],[h,m,S])=>{c&&(c.instances[f]=u,m&&m!==c&&u&&u===h&&(c.leaveGuards.size||(c.leaveGuards=m.leaveGuards),c.updateGuards.size||(c.updateGuards=m.updateGuards))),u&&c&&(!m||!Cn(c,m)||!h)&&(c.enterCallbacks[f]||[]).forEach(C=>C(u))},{flush:"post"}),()=>{const u=r.value,c=e.name,f=l.value,h=f&&f.components[c];if(!h)return Mi(n.default,{Component:h,route:u});const m=f.props[c],S=m?m===!0?u.params:typeof m=="function"?m(u):m:null,P=po(h,_e({},S,t,{onVnodeUnmounted:v=>{v.component.isUnmounted&&(f.instances[c]=null)},ref:a}));return Mi(n.default,{Component:P,route:u})||P}}});function Mi(e,t){if(!e)return null;const n=e(t);return n.length===1?n[0]:n}const Yd=Xd;function Qd(e){const t=Vd(e.routes,e),n=e.parseQuery||Ed,s=e.stringifyQuery||Oi,r=e.history,o=Un(),i=Un(),l=Un(),a=qc(jt);let u=jt;gn&&e.scrollBehavior&&"scrollRestoration"in history&&(history.scrollRestoration="manual");const c=mr.bind(null,y=>""+y),f=mr.bind(null,id),h=mr.bind(null,rs);function m(y,V){let M,X;return Na(y)?(M=t.getRecordMatcher(y),X=V):X=y,t.addRoute(X,M)}function S(y){const V=t.getRecordMatcher(y);V&&t.removeRoute(V)}function C(){return t.getRoutes().map(y=>y.record)}function P(y){return!!t.getRecordMatcher(y)}function v(y,V){if(V=_e({},V||a.value),typeof y=="string"){const _=gr(n,y,V.path),N=t.resolve({path:_.path},V),E=r.createHref(_.fullPath);return _e(_,N,{params:h(N.params),hash:rs(_.hash),redirectedFrom:void 0,href:E})}let M;if(y.path!=null)M=_e({},y,{path:gr(n,y.path,V.path).path});else{const _=_e({},y.params);for(const N in _)_[N]==null&&delete _[N];M=_e({},y,{params:f(_)}),V.params=f(V.params)}const X=t.resolve(M,V),Q=y.hash||"";X.params=c(h(X.params));const p=cd(s,_e({},y,{hash:sd(Q),path:X.path})),g=r.createHref(p);return _e({fullPath:p,hash:Q,query:s===Oi?Sd(y.query):y.query||{}},X,{redirectedFrom:void 0,href:g})}function x(y){return typeof y=="string"?gr(n,y,a.value.path):_e({},y)}function A(y,V){if(u!==y)return An(Ie.NAVIGATION_CANCELLED,{from:V,to:y})}function R(y){return U(y)}function O(y){return R(_e(x(y),{replace:!0}))}function $(y,V){const M=y.matched[y.matched.length-1];if(M&&M.redirect){const{redirect:X}=M;let Q=typeof X=="function"?X(y,V):X;return typeof Q=="string"&&(Q=Q.includes("?")||Q.includes("#")?Q=x(Q):{path:Q},Q.params={}),_e({query:y.query,hash:y.hash,params:Q.path!=null?{}:y.params},Q)}}function U(y,V){const M=u=v(y),X=a.value,Q=y.state,p=y.force,g=y.replace===!0,_=$(M,X);if(_)return U(_e(x(_),{state:typeof _=="object"?_e({},Q,_.state):Q,force:p,replace:g}),V||M);const N=M;N.redirectedFrom=V;let E;return!p&&ud(s,X,M)&&(E=An(Ie.NAVIGATION_DUPLICATED,{to:N,from:X}),re(X,X,!0,!1)),(E?Promise.resolve(E):se(N,X)).catch(T=>Pt(T)?Pt(T,Ie.NAVIGATION_GUARD_REDIRECT)?T:ue(T):I(T,N,X)).then(T=>{if(T){if(Pt(T,Ie.NAVIGATION_GUARD_REDIRECT))return U(_e({replace:g},x(T.to),{state:typeof T.to=="object"?_e({},Q,T.to.state):Q,force:p}),V||N)}else T=W(N,X,!0,g,Q);return oe(N,X,T),T})}function ae(y,V){const M=A(y,V);return M?Promise.reject(M):Promise.resolve()}function Y(y){const V=ge.values().next().value;return V&&typeof V.runWithContext=="function"?V.runWithContext(y):y()}function se(y,V){let M;const[X,Q,p]=Cd(y,V);M=br(X.reverse(),"beforeRouteLeave",y,V);for(const _ of X)_.leaveGuards.forEach(N=>{M.push(Kt(N,y,V))});const g=ae.bind(null,y,V);return M.push(g),w(M).then(()=>{M=[];for(const _ of o.list())M.push(Kt(_,y,V));return M.push(g),w(M)}).then(()=>{M=br(Q,"beforeRouteUpdate",y,V);for(const _ of Q)_.updateGuards.forEach(N=>{M.push(Kt(N,y,V))});return M.push(g),w(M)}).then(()=>{M=[];for(const _ of p)if(_.beforeEnter)if(gt(_.beforeEnter))for(const N of _.beforeEnter)M.push(Kt(N,y,V));else M.push(Kt(_.beforeEnter,y,V));return M.push(g),w(M)}).then(()=>(y.matched.forEach(_=>_.enterCallbacks={}),M=br(p,"beforeRouteEnter",y,V,Y),M.push(g),w(M))).then(()=>{M=[];for(const _ of i.list())M.push(Kt(_,y,V));return M.push(g),w(M)}).catch(_=>Pt(_,Ie.NAVIGATION_CANCELLED)?_:Promise.reject(_))}function oe(y,V,M){l.list().forEach(X=>Y(()=>X(y,V,M)))}function W(y,V,M,X,Q){const p=A(y,V);if(p)return p;const g=V===jt,_=gn?history.state:{};M&&(X||g?r.replace(y.fullPath,_e({scroll:g&&_&&_.scroll},Q)):r.push(y.fullPath,Q)),a.value=y,re(y,V,M,g),ue()}let ce;function fe(){ce||(ce=r.listen((y,V,M)=>{if(!k.listening)return;const X=v(y),Q=$(X,k.currentRoute.value);if(Q){U(_e(Q,{replace:!0,force:!0}),X).catch(Gn);return}u=X;const p=a.value;gn&&bd(Ai(p.fullPath,M.delta),Ys()),se(X,p).catch(g=>Pt(g,Ie.NAVIGATION_ABORTED|Ie.NAVIGATION_CANCELLED)?g:Pt(g,Ie.NAVIGATION_GUARD_REDIRECT)?(U(_e(x(g.to),{force:!0}),X).then(_=>{Pt(_,Ie.NAVIGATION_ABORTED|Ie.NAVIGATION_DUPLICATED)&&!M.delta&&M.type===Br.pop&&r.go(-1,!1)}).catch(Gn),Promise.reject()):(M.delta&&r.go(-M.delta,!1),I(g,X,p))).then(g=>{g=g||W(X,p,!1),g&&(M.delta&&!Pt(g,Ie.NAVIGATION_CANCELLED)?r.go(-M.delta,!1):M.type===Br.pop&&Pt(g,Ie.NAVIGATION_ABORTED|Ie.NAVIGATION_DUPLICATED)&&r.go(-1,!1)),oe(X,p,g)}).catch(Gn)}))}let Pe=Un(),be=Un(),D;function I(y,V,M){ue(y);const X=be.list();return X.length?X.forEach(Q=>Q(y,V,M)):console.error(y),Promise.reject(y)}function J(){return D&&a.value!==jt?Promise.resolve():new Promise((y,V)=>{Pe.add([y,V])})}function ue(y){return D||(D=!y,fe(),Pe.list().forEach(([V,M])=>y?M(y):V()),Pe.reset()),y}function re(y,V,M,X){const{scrollBehavior:Q}=e;if(!gn||!Q)return Promise.resolve();const p=!M&&xd(Ai(y.fullPath,0))||(X||!M)&&history.state&&history.state.scroll||null;return io().then(()=>Q(y,V,p)).then(g=>g&&yd(g)).catch(g=>I(g,y,V))}const de=y=>r.go(y);let Ne;const ge=new Set,k={currentRoute:a,listening:!0,addRoute:m,removeRoute:S,clearRoutes:t.clearRoutes,hasRoute:P,getRoutes:C,resolve:v,options:e,push:R,replace:O,go:de,back:()=>de(-1),forward:()=>de(1),beforeEach:o.add,beforeResolve:i.add,afterEach:l.add,onError:be.add,isReady:J,install(y){y.component("RouterLink",zd),y.component("RouterView",Yd),y.config.globalProperties.$router=k,Object.defineProperty(y.config.globalProperties,"$route",{enumerable:!0,get:()=>xn(a)}),gn&&!Ne&&a.value===jt&&(Ne=!0,R(r.location).catch(X=>{}));const V={};for(const X in jt)Object.defineProperty(V,X,{get:()=>a.value[X],enumerable:!0});y.provide(Qs,k),y.provide(mo,Cl(V)),y.provide(Hr,a);const M=y.unmount;ge.add(y),y.unmount=function(){ge.delete(y),ge.size<1&&(u=jt,ce&&ce(),ce=null,a.value=jt,Ne=!1,D=!1),M()}}};function w(y){return y.reduce((V,M)=>V.then(()=>Y(M)),Promise.resolve())}return k}function Zd(){return pt(Qs)}function ep(e){return pt(mo)}const go="sub_store_remote_uri",yo="sub_store_admin_token",bo="sub_store_token_validated";function La(e){const t=(e||"").trim().replace(/\/+$/,"").replace(/\/api$/,"");if(!t)return"";const n=new URL(t);if(!["http:","https:"].includes(n.protocol))throw new Error("Remote URI must use http or https");return n.toString().replace(/\/+$/,"")}function tp(e,t){const n=La(e);n&&t&&(localStorage.setItem(go,n),localStorage.setItem(yo,t),localStorage.setItem(bo,"true"))}function xo(){return localStorage.getItem(go)||""}function Ua(){return localStorage.getItem(yo)||""}function np(){return localStorage.getItem(bo)==="true"}function sp(){localStorage.removeItem(go),localStorage.removeItem(yo),localStorage.removeItem(bo)}async function rp(e,t){if(!e)return!1;try{const n=La(t),s=await fetch(`${n}/api/env`,{headers:{Authorization:`Bearer ${e}`}});return s.ok?(await s.json()).status==="success":!1}catch{return!1}}function op(){return Ua()}function ip(){var e;return xo()||((e=window.SUB_STORE_CONFIG)==null?void 0:e.apiBaseUrl)||""}const lp={class:"min-h-screen flex bg-gray-50"},ap={class:"w-60 bg-gray-900 text-gray-300 flex flex-col fixed inset-y-0 left-0 z-30"},cp={class:"flex-1 py-3 overflow-y-auto"},up={class:"text-base"},fp={class:"flex-1 ml-60 min-h-screen"},dp={class:"px-6 py-5"},pp={__name:"AdminLayout",setup(e){const t=[{to:"/",icon:"📊",label:"概览"},{to:"/sources",icon:"📡",label:"订阅源"},{to:"/collections",icon:"📁",label:"合集"},{to:"/templates",icon:"📋",label:"模板"},{to:"/recycle-bin",icon:"♻️",label:"回收站"},{to:"/tools",icon:"🔧",label:"工具"},{to:"/settings",icon:"⚙️",label:"设置"}];return(n,s)=>{const r=kr("router-link"),o=kr("router-view");return F(),B("div",lp,[d("aside",ap,[s[0]||(s[0]=d("div",{class:"px-5 py-4 border-b border-gray-700"},[d("h1",{class:"text-lg font-bold text-white flex items-center gap-2"},[d("span",{class:"inline-block w-2 h-2 bg-primary-500 rounded-full"}),ts(" SubStore ")])],-1)),d("nav",cp,[(F(),B(ve,null,Fe(t,i=>Oe(r,{key:i.to,to:i.to,class:je(["flex items-center gap-3 px-5 py-2.5 text-sm transition-colors",n.$route.path===i.to||i.to!=="/"&&n.$route.path.startsWith(i.to)?"bg-gray-800 text-white border-l-2 border-primary-500":"hover:bg-gray-800/50 border-l-2 border-transparent"])},{default:dt(()=>[d("span",up,H(i.icon),1),d("span",null,H(i.label),1)]),_:2},1032,["to","class"])),64))])]),d("main",fp,[d("div",dp,[Oe(o)])])])}}},hp={class:"min-h-screen bg-gray-50 flex items-center justify-center px-4"},mp={key:0,class:"mt-4 text-sm text-red-600"},gp=["disabled"],yp={__name:"Login",setup(e){const t=ep(),n=Zd(),s=Z(xo()||window.location.origin),r=Z(""),o=Z(!1),i=Z("");async function l(){i.value="",o.value=!0;try{if(!await rp(r.value,s.value)){i.value="远程 URI 或 TOKEN 无效";return}tp(s.value,r.value),n.replace(typeof t.query.redirect=="string"?t.query.redirect:"/")}catch{i.value="远程 URI 格式无效"}finally{o.value=!1}}return(a,u)=>(F(),B("div",hp,[d("form",{class:"w-full max-w-sm bg-white border border-gray-200 rounded-lg p-6 shadow-sm",onSubmit:ut(l,["prevent"])},[u[2]||(u[2]=d("label",{class:"block text-sm font-medium text-gray-700",for:"remote-uri"},"远程 URI",-1)),me(d("input",{id:"remote-uri","onUpdate:modelValue":u[0]||(u[0]=c=>s.value=c),type:"url",required:"",autocomplete:"url",placeholder:"https://sub-store.example.com",class:"mt-2 w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-primary-500"},null,512),[[De,s.value,void 0,{trim:!0}]]),u[3]||(u[3]=d("label",{class:"block mt-4 text-sm font-medium text-gray-700",for:"token"},"TOKEN",-1)),me(d("input",{id:"token","onUpdate:modelValue":u[1]||(u[1]=c=>r.value=c),type:"password",required:"",autocomplete:"current-password",class:"mt-2 w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-primary-500"},null,512),[[De,r.value,void 0,{trim:!0}]]),i.value?(F(),B("p",mp,H(i.value),1)):pe("",!0),d("button",{type:"submit",disabled:o.value,class:"mt-6 w-full px-4 py-2 rounded-lg bg-primary-600 text-white text-sm font-medium hover:bg-primary-700 disabled:opacity-60 disabled:cursor-not-allowed"},H(o.value?"登录中...":"登录"),9,gp)],32)]))}},bp={class:"min-h-screen flex items-center justify-center bg-gray-50"},xp={__name:"NotFound",setup(e){return(t,n)=>(F(),B("div",bp,[...n[0]||(n[0]=[d("div",{class:"text-center"},[d("p",{class:"text-7xl font-bold text-gray-300"},"404"),d("p",{class:"mt-4 text-gray-400"},"Page Not Found")],-1)])]))}};function Fa(e,t){return function(){return e.apply(t,arguments)}}const{toString:vp}=Object.prototype,{getPrototypeOf:On}=Object,{iterator:us,toStringTag:Ma}=Symbol,$s=(({hasOwnProperty:e})=>(t,n)=>e.call(t,n))(Object.prototype),os=(e,t)=>{let n=e;const s=[];for(;n!=null&&n!==Object.prototype;){if(s.indexOf(n)!==-1)return!1;if(s.push(n),$s(n,t))return!0;n=On(n)}return!1},_p=(e,t)=>e!=null&&os(e,t)?e[t]:void 0,vo=(e=>t=>{const n=vp.call(t);return e[n]||(e[n]=n.slice(8,-1).toLowerCase())})(Object.create(null)),yt=e=>(e=e.toLowerCase(),t=>vo(t)===e),Zs=e=>t=>typeof t===e,{isArray:fn}=Array,Tn=Zs("undefined");function Nn(e){return e!==null&&!Tn(e)&&e.constructor!==null&&!Tn(e.constructor)&&nt(e.constructor.isBuffer)&&e.constructor.isBuffer(e)}const Va=yt("ArrayBuffer");function wp(e){let t;return typeof ArrayBuffer<"u"&&ArrayBuffer.isView?t=ArrayBuffer.isView(e):t=e&&e.buffer&&Va(e.buffer),t}const Ep=Zs("string"),nt=Zs("function"),Ba=Zs("number"),In=e=>e!==null&&typeof e=="object",Sp=e=>e===!0||e===!1,Es=e=>{if(!In(e))return!1;const t=On(e);return(t===null||t===Object.prototype||On(t)===null)&&!os(e,Ma)&&!os(e,us)},Rp=e=>{if(!In(e)||Nn(e))return!1;try{return Object.keys(e).length===0&&Object.getPrototypeOf(e)===Object.prototype}catch{return!1}},Cp=yt("Date"),Ap=yt("File"),Op=e=>!!(e&&typeof e.uri<"u"),Tp=e=>e&&typeof e.getParts<"u",Pp=yt("Blob"),Np=yt("FileList"),Ip=e=>In(e)&&nt(e.pipe);function kp(){return typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{}}const Vi=kp(),Bi=typeof Vi.FormData<"u"?Vi.FormData:void 0,$p=e=>{if(!e)return!1;if(Bi&&e instanceof Bi)return!0;const t=On(e);if(!t||t===Object.prototype||!nt(e.append))return!1;const n=vo(e);return n==="formdata"||n==="object"&&nt(e.toString)&&e.toString()==="[object FormData]"},Dp=yt("URLSearchParams"),[Lp,Up,Fp,Mp]=["ReadableStream","Request","Response","Headers"].map(yt),Vp=e=>e.trim?e.trim():e.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");function fs(e,t,{allOwnKeys:n=!1}={}){if(e===null||typeof e>"u")return;let s,r;if(typeof e!="object"&&(e=[e]),fn(e))for(s=0,r=e.length;s0;)if(r=n[s],t===r.toLowerCase())return r;return null}const on=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:global,Ha=e=>!Tn(e)&&e!==on;function qr(...e){const{caseless:t,skipUndefined:n}=Ha(this)&&this||{},s={},r=(o,i)=>{if(i==="__proto__"||i==="constructor"||i==="prototype")return;const l=t&&typeof i=="string"&&ja(s,i)||i,a=$s(s,l)?s[l]:void 0;Es(a)&&Es(o)?s[l]=qr(a,o):Es(o)?s[l]=qr({},o):fn(o)?s[l]=o.slice():(!n||!Tn(o))&&(s[l]=o)};for(let o=0,i=e.length;o(fs(t,(r,o)=>{n&&nt(r)?Object.defineProperty(e,o,{__proto__:null,value:Fa(r,n),writable:!0,enumerable:!0,configurable:!0}):Object.defineProperty(e,o,{__proto__:null,value:r,writable:!0,enumerable:!0,configurable:!0})},{allOwnKeys:s}),e),jp=e=>(e.charCodeAt(0)===65279&&(e=e.slice(1)),e),Hp=(e,t,n,s)=>{e.prototype=Object.create(t.prototype,s),Object.defineProperty(e.prototype,"constructor",{__proto__:null,value:e,writable:!0,enumerable:!1,configurable:!0}),Object.defineProperty(e,"super",{__proto__:null,value:t.prototype}),n&&Object.assign(e.prototype,n)},qp=(e,t,n,s)=>{let r,o,i;const l={};if(t=t||{},e==null)return t;do{for(r=Object.getOwnPropertyNames(e),o=r.length;o-- >0;)i=r[o],(!s||s(i,e,t))&&!l[i]&&(t[i]=e[i],l[i]=!0);e=n!==!1&&On(e)}while(e&&(!n||n(e,t))&&e!==Object.prototype);return t},Kp=(e,t,n)=>{e=String(e),(n===void 0||n>e.length)&&(n=e.length),n-=t.length;const s=e.indexOf(t,n);return s!==-1&&s===n},Wp=e=>{if(!e)return null;if(fn(e))return e;let t=e.length;if(!Ba(t))return null;const n=new Array(t);for(;t-- >0;)n[t]=e[t];return n},zp=(e=>t=>e&&t instanceof e)(typeof Uint8Array<"u"&&On(Uint8Array)),Gp=(e,t)=>{const s=(e&&e[us]).call(e);let r;for(;(r=s.next())&&!r.done;){const o=r.value;t.call(e,o[0],o[1])}},Jp=(e,t)=>{let n;const s=[];for(;(n=e.exec(t))!==null;)s.push(n);return s},Xp=yt("HTMLFormElement"),Yp=e=>e.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,function(n,s,r){return s.toUpperCase()+r}),{propertyIsEnumerable:Qp}=Object.prototype,Zp=yt("RegExp"),qa=(e,t)=>{const n=Object.getOwnPropertyDescriptors(e),s={};fs(n,(r,o)=>{let i;(i=t(r,o,e))!==!1&&(s[o]=i||r)}),Object.defineProperties(e,s)},eh=e=>{qa(e,(t,n)=>{if(nt(e)&&["arguments","caller","callee"].includes(n))return!1;const s=e[n];if(nt(s)){if(t.enumerable=!1,"writable"in t){t.writable=!1;return}t.set||(t.set=()=>{throw Error("Can not rewrite read-only method '"+n+"'")})}})},th=(e,t)=>{const n={},s=r=>{r.forEach(o=>{n[o]=!0})};return fn(e)?s(e):s(String(e).split(t)),n},nh=()=>{},sh=(e,t)=>e!=null&&Number.isFinite(e=+e)?e:t;function rh(e){return!!(e&&nt(e.append)&&e[Ma]==="FormData"&&e[us])}const oh=e=>{const t=new WeakSet,n=s=>{if(In(s)){if(t.has(s))return;if(Nn(s))return s;if(!("toJSON"in s)){t.add(s);const r=fn(s)?[]:{};return fs(s,(o,i)=>{const l=n(o);!Tn(l)&&(r[i]=l)}),t.delete(s),r}}return s};return n(e)},ih=yt("AsyncFunction"),lh=e=>e&&(In(e)||nt(e))&&nt(e.then)&&nt(e.catch),Ka=((e,t)=>e?setImmediate:t?((n,s)=>(on.addEventListener("message",({source:r,data:o})=>{r===on&&o===n&&s.length&&s.shift()()},!1),r=>{s.push(r),on.postMessage(n,"*")}))(`axios@${Math.random()}`,[]):n=>setTimeout(n))(typeof setImmediate=="function",nt(on.postMessage)),ah=typeof queueMicrotask<"u"?queueMicrotask.bind(on):typeof process<"u"&&process.nextTick||Ka,Wa=e=>e!=null&&nt(e[us]),ch=e=>e!=null&&os(e,us)&&Wa(e),b={isArray:fn,isArrayBuffer:Va,isBuffer:Nn,isFormData:$p,isArrayBufferView:wp,isString:Ep,isNumber:Ba,isBoolean:Sp,isObject:In,isPlainObject:Es,isEmptyObject:Rp,isReadableStream:Lp,isRequest:Up,isResponse:Fp,isHeaders:Mp,isUndefined:Tn,isDate:Cp,isFile:Ap,isReactNativeBlob:Op,isReactNative:Tp,isBlob:Pp,isRegExp:Zp,isFunction:nt,isStream:Ip,isURLSearchParams:Dp,isTypedArray:zp,isFileList:Np,forEach:fs,merge:qr,extend:Bp,trim:Vp,stripBOM:jp,inherits:Hp,toFlatObject:qp,kindOf:vo,kindOfTest:yt,endsWith:Kp,toArray:Wp,forEachEntry:Gp,matchAll:Jp,isHTMLForm:Xp,hasOwnProperty:$s,hasOwnProp:$s,hasOwnInPrototypeChain:os,getSafeProp:_p,reduceDescriptors:qa,freezeMethods:eh,toObjectSet:th,toCamelCase:Yp,noop:nh,toFiniteNumber:sh,findKey:ja,global:on,isContextDefined:Ha,isSpecCompliantForm:rh,toJSONObject:oh,isAsyncFn:ih,isThenable:lh,setImmediate:Ka,asap:ah,isIterable:Wa,isSafeIterable:ch},uh=b.toObjectSet(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"]),fh=e=>{const t={};let n,s,r;return e&&e.split(` -`).forEach(function(i){r=i.indexOf(":"),n=i.substring(0,r).trim().toLowerCase(),s=i.substring(r+1).trim(),!(!n||t[n]&&uh[n])&&(n==="set-cookie"?t[n]?t[n].push(s):t[n]=[s]:t[n]=t[n]?t[n]+", "+s:s)}),t};function dh(e){let t=0,n=e.length;for(;tt;){const s=e.charCodeAt(n-1);if(s!==9&&s!==32)break;n-=1}return t===0&&n===e.length?e:e.slice(t,n)}const ph=new RegExp("[\\u0000-\\u0008\\u000a-\\u001f\\u007f]+","g"),hh=new RegExp("[^\\u0009\\u0020-\\u007e\\u0080-\\u00ff]+","g");function _o(e,t){return b.isArray(e)?e.map(n=>_o(n,t)):dh(String(e).replace(t,""))}const mh=e=>_o(e,ph),gh=e=>_o(e,hh);function za(e){const t=Object.create(null);return b.forEach(e.toJSON(),(n,s)=>{t[s]=gh(n)}),t}const ji=Symbol("internals");function Fn(e){return e&&String(e).trim().toLowerCase()}function Ss(e){return e===!1||e==null?e:b.isArray(e)?e.map(Ss):mh(String(e))}function yh(e){const t=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let s;for(;s=n.exec(e);)t[s[1]]=s[2];return t}const bh=e=>/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(e.trim());function xr(e,t,n,s,r){if(b.isFunction(s))return s.call(this,t,n);if(r&&(t=n),!!b.isString(t)){if(b.isString(s))return t.indexOf(s)!==-1;if(b.isRegExp(s))return s.test(t)}}function xh(e){return e.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,(t,n,s)=>n.toUpperCase()+s)}function vh(e,t){const n=b.toCamelCase(" "+t);["get","set","has"].forEach(s=>{Object.defineProperty(e,s+n,{__proto__:null,value:function(r,o,i){return this[s].call(this,t,r,o,i)},configurable:!0})})}let Je=class{constructor(t){t&&this.set(t)}set(t,n,s){const r=this;function o(l,a,u){const c=Fn(a);if(!c)return;const f=b.findKey(r,c);(!f||r[f]===void 0||u===!0||u===void 0&&r[f]!==!1)&&(r[f||a]=Ss(l))}const i=(l,a)=>b.forEach(l,(u,c)=>o(u,c,a));if(b.isPlainObject(t)||t instanceof this.constructor)i(t,n);else if(b.isString(t)&&(t=t.trim())&&!bh(t))i(fh(t),n);else if(b.isObject(t)&&b.isSafeIterable(t)){let l=Object.create(null),a,u;for(const c of t){if(!b.isArray(c))throw new TypeError("Object iterator must return a key-value pair");u=c[0],b.hasOwnProp(l,u)?(a=l[u],l[u]=b.isArray(a)?[...a,c[1]]:[a,c[1]]):l[u]=c[1]}i(l,n)}else t!=null&&o(n,t,s);return this}get(t,n){if(t=Fn(t),t){const s=b.findKey(this,t);if(s){const r=this[s];if(!n)return r;if(n===!0)return yh(r);if(b.isFunction(n))return n.call(this,r,s);if(b.isRegExp(n))return n.exec(r);throw new TypeError("parser must be boolean|regexp|function")}}}has(t,n){if(t=Fn(t),t){const s=b.findKey(this,t);return!!(s&&this[s]!==void 0&&(!n||xr(this,this[s],s,n)))}return!1}delete(t,n){const s=this;let r=!1;function o(i){if(i=Fn(i),i){const l=b.findKey(s,i);l&&(!n||xr(s,s[l],l,n))&&(delete s[l],r=!0)}}return b.isArray(t)?t.forEach(o):o(t),r}clear(t){const n=Object.keys(this);let s=n.length,r=!1;for(;s--;){const o=n[s];(!t||xr(this,this[o],o,t,!0))&&(delete this[o],r=!0)}return r}normalize(t){const n=this,s={};return b.forEach(this,(r,o)=>{const i=b.findKey(s,o);if(i){n[i]=Ss(r),delete n[o];return}const l=t?xh(o):String(o).trim();l!==o&&delete n[o],n[l]=Ss(r),s[l]=!0}),this}concat(...t){return this.constructor.concat(this,...t)}toJSON(t){const n=Object.create(null);return b.forEach(this,(s,r)=>{s!=null&&s!==!1&&(n[r]=t&&b.isArray(s)?s.join(", "):s)}),n}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map(([t,n])=>t+": "+n).join(` -`)}getSetCookie(){return this.get("set-cookie")||[]}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(t){return t instanceof this?t:new this(t)}static concat(t,...n){const s=new this(t);return n.forEach(r=>s.set(r)),s}static accessor(t){const s=(this[ji]=this[ji]={accessors:{}}).accessors,r=this.prototype;function o(i){const l=Fn(i);s[l]||(vh(r,i),s[l]=!0)}return b.isArray(t)?t.forEach(o):o(t),this}};Je.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]);b.reduceDescriptors(Je.prototype,({value:e},t)=>{let n=t[0].toUpperCase()+t.slice(1);return{get:()=>e,set(s){this[n]=s}}});b.freezeMethods(Je);const _h="[REDACTED ****]";function wh(e){if(b.hasOwnProp(e,"toJSON"))return!0;let t=Object.getPrototypeOf(e);for(;t&&t!==Object.prototype;){if(b.hasOwnProp(t,"toJSON"))return!0;t=Object.getPrototypeOf(t)}return!1}function Eh(e,t){const n=new Set(t.map(o=>String(o).toLowerCase())),s=[],r=o=>{if(o===null||typeof o!="object"||b.isBuffer(o))return o;if(s.indexOf(o)!==-1)return;o instanceof Je&&(o=o.toJSON()),s.push(o);let i;if(b.isArray(o))i=[],o.forEach((l,a)=>{const u=r(l);b.isUndefined(u)||(i[a]=u)});else{if(!b.isPlainObject(o)&&wh(o))return s.pop(),o;i=Object.create(null);for(const[l,a]of Object.entries(o)){const u=n.has(l.toLowerCase())?_h:r(a);b.isUndefined(u)||(i[l]=u)}}return s.pop(),i};return r(e)}let z=class Ga extends Error{static from(t,n,s,r,o,i){const l=new Ga(t.message,n||t.code,s,r,o);return Object.defineProperty(l,"cause",{__proto__:null,value:t,writable:!0,enumerable:!1,configurable:!0}),l.name=t.name,t.status!=null&&l.status==null&&(l.status=t.status),i&&Object.assign(l,i),l}constructor(t,n,s,r,o){super(t),Object.defineProperty(this,"message",{__proto__:null,value:t,enumerable:!0,writable:!0,configurable:!0}),this.name="AxiosError",this.isAxiosError=!0,n&&(this.code=n),s&&(this.config=s),r&&(this.request=r),o&&(this.response=o,this.status=o.status)}toJSON(){const t=this.config,n=t&&b.hasOwnProp(t,"redact")?t.redact:void 0,s=b.isArray(n)&&n.length>0?Eh(t,n):b.toJSONObject(t);return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:s,code:this.code,status:this.status}}};z.ERR_BAD_OPTION_VALUE="ERR_BAD_OPTION_VALUE";z.ERR_BAD_OPTION="ERR_BAD_OPTION";z.ECONNABORTED="ECONNABORTED";z.ETIMEDOUT="ETIMEDOUT";z.ECONNREFUSED="ECONNREFUSED";z.ERR_NETWORK="ERR_NETWORK";z.ERR_FR_TOO_MANY_REDIRECTS="ERR_FR_TOO_MANY_REDIRECTS";z.ERR_DEPRECATED="ERR_DEPRECATED";z.ERR_BAD_RESPONSE="ERR_BAD_RESPONSE";z.ERR_BAD_REQUEST="ERR_BAD_REQUEST";z.ERR_CANCELED="ERR_CANCELED";z.ERR_NOT_SUPPORT="ERR_NOT_SUPPORT";z.ERR_INVALID_URL="ERR_INVALID_URL";z.ERR_FORM_DATA_DEPTH_EXCEEDED="ERR_FORM_DATA_DEPTH_EXCEEDED";const Sh=null,Ja=100;function Kr(e){return b.isPlainObject(e)||b.isArray(e)}function Xa(e){return b.endsWith(e,"[]")?e.slice(0,-2):e}function vr(e,t,n){return e?e.concat(t).map(function(r,o){return r=Xa(r),!n&&o?"["+r+"]":r}).join(n?".":""):t}function Rh(e){return b.isArray(e)&&!e.some(Kr)}const Ch=b.toFlatObject(b,{},null,function(t){return/^is[A-Z]/.test(t)});function er(e,t,n){if(!b.isObject(e))throw new TypeError("target must be an object");t=t||new FormData,n=b.toFlatObject(n,{metaTokens:!0,dots:!1,indexes:!1},!1,function(x,A){return!b.isUndefined(A[x])});const s=n.metaTokens,r=n.visitor||S,o=n.dots,i=n.indexes,l=n.Blob||typeof Blob<"u"&&Blob,a=n.maxDepth===void 0?Ja:n.maxDepth,u=l&&b.isSpecCompliantForm(t),c=[];if(!b.isFunction(r))throw new TypeError("visitor must be a function");function f(v){if(v===null)return"";if(b.isDate(v))return v.toISOString();if(b.isBoolean(v))return v.toString();if(!u&&b.isBlob(v))throw new z("Blob is not supported. Use a Buffer instead.");if(b.isArrayBuffer(v)||b.isTypedArray(v)){if(u&&typeof l=="function")return new l([v]);if(typeof Buffer<"u")return Buffer.from(v);throw new z("Blob is not supported. Use a Buffer instead.",z.ERR_NOT_SUPPORT)}return v}function h(v){if(v>a)throw new z("Object is too deeply nested ("+v+" levels). Max depth: "+a,z.ERR_FORM_DATA_DEPTH_EXCEEDED)}function m(v,x){if(a===1/0)return JSON.stringify(v);const A=[];return JSON.stringify(v,function(O,$){if(!b.isObject($))return $;for(;A.length&&A[A.length-1]!==this;)A.pop();return A.push($),h(x+A.length-1),$})}function S(v,x,A){let R=v;if(b.isReactNative(t)&&b.isReactNativeBlob(v))return t.append(vr(A,x,o),f(v)),!1;if(v&&!A&&typeof v=="object"){if(b.endsWith(x,"{}"))x=s?x:x.slice(0,-2),v=m(v,1);else if(b.isArray(v)&&Rh(v)||(b.isFileList(v)||b.endsWith(x,"[]"))&&(R=b.toArray(v)))return x=Xa(x),R.forEach(function($,U){!(b.isUndefined($)||$===null)&&t.append(i===!0?vr([x],U,o):i===null?x:x+"[]",f($))}),!1}return Kr(v)?!0:(t.append(vr(A,x,o),f(v)),!1)}const C=Object.assign(Ch,{defaultVisitor:S,convertValue:f,isVisitable:Kr});function P(v,x,A=0){if(!b.isUndefined(v)){if(h(A),c.indexOf(v)!==-1)throw new Error("Circular reference detected in "+x.join("."));c.push(v),b.forEach(v,function(O,$){(!(b.isUndefined(O)||O===null)&&r.call(t,O,b.isString($)?$.trim():$,x,C))===!0&&P(O,x?x.concat($):[$],A+1)}),c.pop()}}if(!b.isObject(e))throw new TypeError("data must be an object");return P(e),t}function Hi(e){const t={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+"};return encodeURIComponent(e).replace(/[!'()~]|%20/g,function(s){return t[s]})}function wo(e,t){this._pairs=[],e&&er(e,this,t)}const Ya=wo.prototype;Ya.append=function(t,n){this._pairs.push([t,n])};Ya.toString=function(t){const n=t?s=>t.call(this,s,Hi):Hi;return this._pairs.map(function(r){return n(r[0])+"="+n(r[1])},"").join("&")};function Ah(e){return encodeURIComponent(e).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+")}function Qa(e,t,n){if(!t)return e;e=e||"";const s=b.isFunction(n)?{serialize:n}:n,r=b.getSafeProp(s,"encode")||Ah,o=b.getSafeProp(s,"serialize");let i;if(o?i=o(t,s):i=b.isURLSearchParams(t)?t.toString():new wo(t,s).toString(r),i){const l=e.indexOf("#");l!==-1&&(e=e.slice(0,l)),e+=(e.indexOf("?")===-1?"?":"&")+i}return e}class qi{constructor(){this.handlers=[]}use(t,n,s){return this.handlers.push({fulfilled:t,rejected:n,synchronous:s?s.synchronous:!1,runWhen:s?s.runWhen:null}),this.handlers.length-1}eject(t){this.handlers[t]&&(this.handlers[t]=null)}clear(){this.handlers&&(this.handlers=[])}forEach(t){b.forEach(this.handlers,function(s){s!==null&&t(s)})}}const Eo={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1,legacyInterceptorReqResOrdering:!0,advertiseZstdAcceptEncoding:!1,validateStatusUndefinedResolves:!0},Oh=typeof URLSearchParams<"u"?URLSearchParams:wo,Th=typeof FormData<"u"?FormData:null,Ph=typeof Blob<"u"?Blob:null,Nh={isBrowser:!0,classes:{URLSearchParams:Oh,FormData:Th,Blob:Ph},protocols:["http","https","file","blob","url","data"]},So=typeof window<"u"&&typeof document<"u",Wr=typeof navigator=="object"&&navigator||void 0,Ih=So&&(!Wr||["ReactNative","NativeScript","NS"].indexOf(Wr.product)<0),kh=typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope&&typeof self.importScripts=="function",$h=So&&window.location.href||"http://localhost",Dh=Object.freeze(Object.defineProperty({__proto__:null,hasBrowserEnv:So,hasStandardBrowserEnv:Ih,hasStandardBrowserWebWorkerEnv:kh,navigator:Wr,origin:$h},Symbol.toStringTag,{value:"Module"})),Be={...Dh,...Nh};function Lh(e,t){return er(e,new Be.classes.URLSearchParams,{visitor:function(n,s,r,o){return Be.isNode&&b.isBuffer(n)?(this.append(s,n.toString("base64")),!1):o.defaultVisitor.apply(this,arguments)},...t})}const Ki=Ja;function Za(e){if(e>Ki)throw new z("FormData field is too deeply nested ("+e+" levels). Max depth: "+Ki,z.ERR_FORM_DATA_DEPTH_EXCEEDED)}function Uh(e){const t=[],n=/\w+|\[(\w*)]/g;let s;for(;(s=n.exec(e))!==null;)Za(t.length),t.push(s[0]==="[]"?"":s[1]||s[0]);return t}function Fh(e){const t={},n=Object.keys(e);let s;const r=n.length;let o;for(s=0;s=n.length;return i=!i&&b.isArray(r)?r.length:i,a?(b.hasOwnProp(r,i)?r[i]=b.isArray(r[i])?r[i].concat(s):[r[i],s]:r[i]=s,!l):((!b.hasOwnProp(r,i)||!b.isObject(r[i]))&&(r[i]=[]),t(n,s,r[i],o)&&b.isArray(r[i])&&(r[i]=Fh(r[i])),!l)}if(b.isFormData(e)&&b.isFunction(e.entries)){const n={};return b.forEachEntry(e,(s,r)=>{t(Uh(s),r,n,0)}),n}return null}const hn=(e,t)=>e!=null&&b.hasOwnProp(e,t)?e[t]:void 0;function Mh(e,t,n){if(b.isString(e))try{return(t||JSON.parse)(e),b.trim(e)}catch(s){if(s.name!=="SyntaxError")throw s}return(n||JSON.stringify)(e)}const ds={transitional:Eo,adapter:["xhr","http","fetch"],transformRequest:[function(t,n){const s=n.getContentType()||"",r=s.indexOf("application/json")>-1,o=b.isObject(t);if(o&&b.isHTMLForm(t)&&(t=new FormData(t)),b.isFormData(t))return r?JSON.stringify(ec(t)):t;if(b.isArrayBuffer(t)||b.isBuffer(t)||b.isStream(t)||b.isFile(t)||b.isBlob(t)||b.isReadableStream(t))return t;if(b.isArrayBufferView(t))return t.buffer;if(b.isURLSearchParams(t))return n.setContentType("application/x-www-form-urlencoded;charset=utf-8",!1),t.toString();let l;if(o){const a=hn(this,"formSerializer");if(s.indexOf("application/x-www-form-urlencoded")>-1)return Lh(t,a).toString();if((l=b.isFileList(t))||s.indexOf("multipart/form-data")>-1){const u=hn(this,"env"),c=u&&u.FormData;return er(l?{"files[]":t}:t,c&&new c,a)}}return o||r?(n.setContentType("application/json",!1),Mh(t)):t}],transformResponse:[function(t){const n=hn(this,"transitional")||ds.transitional,s=n&&n.forcedJSONParsing,r=hn(this,"responseType"),o=r==="json";if(b.isResponse(t)||b.isReadableStream(t))return t;if(t&&b.isString(t)&&(s&&!r||o)){const l=!(n&&n.silentJSONParsing)&&o;try{return JSON.parse(t,hn(this,"parseReviver"))}catch(a){if(l)throw a.name==="SyntaxError"?z.from(a,z.ERR_BAD_RESPONSE,this,null,hn(this,"response")):a}}return t}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,env:{FormData:Be.classes.FormData,Blob:Be.classes.Blob},validateStatus:function(t){return t>=200&&t<300},headers:{common:{Accept:"application/json, text/plain, */*","Content-Type":void 0}}};b.forEach(["delete","get","head","post","put","patch","query"],e=>{ds.headers[e]={}});function _r(e,t){const n=this||ds,s=t||n,r=Je.from(s.headers);let o=s.data;return b.forEach(e,function(l){o=l.call(n,o,r.normalize(),t?t.status:void 0)}),r.normalize(),o}function tc(e){return!!(e&&e.__CANCEL__)}let ps=class extends z{constructor(t,n,s){super(t??"canceled",z.ERR_CANCELED,n,s),this.name="CanceledError",this.__CANCEL__=!0}};function nc(e,t,n){const s=n.config.validateStatus;!n.status||!s||s(n.status)?e(n):t(new z("Request failed with status code "+n.status,n.status>=400&&n.status<500?z.ERR_BAD_REQUEST:z.ERR_BAD_RESPONSE,n.config,n.request,n))}function Vh(e){const t=/^([-+\w]{1,25}):(?:\/\/)?/.exec(e);return t&&t[1]||""}function Bh(e,t){e=e||10;const n=new Array(e),s=new Array(e);let r=0,o=0,i;return t=t!==void 0?t:1e3,function(a){const u=Date.now(),c=s[o];i||(i=u),n[r]=a,s[r]=u;let f=o,h=0;for(;f!==r;)h+=n[f++],f=f%e;if(r=(r+1)%e,r===o&&(o=(o+1)%e),u-i{n=c,r=null,o&&(clearTimeout(o),o=null),e(...u)};return[(...u)=>{const c=Date.now(),f=c-n;f>=s?i(u,c):(r=u,o||(o=setTimeout(()=>{o=null,i(r)},s-f)))},()=>r&&i(r)]}const Ds=(e,t,n=3)=>{let s=0;const r=Bh(50,250);return jh(o=>{if(!o||typeof o.loaded!="number")return;const i=o.loaded,l=o.lengthComputable?o.total:void 0,a=l!=null?Math.min(i,l):i,u=Math.max(0,a-s),c=r(u);s=Math.max(s,a);const f={loaded:a,total:l,progress:l?a/l:void 0,bytes:u,rate:c||void 0,estimated:c&&l?(l-a)/c:void 0,event:o,lengthComputable:l!=null,[t?"download":"upload"]:!0};e(f)},n)},Wi=(e,t)=>{const n=e!=null;return[s=>t[0]({lengthComputable:n,total:e,loaded:s}),t[1]]},zi=e=>(...t)=>b.asap(()=>e(...t)),Hh=Be.hasStandardBrowserEnv?((e,t)=>n=>(n=new URL(n,Be.origin),e.protocol===n.protocol&&e.host===n.host&&(t||e.port===n.port)))(new URL(Be.origin),Be.navigator&&/(msie|trident)/i.test(Be.navigator.userAgent)):()=>!0,qh=Be.hasStandardBrowserEnv?{write(e,t,n,s,r,o,i){if(typeof document>"u")return;const l=[`${e}=${encodeURIComponent(t)}`];b.isNumber(n)&&l.push(`expires=${new Date(n).toUTCString()}`),b.isString(s)&&l.push(`path=${s}`),b.isString(r)&&l.push(`domain=${r}`),o===!0&&l.push("secure"),b.isString(i)&&l.push(`SameSite=${i}`),document.cookie=l.join("; ")},read(e){if(typeof document>"u")return null;const t=document.cookie.split(";");for(let n=0;ne instanceof Je?{...e}:e;function dn(e,t){e=e||{},t=t||{};const n=Object.create(null);Object.defineProperty(n,"hasOwnProperty",{__proto__:null,value:Object.prototype.hasOwnProperty,enumerable:!1,writable:!0,configurable:!0});function s(c,f,h,m){return b.isPlainObject(c)&&b.isPlainObject(f)?b.merge.call({caseless:m},c,f):b.isPlainObject(f)?b.merge({},f):b.isArray(f)?f.slice():f}function r(c,f,h,m){if(b.isUndefined(f)){if(!b.isUndefined(c))return s(void 0,c,h,m)}else return s(c,f,h,m)}function o(c,f){if(!b.isUndefined(f))return s(void 0,f)}function i(c,f){if(b.isUndefined(f)){if(!b.isUndefined(c))return s(void 0,c)}else return s(void 0,f)}function l(c){const f=b.hasOwnProp(t,"transitional")?t.transitional:void 0;if(!b.isUndefined(f))if(b.isPlainObject(f)){if(b.hasOwnProp(f,c))return f[c]}else return;const h=b.hasOwnProp(e,"transitional")?e.transitional:void 0;if(b.isPlainObject(h)&&b.hasOwnProp(h,c))return h[c]}function a(c,f,h){if(b.hasOwnProp(t,h))return s(c,f);if(b.hasOwnProp(e,h))return s(void 0,c)}const u={url:o,method:o,data:o,baseURL:i,transformRequest:i,transformResponse:i,paramsSerializer:i,timeout:i,timeoutMessage:i,withCredentials:i,withXSRFToken:i,adapter:i,responseType:i,xsrfCookieName:i,xsrfHeaderName:i,onUploadProgress:i,onDownloadProgress:i,decompress:i,maxContentLength:i,maxBodyLength:i,beforeRedirect:i,transport:i,httpAgent:i,httpsAgent:i,cancelToken:i,socketPath:i,allowedSocketPaths:i,responseEncoding:i,validateStatus:a,headers:(c,f,h)=>r(Ji(c),Ji(f),h,!0)};return b.forEach(Object.keys({...e,...t}),function(f){if(f==="__proto__"||f==="constructor"||f==="prototype")return;const h=b.hasOwnProp(u,f)?u[f]:r,m=b.hasOwnProp(e,f)?e[f]:void 0,S=b.hasOwnProp(t,f)?t[f]:void 0,C=h(m,S,f);b.isUndefined(C)&&h!==a||(n[f]=C)}),b.hasOwnProp(t,"validateStatus")&&b.isUndefined(t.validateStatus)&&l("validateStatusUndefinedResolves")===!1&&(b.hasOwnProp(e,"validateStatus")?n.validateStatus=s(void 0,e.validateStatus):delete n.validateStatus),n}const Yh=["content-type","content-length"];function Qh(e,t,n){if(n!=="content-only"){e.set(t);return}Object.entries(t||{}).forEach(([s,r])=>{Yh.includes(s.toLowerCase())&&e.set(s,r)})}const Zh=e=>encodeURIComponent(e).replace(/%([0-9A-F]{2})/gi,(t,n)=>String.fromCharCode(parseInt(n,16)));function rc(e){const t=dn({},e),n=h=>b.hasOwnProp(t,h)?t[h]:void 0,s=n("data");let r=n("withXSRFToken");const o=n("xsrfHeaderName"),i=n("xsrfCookieName");let l=n("headers");const a=n("auth"),u=n("baseURL"),c=n("allowAbsoluteUrls"),f=n("url");if(t.headers=l=Je.from(l),t.url=Qa(sc(u,f,c,t),n("params"),n("paramsSerializer")),a){const h=b.getSafeProp(a,"username")||"",m=b.getSafeProp(a,"password")||"";try{l.set("Authorization","Basic "+btoa(h+":"+(m?Zh(m):"")))}catch(S){throw z.from(S,z.ERR_BAD_OPTION_VALUE,e)}}if(b.isFormData(s)&&(Be.hasStandardBrowserEnv||Be.hasStandardBrowserWebWorkerEnv||b.isReactNative(s)?l.setContentType(void 0):b.isFunction(s.getHeaders)&&Qh(l,s.getHeaders(),n("formDataHeaderPolicy"))),Be.hasStandardBrowserEnv&&(b.isFunction(r)&&(r=r(t)),r===!0||r==null&&Hh(t.url))){const m=o&&i&&qh.read(i);m&&l.set(o,m)}return t}const em=typeof XMLHttpRequest<"u",tm=em&&function(e){return new Promise(function(n,s){const r=rc(e);let o=r.data;const i=Je.from(r.headers).normalize();let{responseType:l,onUploadProgress:a,onDownloadProgress:u}=r,c,f,h,m,S;function C(){m&&m(),S&&S(),r.cancelToken&&r.cancelToken.unsubscribe(c),r.signal&&r.signal.removeEventListener("abort",c)}let P=new XMLHttpRequest;P.open(r.method.toUpperCase(),r.url,!0),P.timeout=r.timeout;function v(){if(!P)return;const A=Je.from("getAllResponseHeaders"in P&&P.getAllResponseHeaders()),O={data:!l||l==="text"||l==="json"?P.responseText:P.response,status:P.status,statusText:P.statusText,headers:A,config:e,request:P};nc(function(U){n(U),C()},function(U){s(U),C()},O),P=null}"onloadend"in P?P.onloadend=v:P.onreadystatechange=function(){!P||P.readyState!==4||P.status===0&&!(P.responseURL&&P.responseURL.startsWith("file:"))||setTimeout(v)},P.onabort=function(){P&&(s(new z("Request aborted",z.ECONNABORTED,e,P)),C(),P=null)},P.onerror=function(R){const O=R&&R.message?R.message:"Network Error",$=new z(O,z.ERR_NETWORK,e,P);$.event=R||null,s($),C(),P=null},P.ontimeout=function(){let R=r.timeout?"timeout of "+r.timeout+"ms exceeded":"timeout exceeded";const O=r.transitional||Eo;r.timeoutErrorMessage&&(R=r.timeoutErrorMessage),s(new z(R,O.clarifyTimeoutError?z.ETIMEDOUT:z.ECONNABORTED,e,P)),C(),P=null},o===void 0&&i.setContentType(null),"setRequestHeader"in P&&b.forEach(za(i),function(R,O){P.setRequestHeader(O,R)}),b.isUndefined(r.withCredentials)||(P.withCredentials=!!r.withCredentials),l&&l!=="json"&&(P.responseType=r.responseType),u&&([h,S]=Ds(u,!0),P.addEventListener("progress",h)),a&&P.upload&&([f,m]=Ds(a),P.upload.addEventListener("progress",f),P.upload.addEventListener("loadend",m)),(r.cancelToken||r.signal)&&(c=A=>{P&&(s(!A||A.type?new ps(null,e,P):A),P.abort(),C(),P=null)},r.cancelToken&&r.cancelToken.subscribe(c),r.signal&&(r.signal.aborted?c():r.signal.addEventListener("abort",c)));const x=Vh(r.url);if(x&&!Be.protocols.includes(x)){s(new z("Unsupported protocol "+x+":",z.ERR_BAD_REQUEST,e)),C();return}P.send(o||null)})},nm=(e,t)=>{if(e=e?e.filter(Boolean):[],!t&&!e.length)return;const n=new AbortController;let s=!1;const r=function(a){if(!s){s=!0,i();const u=a instanceof Error?a:this.reason;n.abort(u instanceof z?u:new ps(u instanceof Error?u.message:u))}};let o=t&&setTimeout(()=>{o=null,r(new z(`timeout of ${t}ms exceeded`,z.ETIMEDOUT))},t);const i=()=>{e&&(o&&clearTimeout(o),o=null,e.forEach(a=>{a.unsubscribe?a.unsubscribe(r):a.removeEventListener("abort",r)}),e=null)};e.forEach(a=>a.addEventListener("abort",r,{once:!0}));const{signal:l}=n;return l.unsubscribe=()=>b.asap(i),l},sm=function*(e,t){let n=e.byteLength;if(n{const r=rm(e,t);let o=0,i,l=a=>{i||(i=!0,s&&s(a))};return new ReadableStream({async pull(a){try{const{done:u,value:c}=await r.next();if(u){l(),a.close();return}let f=c.byteLength;if(n){let h=o+=f;n(h)}a.enqueue(new Uint8Array(c))}catch(u){throw l(u),u}},cancel(a){return l(a),r.return()}},{highWaterMark:2})},Ls=e=>e>=48&&e<=57||e>=65&&e<=70||e>=97&&e<=102,im=(e,t,n)=>t+2m>=2&&s.charCodeAt(m-2)===37&&s.charCodeAt(m-1)===51&&(s.charCodeAt(m)===68||s.charCodeAt(m)===100);u>=0&&(s.charCodeAt(u)===61?(a++,u--):c(u)&&(a++,u-=3)),a===1&&u>=0&&(s.charCodeAt(u)===61||c(u))&&a++;const h=Math.floor(i/4)*3-(a||0);return h>0?h:0}let o=0;for(let i=0,l=s.length;i=55296&&a<=56319&&i+1=56320&&u<=57343?(o+=4,i++):o+=3}else o+=3}return o}const Ro="1.18.1",Yi=64*1024,{isFunction:bs}=b,am=e=>encodeURIComponent(e).replace(/%([0-9A-F]{2})/gi,(t,n)=>String.fromCharCode(parseInt(n,16))),Qi=e=>{if(!b.isString(e))return e;try{return decodeURIComponent(e)}catch{return e}},Zi=(e,...t)=>{try{return!!e(...t)}catch{return!1}},cm=e=>{const t=e.indexOf("://");let n=e;return t!==-1&&(n=n.slice(t+3)),n.includes("@")||n.includes(":")},um=e=>{const t=b.global!==void 0&&b.global!==null?b.global:globalThis,{ReadableStream:n,TextEncoder:s}=t;e=b.merge.call({skipUndefined:!0},{Request:t.Request,Response:t.Response},e);const{fetch:r,Request:o,Response:i}=e,l=r?bs(r):typeof fetch=="function",a=bs(o),u=bs(i);if(!l)return!1;const c=l&&bs(n),f=l&&(typeof s=="function"?(v=>x=>v.encode(x))(new s):async v=>new Uint8Array(await new o(v).arrayBuffer())),h=a&&c&&Zi(()=>{let v=!1;const x=new o(Be.origin,{body:new n,method:"POST",get duplex(){return v=!0,"half"}}),A=x.headers.has("Content-Type");return x.body!=null&&x.body.cancel(),v&&!A}),m=u&&c&&Zi(()=>b.isReadableStream(new i("").body)),S={stream:m&&(v=>v.body)};l&&["text","arrayBuffer","blob","formData","stream"].forEach(v=>{!S[v]&&(S[v]=(x,A)=>{let R=x&&x[v];if(R)return R.call(x);throw new z(`Response type '${v}' is not supported`,z.ERR_NOT_SUPPORT,A)})});const C=async v=>{if(v==null)return 0;if(b.isBlob(v))return v.size;if(b.isSpecCompliantForm(v))return(await new o(Be.origin,{method:"POST",body:v}).arrayBuffer()).byteLength;if(b.isArrayBufferView(v)||b.isArrayBuffer(v))return v.byteLength;if(b.isURLSearchParams(v)&&(v=v+""),b.isString(v))return(await f(v)).byteLength},P=async(v,x)=>{const A=b.toFiniteNumber(v.getContentLength());return A??C(x)};return async v=>{let{url:x,method:A,data:R,signal:O,cancelToken:$,timeout:U,onDownloadProgress:ae,onUploadProgress:Y,responseType:se,headers:oe,withCredentials:W="same-origin",fetchOptions:ce,maxContentLength:fe,maxBodyLength:Pe}=rc(v);const be=b.isNumber(fe)&&fe>-1,D=b.isNumber(Pe)&&Pe>-1,I=w=>b.hasOwnProp(v,w)?v[w]:void 0;let J=r||fetch;se=se?(se+"").toLowerCase():"text";let ue=nm([O,$&&$.toAbortSignal()],U),re=null;const de=ue&&ue.unsubscribe&&(()=>{ue.unsubscribe()});let Ne,ge=null;const k=()=>new z("Request body larger than maxBodyLength limit",z.ERR_BAD_REQUEST,v,re);try{let w;const y=I("auth");if(y){const E=b.getSafeProp(y,"username")||"",T=b.getSafeProp(y,"password")||"";w={username:E,password:T}}if(cm(x)){const E=new URL(x,Be.origin);if(!w&&(E.username||E.password)){const T=Qi(E.username),K=Qi(E.password);w={username:T,password:K}}(E.username||E.password)&&(E.username="",E.password="",x=E.href)}if(w&&(oe.delete("authorization"),oe.set("Authorization","Basic "+btoa(am((w.username||"")+":"+(w.password||""))))),be&&typeof x=="string"&&x.startsWith("data:")&&lm(x)>fe)throw new z("maxContentLength size of "+fe+" exceeded",z.ERR_BAD_RESPONSE,v,re);if(D&&A!=="get"&&A!=="head"){const E=await C(R);if(typeof E=="number"&&isFinite(E)&&(Ne=E,E>Pe))throw k()}const V=D&&(b.isReadableStream(R)||b.isStream(R)),M=(E,T,K)=>Xi(E,Yi,j=>{if(D&&j>Pe)throw ge=k();T&&T(j)},K);if(h&&A!=="get"&&A!=="head"&&(Y||V)){if(Ne=Ne??await P(oe,R),Ne!==0||V){let E=new o(x,{method:"POST",body:R,duplex:"half"}),T;if(b.isFormData(R)&&(T=E.headers.get("content-type"))&&oe.setContentType(T),E.body){const[K,j]=Y&&Wi(Ne,Ds(zi(Y)))||[];R=M(E.body,K,j)}}}else if(V&&!a&&c&&A!=="get"&&A!=="head")R=M(R);else if(V&&a&&!h&&A!=="get"&&A!=="head")throw new z("Stream request bodies are not supported by the current fetch implementation",z.ERR_NOT_SUPPORT,v,re);b.isString(W)||(W=W?"include":"omit");const X=a&&"credentials"in o.prototype;if(b.isFormData(R)){const E=oe.getContentType();E&&/^multipart\/form-data/i.test(E)&&!/boundary=/i.test(E)&&oe.delete("content-type")}oe.set("User-Agent","axios/"+Ro,!1);const Q={...ce,signal:ue,method:A.toUpperCase(),headers:za(oe.normalize()),body:R,duplex:"half",credentials:X?W:void 0};re=a&&new o(x,Q);let p=await(a?J(re,ce):J(x,Q));const g=Je.from(p.headers);if(be){const E=b.toFiniteNumber(g.getContentLength());if(E!=null&&E>fe)throw new z("maxContentLength size of "+fe+" exceeded",z.ERR_BAD_RESPONSE,v,re)}const _=m&&(se==="stream"||se==="response");if(m&&p.body&&(ae||be||_&&de)){const E={};["status","statusText","headers"].forEach(ee=>{E[ee]=p[ee]});const T=b.toFiniteNumber(g.getContentLength()),[K,j]=ae&&Wi(T,Ds(zi(ae),!0))||[];let q=0;const L=ee=>{if(be&&(q=ee,q>fe))throw new z("maxContentLength size of "+fe+" exceeded",z.ERR_BAD_RESPONSE,v,re);K&&K(ee)};p=new i(Xi(p.body,Yi,L,()=>{j&&j(),de&&de()}),E)}se=se||"text";let N=await S[b.findKey(S,se)||"text"](p,v);if(be&&!m&&!_){let E;if(N!=null&&(typeof N.byteLength=="number"?E=N.byteLength:typeof N.size=="number"?E=N.size:typeof N=="string"&&(E=typeof s=="function"?new s().encode(N).byteLength:N.length)),typeof E=="number"&&E>fe)throw new z("maxContentLength size of "+fe+" exceeded",z.ERR_BAD_RESPONSE,v,re)}return!_&&de&&de(),await new Promise((E,T)=>{nc(E,T,{data:N,headers:Je.from(p.headers),status:p.status,statusText:p.statusText,config:v,request:re})})}catch(w){if(de&&de(),ue&&ue.aborted&&ue.reason instanceof z){const y=ue.reason;throw y.config=v,re&&(y.request=re),w!==y&&Object.defineProperty(y,"cause",{__proto__:null,value:w,writable:!0,enumerable:!1,configurable:!0}),y}if(ge)throw re&&!ge.request&&(ge.request=re),ge;if(w instanceof z)throw re&&!w.request&&(w.request=re),w;if(w&&w.name==="TypeError"&&/Load failed|fetch/i.test(w.message)){const y=new z("Network Error",z.ERR_NETWORK,v,re,w&&w.response);throw Object.defineProperty(y,"cause",{__proto__:null,value:w.cause||w,writable:!0,enumerable:!1,configurable:!0}),y}throw z.from(w,w&&w.code,v,re,w&&w.response)}}},fm=new Map,oc=e=>{let t=e&&e.env||{};const{fetch:n,Request:s,Response:r}=t,o=[s,r,n];let i=o.length,l=i,a,u,c=fm;for(;l--;)a=o[l],u=c.get(a),u===void 0&&c.set(a,u=l?new Map:um(t)),c=u;return u};oc();const Co={http:Sh,xhr:tm,fetch:{get:oc}};b.forEach(Co,(e,t)=>{if(e){try{Object.defineProperty(e,"name",{__proto__:null,value:t})}catch{}Object.defineProperty(e,"adapterName",{__proto__:null,value:t})}});const el=e=>`- ${e}`,dm=e=>b.isFunction(e)||e===null||e===!1;function pm(e,t){e=b.isArray(e)?e:[e];const{length:n}=e;let s,r;const o={};for(let i=0;i`adapter ${a} `+(u===!1?"is not supported by the environment":"is not available in the build"));let l=n?i.length>1?`since : -`+i.map(el).join(` -`):" "+el(i[0]):"as no adapter specified";throw new z("There is no suitable adapter to dispatch the request "+l,z.ERR_NOT_SUPPORT)}return r}const ic={getAdapter:pm,adapters:Co};function wr(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw new ps(null,e)}function tl(e){return wr(e),e.headers=Je.from(e.headers),e.data=_r.call(e,e.transformRequest),["post","put","patch"].indexOf(e.method)!==-1&&e.headers.setContentType("application/x-www-form-urlencoded",!1),ic.getAdapter(e.adapter||ds.adapter,e)(e).then(function(s){wr(e),e.response=s;try{s.data=_r.call(e,e.transformResponse,s)}finally{delete e.response}return s.headers=Je.from(s.headers),s},function(s){if(!tc(s)&&(wr(e),s&&s.response)){e.response=s.response;try{s.response.data=_r.call(e,e.transformResponse,s.response)}finally{delete e.response}s.response.headers=Je.from(s.response.headers)}return Promise.reject(s)})}const tr={};["object","boolean","number","function","string","symbol"].forEach((e,t)=>{tr[e]=function(s){return typeof s===e||"a"+(t<1?"n ":" ")+e}});const nl={};tr.transitional=function(t,n,s){function r(o,i){return"[Axios v"+Ro+"] Transitional option '"+o+"'"+i+(s?". "+s:"")}return(o,i,l)=>{if(t===!1)throw new z(r(i," has been removed"+(n?" in "+n:"")),z.ERR_DEPRECATED);return n&&!nl[i]&&(nl[i]=!0,console.warn(r(i," has been deprecated since v"+n+" and will be removed in the near future"))),t?t(o,i,l):!0}};tr.spelling=function(t){return(n,s)=>(console.warn(`${s} is likely a misspelling of ${t}`),!0)};function hm(e,t,n){if(typeof e!="object"||e===null)throw new z("options must be an object",z.ERR_BAD_OPTION_VALUE);const s=Object.keys(e);let r=s.length;for(;r-- >0;){const o=s[r],i=Object.prototype.hasOwnProperty.call(t,o)?t[o]:void 0;if(i){const l=e[o],a=l===void 0||i(l,o,e);if(a!==!0)throw new z("option "+o+" must be "+a,z.ERR_BAD_OPTION_VALUE);continue}if(n!==!0)throw new z("Unknown option "+o,z.ERR_BAD_OPTION)}}const Rs={assertOptions:hm,validators:tr},qe=Rs.validators;let cn=class{constructor(t){this.defaults=t||{},this.interceptors={request:new qi,response:new qi}}async request(t,n){try{return await this._request(t,n)}catch(s){if(s instanceof Error){let r={};Error.captureStackTrace?Error.captureStackTrace(r):r=new Error;const o=(()=>{if(!r.stack)return"";const i=r.stack.indexOf(` -`);return i===-1?"":r.stack.slice(i+1)})();try{if(!s.stack)s.stack=o;else if(o){const i=o.indexOf(` -`),l=i===-1?-1:o.indexOf(` -`,i+1),a=l===-1?"":o.slice(l+1);String(s.stack).endsWith(a)||(s.stack+=` -`+o)}}catch{}}throw s}}_request(t,n){typeof t=="string"?(n=n||{},n.url=t):n=t||{},n=dn(this.defaults,n);const{transitional:s,paramsSerializer:r,headers:o}=n;s!==void 0&&Rs.assertOptions(s,{silentJSONParsing:qe.transitional(qe.boolean),forcedJSONParsing:qe.transitional(qe.boolean),clarifyTimeoutError:qe.transitional(qe.boolean),legacyInterceptorReqResOrdering:qe.transitional(qe.boolean),advertiseZstdAcceptEncoding:qe.transitional(qe.boolean),validateStatusUndefinedResolves:qe.transitional(qe.boolean)},!1),r!=null&&(b.isFunction(r)?n.paramsSerializer={serialize:r}:Rs.assertOptions(r,{encode:qe.function,serialize:qe.function},!0)),n.allowAbsoluteUrls!==void 0||(this.defaults.allowAbsoluteUrls!==void 0?n.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:n.allowAbsoluteUrls=!0),Rs.assertOptions(n,{baseUrl:qe.spelling("baseURL"),withXsrfToken:qe.spelling("withXSRFToken")},!0),n.method=(n.method||this.defaults.method||"get").toLowerCase();let i=o&&b.merge(o.common,o[n.method]);o&&b.forEach(["delete","get","head","post","put","patch","query","common"],S=>{delete o[S]}),n.headers=Je.concat(i,o);const l=[];let a=!0;this.interceptors.request.forEach(function(C){if(typeof C.runWhen=="function"&&C.runWhen(n)===!1)return;a=a&&C.synchronous;const P=n.transitional||Eo;P&&P.legacyInterceptorReqResOrdering?l.unshift(C.fulfilled,C.rejected):l.push(C.fulfilled,C.rejected)});const u=[];this.interceptors.response.forEach(function(C){u.push(C.fulfilled,C.rejected)});let c,f=0,h;if(!a){const S=[tl.bind(this),void 0];for(S.unshift(...l),S.push(...u),h=S.length,c=Promise.resolve(n);f{if(!s._listeners)return;let o=s._listeners.length;for(;o-- >0;)s._listeners[o](r);s._listeners=null}),this.promise.then=r=>{let o;const i=new Promise(l=>{s.subscribe(l),o=l}).then(r);return i.cancel=function(){s.unsubscribe(o)},i},t(function(o,i,l){s.reason||(s.reason=new ps(o,i,l),n(s.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(t){if(this.reason){t(this.reason);return}this._listeners?this._listeners.push(t):this._listeners=[t]}unsubscribe(t){if(!this._listeners)return;const n=this._listeners.indexOf(t);n!==-1&&this._listeners.splice(n,1)}toAbortSignal(){const t=new AbortController,n=s=>{t.abort(s)};return this.subscribe(n),t.signal.unsubscribe=()=>this.unsubscribe(n),t.signal}static source(){let t;return{token:new lc(function(r){t=r}),cancel:t}}};function gm(e){return function(n){return e.apply(null,n)}}function ym(e){return b.isObject(e)&&e.isAxiosError===!0}const zr={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511,WebServerIsDown:521,ConnectionTimedOut:522,OriginIsUnreachable:523,TimeoutOccurred:524,SslHandshakeFailed:525,InvalidSslCertificate:526};Object.entries(zr).forEach(([e,t])=>{zr[t]=e});function ac(e){const t=new cn(e),n=Fa(cn.prototype.request,t);return b.extend(n,cn.prototype,t,{allOwnKeys:!0}),b.extend(n,t,null,{allOwnKeys:!0}),n.create=function(r){return ac(dn(e,r))},n}const ke=ac(ds);ke.Axios=cn;ke.CanceledError=ps;ke.CancelToken=mm;ke.isCancel=tc;ke.VERSION=Ro;ke.toFormData=er;ke.AxiosError=z;ke.Cancel=ke.CanceledError;ke.all=function(t){return Promise.all(t)};ke.spread=gm;ke.isAxiosError=ym;ke.mergeConfig=dn;ke.AxiosHeaders=Je;ke.formToJSON=e=>ec(b.isHTMLForm(e)?new FormData(e):e);ke.getAdapter=ic.getAdapter;ke.HttpStatusCode=zr;ke.default=ke;const{Axios:h0,AxiosError:m0,CanceledError:g0,isCancel:y0,CancelToken:b0,VERSION:x0,all:v0,Cancel:_0,isAxiosError:w0,spread:E0,toFormData:S0,AxiosHeaders:R0,HttpStatusCode:C0,formToJSON:A0,getAdapter:O0,mergeConfig:T0,create:P0}=ke,ye=ke.create({timeout:3e4});ye.interceptors.request.use(e=>{e.baseURL=`${ip()}/api`;const t=op();return t&&(e.headers.Authorization=`Bearer ${t}`),e});ye.interceptors.response.use(e=>e.data,e=>{var n,s,r,o;((n=e.response)==null?void 0:n.status)===401&&sp();const t=((o=(r=(s=e.response)==null?void 0:s.data)==null?void 0:r.error)==null?void 0:o.message)||e.message||"Request failed";return Promise.reject(new Error(t))});const bm=()=>ye.get("/env"),xm=()=>ye.get("/settings"),vm=e=>ye.patch("/settings",e),_m=()=>ye.get("/storage"),wm=e=>ye.post("/storage",e),Ao=()=>ye.get("/sources"),Em=e=>ye.post("/sources",e),Sm=(e,t)=>ye.patch(`/sources/${e}`,t),Rm=e=>ye.delete(`/sources/${e}`),cc=()=>ye.get("/collections"),Cm=e=>ye.post("/collections",e),Am=(e,t)=>ye.patch(`/collections/${e}`,t),Om=e=>ye.delete(`/collections/${e}`),Oo=()=>ye.get("/templates"),Tm=e=>ye.post("/templates",e),Pm=(e,t)=>ye.patch(`/templates/${e}`,t),Nm=e=>ye.delete(`/templates/${e}`),Im=()=>ye.get("/recycle-bin"),km=e=>ye.delete(`/recycle-bin/${e}`),$m=e=>ye.post(`/recycle-bin/${e}/restore`),Er=e=>ye.post("/preview/source",e),Sr=e=>ye.post("/preview/collection",e),Dm=(e,t)=>ye.get(`/link/source/${e}`,{params:{}}),Lm=(e,t)=>ye.get(`/link/collection/${e}`,{params:{}}),Um=e=>ye.get(`/source/flow/${e}`),Fm=e=>ye.post("/proxy/parse",e),Mm=e=>ye.post("/rule/parse",e),uc=e=>ye.post("/utils/proxy-uri",e),Vm=e=>ye.post("/utils/node-info",{server:e}),fc=e=>ye.post("/utils/egress-info",e),Bm={class:"grid grid-cols-2 lg:grid-cols-4 gap-4 mb-6"},jm={class:"text-sm text-gray-500"},Hm={class:"grid grid-cols-1 lg:grid-cols-2 gap-4"},qm={class:"bg-white rounded-lg p-4 shadow-sm border"},Km={key:0,class:"space-y-1.5 text-sm"},Wm={class:"flex justify-between"},zm={class:"flex justify-between"},Gm={class:"flex justify-between"},Jm={class:"flex justify-between"},Xm={class:"flex justify-between"},Ym={key:1,class:"text-gray-400 text-sm"},Qm={class:"bg-white rounded-lg p-4 shadow-sm border"},Zm={key:0,class:"flex flex-wrap gap-2"},eg={__name:"Dashboard",setup(e){const t=Z(null),n=Z([]),s=Z([]),r=Z([]),o=tt(()=>[{label:"订阅源",value:n.value.length,color:"text-blue-600"},{label:"合集",value:s.value.length,color:"text-purple-600"},{label:"模板",value:r.value.length,color:"text-green-600"}]),i={buildTimeScripts:"脚本引擎",proxyConversion:"代理转换",ruleConversion:"规则转换",recycleBin:"回收站",nodeInfo:"节点信息",surgeMac:"Surge Mac"};return Xt(async()=>{try{const[l,a,u,c]=await Promise.all([bm(),Ao(),cc(),Oo()]);t.value=l.data,n.value=a.data||[],s.value=u.data||[],r.value=c.data||[]}catch(l){console.error("Failed to load dashboard",l)}}),(l,a)=>{var u;return F(),B("div",null,[a[7]||(a[7]=d("h2",{class:"text-xl font-bold mb-5"},"概览",-1)),d("div",Bm,[(F(!0),B(ve,null,Fe(o.value,c=>(F(),B("div",{key:c.label,class:"bg-white rounded-lg p-4 shadow-sm border"},[d("p",jm,H(c.label),1),d("p",{class:je(["text-2xl font-bold mt-1",c.color])},H(c.value),3)]))),128))]),d("div",Hm,[d("div",qm,[a[5]||(a[5]=d("h3",{class:"font-semibold mb-3"},"环境信息",-1)),t.value?(F(),B("div",Km,[d("div",Wm,[a[0]||(a[0]=d("span",{class:"text-gray-500"},"应用",-1)),d("span",null,H(t.value.app),1)]),d("div",zm,[a[1]||(a[1]=d("span",{class:"text-gray-500"},"后端",-1)),d("span",null,H(t.value.backend),1)]),d("div",Gm,[a[2]||(a[2]=d("span",{class:"text-gray-500"},"版本",-1)),d("span",null,H(t.value.version),1)]),d("div",Jm,[a[3]||(a[3]=d("span",{class:"text-gray-500"},"运行时",-1)),d("span",null,H(t.value.runtime),1)]),d("div",Xm,[a[4]||(a[4]=d("span",{class:"text-gray-500"},"存储",-1)),d("span",null,H(t.value.storage),1)])])):(F(),B("div",Ym,"加载中..."))]),d("div",Qm,[a[6]||(a[6]=d("h3",{class:"font-semibold mb-3"},"功能特性",-1)),(u=t.value)!=null&&u.feature?(F(),B("div",Zm,[(F(!0),B(ve,null,Fe(t.value.feature,(c,f)=>(F(),B("span",{key:f,class:je(["px-2 py-1 rounded text-xs",c?"bg-green-100 text-green-700":"bg-gray-100 text-gray-500"])},H(i[f]||f)+": "+H(c?"✓":"✗"),3))),128))])):pe("",!0)])])])}}},tg={key:0,class:"fixed inset-0 z-50 flex items-center justify-center p-4"},ng={class:"relative bg-white rounded-lg shadow-xl w-full max-w-2xl max-h-[85vh] flex flex-col"},sg={class:"flex items-center justify-between px-6 py-3 border-b"},rg={class:"text-base font-semibold text-gray-900"},og={class:"flex-1 overflow-y-auto px-6 py-4"},ig={key:0,class:"px-6 py-3 border-t flex justify-end gap-2"},Us={__name:"Modal",props:{modelValue:Boolean,title:{type:String,default:""}},emits:["update:modelValue"],setup(e){return(t,n)=>(F(),un(Ml,{to:"body"},[e.modelValue?(F(),B("div",tg,[d("div",{class:"absolute inset-0 bg-black/40",onClick:n[0]||(n[0]=s=>t.$emit("update:modelValue",!1))}),d("div",ng,[d("div",sg,[d("h3",rg,H(e.title),1),d("button",{class:"text-gray-400 hover:text-gray-600 text-xl",onClick:n[1]||(n[1]=s=>t.$emit("update:modelValue",!1))},"×")]),d("div",og,[qo(t.$slots,"default")]),t.$slots.footer?(F(),B("div",ig,[qo(t.$slots,"footer")])):pe("",!0)])])):pe("",!0)]))}},lg={key:0,class:"fixed inset-0 z-[60] flex items-center justify-center p-4"},ag={class:"relative bg-white rounded-lg shadow-xl w-full max-w-sm p-5"},cg={class:"text-base font-semibold text-gray-900 mb-2"},ug={class:"text-sm text-gray-600 mb-4"},fg={class:"flex justify-end gap-2"},nr={__name:"ConfirmDialog",props:{modelValue:Boolean,title:{type:String,default:"确认"},message:{type:String,default:"确定执行此操作?"},confirmText:{type:String,default:"确定"},danger:{type:Boolean,default:!1}},emits:["update:modelValue","confirm"],setup(e){return(t,n)=>(F(),un(Ml,{to:"body"},[e.modelValue?(F(),B("div",lg,[d("div",{class:"absolute inset-0 bg-black/40",onClick:n[0]||(n[0]=s=>t.$emit("update:modelValue",!1))}),d("div",ag,[d("h3",cg,H(e.title),1),d("p",ug,H(e.message),1),d("div",fg,[d("button",{class:"px-4 py-2 text-sm rounded-lg hover:bg-gray-100",onClick:n[1]||(n[1]=s=>t.$emit("update:modelValue",!1))},"取消"),d("button",{class:je(["px-4 py-2 text-sm rounded-lg text-white",e.danger?"bg-red-600 hover:bg-red-700":"bg-primary-600 hover:bg-primary-700"]),onClick:n[2]||(n[2]=s=>t.$emit("confirm"))},H(e.confirmText),3)])])])):pe("",!0)]))}};async function is(e){var n;if((n=navigator.clipboard)!=null&&n.writeText){await navigator.clipboard.writeText(e);return}const t=document.createElement("textarea");t.value=e,t.setAttribute("readonly",""),t.style.position="fixed",t.style.opacity="0",document.body.appendChild(t),t.select();try{if(!document.execCommand("copy"))throw new Error("复制失败")}finally{document.body.removeChild(t)}}const dg={key:0,class:"text-gray-400 text-sm"},pg={key:1,class:"text-gray-400 text-sm py-8 text-center"},hg={key:2,class:"space-y-2"},mg=["onClick"],gg={class:"flex-1 min-w-0"},yg={class:"flex items-center gap-2"},bg={class:"font-medium text-gray-900"},xg={key:0,class:"px-1.5 py-0.5 rounded text-xs bg-red-100 text-red-700"},vg={key:0,class:"text-xs text-gray-500 mt-1"},_g={class:"flex gap-2 mt-1 text-xs text-gray-400"},wg={key:0},Eg={key:1,class:"text-xs text-gray-500 mt-1 truncate"},Sg={class:"flex gap-1 ml-3"},Rg=["disabled","onClick"],Cg=["onClick"],Ag=["onClick"],Og=["onClick"],Tg={key:0,class:"text-gray-400 text-sm py-4 text-center"},Pg={key:1},Ng={class:"overflow-x-auto rounded-lg bg-white"},Ig={class:"w-full text-left text-xs"},kg={class:"divide-y divide-gray-100"},$g={class:"px-3 py-2 text-gray-500"},Dg={class:"px-3 py-2 text-blue-600"},Lg={class:"px-3 py-2 font-mono text-gray-500"},Ug={class:"px-3 py-2 font-mono text-gray-500"},Fg={class:"px-3 py-2 text-gray-500"},Mg={class:"px-3 py-2 text-gray-500"},Vg={class:"px-3 py-2 font-mono text-gray-500"},Bg={class:"px-3 py-2 font-mono text-gray-500"},jg={class:"px-3 py-2 font-mono text-gray-500"},Hg={class:"px-3 py-2 text-gray-500"},qg={class:"px-3 py-2 text-gray-500"},Kg={class:"px-3 py-2"},Wg=["onClick"],zg={key:0,class:"text-xs text-gray-400 mt-2"},Gg={class:"space-y-4"},Jg=["disabled"],Xg={class:"flex gap-2"},Yg={key:0},Qg={key:1},Zg={class:"flex items-center gap-2"},ey={class:"mb-2 rounded-lg bg-gray-50 px-3 py-2 text-xs text-gray-500"},ty={class:"mt-2"},ny={class:"mt-2 w-full border-collapse overflow-hidden rounded-lg bg-white text-left"},sy={class:"border border-gray-200 px-2 py-1 text-gray-700"},ry={class:"border border-gray-200 px-2 py-1"},oy=["onUpdate:modelValue"],iy=["value"],ly=["onUpdate:modelValue"],ay=["onUpdate:modelValue"],cy=["onClick"],uy={__name:"Sources",setup(e){const t=Z([]),n=Z(!0),s=Z(!1),r=Z(!1),o=Z(""),i=Z(!1),l=Z(null),a=Z(""),u=Z(""),c=At({}),f=At({}),h=Z(null),m=Z({show:!1,title:"",message:"",danger:!1,action:null}),S=["include","exclude","rename","dedupe","sort","delete-field","flag","quick","resolve","custom"],C={include:"包含(include)",exclude:"排除(exclude)",rename:"重命名(rename)",dedupe:"去重(dedupe)",sort:"排序(sort)","delete-field":"删除字段(delete-field)",flag:"旗帜(flag)",quick:"快捷规则(quick)",resolve:"解析域名(resolve)",custom:"自定义(custom)"},P=[{type:"include",label:C.include,help:"只保留 field 匹配 pattern 的节点"},{type:"exclude",label:C.exclude,help:"删除 field 匹配 pattern 的节点"},{type:"rename",label:C.rename,help:"按 pattern 处理名称,简易表单适合清理固定前缀/后缀"},{type:"dedupe",label:C.dedupe,help:"按 field 去重,留空按 name 去重"},{type:"sort",label:C.sort,help:"按名称排序"},{type:"delete-field",label:C["delete-field"],help:"从 field 文本中删除匹配 pattern 的片段"},{type:"flag",label:C.flag,help:"给节点名补充或整理地区旗帜"},{type:"quick",label:C.quick,help:"应用快捷清理规则"},{type:"resolve",label:C.resolve,help:"把 server 域名解析为 IP"},{type:"custom",label:C.custom,help:"高级声明式规则链,适合 API/导入配置使用"}],v=()=>({name:"",type:"remote",url:"",content:"",enabled:!0,filters:[]}),x=At(v());function A(k,w="success"){h.value={msg:k,type:w},setTimeout(()=>h.value=null,2500)}function R(k){return k?new Date(k).toLocaleString("zh-CN"):""}function O(k){return k?new Date(k*1e3).toLocaleDateString("zh-CN"):""}function $(k){if(!Number.isFinite(k))return"";const w=["B","KB","MB","GB","TB"];let y=k,V=0;for(;y>=1024&&V=10||V===0?y.toFixed(0):y.toFixed(1)}${w[V]}`}function U(k,...w){for(const y of w){const V=k==null?void 0:k[y];if(V!=null&&V!=="")return V}return"-"}function ae(k){if(k!=null&&k["reality-opts"]||(k==null?void 0:k.security)==="reality")return"reality";const w=U(k,"tls","security");return w===!0?"TLS":w===!1||w==="none"?"-":w}function Y(k){const w=k==null?void 0:k.transport;return typeof w=="string"?w:w!=null&&w.type?w.type:U(k,"network","net")}function se(k){var X,Q,p;const w=f[k.id];if(!w)return"";const y=[];w.planName&&y.push(`套餐: ${w.planName}`);const V=Number(((X=w.usage)==null?void 0:X.upload)||0)+Number(((Q=w.usage)==null?void 0:Q.download)||0),M=Number(w.total||0);return M>0&&y.push(`流量: ${$(V)} / ${$(M)}`),M>V&&y.push(`剩余: ${$(M-V)}`),w.expires&&y.push(`到期: ${O(w.expires)}`),(p=k.meta)!=null&&p.price&&y.push(`计费: ${k.meta.price}${k.meta.billingCycle?`/${k.meta.billingCycle}`:""}`),y.join(" · ")}function oe(k){return{original:(k==null?void 0:k.originalCount)??(Array.isArray(k==null?void 0:k.original)?k.original.length:(k==null?void 0:k.nodes)??0),processed:Array.isArray(k==null?void 0:k.processed)?k.processed.length:0}}function W(k){return{id:k.id,name:k.name,type:k.type,url:k.url,content:k.content,filters:k.filters}}function ce(){Object.assign(x,v()),r.value=!1,s.value=!0}function fe(k){Object.assign(x,{name:k.id,type:k.type||"remote",url:k.url||"",content:k.content||"",enabled:k.enabled!==!1,filters:JSON.parse(JSON.stringify(k.filters||[]))}),r.value=!0,s.value=!0}function Pe(){x.filters.push({type:"include",pattern:"",field:""})}async function be(){try{const k={name:x.name,type:x.type,url:x.url,content:x.content,enabled:x.enabled,filters:x.filters.filter(w=>w.type)};r.value?await Sm(x.name,k):await Em(k),s.value=!1,await de(),A(r.value?"已更新":"已创建")}catch(k){A(k.message,"error")}}async function D(k){m.value={show:!0,title:"删除订阅源",message:`确定删除 "${k.name}"?`,danger:!0,action:async()=>{try{await Rm(k.id),await de(),A("已删除")}catch(w){A(w.message,"error")}}}}async function I(k){if(o.value===k.id){o.value="",l.value=null;return}o.value=k.id,i.value=!0,l.value=null;try{const w=await Er(W(k));l.value=w.data,c[k.id]=oe(w.data)}catch(w){A(w.message,"error"),o.value=""}finally{i.value=!1}}async function J(k){try{const w=await Dm(k.id);await is(w.data.url),A("链接已复制")}catch(w){A(w.message,"error")}}async function ue(k){try{const w=await uc(k);await is(w.data.uri),A("节点链接已复制")}catch(w){A(w.message,"error")}}async function re(k){var w,y;if(!a.value){a.value=k.id,u.value="";try{const V=await Er(W(k)),M=((w=V.data)==null?void 0:w.processed)||((y=V.data)==null?void 0:y.original)||[];c[k.id]=oe(V.data),o.value===k.id&&(l.value=V.data);for(let X=0;X(F(),B("div",null,[d("div",{class:"flex items-center justify-between mb-5"},[w[11]||(w[11]=d("h2",{class:"text-xl font-bold"},"订阅源",-1)),d("button",{class:"px-4 py-2 bg-primary-600 text-white rounded-lg text-sm hover:bg-primary-700",onClick:ce},"+ 新建")]),n.value?(F(),B("div",dg,"加载中...")):t.value.length===0?(F(),B("div",pg,"暂无订阅源")):(F(),B("div",hg,[(F(!0),B(ve,null,Fe(t.value,y=>{var V,M,X;return F(),B("div",{key:y.id,class:"bg-white rounded-lg shadow-sm border overflow-hidden hover:shadow-md transition-shadow"},[d("div",{class:"p-4 flex items-center justify-between cursor-pointer",onClick:Q=>I(y)},[d("div",gg,[d("div",yg,[d("span",bg,H(y.name),1),d("span",{class:je(["px-1.5 py-0.5 rounded text-xs",y.type==="remote"?"bg-blue-100 text-blue-700":"bg-gray-100 text-gray-600"])},H(y.type),3),y.enabled?pe("",!0):(F(),B("span",xg,"已禁用"))]),y.type==="local"?(F(),B("p",vg,"(本地内容)")):pe("",!0),d("div",_g,[d("span",null,"原始节点: "+H(((V=c[y.id])==null?void 0:V.original)??"-"),1),d("span",null,"处理后: "+H(((M=c[y.id])==null?void 0:M.processed)??"-"),1),d("span",null,"过滤器: "+H(((X=y.filters)==null?void 0:X.length)||0),1),y.createdAt?(F(),B("span",wg,"创建: "+H(R(y.createdAt)),1)):pe("",!0)]),se(y)?(F(),B("p",Eg,H(se(y)),1)):pe("",!0)]),d("div",Sg,[d("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-blue-50 text-blue-600 whitespace-nowrap",disabled:!!a.value,onClick:ut(Q=>re(y),["stop"])},H(a.value===y.id?`探测 ${u.value}`:"探测出口"),9,Rg),d("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-gray-100",onClick:ut(Q=>J(y),["stop"])},"复制链接",8,Cg),d("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-blue-50 text-blue-600",onClick:ut(Q=>fe(y),["stop"])},"编辑",8,Ag),d("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-red-50 text-red-600",onClick:ut(Q=>D(y),["stop"])},"删除",8,Og)])],8,mg),o.value===y.id?(F(),B("div",{key:0,class:"border-t bg-gray-50",onClick:w[0]||(w[0]=ut(()=>{},["stop"]))},[i.value?(F(),B("div",Tg,"解析中...")):l.value?(F(),B("div",Pg,[d("div",Ng,[d("table",Ig,[w[12]||(w[12]=d("thead",{class:"sticky top-0 bg-gray-100 text-gray-600"},[d("tr",null,[d("th",{class:"px-3 py-2 font-medium"},"Type"),d("th",{class:"px-3 py-2 font-medium"},"Name"),d("th",{class:"px-3 py-2 font-medium"},"Server"),d("th",{class:"px-3 py-2 font-medium"},"Port"),d("th",{class:"px-3 py-2 font-medium"},"Transport"),d("th",{class:"px-3 py-2 font-medium"},"Tls"),d("th",{class:"px-3 py-2 font-medium"},"Delay"),d("th",{class:"px-3 py-2 font-medium"},"Speed"),d("th",{class:"px-3 py-2 font-medium"},"Egress IP"),d("th",{class:"px-3 py-2 font-medium"},"Country"),d("th",{class:"px-3 py-2 font-medium"},"Region"),d("th",{class:"px-3 py-2 font-medium"},"Link")])],-1)),d("tbody",kg,[(F(!0),B(ve,null,Fe(l.value.processed||l.value.original||[],(Q,p)=>(F(),B("tr",{key:p},[d("td",$g,H(U(Q,"type")),1),d("td",Dg,H(U(Q,"name","remarks")),1),d("td",Lg,H(U(Q,"server","address")),1),d("td",Ug,H(U(Q,"port")),1),d("td",Fg,H(Y(Q)),1),d("td",Mg,H(ae(Q)),1),d("td",Vg,H(U(Q,"latencyMs","delay","latency","ping")),1),d("td",Bg,H(U(Q,"speed","downloadSpeed")),1),d("td",jg,H(U(Q,"egressIp")),1),d("td",Hg,H(U(Q,"egressCountry","country")),1),d("td",qg,H(U(Q,"egressRegion","region")),1),d("td",Kg,[d("button",{class:"px-2 py-1 text-xs rounded hover:bg-gray-100 text-blue-600 whitespace-nowrap",onClick:g=>ue(Q)},"复制",8,Wg)])]))),128))])])]),(l.value.processed||l.value.original||[]).length===0?(F(),B("p",zg,"暂无节点")):pe("",!0)])):pe("",!0)])):pe("",!0)])}),128))])),Oe(Us,{modelValue:s.value,"onUpdate:modelValue":w[8]||(w[8]=y=>s.value=y),title:r.value?"编辑订阅源":"新建订阅源"},{footer:dt(()=>[d("button",{class:"px-4 py-2 text-sm rounded-lg hover:bg-gray-100",onClick:w[7]||(w[7]=y=>s.value=!1)},"取消"),d("button",{class:"px-4 py-2 bg-primary-600 text-white rounded-lg text-sm hover:bg-primary-700",onClick:be},"保存")]),default:dt(()=>[d("div",Gg,[d("div",null,[w[13]||(w[13]=d("label",{class:"block text-sm font-medium mb-1"},"名称 / ID",-1)),me(d("input",{"onUpdate:modelValue":w[1]||(w[1]=y=>x.name=y),disabled:r.value,placeholder:"my-sub",class:"w-full px-3 py-2 border rounded-lg text-sm disabled:bg-gray-100"},null,8,Jg),[[De,x.name]]),w[14]||(w[14]=d("p",{class:"text-xs text-gray-400 mt-0.5"},"仅支持小写字母、数字、下划线、连字符",-1))]),d("div",null,[w[17]||(w[17]=d("label",{class:"block text-sm font-medium mb-1"},"类型",-1)),d("div",Xg,[d("label",{class:je(["flex-1 flex items-center gap-2 px-3 py-2 border rounded-lg text-sm cursor-pointer",x.type==="remote"?"border-primary-500 bg-primary-50 text-primary-700":"border-gray-200"])},[me(d("input",{type:"radio","onUpdate:modelValue":w[2]||(w[2]=y=>x.type=y),value:"remote",class:"text-primary-600"},null,512),[[vi,x.type]]),w[15]||(w[15]=d("span",null,"远程 (URL)",-1))],2),d("label",{class:je(["flex-1 flex items-center gap-2 px-3 py-2 border rounded-lg text-sm cursor-pointer",x.type==="local"?"border-primary-500 bg-primary-50 text-primary-700":"border-gray-200"])},[me(d("input",{type:"radio","onUpdate:modelValue":w[3]||(w[3]=y=>x.type=y),value:"local",class:"text-primary-600"},null,512),[[vi,x.type]]),w[16]||(w[16]=d("span",null,"本地 (内容)",-1))],2)])]),x.type==="remote"?(F(),B("div",Yg,[w[18]||(w[18]=d("label",{class:"block text-sm font-medium mb-1"},"URL",-1)),me(d("textarea",{"onUpdate:modelValue":w[4]||(w[4]=y=>x.url=y),rows:"3",placeholder:"https://example.com/sub (多个URL换行)",class:"w-full px-3 py-2 border rounded-lg text-sm font-mono"},null,512),[[De,x.url]])])):pe("",!0),x.type==="local"?(F(),B("div",Qg,[w[19]||(w[19]=d("label",{class:"block text-sm font-medium mb-1"},"内容",-1)),me(d("textarea",{"onUpdate:modelValue":w[5]||(w[5]=y=>x.content=y),rows:"6",placeholder:"ss://... 或 base64 内容",class:"w-full px-3 py-2 border rounded-lg text-sm font-mono"},null,512),[[De,x.content]])])):pe("",!0),d("div",Zg,[me(d("input",{type:"checkbox",id:"src-enabled","onUpdate:modelValue":w[6]||(w[6]=y=>x.enabled=y),class:"rounded"},null,512),[[zn,x.enabled]]),w[20]||(w[20]=d("label",{for:"src-enabled",class:"text-sm"},"启用",-1))]),d("div",null,[d("div",{class:"flex items-center justify-between mb-1"},[w[21]||(w[21]=d("label",{class:"text-sm font-medium"},"过滤器",-1)),d("button",{class:"text-xs text-primary-600 hover:underline",onClick:Pe},"+ 添加")]),d("details",ey,[w[24]||(w[24]=d("summary",{class:"cursor-pointer text-gray-700"},"使用说明",-1)),d("div",ty,[w[23]||(w[23]=d("p",null,"pattern 支持正则;field 留空默认匹配 name。常用字段:name、type、server、port。",-1)),d("table",ny,[w[22]||(w[22]=d("thead",{class:"bg-gray-100 text-gray-700"},[d("tr",null,[d("th",{class:"border border-gray-200 px-2 py-1 font-medium"},"过滤器"),d("th",{class:"border border-gray-200 px-2 py-1 font-medium"},"说明")])],-1)),d("tbody",null,[(F(),B(ve,null,Fe(P,y=>d("tr",{key:y.type},[d("td",sy,H(y.label),1),d("td",ry,H(y.help),1)])),64))])])])]),(F(!0),B(ve,null,Fe(x.filters,(y,V)=>(F(),B("div",{key:V,class:"flex gap-1 mb-1.5"},[me(d("select",{"onUpdate:modelValue":M=>y.type=M,class:"px-2 py-1 border rounded text-xs w-28"},[(F(),B(ve,null,Fe(S,M=>d("option",{key:M,value:M},H(C[M]||M),9,iy)),64))],8,oy),[[Sn,y.type]]),me(d("input",{"onUpdate:modelValue":M=>y.pattern=M,placeholder:"pattern",class:"flex-1 px-2 py-1 border rounded text-xs"},null,8,ly),[[De,y.pattern]]),me(d("input",{"onUpdate:modelValue":M=>y.field=M,placeholder:"field",class:"w-24 px-2 py-1 border rounded text-xs"},null,8,ay),[[De,y.field]]),d("button",{class:"px-2 py-1 text-xs text-red-500 hover:bg-red-50 rounded",onClick:M=>x.filters.splice(V,1)},"×",8,cy)]))),128))])])]),_:1},8,["modelValue","title"]),Oe(nr,{modelValue:m.value.show,"onUpdate:modelValue":w[9]||(w[9]=y=>m.value.show=y),title:m.value.title,message:m.value.message,danger:m.value.danger,onConfirm:w[10]||(w[10]=y=>{m.value.action(),m.value.show=!1})},null,8,["modelValue","title","message","danger"]),h.value?(F(),B("div",{key:3,class:je(["fixed bottom-4 right-4 px-4 py-2 rounded-lg shadow-lg text-sm z-50",h.value.type==="error"?"bg-red-500 text-white":"bg-green-500 text-white"])},H(h.value.msg),3)):pe("",!0)]))}},fy={key:0,class:"text-gray-400 text-sm"},dy={key:1,class:"text-gray-400 text-sm py-8 text-center"},py={key:2,class:"space-y-2"},hy=["onClick"],my={class:"flex-1 min-w-0"},gy={class:"flex items-center gap-2"},yy={class:"font-medium text-gray-900"},by={key:0,class:"px-1.5 py-0.5 rounded text-xs bg-red-100 text-red-700"},xy={class:"flex gap-3 mt-1 text-xs text-gray-400"},vy={key:0},_y={class:"flex gap-1 ml-3"},wy=["disabled","onClick"],Ey=["onClick"],Sy=["onClick"],Ry=["onClick"],Cy={key:0,class:"text-gray-400 text-sm py-4 text-center"},Ay={key:1},Oy={class:"overflow-x-auto rounded-lg bg-white"},Ty={class:"w-full text-left text-xs"},Py={class:"divide-y divide-gray-100"},Ny={class:"px-3 py-2 text-gray-500"},Iy={class:"px-3 py-2 text-blue-600"},ky={class:"px-3 py-2 font-mono text-gray-500"},$y={class:"px-3 py-2 font-mono text-gray-500"},Dy={class:"px-3 py-2 text-gray-500"},Ly={class:"px-3 py-2 text-gray-500"},Uy={class:"px-3 py-2 font-mono text-gray-500"},Fy={class:"px-3 py-2 font-mono text-gray-500"},My={class:"px-3 py-2 font-mono text-gray-500"},Vy={class:"px-3 py-2 text-gray-500"},By={class:"px-3 py-2 text-gray-500"},jy={class:"px-3 py-2"},Hy=["onClick"],qy={key:0,class:"text-xs text-gray-400 mt-2"},Ky={class:"space-y-4"},Wy=["disabled"],zy={class:"max-h-32 overflow-y-auto border rounded-lg p-2 space-y-1"},Gy=["value"],Jy={class:"text-xs text-gray-400"},Xy={key:0,class:"text-xs text-gray-400 py-1"},Yy=["value"],Qy={class:"flex items-center gap-4"},Zy={class:"flex items-center gap-2 text-sm"},eb={class:"flex items-center gap-2 text-sm"},tb={class:"flex items-center justify-between mb-1"},nb=["onUpdate:modelValue"],sb=["value"],rb=["onUpdate:modelValue"],ob=["onClick"],ib={__name:"Collections",setup(e){const t=Z([]),n=Z([]),s=Z([]),r=Z(!0),o=Z(!1),i=Z(!1),l=Z(""),a=Z(!1),u=Z(null),c=Z(""),f=Z(""),h=Z(null),m=At({}),S=Z({show:!1,title:"",message:"",danger:!1,action:null}),C=["include","exclude","rename","dedupe","sort","delete-field","flag","quick","resolve","custom"],P=()=>({name:"",sourceIds:[],filters:[],templateId:"",ignoreFailed:!0,enabled:!0}),v=At(P());function x(D,I="success"){h.value={msg:D,type:I},setTimeout(()=>h.value=null,2500)}function A(D,...I){for(const J of I){const ue=D==null?void 0:D[J];if(ue!=null&&ue!=="")return ue}return"-"}function R(D){if(D!=null&&D["reality-opts"]||(D==null?void 0:D.security)==="reality")return"reality";const I=A(D,"tls","security");return I===!0?"TLS":I===!1||I==="none"?"-":I}function O(D){const I=D==null?void 0:D.transport;return typeof I=="string"?I:I!=null&&I.type?I.type:A(D,"network","net")}function $(D){return{original:(D==null?void 0:D.originalCount)??(Array.isArray(D==null?void 0:D.original)?D.original.length:(D==null?void 0:D.nodes)??0),processed:Array.isArray(D==null?void 0:D.processed)?D.processed.length:0}}function U(){Object.assign(v,P()),i.value=!1,o.value=!0}function ae(D){Object.assign(v,{name:D.id,sourceIds:[...D.sourceIds||[]],filters:JSON.parse(JSON.stringify(D.filters||[])),templateId:D.templateId||"",ignoreFailed:D.ignoreFailed!==!1,enabled:D.enabled!==!1}),i.value=!0,o.value=!0}async function Y(){try{const D={...v};i.value?await Am(v.name,D):await Cm(D),o.value=!1,await Pe(),x(i.value?"已更新":"已创建")}catch(D){x(D.message,"error")}}async function se(D){S.value={show:!0,title:"删除合集",message:`确定删除 "${D.name}"?`,danger:!0,action:async()=>{try{await Om(D.id),await Pe(),x("已删除")}catch(I){x(I.message,"error")}}}}async function oe(D){try{const I=await Lm(D.id);await is(I.data.url),x("链接已复制")}catch(I){x(I.message,"error")}}async function W(D){if(l.value===D.id){l.value="",u.value=null;return}l.value=D.id,a.value=!0,u.value=null;try{const I=await Sr(D);u.value=I.data,m[D.id]=$(I.data)}catch(I){x(I.message,"error"),l.value=""}finally{a.value=!1}}async function ce(D){try{const I=await uc(D);await is(I.data.uri),x("节点链接已复制")}catch(I){x(I.message,"error")}}async function fe(D){var I,J;if(!c.value){c.value=D.id,f.value="";try{const ue=await Sr(D),re=((I=ue.data)==null?void 0:I.processed)||((J=ue.data)==null?void 0:J.original)||[];m[D.id]=$(ue.data),l.value===D.id&&(u.value=ue.data);for(let de=0;de(F(),B("div",null,[d("div",{class:"flex items-center justify-between mb-5"},[I[11]||(I[11]=d("h2",{class:"text-xl font-bold"},"合集",-1)),d("button",{class:"px-4 py-2 bg-primary-600 text-white rounded-lg text-sm hover:bg-primary-700",onClick:U},"+ 新建")]),r.value?(F(),B("div",fy,"加载中...")):t.value.length===0?(F(),B("div",dy,"暂无合集")):(F(),B("div",py,[(F(!0),B(ve,null,Fe(t.value,J=>{var ue,re,de,Ne;return F(),B("div",{key:J.id,class:"bg-white rounded-lg shadow-sm border overflow-hidden hover:shadow-md transition-shadow"},[d("div",{class:"p-4 flex items-center justify-between cursor-pointer",onClick:ge=>W(J)},[d("div",my,[d("div",gy,[d("span",yy,H(J.name),1),J.enabled?pe("",!0):(F(),B("span",by,"已禁用"))]),d("div",xy,[d("span",null,"原始节点: "+H(((ue=m[J.id])==null?void 0:ue.original)??"-"),1),d("span",null,"处理后: "+H(((re=m[J.id])==null?void 0:re.processed)??"-"),1),d("span",null,"订阅源: "+H(((de=J.sourceIds)==null?void 0:de.length)||0),1),d("span",null,"过滤器: "+H(((Ne=J.filters)==null?void 0:Ne.length)||0),1),d("span",null,"模板: "+H(J.templateId||"default"),1),J.ignoreFailed?(F(),B("span",vy,"忽略失败")):pe("",!0)])]),d("div",_y,[d("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-blue-50 text-blue-600 whitespace-nowrap",disabled:!!c.value,onClick:ut(ge=>fe(J),["stop"])},H(c.value===J.id?`探测 ${f.value}`:"探测出口"),9,wy),d("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-gray-100",onClick:ut(ge=>oe(J),["stop"])},"复制链接",8,Ey),d("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-blue-50 text-blue-600",onClick:ut(ge=>ae(J),["stop"])},"编辑",8,Sy),d("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-red-50 text-red-600",onClick:ut(ge=>se(J),["stop"])},"删除",8,Ry)])],8,hy),l.value===J.id?(F(),B("div",{key:0,class:"border-t bg-gray-50",onClick:I[0]||(I[0]=ut(()=>{},["stop"]))},[a.value?(F(),B("div",Cy,"解析中...")):u.value?(F(),B("div",Ay,[d("div",Oy,[d("table",Ty,[I[12]||(I[12]=d("thead",{class:"sticky top-0 bg-gray-100 text-gray-600"},[d("tr",null,[d("th",{class:"px-3 py-2 font-medium"},"Type"),d("th",{class:"px-3 py-2 font-medium"},"Name"),d("th",{class:"px-3 py-2 font-medium"},"Server"),d("th",{class:"px-3 py-2 font-medium"},"Port"),d("th",{class:"px-3 py-2 font-medium"},"Transport"),d("th",{class:"px-3 py-2 font-medium"},"Tls"),d("th",{class:"px-3 py-2 font-medium"},"Delay"),d("th",{class:"px-3 py-2 font-medium"},"Speed"),d("th",{class:"px-3 py-2 font-medium"},"Egress IP"),d("th",{class:"px-3 py-2 font-medium"},"Country"),d("th",{class:"px-3 py-2 font-medium"},"Region"),d("th",{class:"px-3 py-2 font-medium"},"Link")])],-1)),d("tbody",Py,[(F(!0),B(ve,null,Fe(u.value.processed||u.value.original||[],(ge,k)=>(F(),B("tr",{key:k},[d("td",Ny,H(A(ge,"type")),1),d("td",Iy,H(A(ge,"name","remarks")),1),d("td",ky,H(A(ge,"server","address")),1),d("td",$y,H(A(ge,"port")),1),d("td",Dy,H(O(ge)),1),d("td",Ly,H(R(ge)),1),d("td",Uy,H(A(ge,"latencyMs","delay","latency","ping")),1),d("td",Fy,H(A(ge,"speed","downloadSpeed")),1),d("td",My,H(A(ge,"egressIp")),1),d("td",Vy,H(A(ge,"egressCountry","country")),1),d("td",By,H(A(ge,"egressRegion","region")),1),d("td",jy,[d("button",{class:"px-2 py-1 text-xs rounded hover:bg-gray-100 text-blue-600 whitespace-nowrap",onClick:w=>ce(ge)},"复制",8,Hy)])]))),128))])])]),(u.value.processed||u.value.original||[]).length===0?(F(),B("p",qy,"暂无节点")):pe("",!0)])):pe("",!0)])):pe("",!0)])}),128))])),Oe(Us,{modelValue:o.value,"onUpdate:modelValue":I[8]||(I[8]=J=>o.value=J),title:i.value?"编辑合集":"新建合集"},{footer:dt(()=>[d("button",{class:"px-4 py-2 text-sm rounded-lg hover:bg-gray-100",onClick:I[7]||(I[7]=J=>o.value=!1)},"取消"),d("button",{class:"px-4 py-2 bg-primary-600 text-white rounded-lg text-sm hover:bg-primary-700",onClick:Y},"保存")]),default:dt(()=>[d("div",Ky,[d("div",null,[I[13]||(I[13]=d("label",{class:"block text-sm font-medium mb-1"},"名称 / ID",-1)),me(d("input",{"onUpdate:modelValue":I[1]||(I[1]=J=>v.name=J),disabled:i.value,placeholder:"my-collection",class:"w-full px-3 py-2 border rounded-lg text-sm disabled:bg-gray-100"},null,8,Wy),[[De,v.name]])]),d("div",null,[I[14]||(I[14]=d("label",{class:"block text-sm font-medium mb-1"},"订阅源 (多选)",-1)),d("div",zy,[(F(!0),B(ve,null,Fe(n.value,J=>(F(),B("label",{key:J.id,class:"flex items-center gap-2 text-sm cursor-pointer hover:bg-gray-50 px-1 py-0.5 rounded"},[me(d("input",{type:"checkbox",value:J.id,"onUpdate:modelValue":I[2]||(I[2]=ue=>v.sourceIds=ue),class:"rounded"},null,8,Gy),[[zn,v.sourceIds]]),d("span",null,H(J.name),1),d("span",Jy,"("+H(J.type)+")",1)]))),128)),n.value.length===0?(F(),B("p",Xy,"无可用订阅源")):pe("",!0)])]),d("div",null,[I[16]||(I[16]=d("label",{class:"block text-sm font-medium mb-1"},"模板",-1)),me(d("select",{"onUpdate:modelValue":I[3]||(I[3]=J=>v.templateId=J),class:"w-full px-3 py-2 border rounded-lg text-sm"},[I[15]||(I[15]=d("option",{value:""},"默认",-1)),(F(!0),B(ve,null,Fe(s.value,J=>(F(),B("option",{key:J.id,value:J.id},H(J.name)+" ("+H(J.target)+")",9,Yy))),128))],512),[[Sn,v.templateId]])]),d("div",Qy,[d("label",Zy,[me(d("input",{type:"checkbox","onUpdate:modelValue":I[4]||(I[4]=J=>v.enabled=J),class:"rounded"},null,512),[[zn,v.enabled]]),I[17]||(I[17]=ts(" 启用 ",-1))]),d("label",eb,[me(d("input",{type:"checkbox","onUpdate:modelValue":I[5]||(I[5]=J=>v.ignoreFailed=J),class:"rounded"},null,512),[[zn,v.ignoreFailed]]),I[18]||(I[18]=ts(" 忽略失败源 ",-1))])]),d("div",null,[d("div",tb,[I[19]||(I[19]=d("label",{class:"text-sm font-medium"},"过滤器",-1)),d("button",{class:"text-xs text-primary-600 hover:underline",onClick:I[6]||(I[6]=J=>v.filters.push({type:"include",pattern:""}))},"+ 添加")]),(F(!0),B(ve,null,Fe(v.filters,(J,ue)=>(F(),B("div",{key:ue,class:"flex gap-1 mb-1.5"},[me(d("select",{"onUpdate:modelValue":re=>J.type=re,class:"px-2 py-1 border rounded text-xs w-28"},[(F(),B(ve,null,Fe(C,re=>d("option",{key:re,value:re},H(re),9,sb)),64))],8,nb),[[Sn,J.type]]),me(d("input",{"onUpdate:modelValue":re=>J.pattern=re,placeholder:"pattern",class:"flex-1 px-2 py-1 border rounded text-xs"},null,8,rb),[[De,J.pattern]]),d("button",{class:"px-2 py-1 text-xs text-red-500 hover:bg-red-50 rounded",onClick:re=>v.filters.splice(ue,1)},"×",8,ob)]))),128))])])]),_:1},8,["modelValue","title"]),Oe(nr,{modelValue:S.value.show,"onUpdate:modelValue":I[9]||(I[9]=J=>S.value.show=J),title:S.value.title,message:S.value.message,danger:S.value.danger,onConfirm:I[10]||(I[10]=J=>{S.value.action(),S.value.show=!1})},null,8,["modelValue","title","message","danger"]),h.value?(F(),B("div",{key:3,class:je(["fixed bottom-4 right-4 px-4 py-2 rounded-lg shadow-lg text-sm z-50",h.value.type==="error"?"bg-red-500 text-white":"bg-green-500 text-white"])},H(h.value.msg),3)):pe("",!0)]))}},lb={key:0,class:"text-gray-400 text-sm"},ab={key:1,class:"text-gray-400 text-sm py-8 text-center"},cb={key:2,class:"space-y-2"},ub={class:"flex-1 min-w-0"},fb={class:"flex items-center gap-2"},db={class:"font-medium text-gray-900"},pb={class:"px-1.5 py-0.5 rounded text-xs bg-purple-100 text-purple-700"},hb={key:0,class:"px-1.5 py-0.5 rounded text-xs bg-gray-100 text-gray-500"},mb={class:"text-xs text-gray-500 mt-1"},gb={key:0,class:"flex gap-1 ml-3"},yb=["onClick"],bb=["onClick"],xb={key:1,class:"flex gap-1 ml-3"},vb=["onClick"],_b={class:"space-y-4"},wb=["disabled"],Eb=["value"],Sb={key:0,class:"text-xs text-red-500 mt-1"},Rb={class:"text-xs font-mono bg-gray-50 p-3 rounded max-h-96 overflow-auto"},Cb={__name:"Templates",setup(e){const t=Z([]),n=Z(!0),s=Z(!1),r=Z(!1),o=Z(!1),i=Z(null),l=Z(null),a=Z({show:!1,title:"",message:"",danger:!1,action:null}),u=["mihomo","stash","surge","surge-mac","surfboard","loon","egern","shadowrocket","qx","sing-box","v2ray","uri","json"],c=()=>({name:"",target:"mihomo",configStr:"{}"}),f=At(c()),h=tt(()=>{try{return JSON.parse(f.configStr),""}catch{return"JSON 格式错误"}});function m(R,O="success"){l.value={msg:R,type:O},setTimeout(()=>l.value=null,2500)}function S(){Object.assign(f,c()),r.value=!1,s.value=!0}function C(R){Object.assign(f,{name:R.id,target:R.target,configStr:JSON.stringify(R.config||{},null,2)}),r.value=!0,s.value=!0}function P(R){i.value=R.config,o.value=!0}async function v(){if(h.value){m(h.value,"error");return}try{const R={name:f.name,target:f.target,config:JSON.parse(f.configStr)};r.value?await Pm(f.name,R):await Tm(R),s.value=!1,await A(),m(r.value?"已更新":"已创建")}catch(R){m(R.message,"error")}}async function x(R){a.value={show:!0,title:"删除模板",message:`确定删除 "${R.name}"?`,danger:!0,action:async()=>{try{await Nm(R.id),await A(),m("已删除")}catch(O){m(O.message,"error")}}}}async function A(){n.value=!0;try{const R=await Oo();t.value=R.data||[]}catch(R){m(R.message,"error")}finally{n.value=!1}}return Xt(A),(R,O)=>(F(),B("div",null,[d("div",{class:"flex items-center justify-between mb-5"},[O[8]||(O[8]=d("h2",{class:"text-xl font-bold"},"模板",-1)),d("button",{class:"px-4 py-2 bg-primary-600 text-white rounded-lg text-sm hover:bg-primary-700",onClick:S},"+ 新建")]),n.value?(F(),B("div",lb,"加载中...")):t.value.length===0?(F(),B("div",ab,"暂无模板")):(F(),B("div",cb,[(F(!0),B(ve,null,Fe(t.value,$=>(F(),B("div",{key:$.id,class:"bg-white rounded-lg p-4 shadow-sm border flex items-center justify-between hover:shadow-md transition-shadow"},[d("div",ub,[d("div",fb,[d("span",db,H($.name),1),d("span",pb,H($.target),1),$.readonly?(F(),B("span",hb,"内置")):pe("",!0)]),d("p",mb,H(Object.keys($.config||{}).length)+" 个配置项",1)]),$.readonly?(F(),B("div",xb,[d("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-gray-100",onClick:U=>P($)},"查看",8,vb)])):(F(),B("div",gb,[d("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-blue-50 text-blue-600",onClick:U=>C($)},"编辑",8,yb),d("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-red-50 text-red-600",onClick:U=>x($)},"删除",8,bb)]))]))),128))])),Oe(Us,{modelValue:s.value,"onUpdate:modelValue":O[4]||(O[4]=$=>s.value=$),title:r.value?"编辑模板":"新建模板"},{footer:dt(()=>[d("button",{class:"px-4 py-2 text-sm rounded-lg hover:bg-gray-100",onClick:O[3]||(O[3]=$=>s.value=!1)},"取消"),d("button",{class:"px-4 py-2 bg-primary-600 text-white rounded-lg text-sm hover:bg-primary-700",onClick:v},"保存")]),default:dt(()=>[d("div",_b,[d("div",null,[O[9]||(O[9]=d("label",{class:"block text-sm font-medium mb-1"},"名称 / ID",-1)),me(d("input",{"onUpdate:modelValue":O[0]||(O[0]=$=>f.name=$),disabled:r.value,placeholder:"my-template",class:"w-full px-3 py-2 border rounded-lg text-sm disabled:bg-gray-100"},null,8,wb),[[De,f.name]])]),d("div",null,[O[10]||(O[10]=d("label",{class:"block text-sm font-medium mb-1"},"目标平台",-1)),me(d("select",{"onUpdate:modelValue":O[1]||(O[1]=$=>f.target=$),class:"w-full px-3 py-2 border rounded-lg text-sm"},[(F(),B(ve,null,Fe(u,$=>d("option",{key:$,value:$},H($),9,Eb)),64))],512),[[Sn,f.target]])]),d("div",null,[O[11]||(O[11]=d("label",{class:"block text-sm font-medium mb-1"},"配置 (JSON)",-1)),me(d("textarea",{"onUpdate:modelValue":O[2]||(O[2]=$=>f.configStr=$),rows:"12",placeholder:'{"proxy-groups": [], "rules": []}',class:"w-full px-3 py-2 border rounded-lg text-sm font-mono"},null,512),[[De,f.configStr]]),h.value?(F(),B("p",Sb,H(h.value),1)):pe("",!0)])])]),_:1},8,["modelValue","title"]),Oe(Us,{modelValue:o.value,"onUpdate:modelValue":O[5]||(O[5]=$=>o.value=$),title:"查看模板配置"},{default:dt(()=>[d("pre",Rb,H(JSON.stringify(i.value,null,2)),1)]),_:1},8,["modelValue"]),Oe(nr,{modelValue:a.value.show,"onUpdate:modelValue":O[6]||(O[6]=$=>a.value.show=$),title:a.value.title,message:a.value.message,danger:a.value.danger,onConfirm:O[7]||(O[7]=$=>{a.value.action(),a.value.show=!1})},null,8,["modelValue","title","message","danger"]),l.value?(F(),B("div",{key:3,class:je(["fixed bottom-4 right-4 px-4 py-2 rounded-lg shadow-lg text-sm z-50",l.value.type==="error"?"bg-red-500 text-white":"bg-green-500 text-white"])},H(l.value.msg),3)):pe("",!0)]))}},Ab={key:0,class:"text-gray-400 text-sm"},Ob={key:1,class:"text-gray-400 text-sm py-8 text-center"},Tb={key:2,class:"space-y-2"},Pb={class:"flex-1 min-w-0"},Nb={class:"flex items-center gap-2"},Ib={class:"font-medium text-gray-900"},kb={class:"text-xs text-gray-400 mt-1"},$b={class:"flex gap-1 ml-3"},Db=["onClick"],Lb=["onClick"],Ub={__name:"RecycleBin",setup(e){const t=Z([]),n=Z(!0),s=Z(null),r=Z({show:!1,title:"",message:"",danger:!1,confirmText:"确定",action:null});function o(f,h="success"){s.value={msg:f,type:h},setTimeout(()=>s.value=null,2500)}function i(f){return f?new Date(f).toLocaleString("zh-CN"):""}function l(f){return{source:"bg-blue-100 text-blue-700",collection:"bg-purple-100 text-purple-700",template:"bg-green-100 text-green-700"}[f]||"bg-gray-100 text-gray-600"}async function a(f){r.value={show:!0,title:"恢复",message:`恢复 "${f.resourceId}"?`,danger:!1,confirmText:"恢复",action:async()=>{try{await $m(f.id),await c(),o("已恢复")}catch(h){o(h.message,"error")}}}}async function u(f){r.value={show:!0,title:"彻底删除",message:`彻底删除 "${f.resourceId}"?此操作不可撤销!`,danger:!0,confirmText:"彻底删除",action:async()=>{try{await km(f.id),await c(),o("已彻底删除")}catch(h){o(h.message,"error")}}}}async function c(){n.value=!0;try{const f=await Im();t.value=f.data||[]}catch(f){o(f.message,"error")}finally{n.value=!1}}return Xt(c),(f,h)=>(F(),B("div",null,[h[2]||(h[2]=d("h2",{class:"text-xl font-bold mb-5"},"回收站",-1)),n.value?(F(),B("div",Ab,"加载中...")):t.value.length===0?(F(),B("div",Ob,"回收站为空")):(F(),B("div",Tb,[(F(!0),B(ve,null,Fe(t.value,m=>(F(),B("div",{key:m.id,class:"bg-white rounded-lg p-4 shadow-sm border flex items-center justify-between"},[d("div",Pb,[d("div",Nb,[d("span",{class:je(["px-1.5 py-0.5 rounded text-xs",l(m.resourceType)])},H(m.resourceType),3),d("span",Ib,H(m.resourceId),1)]),d("p",kb,"删除于: "+H(i(m.deletedAt)),1)]),d("div",$b,[d("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-blue-50 text-blue-600",onClick:S=>a(m)},"恢复",8,Db),d("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-red-50 text-red-600",onClick:S=>u(m)},"彻底删除",8,Lb)])]))),128))])),Oe(nr,{modelValue:r.value.show,"onUpdate:modelValue":h[0]||(h[0]=m=>r.value.show=m),title:r.value.title,message:r.value.message,danger:r.value.danger,confirmText:r.value.confirmText,onConfirm:h[1]||(h[1]=m=>{r.value.action(),r.value.show=!1})},null,8,["modelValue","title","message","danger","confirmText"]),s.value?(F(),B("div",{key:3,class:je(["fixed bottom-4 right-4 px-4 py-2 rounded-lg shadow-lg text-sm z-50",s.value.type==="error"?"bg-red-500 text-white":"bg-green-500 text-white"])},H(s.value.msg),3)):pe("",!0)]))}},Fb={class:"bg-white rounded-lg p-4 shadow-sm border mb-4"},Mb={class:"flex gap-2 mb-3"},Vb=["value"],Bb={class:"flex gap-2 mb-2"},jb=["disabled"],Hb={key:0,class:"text-xs text-gray-500 mb-2"},qb={class:"bg-white rounded-lg p-4 shadow-sm border mb-4"},Kb={class:"flex gap-2 mb-3"},Wb=["disabled"],zb={key:0,class:"bg-gray-50 rounded-lg p-3 text-sm space-y-1"},Gb={class:"flex justify-between"},Jb={class:"flex justify-between"},Xb={class:"flex justify-between"},Yb={class:"flex justify-between"},Qb={key:0,class:"flex justify-between"},Zb={class:"bg-white rounded-lg p-4 shadow-sm border"},e0={class:"flex gap-2"},t0={class:"px-4 py-2 bg-gray-600 text-white rounded-lg text-sm hover:bg-gray-700 cursor-pointer"},n0={__name:"Tools",setup(e){const t=["mihomo","stash","surge","surge-mac","surfboard","loon","egern","shadowrocket","qx","sing-box","v2ray","uri","json"],n=["mihomo","surge","loon","qx"],s=Z("proxy"),r=Z("mihomo"),o=Z(""),i=Z(""),l=Z(""),a=Z(!1),u=Z(""),c=Z(null),f=Z(!1),h=Z(null),m=tt(()=>s.value==="proxy"?t:n);function S(R,O="success"){h.value={msg:R,type:O},setTimeout(()=>h.value=null,2500)}async function C(R){try{await is(R),S("已复制")}catch(O){S(O.message,"error")}}async function P(){var R;if(!o.value.trim()){S("请输入内容","error");return}a.value=!0,i.value="",l.value="";try{const $=await(s.value==="proxy"?Fm:Mm)({content:o.value,target:r.value});i.value=$.data.content||$.data.par_res||"",l.value=`解析: ${$.data.parsed||0} · 输出: ${$.data.emitted||0} · 跳过: ${$.data.skipped||0}`,(R=$.data.warnings)!=null&&R.length&&(l.value+=" · ⚠ "+$.data.warnings.join("; ")),S("转换成功")}catch(O){S(O.message,"error")}finally{a.value=!1}}async function v(){f.value=!0,c.value=null;try{const R=await Vm(u.value);c.value=R.data}catch(R){S(R.message,"error")}finally{f.value=!1}}async function x(){try{const R=await _m(),O=new Blob([JSON.stringify(R,null,2)],{type:"application/json"}),$=URL.createObjectURL(O),U=document.createElement("a");U.href=$,U.download=`sub-store-backup-${Date.now()}.json`,U.click(),URL.revokeObjectURL($),S("已导出")}catch(R){S(R.message,"error")}}async function A(R){var $;const O=($=R.target.files)==null?void 0:$[0];if(O){try{const U=await O.text(),ae=JSON.parse(U);await wm(ae),S("导入成功")}catch(U){S(U.message,"error")}R.target.value=""}}return(R,O)=>{var $;return F(),B("div",null,[O[16]||(O[16]=d("h2",{class:"text-xl font-bold mb-5"},"工具",-1)),d("div",Fb,[O[7]||(O[7]=d("h3",{class:"font-semibold mb-3"},"转换器",-1)),d("div",Mb,[me(d("select",{"onUpdate:modelValue":O[0]||(O[0]=U=>s.value=U),class:"px-3 py-2 border rounded-lg text-sm"},[...O[6]||(O[6]=[d("option",{value:"proxy"},"代理转换",-1),d("option",{value:"rule"},"规则转换",-1)])],512),[[Sn,s.value]]),me(d("select",{"onUpdate:modelValue":O[1]||(O[1]=U=>r.value=U),class:"px-3 py-2 border rounded-lg text-sm"},[(F(!0),B(ve,null,Fe(m.value,U=>(F(),B("option",{key:U,value:U},H(U),9,Vb))),128))],512),[[Sn,r.value]])]),me(d("textarea",{"onUpdate:modelValue":O[2]||(O[2]=U=>o.value=U),rows:"5",placeholder:"粘贴订阅内容或规则...",class:"w-full px-3 py-2 border rounded-lg text-sm font-mono mb-2"},null,512),[[De,o.value]]),d("div",Bb,[d("button",{class:"px-4 py-2 bg-primary-600 text-white rounded-lg text-sm hover:bg-primary-700",disabled:a.value,onClick:P},H(a.value?"转换中...":"转换"),9,jb),i.value?(F(),B("button",{key:0,class:"px-4 py-2 text-sm rounded-lg hover:bg-gray-100",onClick:O[3]||(O[3]=U=>C(i.value))},"复制结果")):pe("",!0)]),l.value?(F(),B("p",Hb,H(l.value),1)):pe("",!0),i.value?me((F(),B("textarea",{key:1,"onUpdate:modelValue":O[4]||(O[4]=U=>i.value=U),rows:"8",readonly:"",class:"w-full px-3 py-2 border rounded-lg text-sm font-mono bg-gray-50"},null,512)),[[De,i.value]]):pe("",!0)]),d("div",qb,[O[13]||(O[13]=d("h3",{class:"font-semibold mb-3"},"节点信息查询",-1)),d("div",Kb,[me(d("input",{"onUpdate:modelValue":O[5]||(O[5]=U=>u.value=U),placeholder:"服务器地址 / IP",class:"flex-1 px-3 py-2 border rounded-lg text-sm",onKeyup:Ff(v,["enter"])},null,544),[[De,u.value]]),d("button",{class:"px-4 py-2 bg-primary-600 text-white rounded-lg text-sm hover:bg-primary-700",disabled:!u.value||f.value,onClick:v},H(f.value?"查询中...":"查询"),9,Wb)]),c.value?(F(),B("div",zb,[d("div",Gb,[O[8]||(O[8]=d("span",{class:"text-gray-500"},"IP",-1)),d("span",null,H(c.value.ip),1)]),d("div",Jb,[O[9]||(O[9]=d("span",{class:"text-gray-500"},"国家",-1)),d("span",null,H(c.value.country),1)]),d("div",Xb,[O[10]||(O[10]=d("span",{class:"text-gray-500"},"地区",-1)),d("span",null,H(c.value.region),1)]),d("div",Yb,[O[11]||(O[11]=d("span",{class:"text-gray-500"},"城市",-1)),d("span",null,H(c.value.city),1)]),c.value.connection?(F(),B("div",Qb,[O[12]||(O[12]=d("span",{class:"text-gray-500"},"ISP",-1)),d("span",null,H((($=c.value.connection)==null?void 0:$.isp)||"-"),1)])):pe("",!0)])):pe("",!0)]),d("div",Zb,[O[15]||(O[15]=d("h3",{class:"font-semibold mb-3"},"数据备份",-1)),d("div",e0,[d("button",{class:"px-4 py-2 bg-green-600 text-white rounded-lg text-sm hover:bg-green-700",onClick:x},"导出全部"),d("label",t0,[O[14]||(O[14]=ts(" 导入备份 ",-1)),d("input",{type:"file",accept:".json",class:"hidden",onChange:A},null,32)])])]),h.value?(F(),B("div",{key:0,class:je(["fixed bottom-4 right-4 px-4 py-2 rounded-lg shadow-lg text-sm z-50",h.value.type==="error"?"bg-red-500 text-white":"bg-green-500 text-white"])},H(h.value.msg),3)):pe("",!0)])}}},s0={key:0,class:"text-gray-400 text-sm"},r0={key:1,class:"space-y-4"},o0={class:"bg-white rounded-lg p-4 shadow-sm border"},i0={class:"space-y-3"},l0={class:"flex items-center gap-2"},a0={class:"bg-white rounded-lg p-4 shadow-sm border"},c0={__name:"Settings",setup(e){const t=Z(null),n=Z(!0),s=Z(null);function r(i,l="success"){s.value={msg:i,type:l},setTimeout(()=>s.value=null,2500)}async function o(){try{await vm(t.value),r("设置已保存")}catch(i){r(i.message,"error")}}return Xt(async()=>{try{const i=await xm();t.value=i.data}catch(i){r(i.message,"error")}finally{n.value=!1}}),(i,l)=>(F(),B("div",null,[l[16]||(l[16]=d("h2",{class:"text-xl font-bold mb-5"},"设置",-1)),n.value?(F(),B("div",s0,"加载中...")):(F(),B("div",r0,[d("div",o0,[l[13]||(l[13]=d("h3",{class:"font-semibold mb-3 text-sm"},"通用",-1)),d("div",i0,[d("div",null,[l[7]||(l[7]=d("label",{class:"block text-sm mb-1"},"默认 User-Agent",-1)),me(d("input",{"onUpdate:modelValue":l[0]||(l[0]=a=>t.value.defaultUserAgent=a),class:"w-full px-3 py-2 border rounded-lg text-sm"},null,512),[[De,t.value.defaultUserAgent]])]),d("div",null,[l[8]||(l[8]=d("label",{class:"block text-sm mb-1"},"默认流量查询 User-Agent",-1)),me(d("input",{"onUpdate:modelValue":l[1]||(l[1]=a=>t.value.defaultFlowUserAgent=a),class:"w-full px-3 py-2 border rounded-lg text-sm"},null,512),[[De,t.value.defaultFlowUserAgent]])]),d("div",null,[l[9]||(l[9]=d("label",{class:"block text-sm mb-1"},"请求超时 (ms)",-1)),me(d("input",{"onUpdate:modelValue":l[2]||(l[2]=a=>t.value.defaultTimeout=a),class:"w-full px-3 py-2 border rounded-lg text-sm"},null,512),[[De,t.value.defaultTimeout]])]),d("div",null,[l[10]||(l[10]=d("label",{class:"block text-sm mb-1"},"后端并发数",-1)),me(d("input",{"onUpdate:modelValue":l[3]||(l[3]=a=>t.value.backendRequestConcurrency=a),class:"w-full px-3 py-2 border rounded-lg text-sm"},null,512),[[De,t.value.backendRequestConcurrency]])]),d("div",null,[l[11]||(l[11]=d("label",{class:"block text-sm mb-1"},"远程缓存 TTL (秒)",-1)),me(d("input",{"onUpdate:modelValue":l[4]||(l[4]=a=>t.value.remoteCacheTtl=a),class:"w-full px-3 py-2 border rounded-lg text-sm"},null,512),[[De,t.value.remoteCacheTtl]])]),d("div",l0,[me(d("input",{type:"checkbox",id:"cache-stale","onUpdate:modelValue":l[5]||(l[5]=a=>t.value.remoteCacheStaleOnError=a),class:"rounded"},null,512),[[zn,t.value.remoteCacheStaleOnError]]),l[12]||(l[12]=d("label",{for:"cache-stale",class:"text-sm"},"缓存过期时仍返回旧数据",-1))])])]),d("div",a0,[l[14]||(l[14]=d("h3",{class:"font-semibold mb-3 text-sm"},"节点信息 API",-1)),me(d("input",{"onUpdate:modelValue":l[6]||(l[6]=a=>t.value.nodeInfoApiUrl=a),placeholder:"https://ipwho.is/{ip}",class:"w-full px-3 py-2 border rounded-lg text-sm font-mono"},null,512),[[De,t.value.nodeInfoApiUrl]]),l[15]||(l[15]=d("p",{class:"text-xs text-gray-400 mt-1"},"URL 中 {ip} 会被替换为查询的 IP",-1))]),d("button",{class:"px-4 py-2 bg-primary-600 text-white rounded-lg text-sm hover:bg-primary-700",onClick:o},"保存设置")])),s.value?(F(),B("div",{key:2,class:je(["fixed bottom-4 right-4 px-4 py-2 rounded-lg shadow-lg text-sm z-50",s.value.type==="error"?"bg-red-500 text-white":"bg-green-500 text-white"])},H(s.value.msg),3)):pe("",!0)]))}},u0=[{path:"/login",name:"login",component:yp,meta:{title:"登录"}},{path:"/",component:pp,children:[{path:"",name:"dashboard",component:eg,meta:{title:"概览"}},{path:"sources",name:"sources",component:uy,meta:{title:"订阅源"}},{path:"collections",name:"collections",component:ib,meta:{title:"合集"}},{path:"templates",name:"templates",component:Cb,meta:{title:"模板"}},{path:"recycle-bin",name:"recycle-bin",component:Ub,meta:{title:"回收站"}},{path:"tools",name:"tools",component:n0,meta:{title:"工具"}},{path:"settings",name:"settings",component:c0,meta:{title:"设置"}}]},{path:"/:pathMatch(.*)*",name:"not-found",component:xp}],dc=Qd({history:Pd(),routes:u0});dc.beforeEach((e,t,n)=>{if(e.name==="login"||e.name==="not-found")return n();const s=xo(),r=Ua(),o=np();if(!s||!r||!o)return n({name:"login",query:{redirect:e.fullPath}});n()});const To=Bf(Wf);To.use(Kf());To.use(dc);To.mount("#app"); diff --git a/frontend/dist/assets/index-CgvGHl8V.js b/frontend/dist/assets/index-CgvGHl8V.js new file mode 100644 index 0000000..7585a91 --- /dev/null +++ b/frontend/dist/assets/index-CgvGHl8V.js @@ -0,0 +1,37 @@ +(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))s(r);new MutationObserver(r=>{for(const o of r)if(o.type==="childList")for(const i of o.addedNodes)i.tagName==="LINK"&&i.rel==="modulepreload"&&s(i)}).observe(document,{childList:!0,subtree:!0});function n(r){const o={};return r.integrity&&(o.integrity=r.integrity),r.referrerPolicy&&(o.referrerPolicy=r.referrerPolicy),r.crossOrigin==="use-credentials"?o.credentials="include":r.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function s(r){if(r.ep)return;r.ep=!0;const o=n(r);fetch(r.href,o)}})();/** +* @vue/shared v3.5.40 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/function Gr(e){const t=Object.create(null);for(const n of e.split(","))t[n]=1;return n=>n in t}const Ce={},xn=[],Ct=()=>{},sl=()=>!1,Fs=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),Ms=e=>e.startsWith("onUpdate:"),Ue=Object.assign,Jr=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},pu=Object.prototype.hasOwnProperty,_e=(e,t)=>pu.call(e,t),ne=Array.isArray,vn=e=>ls(e)==="[object Map]",Nn=e=>ls(e)==="[object Set]",ko=e=>ls(e)==="[object Date]",le=e=>typeof e=="function",Pe=e=>typeof e=="string",ht=e=>typeof e=="symbol",Ee=e=>e!==null&&typeof e=="object",rl=e=>(Ee(e)||le(e))&&le(e.then)&&le(e.catch),ol=Object.prototype.toString,ls=e=>ol.call(e),hu=e=>ls(e).slice(8,-1),il=e=>ls(e)==="[object Object]",Xr=e=>Pe(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,Hn=Gr(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Vs=e=>{const t=Object.create(null);return(n=>t[n]||(t[n]=e(n)))},mu=/-\w/g,et=Vs(e=>e.replace(mu,t=>t.slice(1).toUpperCase())),gu=/\B([A-Z])/g,Xt=Vs(e=>e.replace(gu,"-$1").toLowerCase()),Bs=Vs(e=>e.charAt(0).toUpperCase()+e.slice(1)),sr=Vs(e=>e?`on${Bs(e)}`:""),Rt=(e,t)=>!Object.is(e,t),xs=(e,...t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:s,value:n})},js=e=>{const t=parseFloat(e);return isNaN(t)?e:t},yu=e=>{const t=Pe(e)?Number(e):NaN;return isNaN(t)?e:t};let $o;const Hs=()=>$o||($o=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function Yr(e){if(ne(e)){const t={};for(let n=0;n{if(n){const s=n.split(xu);s.length>1&&(t[s[0].trim()]=s[1].trim())}}),t}function Fe(e){let t="";if(Pe(e))t=e;else if(ne(e))for(let n=0;nzt(n,t))}const ul=e=>!!(e&&e.__v_isRef===!0),j=e=>Pe(e)?e:e==null?"":ne(e)||Ee(e)&&(e.toString===ol||!le(e.toString))?ul(e)?j(e.value):JSON.stringify(e,cl,2):String(e),cl=(e,t)=>ul(t)?cl(e,t.value):vn(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((n,[s,r],o)=>(n[rr(s,o)+" =>"]=r,n),{})}:Nn(t)?{[`Set(${t.size})`]:[...t.values()].map(n=>rr(n))}:ht(t)?rr(t):Ee(t)&&!ne(t)&&!il(t)?String(t):t,rr=(e,t="")=>{var n;return ht(e)?`Symbol(${(n=e.description)!=null?n:t})`:e};/** +* @vue/reactivity v3.5.40 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/let Ve;class fl{constructor(t=!1){this.detached=t,this._active=!0,this._on=0,this.effects=[],this.cleanups=[],this._isPaused=!1,this._warnOnRun=!0,this.__v_skip=!0,!t&&Ve&&(Ve.active?(this.parent=Ve,this.index=(Ve.scopes||(Ve.scopes=[])).push(this)-1):(this._active=!1,this._warnOnRun=!1))}get active(){return this._active}pause(){if(this._active){this._isPaused=!0;let t,n;if(this.scopes){const s=this.scopes.slice();for(t=0,n=s.length;t0&&--this._on===0){if(Ve===this)Ve=this.prevScope;else{let t=Ve;for(;t;){if(t.prevScope===this){t.prevScope=this.prevScope;break}t=t.prevScope}}this.prevScope=void 0}}stop(t){if(this._active){this._active=!1;let n,s;for(n=0,s=this.effects.length;n0)return;if(Kn){let t=Kn;for(Kn=void 0;t;){const n=t.next;t.next=void 0,t.flags&=-9,t=n}}let e;for(;qn;){let t=qn;for(qn=void 0;t;){const n=t.next;if(t.next=void 0,t.flags&=-9,t.flags&1)try{t.trigger()}catch(s){e||(e=s)}t=n}}if(e)throw e}function ml(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function gl(e){let t,n=e.depsTail,s=n;for(;s;){const r=s.prevDep;s.version===-1?(s===n&&(n=r),to(s),Au(s)):t=s,s.dep.activeLink=s.prevActiveLink,s.prevActiveLink=void 0,s=r}e.deps=t,e.depsTail=n}function Rr(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&(yl(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function yl(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===Jn)||(e.globalVersion=Jn,!e.isSSR&&e.flags&128&&(!e.deps&&!e._dirty||!Rr(e))))return;e.flags|=2;const t=e.dep,n=Ae,s=ft;Ae=e,ft=!0;try{ml(e);const r=e.fn(e._value);(t.version===0||Rt(r,e._value))&&(e.flags|=128,e._value=r,t.version++)}catch(r){throw t.version++,r}finally{Ae=n,ft=s,gl(e),e.flags&=-3}}function to(e,t=!1){const{dep:n,prevSub:s,nextSub:r}=e;if(s&&(s.nextSub=r,e.prevSub=void 0),r&&(r.prevSub=s,e.nextSub=void 0),n.subs===e&&(n.subs=s,!s&&n.computed)){n.computed.flags&=-5;for(let o=n.computed.deps;o;o=o.nextDep)to(o,!0)}!t&&!--n.sc&&n.map&&n.map.delete(n.key)}function Au(e){const{prevDep:t,nextDep:n}=e;t&&(t.nextDep=n,e.prevDep=void 0),n&&(n.prevDep=t,e.nextDep=void 0)}let ft=!0;const bl=[];function Ut(){bl.push(ft),ft=!1}function Ft(){const e=bl.pop();ft=e===void 0?!0:e}function Do(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const n=Ae;Ae=void 0;try{t()}finally{Ae=n}}}let Jn=0;class Ou{constructor(t,n){this.sub=t,this.dep=n,this.version=n.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}}class no{constructor(t){this.computed=t,this.version=0,this.activeLink=void 0,this.subs=void 0,this.map=void 0,this.key=void 0,this.sc=0,this.__v_skip=!0}track(t){if(!Ae||!ft||Ae===this.computed)return;let n=this.activeLink;if(n===void 0||n.sub!==Ae)n=this.activeLink=new Ou(Ae,this),Ae.deps?(n.prevDep=Ae.depsTail,Ae.depsTail.nextDep=n,Ae.depsTail=n):Ae.deps=Ae.depsTail=n,xl(n);else if(n.version===-1&&(n.version=this.version,n.nextDep)){const s=n.nextDep;s.prevDep=n.prevDep,n.prevDep&&(n.prevDep.nextDep=s),n.prevDep=Ae.depsTail,n.nextDep=void 0,Ae.depsTail.nextDep=n,Ae.depsTail=n,Ae.deps===n&&(Ae.deps=s)}return n}trigger(t){this.version++,Jn++,this.notify(t)}notify(t){Zr();try{for(let n=this.subs;n;n=n.prevSub)n.sub.notify()&&n.sub.dep.notify()}finally{eo()}}}function xl(e){if(e.dep.sc++,e.sub.flags&4){const t=e.dep.computed;if(t&&!e.dep.subs){t.flags|=20;for(let s=t.deps;s;s=s.nextDep)xl(s)}const n=e.dep.subs;n!==e&&(e.prevSub=n,n&&(n.nextSub=e)),e.dep.subs=e}}const Cr=new WeakMap,an=Symbol(""),Ar=Symbol(""),Xn=Symbol("");function Ke(e,t,n){if(ft&&Ae){let s=Cr.get(e);s||Cr.set(e,s=new Map);let r=s.get(n);r||(s.set(n,r=new no),r.map=s,r.key=n),r.track()}}function kt(e,t,n,s,r,o){const i=Cr.get(e);if(!i){Jn++;return}const l=a=>{a&&a.trigger()};if(Zr(),t==="clear")i.forEach(l);else{const a=ne(e),c=a&&Xr(n);if(a&&n==="length"){const u=Number(s);i.forEach((f,h)=>{(h==="length"||h===Xn||!ht(h)&&h>=u)&&l(f)})}else switch((n!==void 0||i.has(void 0))&&l(i.get(n)),c&&l(i.get(Xn)),t){case"add":a?c&&l(i.get("length")):(l(i.get(an)),vn(e)&&l(i.get(Ar)));break;case"delete":a||(l(i.get(an)),vn(e)&&l(i.get(Ar)));break;case"set":vn(e)&&l(i.get(an));break}}eo()}function hn(e){const t=xe(e);return t===e?t:(Ke(t,"iterate",Xn),lt(e)?t:t.map(mt))}function qs(e){return Ke(e=xe(e),"iterate",Xn),e}function Et(e,t){return Mt(e)?Rn(un(e)?mt(t):t):mt(t)}const Tu={__proto__:null,[Symbol.iterator](){return ir(this,Symbol.iterator,e=>Et(this,e))},concat(...e){return hn(this).concat(...e.map(t=>ne(t)?hn(t):t))},entries(){return ir(this,"entries",e=>(e[1]=Et(this,e[1]),e))},every(e,t){return Ot(this,"every",e,t,void 0,arguments)},filter(e,t){return Ot(this,"filter",e,t,n=>n.map(s=>Et(this,s)),arguments)},find(e,t){return Ot(this,"find",e,t,n=>Et(this,n),arguments)},findIndex(e,t){return Ot(this,"findIndex",e,t,void 0,arguments)},findLast(e,t){return Ot(this,"findLast",e,t,n=>Et(this,n),arguments)},findLastIndex(e,t){return Ot(this,"findLastIndex",e,t,void 0,arguments)},forEach(e,t){return Ot(this,"forEach",e,t,void 0,arguments)},includes(...e){return lr(this,"includes",e)},indexOf(...e){return lr(this,"indexOf",e)},join(e){return hn(this).join(e)},lastIndexOf(...e){return lr(this,"lastIndexOf",e)},map(e,t){return Ot(this,"map",e,t,void 0,arguments)},pop(){return Dn(this,"pop")},push(...e){return Dn(this,"push",e)},reduce(e,...t){return Lo(this,"reduce",e,t)},reduceRight(e,...t){return Lo(this,"reduceRight",e,t)},shift(){return Dn(this,"shift")},some(e,t){return Ot(this,"some",e,t,void 0,arguments)},splice(...e){return Dn(this,"splice",e)},toReversed(){return hn(this).toReversed()},toSorted(e){return hn(this).toSorted(e)},toSpliced(...e){return hn(this).toSpliced(...e)},unshift(...e){return Dn(this,"unshift",e)},values(){return ir(this,"values",e=>Et(this,e))}};function ir(e,t,n){const s=qs(e),r=s[t]();return s!==e&&!lt(e)&&(r._next=r.next,r.next=()=>{const o=r._next();return o.done||(o.value=n(o.value)),o}),r}const Pu=Array.prototype;function Ot(e,t,n,s,r,o){const i=qs(e),l=i!==e&&!lt(e),a=i[t];if(a!==Pu[t]){const f=a.apply(e,o);return l?mt(f):f}let c=n;i!==e&&(l?c=function(f,h){return n.call(this,Et(e,f),h,e)}:n.length>2&&(c=function(f,h){return n.call(this,f,h,e)}));const u=a.call(i,c,s);return l&&r?r(u):u}function Lo(e,t,n,s){const r=qs(e),o=r!==e&&!lt(e);let i=n,l=!1;r!==e&&(o?(l=s.length===0,i=function(c,u,f){return l&&(l=!1,c=Et(e,c)),n.call(this,c,Et(e,u),f,e)}):n.length>3&&(i=function(c,u,f){return n.call(this,c,u,f,e)}));const a=r[t](i,...s);return l?Et(e,a):a}function lr(e,t,n){const s=xe(e);Ke(s,"iterate",Xn);const r=s[t](...n);return(r===-1||r===!1)&&oo(n[0])?(n[0]=xe(n[0]),s[t](...n)):r}function Dn(e,t,n=[]){Ut(),Zr();const s=xe(e)[t].apply(e,n);return eo(),Ft(),s}const Nu=Gr("__proto__,__v_isRef,__isVue"),vl=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(ht));function Iu(e){ht(e)||(e=String(e));const t=xe(this);return Ke(t,"has",e),t.hasOwnProperty(e)}class _l{constructor(t=!1,n=!1){this._isReadonly=t,this._isShallow=n}get(t,n,s){if(n==="__v_skip")return t.__v_skip;const r=this._isReadonly,o=this._isShallow;if(n==="__v_isReactive")return!r;if(n==="__v_isReadonly")return r;if(n==="__v_isShallow")return o;if(n==="__v_raw")return s===(r?o?ju:Rl:o?Sl:El).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(s)?t:void 0;const i=ne(t);if(!r){let a;if(i&&(a=Tu[n]))return a;if(n==="hasOwnProperty")return Iu}const l=Reflect.get(t,n,Ge(t)?t:s);if((ht(n)?vl.has(n):Nu(n))||(r||Ke(t,"get",n),o))return l;if(Ge(l)){const a=i&&Xr(n)?l:l.value;return r&&Ee(a)?Tr(a):a}return Ee(l)?r?Tr(l):At(l):l}}class wl extends _l{constructor(t=!1){super(!1,t)}set(t,n,s,r){let o=t[n];const i=ne(t)&&Xr(n);if(!this._isShallow){const c=Mt(o);if(!lt(s)&&!Mt(s)&&(o=xe(o),s=xe(s)),!i&&Ge(o)&&!Ge(s))return c||(o.value=s),!0}const l=i?Number(n)e,hs=e=>Reflect.getPrototypeOf(e);function Uu(e,t,n){return function(...s){const r=this.__v_raw,o=xe(r),i=vn(o),l=e==="entries"||e===Symbol.iterator&&i,a=e==="keys"&&i,c=r[e](...s),u=n?Or:t?Rn:mt;return!t&&Ke(o,"iterate",a?Ar:an),Ue(Object.create(c),{next(){const{value:f,done:h}=c.next();return h?{value:f,done:h}:{value:l?[u(f[0]),u(f[1])]:u(f),done:h}}})}}function ms(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function Fu(e,t){const n={get(r){const o=this.__v_raw,i=xe(o),l=xe(r);e||(Rt(r,l)&&Ke(i,"get",r),Ke(i,"get",l));const{has:a}=hs(i),c=t?Or:e?Rn:mt;if(a.call(i,r))return c(o.get(r));if(a.call(i,l))return c(o.get(l));o!==i&&o.get(r)},get size(){const r=this.__v_raw;return!e&&Ke(xe(r),"iterate",an),r.size},has(r){const o=this.__v_raw,i=xe(o),l=xe(r);return e||(Rt(r,l)&&Ke(i,"has",r),Ke(i,"has",l)),r===l?o.has(r):o.has(r)||o.has(l)},forEach(r,o){const i=this,l=i.__v_raw,a=xe(l),c=t?Or:e?Rn:mt;return!e&&Ke(a,"iterate",an),l.forEach((u,f)=>r.call(o,c(u),c(f),i))}};return Ue(n,e?{add:ms("add"),set:ms("set"),delete:ms("delete"),clear:ms("clear")}:{add(r){const o=xe(this),i=hs(o),l=xe(r),a=!t&&!lt(r)&&!Mt(r)?l:r;return i.has.call(o,a)||Rt(r,a)&&i.has.call(o,r)||Rt(l,a)&&i.has.call(o,l)||(o.add(a),kt(o,"add",a,a)),this},set(r,o){!t&&!lt(o)&&!Mt(o)&&(o=xe(o));const i=xe(this),{has:l,get:a}=hs(i);let c=l.call(i,r);c||(r=xe(r),c=l.call(i,r));const u=a.call(i,r);return i.set(r,o),c?Rt(o,u)&&kt(i,"set",r,o):kt(i,"add",r,o),this},delete(r){const o=xe(this),{has:i,get:l}=hs(o);let a=i.call(o,r);a||(r=xe(r),a=i.call(o,r)),l&&l.call(o,r);const c=o.delete(r);return a&&kt(o,"delete",r,void 0),c},clear(){const r=xe(this),o=r.size!==0,i=r.clear();return o&&kt(r,"clear",void 0,void 0),i}}),["keys","values","entries",Symbol.iterator].forEach(r=>{n[r]=Uu(r,e,t)}),n}function so(e,t){const n=Fu(e,t);return(s,r,o)=>r==="__v_isReactive"?!e:r==="__v_isReadonly"?e:r==="__v_raw"?s:Reflect.get(_e(n,r)&&r in s?n:s,r,o)}const Mu={get:so(!1,!1)},Vu={get:so(!1,!0)},Bu={get:so(!0,!1)};const El=new WeakMap,Sl=new WeakMap,Rl=new WeakMap,ju=new WeakMap;function Hu(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function At(e){return Mt(e)?e:ro(e,!1,$u,Mu,El)}function Cl(e){return ro(e,!1,Lu,Vu,Sl)}function Tr(e){return ro(e,!0,Du,Bu,Rl)}function ro(e,t,n,s,r){if(!Ee(e)||e.__v_raw&&!(t&&e.__v_isReactive)||e.__v_skip||!Object.isExtensible(e))return e;const o=r.get(e);if(o)return o;const i=Hu(hu(e));if(i===0)return e;const l=new Proxy(e,i===2?s:n);return r.set(e,l),l}function un(e){return Mt(e)?un(e.__v_raw):!!(e&&e.__v_isReactive)}function Mt(e){return!!(e&&e.__v_isReadonly)}function lt(e){return!!(e&&e.__v_isShallow)}function oo(e){return e?!!e.__v_raw:!1}function xe(e){const t=e&&e.__v_raw;return t?xe(t):e}function Al(e){return!_e(e,"__v_skip")&&Object.isExtensible(e)&&ll(e,"__v_skip",!0),e}const mt=e=>Ee(e)?At(e):e,Rn=e=>Ee(e)?Tr(e):e;function Ge(e){return e?e.__v_isRef===!0:!1}function Z(e){return Ol(e,!1)}function qu(e){return Ol(e,!0)}function Ol(e,t){return Ge(e)?e:new Ku(e,t)}class Ku{constructor(t,n){this.dep=new no,this.__v_isRef=!0,this.__v_isShallow=!1,this._rawValue=n?t:xe(t),this._value=n?t:mt(t),this.__v_isShallow=n}get value(){return this.dep.track(),this._value}set value(t){const n=this._rawValue,s=this.__v_isShallow||lt(t)||Mt(t);t=s?t:xe(t),Rt(t,n)&&(this._rawValue=t,this._value=s?t:mt(t),this.dep.trigger())}}function _n(e){return Ge(e)?e.value:e}const Wu={get:(e,t,n)=>t==="__v_raw"?e:_n(Reflect.get(e,t,n)),set:(e,t,n,s)=>{const r=e[t];return Ge(r)&&!Ge(n)?(r.value=n,!0):Reflect.set(e,t,n,s)}};function Tl(e){return un(e)?e:new Proxy(e,Wu)}class zu{constructor(t,n,s){this.fn=t,this.setter=n,this._value=void 0,this.dep=new no(this),this.__v_isRef=!0,this.deps=void 0,this.depsTail=void 0,this.flags=16,this.globalVersion=Jn-1,this.next=void 0,this.effect=this,this.__v_isReadonly=!n,this.isSSR=s}notify(){if(this.flags|=16,!(this.flags&8)&&Ae!==this)return hl(this,!0),!0}get value(){const t=this.dep.track();return yl(this),t&&(t.version=this.dep.version),this._value}set value(t){this.setter&&this.setter(t)}}function Gu(e,t,n=!1){let s,r;return le(e)?s=e:(s=e.get,r=e.set),new zu(s,r,n)}const gs={},Cs=new WeakMap;let nn;function Ju(e,t=!1,n=nn){if(n){let s=Cs.get(n);s||Cs.set(n,s=[]),s.push(e)}}function Xu(e,t,n=Ce){const{immediate:s,deep:r,once:o,scheduler:i,augmentJob:l,call:a}=n,c=E=>r?E:lt(E)||r===!1||r===0?$t(E,1):$t(E);let u,f,h,m,R=!1,C=!1;if(Ge(e)?(f=()=>e.value,R=lt(e)):un(e)?(f=()=>c(e),R=!0):ne(e)?(C=!0,R=e.some(E=>un(E)||lt(E)),f=()=>e.map(E=>{if(Ge(E))return E.value;if(un(E))return c(E);if(le(E))return a?a(E,2):E()})):le(e)?t?f=a?()=>a(e,2):e:f=()=>{if(h){Ut();try{h()}finally{Ft()}}const E=nn;nn=u;try{return a?a(e,3,[m]):e(m)}finally{nn=E}}:f=Ct,t&&r){const E=f,O=r===!0?1/0:r;f=()=>$t(E(),O)}const P=Cu(),_=()=>{u.stop(),P&&P.active&&Jr(P.effects,u)};if(o&&t){const E=t;t=(...O)=>{const D=E(...O);return _(),D}}let b=C?new Array(e.length).fill(gs):gs;const A=E=>{if(!(!(u.flags&1)||!u.dirty&&!E))if(t){const O=u.run();if(E||r||R||(C?O.some((D,L)=>Rt(D,b[L])):Rt(O,b))){h&&h();const D=nn;nn=u;try{const L=[O,b===gs?void 0:C&&b[0]===gs?[]:b,m];b=O,a?a(t,3,L):t(...L)}finally{nn=D}}}else u.run()};return l&&l(A),u=new dl(f),u.scheduler=i?()=>i(A,!1):A,m=E=>Ju(E,!1,u),h=u.onStop=()=>{const E=Cs.get(u);if(E){if(a)a(E,4);else for(const O of E)O();Cs.delete(u)}},t?s?A(!0):b=u.run():i?i(A.bind(null,!0),!0):u.run(),_.pause=u.pause.bind(u),_.resume=u.resume.bind(u),_.stop=_,_}function $t(e,t=1/0,n){if(t<=0||!Ee(e)||e.__v_skip||(n=n||new Map,(n.get(e)||0)>=t))return e;if(n.set(e,t),t--,Ge(e))$t(e.value,t,n);else if(ne(e))for(let s=0;s{$t(s,t,n)});else if(il(e)){for(const s in e)$t(e[s],t,n);for(const s of Object.getOwnPropertySymbols(e))Object.prototype.propertyIsEnumerable.call(e,s)&&$t(e[s],t,n)}return e}/** +* @vue/runtime-core v3.5.40 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/function as(e,t,n,s){try{return s?e(...s):e()}catch(r){Ks(r,t,n)}}function ut(e,t,n,s){if(le(e)){const r=as(e,t,n,s);return r&&rl(r)&&r.catch(o=>{Ks(o,t,n)}),r}if(ne(e)){const r=[];for(let o=0;o>>1,r=Ze[s],o=Yn(r);o=Yn(n)?Ze.push(e):Ze.splice(Qu(t),0,e),e.flags|=1,Nl()}}function Nl(){As||(As=Pl.then(kl))}function Zu(e){ne(e)?wn.push(...e):qt&&e.id===-1?qt.splice(gn+1,0,e):e.flags&1||(wn.push(e),e.flags|=1),Nl()}function Uo(e,t,n=wt+1){for(;nYn(n)-Yn(s));if(wn.length=0,qt){qt.push(...t);return}for(qt=t,gn=0;gne.id==null?e.flags&2?-1:1/0:e.id;function kl(e){try{for(wt=0;wt{s._d&&Ns(-1);const o=Os(t),i=Lt.length;let l;try{l=e(...r)}finally{for(let a=Lt.length;a>i;a--)fo();Os(o),s._d&&Ns(1)}return l};return s._n=!0,s._c=!0,s._d=!0,s}function ye(e,t){if(He===null)return e;const n=Xs(He),s=e.dirs||(e.dirs=[]);for(let r=0;r1)return n&&le(t)?t.call(s&&s.proxy):t}}const ec=Symbol.for("v-scx"),tc=()=>pt(ec);function _s(e,t,n){return Dl(e,t,n)}function Dl(e,t,n=Ce){const{immediate:s,deep:r,flush:o,once:i}=n,l=Ue({},n),a=t&&s||!t&&o!=="post";let c;if(ts){if(o==="sync"){const m=tc();c=m.__watcherHandles||(m.__watcherHandles=[])}else if(!a){const m=()=>{};return m.stop=Ct,m.resume=Ct,m.pause=Ct,m}}const u=ze;l.call=(m,R,C)=>ut(m,u,R,C);let f=!1;o==="post"?l.scheduler=m=>{Ye(m,u&&u.suspense)}:o!=="sync"&&(f=!0,l.scheduler=(m,R)=>{R?m():lo(m)}),l.augmentJob=m=>{t&&(m.flags|=4),f&&(m.flags|=2,u&&(m.id=u.uid,m.i=u))};const h=Xu(e,t,l);return ts&&(c?c.push(h):a&&h()),h}function nc(e,t,n){const s=this.proxy,r=Pe(e)?e.includes(".")?Ll(s,e):()=>s[e]:e.bind(s,s);let o;le(t)?o=t:(o=t.handler,n=t);const i=us(this),l=Dl(r,o.bind(s),n);return i(),l}function Ll(e,t){const n=t.split(".");return()=>{let s=e;for(let r=0;re.__isTeleport,sn=e=>e&&(e.disabled||e.disabled===""),sc=e=>e&&(e.defer||e.defer===""),Fo=e=>typeof SVGElement<"u"&&e instanceof SVGElement,Mo=e=>typeof MathMLElement=="function"&&e instanceof MathMLElement,Pr=(e,t)=>{const n=e&&e.to;return Pe(n)?t?t(n):null:n},rc={name:"Teleport",__isTeleport:!0,process(e,t,n,s,r,o,i,l,a,c){const{mc:u,pc:f,pbc:h,o:{insert:m,querySelector:R,createText:C,createComment:P,parentNode:_}}=c,b=sn(t.props);let{dynamicChildren:A}=t;const E=(L,ae,Y)=>{L.shapeFlag&16&&u(L.children,ae,Y,r,o,i,l,a)},O=(L=t)=>{const ae=sn(L.props),Y=L.target=Pr(L.props,R),se=Nr(Y,L,C,m);Y&&(i!=="svg"&&Fo(Y)?i="svg":i!=="mathml"&&Mo(Y)&&(i="mathml"),r&&r.isCE&&(r.ce._teleportTargets||(r.ce._teleportTargets=new Set)).add(Y),ae||(E(L,Y,se),Vn(L,!1)))},D=L=>{const ae=()=>{if(Ht.get(L)===ae){if(Ht.delete(L),sn(L.props)){const Y=_(L.el)||n;E(L,Y,L.anchor),Vn(L,!0)}O(L)}};Ht.set(L,ae),Ye(ae,o)};if(e==null){const L=t.el=C(""),ae=t.anchor=C("");if(m(L,n,s),m(ae,n,s),sc(t.props)||o&&o.pendingBranch){D(t);return}b&&(E(t,n,ae),Vn(t,!0)),O()}else{t.el=e.el;const L=t.anchor=e.anchor,ae=Ht.get(e);if(ae){ae.flags|=8,Ht.delete(e),D(t);return}t.targetStart=e.targetStart;const Y=t.target=e.target,se=t.targetAnchor=e.targetAnchor,oe=sn(e.props),W=oe?n:Y,ue=oe?L:se;if(i==="svg"||Fo(Y)?i="svg":(i==="mathml"||Mo(Y))&&(i="mathml"),A?(h(e.dynamicChildren,A,W,r,o,i,l),co(e,t,!0)):a||f(e,t,W,ue,r,o,i,l,!1),b)oe?t.props&&e.props&&t.props.to!==e.props.to&&(t.props.to=e.props.to):ys(t,n,L,c,1);else if((t.props&&t.props.to)!==(e.props&&e.props.to)){const fe=Pr(t.props,R);fe&&(t.target=fe,ys(t,fe,null,c,0))}else oe&&ys(t,Y,se,c,1);Vn(t,b)}},remove(e,t,n,{um:s,o:{remove:r}},o){const{shapeFlag:i,children:l,anchor:a,targetStart:c,targetAnchor:u,target:f,props:h}=e,m=sn(h),R=o||!m,C=Ht.get(e);if(C&&(C.flags|=8,Ht.delete(e)),f&&(r(c),r(u)),o&&r(a),!C&&(m||f)&&i&16)for(let P=0;P{e.isMounted=!0}),Gl(()=>{e.isUnmounting=!0}),e}const ot=[Function,Array],Vl={mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:ot,onEnter:ot,onAfterEnter:ot,onEnterCancelled:ot,onBeforeLeave:ot,onLeave:ot,onAfterLeave:ot,onLeaveCancelled:ot,onBeforeAppear:ot,onAppear:ot,onAfterAppear:ot,onAppearCancelled:ot},Bl=e=>{const t=e.subTree;return t.component?Bl(t.component):t},lc={name:"BaseTransition",props:Vl,setup(e,{slots:t}){const n=ba(),s=ic();return()=>{const r=t.default&&ql(t.default(),!0),o=r&&r.length?jl(r):n.subTree?ce():void 0;if(!o)return;const i=xe(e),{mode:l}=i;if(s.isLeaving)return ar(o);const a=Vo(o);if(!a)return ar(o);let c=Ir(a,i,s,n,f=>c=f);a.type!==We&&Qn(a,c);let u=n.subTree&&Vo(n.subTree);if(u&&u.type!==We&&!rn(u,a)&&Bl(n).type!==We){let f=Ir(u,i,s,n);if(Qn(u,f),l==="out-in"&&a.type!==We)return s.isLeaving=!0,f.afterLeave=()=>{s.isLeaving=!1,n.job.flags&8||n.update(),delete f.afterLeave,u=void 0},ar(o);l==="in-out"&&a.type!==We?f.delayLeave=(h,m,R)=>{const C=Hl(s,u);C[String(u.key)]=u,h[it]=()=>{m(),h[it]=void 0,delete c.delayedLeave,u=void 0},c.delayedLeave=()=>{R(),delete c.delayedLeave,u=void 0}}:u=void 0}else u&&(u=void 0);return o}}};function jl(e){let t=e[0];if(e.length>1){for(const n of e)if(n.type!==We){t=n;break}}return t}const ac=lc;function Hl(e,t){const{leavingVNodes:n}=e;let s=n.get(t.type);return s||(s=Object.create(null),n.set(t.type,s)),s}function Ir(e,t,n,s,r){const{appear:o,mode:i,persisted:l=!1,onBeforeEnter:a,onEnter:c,onAfterEnter:u,onEnterCancelled:f,onBeforeLeave:h,onLeave:m,onAfterLeave:R,onLeaveCancelled:C,onBeforeAppear:P,onAppear:_,onAfterAppear:b,onAppearCancelled:A}=t,E=String(e.key),O=Hl(n,e),D=(Y,se)=>{Y&&ut(Y,s,9,se)},L=(Y,se)=>{const oe=se[1];D(Y,se),ne(Y)?Y.every(W=>W.length<=1)&&oe():Y.length<=1&&oe()},ae={mode:i,persisted:l,beforeEnter(Y){let se=a;if(!n.isMounted)if(o)se=P||a;else return;Y[it]&&Y[it](!0);const oe=O[E];oe&&rn(e,oe)&&oe.el[it]&&oe.el[it](),D(se,[Y])},enter(Y){if(O[E]===e)return;let se=c,oe=u,W=f;if(!n.isMounted)if(o)se=_||c,oe=b||u,W=A||f;else return;let ue=!1;Y[Ln]=Ne=>{ue||(ue=!0,Ne?D(W,[Y]):D(oe,[Y]),ae.delayedLeave&&ae.delayedLeave(),Y[Ln]=void 0)};const fe=Y[Ln].bind(null,!1);se?L(se,[Y,fe]):fe()},leave(Y,se){const oe=String(e.key);if(Y[Ln]&&Y[Ln](!0),n.isUnmounting)return se();D(h,[Y]);let W=!1;Y[it]=fe=>{W||(W=!0,se(),fe?D(C,[Y]):D(R,[Y]),Y[it]=void 0,O[oe]===e&&delete O[oe])};const ue=Y[it].bind(null,!1);O[oe]=e,m?L(m,[Y,ue]):ue()},clone(Y){const se=Ir(Y,t,n,s,r);return r&&r(se),se}};return ae}function ar(e){if(Ws(e))return e=Gt(e),e.children=null,e}function Vo(e){if(!Ws(e))return Fl(e.type)&&e.children?jl(e.children):e;if(e.component)return e.component.subTree;const{shapeFlag:t,children:n}=e;if(n){if(t&16)return n[0];if(t&32&&le(n.default))return n.default()}}function Qn(e,t){e.shapeFlag&6&&e.component?(e.transition=t,Qn(e.component.subTree,t)):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function ql(e,t=!1,n){let s=[],r=0;for(let o=0;o1)for(let o=0;oWn(C,t&&(ne(t)?t[P]:t),n,s,r));return}if(En(s)&&!r){s.shapeFlag&512&&s.type.__asyncResolved&&s.component.subTree.component&&Wn(e,t,n,s.component.subTree);return}const o=s.shapeFlag&4?Xs(s.component):s.el,i=r?null:o,{i:l,r:a}=e,c=t&&t.r,u=l.refs===Ce?l.refs={}:l.refs,f=l.setupState,h=xe(f),m=f===Ce?sl:C=>Bo(u,C)?!1:_e(h,C),R=(C,P)=>!(P&&Bo(u,P));if(c!=null&&c!==a){if(jo(t),Pe(c))u[c]=null,m(c)&&(f[c]=null);else if(Ge(c)){const C=t;R(c,C.k)&&(c.value=null),C.k&&(u[C.k]=null)}}if(le(a))as(a,l,12,[i,u]);else{const C=Pe(a),P=Ge(a);if(C||P){const _=()=>{if(e.f){const b=C?m(a)?f[a]:u[a]:R()||!e.k?a.value:u[e.k];if(r)ne(b)&&Jr(b,o);else if(ne(b))b.includes(o)||b.push(o);else if(C)u[a]=[o],m(a)&&(f[a]=u[a]);else{const A=[o];R(a,e.k)&&(a.value=A),e.k&&(u[e.k]=A)}}else C?(u[a]=i,m(a)&&(f[a]=i)):P&&(R(a,e.k)&&(a.value=i),e.k&&(u[e.k]=i))};if(i){const b=()=>{_(),Ts.delete(e)};b.id=-1,Ts.set(e,b),Ye(b,n)}else jo(e),_()}}}function jo(e){const t=Ts.get(e);t&&(t.flags|=8,Ts.delete(e))}Hs().requestIdleCallback;Hs().cancelIdleCallback;const En=e=>!!e.type.__asyncLoader,Ws=e=>e.type.__isKeepAlive;function uc(e,t){zl(e,"a",t)}function cc(e,t){zl(e,"da",t)}function zl(e,t,n=ze){const s=e.__wdc||(e.__wdc=()=>{let r=n;for(;r;){if(r.isDeactivated)return;r=r.parent}return e()});if(zs(t,s,n),n){let r=n.parent;for(;r&&r.parent;)Ws(r.parent.vnode)&&fc(s,t,n,r),r=r.parent}}function fc(e,t,n,s){const r=zs(t,e,s,!0);Jl(()=>{Jr(s[t],r)},n)}function zs(e,t,n=ze,s=!1){if(n){const r=n[e]||(n[e]=[]),o=t.__weh||(t.__weh=(...i)=>{Ut();const l=us(n),a=ut(t,n,e,i);return l(),Ft(),a});return s?r.unshift(o):r.push(o),o}}const Vt=e=>(t,n=ze)=>{(!ts||e==="sp")&&zs(e,(...s)=>t(...s),n)},dc=Vt("bm"),Yt=Vt("m"),pc=Vt("bu"),hc=Vt("u"),Gl=Vt("bum"),Jl=Vt("um"),mc=Vt("sp"),gc=Vt("rtg"),yc=Vt("rtc");function bc(e,t=ze){zs("ec",e,t)}const Xl="components";function kr(e,t){return Ql(Xl,e,!0,t)||e}const Yl=Symbol.for("v-ndc");function xc(e){return Pe(e)?Ql(Xl,e,!1)||e:e||Yl}function Ql(e,t,n=!0,s=!1){const r=He||ze;if(r){const o=r.type;{const l=nf(o,!1);if(l&&(l===t||l===et(t)||l===Bs(et(t))))return o}const i=Ho(r[e]||o[e],t)||Ho(r.appContext[e],t);return!i&&s?o:i}}function Ho(e,t){return e&&(e[t]||e[et(t)]||e[Bs(et(t))])}function Be(e,t,n,s){let r;const o=n,i=ne(e);if(i||Pe(e)){const l=i&&un(e);let a=!1,c=!1;l&&(a=!lt(e),c=Mt(e),e=qs(e)),r=new Array(e.length);for(let u=0,f=e.length;ut(l,a,void 0,o));else{const l=Object.keys(e);r=new Array(l.length);for(let a=0,c=l.length;a0;return t!=="default"&&(c.name=t),F(),fn(we,null,[Te("slot",c,s)],u?-2:64)}let i=e[t];i&&i._c&&(i._d=!1);const l=Lt.length;F();let a;try{const c=i&&Zl(i(n)),u=n.key||o||c&&c.key;a=fn(we,{key:(u&&!ht(u)?u:`_${t}`)+(!c&&s?"_fb":"")},c||(s?s():[]),c&&e._===1?64:-2)}catch(c){for(let u=Lt.length;u>l;u--)fo();throw c}finally{i&&i._c&&(i._d=!0)}return a.scopeId&&(a.slotScopeIds=[a.scopeId+"-s"]),a}function Zl(e){return e.some(t=>es(t)?!(t.type===We||t.type===we&&!Zl(t.children)):!0)?e:null}const $r=e=>e?xa(e)?Xs(e):$r(e.parent):null,zn=Ue(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>$r(e.parent),$root:e=>$r(e.root),$host:e=>e.ce,$emit:e=>e.emit,$options:e=>ta(e),$forceUpdate:e=>e.f||(e.f=()=>{lo(e.update)}),$nextTick:e=>e.n||(e.n=io.bind(e.proxy)),$watch:e=>nc.bind(e)}),ur=(e,t)=>e!==Ce&&!e.__isScriptSetup&&_e(e,t),vc={get({_:e},t){if(t==="__v_skip")return!0;const{ctx:n,setupState:s,data:r,props:o,accessCache:i,type:l,appContext:a}=e;if(t[0]!=="$"){const h=i[t];if(h!==void 0)switch(h){case 1:return s[t];case 2:return r[t];case 4:return n[t];case 3:return o[t]}else{if(ur(s,t))return i[t]=1,s[t];if(r!==Ce&&_e(r,t))return i[t]=2,r[t];if(_e(o,t))return i[t]=3,o[t];if(n!==Ce&&_e(n,t))return i[t]=4,n[t];Dr&&(i[t]=0)}}const c=zn[t];let u,f;if(c)return t==="$attrs"&&Ke(e.attrs,"get",""),c(e);if((u=l.__cssModules)&&(u=u[t]))return u;if(n!==Ce&&_e(n,t))return i[t]=4,n[t];if(f=a.config.globalProperties,_e(f,t))return f[t]},set({_:e},t,n){const{data:s,setupState:r,ctx:o}=e;return ur(r,t)?(r[t]=n,!0):s!==Ce&&_e(s,t)?(s[t]=n,!0):_e(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(o[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:s,appContext:r,props:o,type:i}},l){let a;return!!(n[l]||e!==Ce&&l[0]!=="$"&&_e(e,l)||ur(t,l)||_e(o,l)||_e(s,l)||_e(zn,l)||_e(r.config.globalProperties,l)||(a=i.__cssModules)&&a[l])},defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:_e(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}};function Ko(e){return ne(e)?e.reduce((t,n)=>(t[n]=null,t),{}):e}let Dr=!0;function _c(e){const t=ta(e),n=e.proxy,s=e.ctx;Dr=!1,t.beforeCreate&&Wo(t.beforeCreate,e,"bc");const{data:r,computed:o,methods:i,watch:l,provide:a,inject:c,created:u,beforeMount:f,mounted:h,beforeUpdate:m,updated:R,activated:C,deactivated:P,beforeDestroy:_,beforeUnmount:b,destroyed:A,unmounted:E,render:O,renderTracked:D,renderTriggered:L,errorCaptured:ae,serverPrefetch:Y,expose:se,inheritAttrs:oe,components:W,directives:ue,filters:fe}=t;if(c&&wc(c,s,null),i)for(const pe in i){const $=i[pe];le($)&&(s[pe]=$.bind(n))}if(r){const pe=r.call(n,n);Ee(pe)&&(e.data=At(pe))}if(Dr=!0,o)for(const pe in o){const $=o[pe],k=le($)?$.bind(n,n):le($.get)?$.get.bind(n,n):Ct,z=!le($)&&le($.set)?$.set.bind(n):Ct,re=tt({get:k,set:z});Object.defineProperty(s,pe,{enumerable:!0,configurable:!0,get:()=>re.value,set:he=>re.value=he})}if(l)for(const pe in l)ea(l[pe],s,n,pe);if(a){const pe=le(a)?a.call(n):a;Reflect.ownKeys(pe).forEach($=>{vs($,pe[$])})}u&&Wo(u,e,"c");function me(pe,$){ne($)?$.forEach(k=>pe(k.bind(n))):$&&pe($.bind(n))}if(me(dc,f),me(Yt,h),me(pc,m),me(hc,R),me(uc,C),me(cc,P),me(bc,ae),me(yc,D),me(gc,L),me(Gl,b),me(Jl,E),me(mc,Y),ne(se))if(se.length){const pe=e.exposed||(e.exposed={});se.forEach($=>{Object.defineProperty(pe,$,{get:()=>n[$],set:k=>n[$]=k,enumerable:!0})})}else e.exposed||(e.exposed={});O&&e.render===Ct&&(e.render=O),oe!=null&&(e.inheritAttrs=oe),W&&(e.components=W),ue&&(e.directives=ue),Y&&Wl(e)}function wc(e,t,n=Ct){ne(e)&&(e=Lr(e));for(const s in e){const r=e[s];let o;Ee(r)?"default"in r?o=pt(r.from||s,r.default,!0):o=pt(r.from||s):o=pt(r),Ge(o)?Object.defineProperty(t,s,{enumerable:!0,configurable:!0,get:()=>o.value,set:i=>o.value=i}):t[s]=o}}function Wo(e,t,n){ut(ne(e)?e.map(s=>s.bind(t.proxy)):e.bind(t.proxy),t,n)}function ea(e,t,n,s){let r=s.includes(".")?Ll(n,s):()=>n[s];if(Pe(e)){const o=t[e];le(o)&&_s(r,o)}else if(le(e))_s(r,e.bind(n));else if(Ee(e))if(ne(e))e.forEach(o=>ea(o,t,n,s));else{const o=le(e.handler)?e.handler.bind(n):t[e.handler];le(o)&&_s(r,o,e)}}function ta(e){const t=e.type,{mixins:n,extends:s}=t,{mixins:r,optionsCache:o,config:{optionMergeStrategies:i}}=e.appContext,l=o.get(t);let a;return l?a=l:!r.length&&!n&&!s?a=t:(a={},r.length&&r.forEach(c=>Ps(a,c,i,!0)),Ps(a,t,i)),Ee(t)&&o.set(t,a),a}function Ps(e,t,n,s=!1){const{mixins:r,extends:o}=t;o&&Ps(e,o,n,!0),r&&r.forEach(i=>Ps(e,i,n,!0));for(const i in t)if(!(s&&i==="expose")){const l=Ec[i]||n&&n[i];e[i]=l?l(e[i],t[i]):t[i]}return e}const Ec={data:zo,props:Go,emits:Go,methods:Bn,computed:Bn,beforeCreate:Xe,created:Xe,beforeMount:Xe,mounted:Xe,beforeUpdate:Xe,updated:Xe,beforeDestroy:Xe,beforeUnmount:Xe,destroyed:Xe,unmounted:Xe,activated:Xe,deactivated:Xe,errorCaptured:Xe,serverPrefetch:Xe,components:Bn,directives:Bn,watch:Rc,provide:zo,inject:Sc};function zo(e,t){return t?e?function(){return Ue(le(e)?e.call(this,this):e,le(t)?t.call(this,this):t)}:t:e}function Sc(e,t){return Bn(Lr(e),Lr(t))}function Lr(e){if(ne(e)){const t={};for(let n=0;nt==="modelValue"||t==="model-value"?e.modelModifiers:e[`${t}Modifiers`]||e[`${et(t)}Modifiers`]||e[`${Xt(t)}Modifiers`];function Tc(e,t,...n){if(e.isUnmounted)return;const s=e.vnode.props||Ce;let r=n;const o=t.startsWith("update:"),i=o&&Oc(s,t.slice(7));i&&(i.trim&&(r=n.map(u=>Pe(u)?u.trim():u)),i.number&&(r=n.map(js)));let l,a=s[l=sr(t)]||s[l=sr(et(t))];!a&&o&&(a=s[l=sr(Xt(t))]),a&&ut(a,e,6,r);const c=s[l+"Once"];if(c){if(!e.emitted)e.emitted={};else if(e.emitted[l])return;e.emitted[l]=!0,ut(c,e,6,r)}}const Pc=new WeakMap;function sa(e,t,n=!1){const s=n?Pc:t.emitsCache,r=s.get(e);if(r!==void 0)return r;const o=e.emits;let i={},l=!1;if(!le(e)){const a=c=>{const u=sa(c,t,!0);u&&(l=!0,Ue(i,u))};!n&&t.mixins.length&&t.mixins.forEach(a),e.extends&&a(e.extends),e.mixins&&e.mixins.forEach(a)}return!o&&!l?(Ee(e)&&s.set(e,null),null):(ne(o)?o.forEach(a=>i[a]=null):Ue(i,o),Ee(e)&&s.set(e,i),i)}function Gs(e,t){return!e||!Fs(t)?!1:(t=t.slice(2),t=t==="Once"?t:t.replace(/Once$/,""),_e(e,t[0].toLowerCase()+t.slice(1))||_e(e,Xt(t))||_e(e,t))}function Jo(e){const{type:t,vnode:n,proxy:s,withProxy:r,propsOptions:[o],slots:i,attrs:l,emit:a,render:c,renderCache:u,props:f,data:h,setupState:m,ctx:R,inheritAttrs:C}=e,P=Os(e);let _,b;try{if(n.shapeFlag&4){const E=r||s,O=E;_=St(c.call(O,E,u,f,m,h,R)),b=l}else{const E=t;_=St(E.length>1?E(f,{attrs:l,slots:i,emit:a}):E(f,null)),b=t.props?l:Nc(l)}}catch(E){Lt.length=0,Ks(E,e,1),_=Te(We)}let A=_;if(b&&C!==!1){const E=Object.keys(b),{shapeFlag:O}=A;E.length&&O&7&&(o&&E.some(Ms)&&(b=Ic(b,o)),A=Gt(A,b,!1,!0))}return n.dirs&&(A=Gt(A,null,!1,!0),A.dirs=A.dirs?A.dirs.concat(n.dirs):n.dirs),n.transition&&Qn(A,n.transition),_=A,Os(P),_}const Nc=e=>{let t;for(const n in e)(n==="class"||n==="style"||Fs(n))&&((t||(t={}))[n]=e[n]);return t},Ic=(e,t)=>{const n={};for(const s in e)(!Ms(s)||!(s.slice(9)in t))&&(n[s]=e[s]);return n};function kc(e,t,n){const{props:s,children:r,component:o}=e,{props:i,children:l,patchFlag:a}=t,c=o.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&a>=0){if(a&1024)return!0;if(a&16)return s?Xo(s,i,c):!!i;if(a&8){const u=t.dynamicProps;for(let f=0;fObject.create(oa),la=e=>Object.getPrototypeOf(e)===oa;function Dc(e,t,n,s=!1){const r={},o=ia();e.propsDefaults=Object.create(null),aa(e,t,r,o);for(const i in e.propsOptions[0])i in r||(r[i]=void 0);n?e.props=s?r:Cl(r):e.type.props?e.props=r:e.props=o,e.attrs=o}function Lc(e,t,n,s){const{props:r,attrs:o,vnode:{patchFlag:i}}=e,l=xe(r),[a]=e.propsOptions;let c=!1;if((s||i>0)&&!(i&16)){if(i&8){const u=e.vnode.dynamicProps;for(let f=0;f{a=!0;const[h,m]=ua(f,t,!0);Ue(i,h),m&&l.push(...m)};!n&&t.mixins.length&&t.mixins.forEach(u),e.extends&&u(e.extends),e.mixins&&e.mixins.forEach(u)}if(!o&&!a)return Ee(e)&&s.set(e,xn),xn;if(ne(o))for(let u=0;ue==="_"||e==="_ctx"||e==="$stable",uo=e=>ne(e)?e.map(St):[St(e)],Fc=(e,t,n)=>{if(t._n)return t;const s=dt((...r)=>uo(t(...r)),n);return s._c=!1,s},ca=(e,t,n)=>{const s=e._ctx;for(const r in e){if(ao(r))continue;const o=e[r];if(le(o))t[r]=Fc(r,o,s);else if(o!=null){const i=uo(o);t[r]=()=>i}}},fa=(e,t)=>{const n=uo(t);e.slots.default=()=>n},da=(e,t,n)=>{for(const s in t)(n||!ao(s))&&(e[s]=t[s])},Mc=(e,t,n)=>{const s=e.slots=ia();if(e.vnode.shapeFlag&32){const r=t._;r?(da(s,t,n),n&&ll(s,"_",r,!0)):ca(t,s)}else t&&fa(e,t)},Vc=(e,t,n)=>{const{vnode:s,slots:r}=e;let o=!0,i=Ce;if(s.shapeFlag&32){const l=t._;l?n&&l===1?o=!1:da(r,t,n):(o=!t.$stable,ca(t,r)),i=t}else t&&(fa(e,t),i={default:1});if(o)for(const l in r)!ao(l)&&i[l]==null&&delete r[l]},Ye=Kc;function Bc(e){return jc(e)}function jc(e,t){const n=Hs();n.__VUE__=!0;const{insert:s,remove:r,patchProp:o,createElement:i,createText:l,createComment:a,setText:c,setElementText:u,parentNode:f,nextSibling:h,setScopeId:m=Ct,insertStaticContent:R}=e,C=(p,g,v,N=null,S=null,T=null,K=void 0,H=null,q=!!g.dynamicChildren)=>{if(p===g)return;p&&!rn(p,g)&&(N=y(p),he(p,S,T,!0),p=null),g.patchFlag===-2&&(q=!1,g.dynamicChildren=null);const{type:U,ref:ee,shapeFlag:J}=g;switch(U){case Js:P(p,g,v,N);break;case We:_(p,g,v,N);break;case fr:p==null&&b(g,v,N,K);break;case we:W(p,g,v,N,S,T,K,H,q);break;default:J&1?O(p,g,v,N,S,T,K,H,q):J&6?ue(p,g,v,N,S,T,K,H,q):(J&64||J&128)&&U.process(p,g,v,N,S,T,K,H,q,X)}ee!=null&&S?Wn(ee,p&&p.ref,T,g||p,!g):ee==null&&p&&p.ref!=null&&Wn(p.ref,null,T,p,!0)},P=(p,g,v,N)=>{if(p==null)s(g.el=l(g.children),v,N);else{const S=g.el=p.el;g.children!==p.children&&c(S,g.children)}},_=(p,g,v,N)=>{p==null?s(g.el=a(g.children||""),v,N):g.el=p.el},b=(p,g,v,N)=>{[p.el,p.anchor]=R(p.children,g,v,N,p.el,p.anchor)},A=({el:p,anchor:g},v,N)=>{let S;for(;p&&p!==g;)S=h(p),s(p,v,N),p=S;s(g,v,N)},E=({el:p,anchor:g})=>{let v;for(;p&&p!==g;)v=h(p),r(p),p=v;r(g)},O=(p,g,v,N,S,T,K,H,q)=>{if(g.type==="svg"?K="svg":g.type==="math"&&(K="mathml"),p==null)D(g,v,N,S,T,K,H,q);else{const U=p.el&&p.el._isVueCE?p.el:null;try{U&&U._beginPatch(),Y(p,g,S,T,K,H,q)}finally{U&&U._endPatch()}}},D=(p,g,v,N,S,T,K,H)=>{let q,U;const{props:ee,shapeFlag:J,transition:te,dirs:ie}=p;if(q=p.el=i(p.type,T,ee&&ee.is,ee),J&8?u(q,p.children):J&16&&ae(p.children,q,null,N,S,cr(p,T),K,H),ie&&Qt(p,null,N,"created"),L(q,p,p.scopeId,K,N),ee){for(const Re in ee)Re!=="value"&&!Hn(Re)&&o(q,Re,null,ee[Re],T,N);"value"in ee&&o(q,"value",null,ee.value,T),(U=ee.onVnodeBeforeMount)&&_t(U,N,p)}ie&&Qt(p,null,N,"beforeMount");const ge=Hc(S,te);ge&&te.beforeEnter(q),s(q,g,v),((U=ee&&ee.onVnodeMounted)||ge||ie)&&Ye(()=>{try{U&&_t(U,N,p),ge&&te.enter(q),ie&&Qt(p,null,N,"mounted")}finally{}},S)},L=(p,g,v,N,S)=>{if(v&&m(p,v),N)for(let T=0;T{for(let U=q;U{const H=g.el=p.el;let{patchFlag:q,dynamicChildren:U,dirs:ee}=g;q|=p.patchFlag&16;const J=p.props||Ce,te=g.props||Ce;let ie;if(v&&Zt(v,!1),(ie=te.onVnodeBeforeUpdate)&&_t(ie,v,g,p),ee&&Qt(g,p,v,"beforeUpdate"),v&&Zt(v,!0),U&&(!p.dynamicChildren||p.dynamicChildren.length!==U.length)&&(q=0,K=!1,U=null),(J.innerHTML&&te.innerHTML==null||J.textContent&&te.textContent==null)&&u(H,""),U?se(p.dynamicChildren,U,H,v,N,cr(g,S),T):K||$(p,g,H,null,v,N,cr(g,S),T,!1),q>0){if(q&16)oe(H,J,te,v,S);else if(q&2&&J.class!==te.class&&o(H,"class",null,te.class,S),q&4&&o(H,"style",J.style,te.style,S),q&8){const ge=g.dynamicProps;for(let Re=0;Re{ie&&_t(ie,v,g,p),ee&&Qt(g,p,v,"updated")},N)},se=(p,g,v,N,S,T,K)=>{for(let H=0;H{if(g!==v){if(g!==Ce)for(const T in g)!Hn(T)&&!(T in v)&&o(p,T,g[T],null,S,N);for(const T in v){if(Hn(T))continue;const K=v[T],H=g[T];K!==H&&T!=="value"&&o(p,T,H,K,S,N)}"value"in v&&o(p,"value",g.value,v.value,S)}},W=(p,g,v,N,S,T,K,H,q)=>{const U=g.el=p?p.el:l(""),ee=g.anchor=p?p.anchor:l("");let{patchFlag:J,dynamicChildren:te,slotScopeIds:ie}=g;ie&&(H=H?H.concat(ie):ie),p==null?(s(U,v,N),s(ee,v,N),ae(g.children||[],v,ee,S,T,K,H,q)):J>0&&J&64&&te&&p.dynamicChildren&&p.dynamicChildren.length===te.length?(se(p.dynamicChildren,te,v,S,T,K,H),(g.key!=null||S&&g===S.subTree)&&co(p,g,!0)):$(p,g,v,ee,S,T,K,H,q)},ue=(p,g,v,N,S,T,K,H,q)=>{g.slotScopeIds=H,p==null?g.shapeFlag&512?S.ctx.activate(g,v,N,K,q):fe(g,v,N,S,T,K,q):Ne(p,g,q)},fe=(p,g,v,N,S,T,K)=>{const H=p.component=Yc(p,N,S);if(Ws(p)&&(H.ctx.renderer=X),Qc(H,!1,K),H.asyncDep){if(S&&S.registerDep(H,me,K),!p.el){const q=H.subTree=Te(We);_(null,q,g,v),p.placeholder=q.el}}else me(H,p,g,v,S,T,K)},Ne=(p,g,v)=>{const N=g.component=p.component;if(kc(p,g,v))if(N.asyncDep&&!N.asyncResolved){pe(N,g,v);return}else N.next=g,N.update();else g.el=p.el,N.vnode=g},me=(p,g,v,N,S,T,K)=>{const H=()=>{if(p.isMounted){let{next:J,bu:te,u:ie,parent:ge,vnode:Re}=p;{const xt=pa(p);if(xt){J&&(J.el=Re.el,pe(p,J,K)),xt.asyncDep.then(()=>{Ye(()=>{p.isUnmounted||U()},S)});return}}let Se=J,$e;Zt(p,!1),J?(J.el=Re.el,pe(p,J,K)):J=Re,te&&xs(te),($e=J.props&&J.props.onVnodeBeforeUpdate)&&_t($e,ge,J,Re),Zt(p,!0);const Me=Jo(p),bt=p.subTree;p.subTree=Me,C(bt,Me,f(bt.el),y(bt),p,S,T),J.el=Me.el,Se===null&&$c(p,Me.el),ie&&Ye(ie,S),($e=J.props&&J.props.onVnodeUpdated)&&Ye(()=>_t($e,ge,J,Re),S)}else{let J;const{el:te,props:ie}=g,{bm:ge,m:Re,parent:Se,root:$e,type:Me}=p,bt=En(g);Zt(p,!1),ge&&xs(ge),!bt&&(J=ie&&ie.onVnodeBeforeMount)&&_t(J,Se,g),Zt(p,!0);{$e.ce&&$e.ce._hasShadowRoot()&&$e.ce._injectChildStyle(Me,p.parent?p.parent.type:void 0);const xt=p.subTree=Jo(p);C(null,xt,v,N,p,S,T),g.el=xt.el}if(Re&&Ye(Re,S),!bt&&(J=ie&&ie.onVnodeMounted)){const xt=g;Ye(()=>_t(J,Se,xt),S)}(g.shapeFlag&256||Se&&En(Se.vnode)&&Se.vnode.shapeFlag&256)&&p.a&&Ye(p.a,S),p.isMounted=!0,g=v=N=null}};p.scope.on();const q=p.effect=new dl(H);p.scope.off();const U=p.update=q.run.bind(q),ee=p.job=q.runIfDirty.bind(q);ee.i=p,ee.id=p.uid,q.scheduler=()=>lo(ee),Zt(p,!0),U()},pe=(p,g,v)=>{g.component=p;const N=p.vnode.props;p.vnode=g,p.next=null,Lc(p,g.props,N,v),Vc(p,g.children,v),Ut(),Uo(p),Ft()},$=(p,g,v,N,S,T,K,H,q=!1)=>{const U=p&&p.children,ee=p?p.shapeFlag:0,J=g.children,{patchFlag:te,shapeFlag:ie}=g;if(te>0){if(te&128){z(U,J,v,N,S,T,K,H,q);return}else if(te&256){k(U,J,v,N,S,T,K,H,q);return}}ie&8?(ee&16&&w(U,S,T),J!==U&&u(v,J)):ee&16?ie&16?z(U,J,v,N,S,T,K,H,q):w(U,S,T,!0):(ee&8&&u(v,""),ie&16&&ae(J,v,N,S,T,K,H,q))},k=(p,g,v,N,S,T,K,H,q)=>{p=p||xn,g=g||xn;const U=p.length,ee=g.length,J=Math.min(U,ee);let te;for(te=0;teee?w(p,S,T,!0,!1,J):ae(g,v,N,S,T,K,H,q,J)},z=(p,g,v,N,S,T,K,H,q)=>{let U=0;const ee=g.length;let J=p.length-1,te=ee-1;for(;U<=J&&U<=te;){const ie=p[U],ge=g[U]=q?It(g[U]):St(g[U]);if(rn(ie,ge))C(ie,ge,v,null,S,T,K,H,q);else break;U++}for(;U<=J&&U<=te;){const ie=p[J],ge=g[te]=q?It(g[te]):St(g[te]);if(rn(ie,ge))C(ie,ge,v,null,S,T,K,H,q);else break;J--,te--}if(U>J){if(U<=te){const ie=te+1,ge=iete)for(;U<=J;)he(p[U],S,T,!0),U++;else{const ie=U,ge=U,Re=new Map;for(U=ge;U<=te;U++){const st=g[U]=q?It(g[U]):St(g[U]);st.key!=null&&Re.set(st.key,U)}let Se,$e=0;const Me=te-ge+1;let bt=!1,xt=0;const $n=new Array(Me);for(U=0;U=Me){he(st,S,T,!0);continue}let vt;if(st.key!=null)vt=Re.get(st.key);else for(Se=ge;Se<=te;Se++)if($n[Se-ge]===0&&rn(st,g[Se])){vt=Se;break}vt===void 0?he(st,S,T,!0):($n[vt-ge]=U+1,vt>=xt?xt=vt:bt=!0,C(st,g[vt],v,null,S,T,K,H,q),$e++)}const Po=bt?qc($n):xn;for(Se=Po.length-1,U=Me-1;U>=0;U--){const st=ge+U,vt=g[st],No=g[st+1],Io=st+1{const{el:T,type:K,transition:H,children:q,shapeFlag:U}=p;if(U&6){re(p.component.subTree,g,v,N);return}if(U&128){p.suspense.move(g,v,N);return}if(U&64){K.move(p,g,v,X);return}if(K===we){s(T,g,v);for(let J=0;JH.enter(T),S));else{const{leave:J,delayLeave:te,afterLeave:ie}=H,ge=()=>{p.ctx.isUnmounted?r(T):s(T,g,v)},Re=()=>{const Se=T._isLeaving||!!T[it];T._isLeaving&&T[it](!0),H.persisted&&!Se?ge():J(T,()=>{ge(),ie&&ie()})};te?te(T,ge,Re):Re()}else s(T,g,v)},he=(p,g,v,N=!1,S=!1)=>{const{type:T,props:K,ref:H,children:q,dynamicChildren:U,shapeFlag:ee,patchFlag:J,dirs:te,cacheIndex:ie,memo:ge}=p;if(J===-2&&(S=!1),H!=null&&(Ut(),Wn(H,null,v,p,!0),Ft()),ie!=null&&(g.renderCache[ie]=void 0),ee&256){g.ctx.deactivate(p);return}const Re=ee&1&&te,Se=!En(p);let $e;if(Se&&($e=K&&K.onVnodeBeforeUnmount)&&_t($e,g,p),ee&6)I(p.component,v,N);else{if(ee&128){p.suspense.unmount(v,N);return}Re&&Qt(p,null,g,"beforeUnmount"),ee&64?p.type.remove(p,g,v,X,N):U&&!U.hasOnce&&(T!==we||J>0&&J&64)?w(U,g,v,!1,!0):(T===we&&J&384||!S&&ee&16)&&w(q,g,v),N&&Oe(p)}const Me=ge!=null&&ie==null;(Se&&($e=K&&K.onVnodeUnmounted)||Re||Me)&&Ye(()=>{$e&&_t($e,g,p),Re&&Qt(p,null,g,"unmounted"),Me&&(p.el=null)},v)},Oe=p=>{const{type:g,el:v,anchor:N,transition:S}=p;if(g===we){de(v,N);return}if(g===fr){E(p);return}const T=()=>{r(v),S&&!S.persisted&&S.afterLeave&&S.afterLeave()};if(p.shapeFlag&1&&S&&!S.persisted){const{leave:K,delayLeave:H}=S,q=()=>K(v,T);H?H(p.el,T,q):q()}else T()},de=(p,g)=>{let v;for(;p!==g;)v=h(p),r(p),p=v;r(g)},I=(p,g,v)=>{const{bum:N,scope:S,job:T,subTree:K,um:H,m:q,a:U}=p;Qo(q),Qo(U),N&&xs(N),S.stop(),T&&(T.flags|=8,he(K,p,g,v)),H&&Ye(H,g),Ye(()=>{p.isUnmounted=!0},g)},w=(p,g,v,N=!1,S=!1,T=0)=>{for(let K=T;K{if(p.shapeFlag&6)return y(p.component.subTree);if(p.shapeFlag&128)return p.suspense.next();const g=h(p.anchor||p.el),v=g&&g[Ul];return v?h(v):g};let B=!1;const M=(p,g,v)=>{let N;p==null?g._vnode&&(he(g._vnode,null,null,!0),N=g._vnode.component):C(g._vnode||null,p,g,null,null,null,v),g._vnode=p,B||(B=!0,Uo(N),Il(),B=!1)},X={p:C,um:he,m:re,r:Oe,mt:fe,mc:ae,pc:$,pbc:se,n:y,o:e};return{render:M,hydrate:void 0,createApp:Ac(M)}}function cr({type:e,props:t},n){return n==="svg"&&e==="foreignObject"||n==="mathml"&&e==="annotation-xml"&&t&&t.encoding&&t.encoding.includes("html")?void 0:n}function Zt({effect:e,job:t},n){n?(e.flags|=32,t.flags|=4):(e.flags&=-33,t.flags&=-5)}function Hc(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function co(e,t,n=!1){const s=e.children,r=t.children;if(ne(s)&&ne(r))for(let o=0;o>1,e[n[l]]0&&(t[s]=n[o-1]),n[o]=s)}}for(o=n.length,i=n[o-1];o-- >0;)n[o]=i,i=t[i];return n}function pa(e){const t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:pa(t)}function Qo(e){if(e)for(let t=0;te.__isSuspense;function Kc(e,t){t&&t.pendingBranch?ne(e)?t.effects.push(...e):t.effects.push(e):Zu(e)}const we=Symbol.for("v-fgt"),Js=Symbol.for("v-txt"),We=Symbol.for("v-cmt"),fr=Symbol.for("v-stc"),Lt=[];let rt=null;function F(e=!1){Lt.push(rt=e?null:[])}function fo(){Lt.pop(),rt=Lt[Lt.length-1]||null}let Zn=1;function Ns(e,t=!1){Zn+=e,e<0&&rt&&t&&(rt.hasOnce=!0)}function ga(e){return e.dynamicChildren=Zn>0?rt||xn:null,fo(),Zn>0&&rt&&rt.push(e),e}function V(e,t,n,s,r,o){return ga(d(e,t,n,s,r,o,!0))}function fn(e,t,n,s,r){return ga(Te(e,t,n,s,r,!0))}function es(e){return e?e.__v_isVNode===!0:!1}function rn(e,t){return e.type===t.type&&e.key===t.key}const ya=({key:e})=>e??null,ws=({ref:e,ref_key:t,ref_for:n})=>(typeof e=="number"&&(e=""+e),e!=null?Pe(e)||Ge(e)||le(e)?{i:He,r:e,k:t,f:!!n}:e:null);function d(e,t=null,n=null,s=0,r=null,o=e===we?0:1,i=!1,l=!1){const a={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&ya(t),ref:t&&ws(t),scopeId:$l,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetStart:null,targetAnchor:null,staticCount:0,shapeFlag:o,patchFlag:s,dynamicProps:r,dynamicChildren:null,appContext:null,ctx:He};return l?(Is(a,n),o&128&&e.normalize(a)):n&&(a.shapeFlag|=Pe(n)?8:16),Zn>0&&!i&&rt&&(a.patchFlag>0||o&6)&&a.patchFlag!==32&&rt.push(a),a}const Te=Wc;function Wc(e,t=null,n=null,s=0,r=null,o=!1){if((!e||e===Yl)&&(e=We),es(e)){const l=Gt(e,t,!0);return n&&Is(l,n),Zn>0&&!o&&rt&&(l.shapeFlag&6?rt[rt.indexOf(e)]=l:rt.push(l)),l.patchFlag=-2,l}if(sf(e)&&(e=e.__vccOpts),t){t=zc(t);let{class:l,style:a}=t;l&&!Pe(l)&&(t.class=Fe(l)),Ee(a)&&(oo(a)&&!ne(a)&&(a=Ue({},a)),t.style=Yr(a))}const i=Pe(e)?1:ma(e)?128:Fl(e)?64:Ee(e)?4:le(e)?2:0;return d(e,t,n,s,r,i,o,!0)}function zc(e){return e?oo(e)||la(e)?Ue({},e):e:null}function Gt(e,t,n=!1,s=!1){const{props:r,ref:o,patchFlag:i,children:l,transition:a}=e,c=t?Gc(r||{},t):r,u={__v_isVNode:!0,__v_skip:!0,type:e.type,props:c,key:c&&ya(c),ref:t&&t.ref?n&&o?ne(o)?o.concat(ws(t)):[o,ws(t)]:ws(t):o,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:l,target:e.target,targetStart:e.targetStart,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==we?i===-1?16:i|16:i,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:a,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&Gt(e.ssContent),ssFallback:e.ssFallback&&Gt(e.ssFallback),placeholder:e.placeholder,el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce};return a&&s&&Qn(u,a.clone(u)),u}function Wt(e=" ",t=0){return Te(Js,null,e,t)}function ce(e="",t=!1){return t?(F(),fn(We,null,e)):Te(We,null,e)}function St(e){return e==null||typeof e=="boolean"?Te(We):ne(e)?Te(we,null,e.slice()):es(e)?It(e):Te(Js,null,String(e))}function It(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:Gt(e)}function Is(e,t){let n=0;const{shapeFlag:s}=e;if(t==null)t=null;else if(ne(t))n=16;else if(typeof t=="object")if(s&65){const r=t.default;r&&(r._c&&(r._d=!1),Is(e,r()),r._c&&(r._d=!0));return}else{n=32;const r=t._;!r&&!la(t)?t._ctx=He:r===3&&He&&(He.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else if(le(t)){if(s&65){Is(e,{default:t});return}t={default:t,_ctx:He},n=32}else t=String(t),s&64?(n=16,t=[Wt(t)]):n=8;e.children=t,e.shapeFlag|=n}function Gc(...e){const t={};for(let n=0;nze||He;let ks,Fr;{const e=Hs(),t=(n,s)=>{let r;return(r=e[n])||(r=e[n]=[]),r.push(s),o=>{r.length>1?r.forEach(i=>i(o)):r[0](o)}};ks=t("__VUE_INSTANCE_SETTERS__",n=>ze=n),Fr=t("__VUE_SSR_SETTERS__",n=>ts=n)}const us=e=>{const t=ze;return ks(e),e.scope.on(),()=>{e.scope.off(),ks(t)}},Zo=()=>{ze&&ze.scope.off(),ks(null)};function xa(e){return e.vnode.shapeFlag&4}let ts=!1;function Qc(e,t=!1,n=!1){t&&Fr(t);const{props:s,children:r}=e.vnode,o=xa(e);Dc(e,s,o,t),Mc(e,r,n||t);const i=o?Zc(e,t):void 0;return t&&Fr(!1),i}function Zc(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=new Proxy(e.ctx,vc);const{setup:s}=n;if(s){Ut();const r=e.setupContext=s.length>1?tf(e):null,o=us(e),i=as(s,e,0,[e.props,r]),l=rl(i);if(Ft(),o(),(l||e.sp)&&!En(e)&&Wl(e),l){if(i.then(Zo,Zo),t)return i.then(a=>{ei(e,a)}).catch(a=>{Ks(a,e,0)});e.asyncDep=i}else ei(e,i)}else va(e)}function ei(e,t,n){le(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:Ee(t)&&(e.setupState=Tl(t)),va(e)}function va(e,t,n){const s=e.type;e.render||(e.render=s.render||Ct);{const r=us(e);Ut();try{_c(e)}finally{Ft(),r()}}}const ef={get(e,t){return Ke(e,"get",""),e[t]}};function tf(e){const t=n=>{e.exposed=n||{}};return{attrs:new Proxy(e.attrs,ef),slots:e.slots,emit:e.emit,expose:t}}function Xs(e){return e.exposed?e.exposeProxy||(e.exposeProxy=new Proxy(Tl(Al(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in zn)return zn[n](e)},has(t,n){return n in t||n in zn}})):e.proxy}function nf(e,t=!0){return le(e)?e.displayName||e.name:e.name||t&&e.__name}function sf(e){return le(e)&&"__vccOpts"in e}const tt=(e,t)=>Gu(e,t,ts);function po(e,t,n){try{Ns(-1);const s=arguments.length;return s===2?Ee(t)&&!ne(t)?es(t)?Te(e,null,[t]):Te(e,t):Te(e,null,t):(s>3?n=Array.prototype.slice.call(arguments,2):s===3&&es(n)&&(n=[n]),Te(e,t,n))}finally{Ns(1)}}const rf="3.5.40";/** +* @vue/runtime-dom v3.5.40 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/let Mr;const ti=typeof window<"u"&&window.trustedTypes;if(ti)try{Mr=ti.createPolicy("vue",{createHTML:e=>e})}catch{}const _a=Mr?e=>Mr.createHTML(e):e=>e,of="http://www.w3.org/2000/svg",lf="http://www.w3.org/1998/Math/MathML",Nt=typeof document<"u"?document:null,ni=Nt&&Nt.createElement("template"),af={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,s)=>{const r=t==="svg"?Nt.createElementNS(of,e):t==="mathml"?Nt.createElementNS(lf,e):n?Nt.createElement(e,{is:n}):Nt.createElement(e);return e==="select"&&s&&s.multiple!=null&&r.setAttribute("multiple",s.multiple),r},createText:e=>Nt.createTextNode(e),createComment:e=>Nt.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>Nt.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,s,r,o){const i=n?n.previousSibling:t.lastChild;if(r&&(r===o||r.nextSibling))for(;t.insertBefore(r.cloneNode(!0),n),!(r===o||!(r=r.nextSibling)););else{ni.innerHTML=_a(s==="svg"?`${e}`:s==="mathml"?`${e}`:e);const l=ni.content;if(s==="svg"||s==="mathml"){const a=l.firstChild;for(;a.firstChild;)l.appendChild(a.firstChild);l.removeChild(a)}t.insertBefore(l,n)}return[i?i.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},Bt="transition",Un="animation",ns=Symbol("_vtc"),wa={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String},uf=Ue({},Vl,wa),cf=e=>(e.displayName="Transition",e.props=uf,e),ff=cf((e,{slots:t})=>po(ac,df(e),t)),en=(e,t=[])=>{ne(e)?e.forEach(n=>n(...t)):e&&e(...t)},si=e=>e?ne(e)?e.some(t=>t.length>1):e.length>1:!1;function df(e){const t={};for(const W in e)W in wa||(t[W]=e[W]);if(e.css===!1)return t;const{name:n="v",type:s,duration:r,enterFromClass:o=`${n}-enter-from`,enterActiveClass:i=`${n}-enter-active`,enterToClass:l=`${n}-enter-to`,appearFromClass:a=o,appearActiveClass:c=i,appearToClass:u=l,leaveFromClass:f=`${n}-leave-from`,leaveActiveClass:h=`${n}-leave-active`,leaveToClass:m=`${n}-leave-to`}=e,R=pf(r),C=R&&R[0],P=R&&R[1],{onBeforeEnter:_,onEnter:b,onEnterCancelled:A,onLeave:E,onLeaveCancelled:O,onBeforeAppear:D=_,onAppear:L=b,onAppearCancelled:ae=A}=t,Y=(W,ue,fe,Ne)=>{W._enterCancelled=Ne,tn(W,ue?u:l),tn(W,ue?c:i),fe&&fe()},se=(W,ue)=>{W._isLeaving=!1,tn(W,f),tn(W,m),tn(W,h),ue&&ue()},oe=W=>(ue,fe)=>{const Ne=W?L:b,me=()=>Y(ue,W,fe);en(Ne,[ue,me]),ri(()=>{tn(ue,W?a:o),Tt(ue,W?u:l),si(Ne)||oi(ue,s,C,me)})};return Ue(t,{onBeforeEnter(W){en(_,[W]),Tt(W,o),Tt(W,i)},onBeforeAppear(W){en(D,[W]),Tt(W,a),Tt(W,c)},onEnter:oe(!1),onAppear:oe(!0),onLeave(W,ue){W._isLeaving=!0;const fe=()=>se(W,ue);Tt(W,f),W._enterCancelled?(Tt(W,h),ai(W)):(ai(W),Tt(W,h)),ri(()=>{W._isLeaving&&(tn(W,f),Tt(W,m),si(E)||oi(W,s,P,fe))}),en(E,[W,fe])},onEnterCancelled(W){Y(W,!1,void 0,!0),en(A,[W])},onAppearCancelled(W){Y(W,!0,void 0,!0),en(ae,[W])},onLeaveCancelled(W){se(W),en(O,[W])}})}function pf(e){if(e==null)return null;if(Ee(e))return[dr(e.enter),dr(e.leave)];{const t=dr(e);return[t,t]}}function dr(e){return yu(e)}function Tt(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e[ns]||(e[ns]=new Set)).add(t)}function tn(e,t){t.split(/\s+/).forEach(s=>s&&e.classList.remove(s));const n=e[ns];n&&(n.delete(t),n.size||(e[ns]=void 0))}function ri(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let hf=0;function oi(e,t,n,s){const r=e._endId=++hf,o=()=>{r===e._endId&&s()};if(n!=null)return setTimeout(o,n);const{type:i,timeout:l,propCount:a}=mf(e,t);if(!i)return s();const c=i+"end";let u=0;const f=()=>{e.removeEventListener(c,h),o()},h=m=>{m.target===e&&++u>=a&&f()};setTimeout(()=>{u(n[R]||"").split(", "),r=s(`${Bt}Delay`),o=s(`${Bt}Duration`),i=ii(r,o),l=s(`${Un}Delay`),a=s(`${Un}Duration`),c=ii(l,a);let u=null,f=0,h=0;t===Bt?i>0&&(u=Bt,f=i,h=o.length):t===Un?c>0&&(u=Un,f=c,h=a.length):(f=Math.max(i,c),u=f>0?i>c?Bt:Un:null,h=u?u===Bt?o.length:a.length:0);const m=u===Bt&&/\b(?:transform|all)(?:,|$)/.test(s(`${Bt}Property`).toString());return{type:u,timeout:f,propCount:h,hasTransform:m}}function ii(e,t){for(;e.lengthli(n)+li(e[s])))}function li(e){return e==="auto"?0:Number(e.slice(0,-1).replace(",","."))*1e3}function ai(e){return(e?e.ownerDocument:document).body.offsetHeight}function gf(e,t,n){const s=e[ns];s&&(t=(t?[t,...s]:[...s]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}const ui=Symbol("_vod"),yf=Symbol("_vsh"),bf=Symbol(""),xf=/(?:^|;)\s*display\s*:/;function vf(e,t,n){const s=e.style,r=Pe(n);let o=!1;if(n&&!r){if(t)if(Pe(t))for(const i of t.split(";")){const l=i.slice(0,i.indexOf(":")).trim();n[l]==null&&jn(s,l,"")}else for(const i in t)n[i]==null&&jn(s,i,"");for(const i in n){i==="display"&&(o=!0);const l=n[i];l!=null?wf(e,i,!Pe(t)&&t?t[i]:void 0,l)||jn(s,i,l):jn(s,i,"")}}else if(r){if(t!==n){const i=s[bf];i&&(n+=";"+i),s.cssText=n,o=xf.test(n)}}else t&&e.removeAttribute("style");ui in e&&(e[ui]=o?s.display:"",e[yf]&&(s.display="none"))}const ci=/\s*!important$/;function jn(e,t,n){if(ne(n))n.forEach(s=>jn(e,t,s));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const s=_f(e,t);ci.test(n)?e.setProperty(Xt(s),n.replace(ci,""),"important"):e[s]=n}}const fi=["Webkit","Moz","ms"],pr={};function _f(e,t){const n=pr[t];if(n)return n;let s=et(t);if(s!=="filter"&&s in e)return pr[t]=s;s=Bs(s);for(let r=0;rhr||(Of.then(()=>hr=0),hr=Date.now());function Pf(e,t){const n=s=>{if(!s._vts)s._vts=Date.now();else if(s._vts<=n.attached)return;const r=n.value;if(ne(r)){const o=s.stopImmediatePropagation;s.stopImmediatePropagation=()=>{o.call(s),s._stopped=!0};const i=r.slice(),l=[s];for(let a=0;ae.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,Nf=(e,t,n,s,r,o)=>{const i=r==="svg";t==="class"?gf(e,s,i):t==="style"?vf(e,n,s):Fs(t)?Ms(t)||Sf(e,t,n,s,o):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):If(e,t,s,i))?(hi(e,t,s),!e.tagName.includes("-")&&(t==="value"||t==="checked"||t==="selected")&&pi(e,t,s,i,o,t!=="value")):e._isVueCE&&(kf(e,t)||e._def.__asyncLoader&&(/[A-Z]/.test(t)||!Pe(s)))?hi(e,et(t),s,o,t):(t==="true-value"?e._trueValue=s:t==="false-value"&&(e._falseValue=s),pi(e,t,s,i))};function If(e,t,n,s){if(s)return!!(t==="innerHTML"||t==="textContent"||t in e&&gi(t)&&le(n));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="autocorrect"||t==="sandbox"&&e.tagName==="IFRAME"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const r=e.tagName;if(r==="IMG"||r==="VIDEO"||r==="CANVAS"||r==="SOURCE")return!1}return gi(t)&&Pe(n)?!1:t in e}function kf(e,t){const n=e._def.props;if(!n)return!1;const s=et(t);return Array.isArray(n)?n.some(r=>et(r)===s):Object.keys(n).some(r=>et(r)===s)}const Jt=e=>{const t=e.props["onUpdate:modelValue"]||!1;return ne(t)?n=>xs(t,n):t};function $f(e){e.target.composing=!0}function yi(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const at=Symbol("_assign");function bi(e,t,n){return t&&(e=e.trim()),n&&(e=js(e)),e}const De={created(e,{modifiers:{lazy:t,trim:n,number:s}},r){e[at]=Jt(r);const o=s||r.props&&r.props.type==="number";Dt(e,t?"change":"input",i=>{i.target.composing||e[at](bi(e.value,n,o))}),(n||o)&&Dt(e,"change",()=>{e.value=bi(e.value,n,o)}),t||(Dt(e,"compositionstart",$f),Dt(e,"compositionend",yi),Dt(e,"change",yi))},mounted(e,{value:t}){e.value=t??""},beforeUpdate(e,{value:t,oldValue:n,modifiers:{lazy:s,trim:r,number:o}},i){if(e[at]=Jt(i),e.composing)return;const l=(o||e.type==="number")&&!/^0\d/.test(e.value)?js(e.value):e.value,a=t??"";if(l===a)return;const c=e.getRootNode();(c instanceof Document||c instanceof ShadowRoot)&&c.activeElement===e&&e.type!=="range"&&(s&&t===n||r&&e.value.trim()===a)||(e.value=a)}},bn={deep:!0,created(e,t,n){e[at]=Jt(n),Dt(e,"change",()=>{const s=e._modelValue,r=Cn(e),o=e.checked,i=e[at];if(ne(s)){const l=Qr(s,r),a=l!==-1;if(o&&!a)i(s.concat(r));else if(!o&&a){const c=[...s];c.splice(l,1),i(c)}}else if(Nn(s)){const l=new Set(s);o?l.add(r):l.delete(r),i(l)}else i(Ea(e,o))})},mounted:xi,beforeUpdate(e,t,n){e[at]=Jt(n),xi(e,t,n)}};function xi(e,{value:t,oldValue:n},s){e._modelValue=t;let r;if(ne(t))r=Qr(t,s.props.value)>-1;else if(Nn(t))r=t.has(s.props.value);else{if(t===n)return;r=zt(t,Ea(e,!0))}e.checked!==r&&(e.checked=r)}const vi={created(e,{value:t},n){e.checked=zt(t,n.props.value),e[at]=Jt(n),Dt(e,"change",()=>{e[at](Cn(e))})},beforeUpdate(e,{value:t,oldValue:n},s){e[at]=Jt(s),t!==n&&(e.checked=zt(t,s.props.value))}},ss={deep:!0,created(e,{value:t,modifiers:{number:n}},s){e._modelValue=t,Dt(e,"change",()=>{const r=Array.prototype.filter.call(e.options,o=>o.selected).map(o=>n?js(Cn(o)):Cn(o));e[at](e.multiple?Nn(e._modelValue)?new Set(r):r:r[0]),e._assigning=!0,io(()=>{e._assigning=!1})}),e[at]=Jt(s)},mounted(e,{value:t}){_i(e,t)},beforeUpdate(e,{value:t},n){e._modelValue=t,e[at]=Jt(n)},updated(e,{value:t}){e._assigning||_i(e,t)}};function _i(e,t){const n=e.multiple,s=ne(t);if(!(n&&!s&&!Nn(t))){for(let r=0,o=e.options.length;rString(c)===String(l)):i.selected=Qr(t,l)>-1}else i.selected=t.has(l);else if(zt(Cn(i),t)){e.selectedIndex!==r&&(e.selectedIndex=r);return}}!n&&e.selectedIndex!==-1&&(e.selectedIndex=-1)}}function Cn(e){return"_value"in e?e._value:e.value}function Ea(e,t){const n=t?"_trueValue":"_falseValue";return n in e?e[n]:t}const Df=["ctrl","shift","alt","meta"],Lf={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>"button"in e&&e.button!==0,middle:e=>"button"in e&&e.button!==1,right:e=>"button"in e&&e.button!==2,exact:(e,t)=>Df.some(n=>e[`${n}Key`]&&!t.includes(n))},ct=(e,t)=>{if(!e)return e;const n=e._withMods||(e._withMods={}),s=t.join(".");return n[s]||(n[s]=((r,...o)=>{for(let i=0;i{const n=e._withKeys||(e._withKeys={}),s=t.join(".");return n[s]||(n[s]=(r=>{if(!("key"in r))return;const o=Xt(r.key);if(t.some(i=>i===o||Uf[i]===o))return e(r)}))},Mf=Ue({patchProp:Nf},af);let wi;function Vf(){return wi||(wi=Bc(Mf))}const Bf=((...e)=>{const t=Vf().createApp(...e),{mount:n}=t;return t.mount=s=>{const r=Hf(s);if(!r)return;const o=t._component;!le(o)&&!o.render&&!o.template&&(o.template=r.innerHTML),r.nodeType===1&&(r.textContent="");const i=n(r,!1,jf(r));return r instanceof Element&&(r.removeAttribute("v-cloak"),r.setAttribute("data-v-app","")),i},t});function jf(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function Hf(e){return Pe(e)?document.querySelector(e):e}/*! + * pinia v2.3.1 + * (c) 2025 Eduardo San Martin Morote + * @license MIT + */const qf=Symbol();var Ei;(function(e){e.direct="direct",e.patchObject="patch object",e.patchFunction="patch function"})(Ei||(Ei={}));function Kf(){const e=Ru(!0),t=e.run(()=>Z({}));let n=[],s=[];const r=Al({install(o){r._a=o,o.provide(qf,r),o.config.globalProperties.$pinia=r,s.forEach(i=>n.push(i)),s=[]},use(o){return this._a?n.push(o):s.push(o),this},_p:n,_a:null,_e:e,_s:new Map,state:t});return r}const Wf={__name:"App",setup(e){return(t,n)=>{const s=kr("router-view");return F(),fn(s,null,{default:dt(({Component:r})=>[Te(ff,{name:"fade",mode:"out-in"},{default:dt(()=>[(F(),fn(xc(r)))]),_:2},1024)]),_:1})}}};/*! + * vue-router v4.6.4 + * (c) 2025 Eduardo San Martin Morote + * @license MIT + */const yn=typeof document<"u";function Sa(e){return typeof e=="object"||"displayName"in e||"props"in e||"__vccOpts"in e}function zf(e){return e.__esModule||e[Symbol.toStringTag]==="Module"||e.default&&Sa(e.default)}const ve=Object.assign;function mr(e,t){const n={};for(const s in t){const r=t[s];n[s]=gt(r)?r.map(e):e(r)}return n}const Gn=()=>{},gt=Array.isArray;function Si(e,t){const n={};for(const s in e)n[s]=s in t?t[s]:e[s];return n}const Ra=/#/g,Gf=/&/g,Jf=/\//g,Xf=/=/g,Yf=/\?/g,Ca=/\+/g,Qf=/%5B/g,Zf=/%5D/g,Aa=/%5E/g,ed=/%60/g,Oa=/%7B/g,td=/%7C/g,Ta=/%7D/g,nd=/%20/g;function ho(e){return e==null?"":encodeURI(""+e).replace(td,"|").replace(Qf,"[").replace(Zf,"]")}function sd(e){return ho(e).replace(Oa,"{").replace(Ta,"}").replace(Aa,"^")}function Vr(e){return ho(e).replace(Ca,"%2B").replace(nd,"+").replace(Ra,"%23").replace(Gf,"%26").replace(ed,"`").replace(Oa,"{").replace(Ta,"}").replace(Aa,"^")}function rd(e){return Vr(e).replace(Xf,"%3D")}function od(e){return ho(e).replace(Ra,"%23").replace(Yf,"%3F")}function id(e){return od(e).replace(Jf,"%2F")}function rs(e){if(e==null)return null;try{return decodeURIComponent(""+e)}catch{}return""+e}const ld=/\/$/,ad=e=>e.replace(ld,"");function gr(e,t,n="/"){let s,r={},o="",i="";const l=t.indexOf("#");let a=t.indexOf("?");return a=l>=0&&a>l?-1:a,a>=0&&(s=t.slice(0,a),o=t.slice(a,l>0?l:t.length),r=e(o.slice(1))),l>=0&&(s=s||t.slice(0,l),i=t.slice(l,t.length)),s=dd(s??t,n),{fullPath:s+o+i,path:s,query:r,hash:rs(i)}}function ud(e,t){const n=t.query?e(t.query):"";return t.path+(n&&"?")+n+(t.hash||"")}function Ri(e,t){return!t||!e.toLowerCase().startsWith(t.toLowerCase())?e:e.slice(t.length)||"/"}function cd(e,t,n){const s=t.matched.length-1,r=n.matched.length-1;return s>-1&&s===r&&An(t.matched[s],n.matched[r])&&Pa(t.params,n.params)&&e(t.query)===e(n.query)&&t.hash===n.hash}function An(e,t){return(e.aliasOf||e)===(t.aliasOf||t)}function Pa(e,t){if(Object.keys(e).length!==Object.keys(t).length)return!1;for(var n in e)if(!fd(e[n],t[n]))return!1;return!0}function fd(e,t){return gt(e)?Ci(e,t):gt(t)?Ci(t,e):(e==null?void 0:e.valueOf())===(t==null?void 0:t.valueOf())}function Ci(e,t){return gt(t)?e.length===t.length&&e.every((n,s)=>n===t[s]):e.length===1&&e[0]===t}function dd(e,t){if(e.startsWith("/"))return e;if(!e)return t;const n=t.split("/"),s=e.split("/"),r=s[s.length-1];(r===".."||r===".")&&s.push("");let o=n.length-1,i,l;for(i=0;i1&&o--;else break;return n.slice(0,o).join("/")+"/"+s.slice(i).join("/")}const jt={path:"/",name:void 0,params:{},query:{},hash:"",fullPath:"/",matched:[],meta:{},redirectedFrom:void 0};let Br=(function(e){return e.pop="pop",e.push="push",e})({}),yr=(function(e){return e.back="back",e.forward="forward",e.unknown="",e})({});function pd(e){if(!e)if(yn){const t=document.querySelector("base");e=t&&t.getAttribute("href")||"/",e=e.replace(/^\w+:\/\/[^\/]+/,"")}else e="/";return e[0]!=="/"&&e[0]!=="#"&&(e="/"+e),ad(e)}const hd=/^[^#]+#/;function md(e,t){return e.replace(hd,"#")+t}function gd(e,t){const n=document.documentElement.getBoundingClientRect(),s=e.getBoundingClientRect();return{behavior:t.behavior,left:s.left-n.left-(t.left||0),top:s.top-n.top-(t.top||0)}}const Ys=()=>({left:window.scrollX,top:window.scrollY});function yd(e){let t;if("el"in e){const n=e.el,s=typeof n=="string"&&n.startsWith("#"),r=typeof n=="string"?s?document.getElementById(n.slice(1)):document.querySelector(n):n;if(!r)return;t=gd(r,e)}else t=e;"scrollBehavior"in document.documentElement.style?window.scrollTo(t):window.scrollTo(t.left!=null?t.left:window.scrollX,t.top!=null?t.top:window.scrollY)}function Ai(e,t){return(history.state?history.state.position-t:-1)+e}const jr=new Map;function bd(e,t){jr.set(e,t)}function xd(e){const t=jr.get(e);return jr.delete(e),t}function vd(e){return typeof e=="string"||e&&typeof e=="object"}function Na(e){return typeof e=="string"||typeof e=="symbol"}let Ie=(function(e){return e[e.MATCHER_NOT_FOUND=1]="MATCHER_NOT_FOUND",e[e.NAVIGATION_GUARD_REDIRECT=2]="NAVIGATION_GUARD_REDIRECT",e[e.NAVIGATION_ABORTED=4]="NAVIGATION_ABORTED",e[e.NAVIGATION_CANCELLED=8]="NAVIGATION_CANCELLED",e[e.NAVIGATION_DUPLICATED=16]="NAVIGATION_DUPLICATED",e})({});const Ia=Symbol("");Ie.MATCHER_NOT_FOUND+"",Ie.NAVIGATION_GUARD_REDIRECT+"",Ie.NAVIGATION_ABORTED+"",Ie.NAVIGATION_CANCELLED+"",Ie.NAVIGATION_DUPLICATED+"";function On(e,t){return ve(new Error,{type:e,[Ia]:!0},t)}function Pt(e,t){return e instanceof Error&&Ia in e&&(t==null||!!(e.type&t))}const _d=["params","query","hash"];function wd(e){if(typeof e=="string")return e;if(e.path!=null)return e.path;const t={};for(const n of _d)n in e&&(t[n]=e[n]);return JSON.stringify(t,null,2)}function Ed(e){const t={};if(e===""||e==="?")return t;const n=(e[0]==="?"?e.slice(1):e).split("&");for(let s=0;sr&&Vr(r)):[s&&Vr(s)]).forEach(r=>{r!==void 0&&(t+=(t.length?"&":"")+n,r!=null&&(t+="="+r))})}return t}function Sd(e){const t={};for(const n in e){const s=e[n];s!==void 0&&(t[n]=gt(s)?s.map(r=>r==null?null:""+r):s==null?s:""+s)}return t}const Rd=Symbol(""),Ti=Symbol(""),Qs=Symbol(""),mo=Symbol(""),Hr=Symbol("");function Fn(){let e=[];function t(s){return e.push(s),()=>{const r=e.indexOf(s);r>-1&&e.splice(r,1)}}function n(){e=[]}return{add:t,list:()=>e.slice(),reset:n}}function Kt(e,t,n,s,r,o=i=>i()){const i=s&&(s.enterCallbacks[r]=s.enterCallbacks[r]||[]);return()=>new Promise((l,a)=>{const c=h=>{h===!1?a(On(Ie.NAVIGATION_ABORTED,{from:n,to:t})):h instanceof Error?a(h):vd(h)?a(On(Ie.NAVIGATION_GUARD_REDIRECT,{from:t,to:h})):(i&&s.enterCallbacks[r]===i&&typeof h=="function"&&i.push(h),l())},u=o(()=>e.call(s&&s.instances[r],t,n,c));let f=Promise.resolve(u);e.length<3&&(f=f.then(c)),f.catch(h=>a(h))})}function br(e,t,n,s,r=o=>o()){const o=[];for(const i of e)for(const l in i.components){let a=i.components[l];if(!(t!=="beforeRouteEnter"&&!i.instances[l]))if(Sa(a)){const c=(a.__vccOpts||a)[t];c&&o.push(Kt(c,n,s,i,l,r))}else{let c=a();o.push(()=>c.then(u=>{if(!u)throw new Error(`Couldn't resolve component "${l}" at "${i.path}"`);const f=zf(u)?u.default:u;i.mods[l]=u,i.components[l]=f;const h=(f.__vccOpts||f)[t];return h&&Kt(h,n,s,i,l,r)()}))}}return o}function Cd(e,t){const n=[],s=[],r=[],o=Math.max(t.matched.length,e.matched.length);for(let i=0;iAn(c,l))?s.push(l):n.push(l));const a=e.matched[i];a&&(t.matched.find(c=>An(c,a))||r.push(a))}return[n,s,r]}/*! + * vue-router v4.6.4 + * (c) 2025 Eduardo San Martin Morote + * @license MIT + */let Ad=()=>location.protocol+"//"+location.host;function ka(e,t){const{pathname:n,search:s,hash:r}=t,o=e.indexOf("#");if(o>-1){let i=r.includes(e.slice(o))?e.slice(o).length:1,l=r.slice(i);return l[0]!=="/"&&(l="/"+l),Ri(l,"")}return Ri(n,e)+s+r}function Od(e,t,n,s){let r=[],o=[],i=null;const l=({state:h})=>{const m=ka(e,location),R=n.value,C=t.value;let P=0;if(h){if(n.value=m,t.value=h,i&&i===R){i=null;return}P=C?h.position-C.position:0}else s(m);r.forEach(_=>{_(n.value,R,{delta:P,type:Br.pop,direction:P?P>0?yr.forward:yr.back:yr.unknown})})};function a(){i=n.value}function c(h){r.push(h);const m=()=>{const R=r.indexOf(h);R>-1&&r.splice(R,1)};return o.push(m),m}function u(){if(document.visibilityState==="hidden"){const{history:h}=window;if(!h.state)return;h.replaceState(ve({},h.state,{scroll:Ys()}),"")}}function f(){for(const h of o)h();o=[],window.removeEventListener("popstate",l),window.removeEventListener("pagehide",u),document.removeEventListener("visibilitychange",u)}return window.addEventListener("popstate",l),window.addEventListener("pagehide",u),document.addEventListener("visibilitychange",u),{pauseListeners:a,listen:c,destroy:f}}function Pi(e,t,n,s=!1,r=!1){return{back:e,current:t,forward:n,replaced:s,position:window.history.length,scroll:r?Ys():null}}function Td(e){const{history:t,location:n}=window,s={value:ka(e,n)},r={value:t.state};r.value||o(s.value,{back:null,current:s.value,forward:null,position:t.length-1,replaced:!0,scroll:null},!0);function o(a,c,u){const f=e.indexOf("#"),h=f>-1?(n.host&&document.querySelector("base")?e:e.slice(f))+a:Ad()+e+a;try{t[u?"replaceState":"pushState"](c,"",h),r.value=c}catch(m){console.error(m),n[u?"replace":"assign"](h)}}function i(a,c){o(a,ve({},t.state,Pi(r.value.back,a,r.value.forward,!0),c,{position:r.value.position}),!0),s.value=a}function l(a,c){const u=ve({},r.value,t.state,{forward:a,scroll:Ys()});o(u.current,u,!0),o(a,ve({},Pi(s.value,a,null),{position:u.position+1},c),!1),s.value=a}return{location:s,state:r,push:l,replace:i}}function Pd(e){e=pd(e);const t=Td(e),n=Od(e,t.state,t.location,t.replace);function s(o,i=!0){i||n.pauseListeners(),history.go(o)}const r=ve({location:"",base:e,go:s,createHref:md.bind(null,e)},t,n);return Object.defineProperty(r,"location",{enumerable:!0,get:()=>t.location.value}),Object.defineProperty(r,"state",{enumerable:!0,get:()=>t.state.value}),r}let on=(function(e){return e[e.Static=0]="Static",e[e.Param=1]="Param",e[e.Group=2]="Group",e})({});var Le=(function(e){return e[e.Static=0]="Static",e[e.Param=1]="Param",e[e.ParamRegExp=2]="ParamRegExp",e[e.ParamRegExpEnd=3]="ParamRegExpEnd",e[e.EscapeNext=4]="EscapeNext",e})(Le||{});const Nd={type:on.Static,value:""},Id=/[a-zA-Z0-9_]/;function kd(e){if(!e)return[[]];if(e==="/")return[[Nd]];if(!e.startsWith("/"))throw new Error(`Invalid path "${e}"`);function t(m){throw new Error(`ERR (${n})/"${c}": ${m}`)}let n=Le.Static,s=n;const r=[];let o;function i(){o&&r.push(o),o=[]}let l=0,a,c="",u="";function f(){c&&(n===Le.Static?o.push({type:on.Static,value:c}):n===Le.Param||n===Le.ParamRegExp||n===Le.ParamRegExpEnd?(o.length>1&&(a==="*"||a==="+")&&t(`A repeatable param (${c}) must be alone in its segment. eg: '/:ids+.`),o.push({type:on.Param,value:c,regexp:u,repeatable:a==="*"||a==="+",optional:a==="*"||a==="?"})):t("Invalid state to consume buffer"),c="")}function h(){c+=a}for(;lt.length?t.length===1&&t[0]===Qe.Static+Qe.Segment?1:-1:0}function $a(e,t){let n=0;const s=e.score,r=t.score;for(;n0&&t[t.length-1]<0}const Fd={strict:!1,end:!0,sensitive:!1};function Md(e,t,n){const s=Ld(kd(e.path),n),r=ve(s,{record:e,parent:t,children:[],alias:[]});return t&&!r.record.aliasOf==!t.record.aliasOf&&t.children.push(r),r}function Vd(e,t){const n=[],s=new Map;t=Si(Fd,t);function r(f){return s.get(f)}function o(f,h,m){const R=!m,C=$i(f);C.aliasOf=m&&m.record;const P=Si(t,f),_=[C];if("alias"in f){const E=typeof f.alias=="string"?[f.alias]:f.alias;for(const O of E)_.push($i(ve({},C,{components:m?m.record.components:C.components,path:O,aliasOf:m?m.record:C})))}let b,A;for(const E of _){const{path:O}=E;if(h&&O[0]!=="/"){const D=h.record.path,L=D[D.length-1]==="/"?"":"/";E.path=h.record.path+(O&&L+O)}if(b=Md(E,h,P),m?m.alias.push(b):(A=A||b,A!==b&&A.alias.push(b),R&&f.name&&!Di(b)&&i(f.name)),Da(b)&&a(b),C.children){const D=C.children;for(let L=0;L{i(A)}:Gn}function i(f){if(Na(f)){const h=s.get(f);h&&(s.delete(f),n.splice(n.indexOf(h),1),h.children.forEach(i),h.alias.forEach(i))}else{const h=n.indexOf(f);h>-1&&(n.splice(h,1),f.record.name&&s.delete(f.record.name),f.children.forEach(i),f.alias.forEach(i))}}function l(){return n}function a(f){const h=Hd(f,n);n.splice(h,0,f),f.record.name&&!Di(f)&&s.set(f.record.name,f)}function c(f,h){let m,R={},C,P;if("name"in f&&f.name){if(m=s.get(f.name),!m)throw On(Ie.MATCHER_NOT_FOUND,{location:f});P=m.record.name,R=ve(ki(h.params,m.keys.filter(A=>!A.optional).concat(m.parent?m.parent.keys.filter(A=>A.optional):[]).map(A=>A.name)),f.params&&ki(f.params,m.keys.map(A=>A.name))),C=m.stringify(R)}else if(f.path!=null)C=f.path,m=n.find(A=>A.re.test(C)),m&&(R=m.parse(C),P=m.record.name);else{if(m=h.name?s.get(h.name):n.find(A=>A.re.test(h.path)),!m)throw On(Ie.MATCHER_NOT_FOUND,{location:f,currentLocation:h});P=m.record.name,R=ve({},h.params,f.params),C=m.stringify(R)}const _=[];let b=m;for(;b;)_.unshift(b.record),b=b.parent;return{name:P,path:C,params:R,matched:_,meta:jd(_)}}e.forEach(f=>o(f));function u(){n.length=0,s.clear()}return{addRoute:o,resolve:c,removeRoute:i,clearRoutes:u,getRoutes:l,getRecordMatcher:r}}function ki(e,t){const n={};for(const s of t)s in e&&(n[s]=e[s]);return n}function $i(e){const t={path:e.path,redirect:e.redirect,name:e.name,meta:e.meta||{},aliasOf:e.aliasOf,beforeEnter:e.beforeEnter,props:Bd(e),children:e.children||[],instances:{},leaveGuards:new Set,updateGuards:new Set,enterCallbacks:{},components:"components"in e?e.components||null:e.component&&{default:e.component}};return Object.defineProperty(t,"mods",{value:{}}),t}function Bd(e){const t={},n=e.props||!1;if("component"in e)t.default=n;else for(const s in e.components)t[s]=typeof n=="object"?n[s]:n;return t}function Di(e){for(;e;){if(e.record.aliasOf)return!0;e=e.parent}return!1}function jd(e){return e.reduce((t,n)=>ve(t,n.meta),{})}function Hd(e,t){let n=0,s=t.length;for(;n!==s;){const o=n+s>>1;$a(e,t[o])<0?s=o:n=o+1}const r=qd(e);return r&&(s=t.lastIndexOf(r,s-1)),s}function qd(e){let t=e;for(;t=t.parent;)if(Da(t)&&$a(e,t)===0)return t}function Da({record:e}){return!!(e.name||e.components&&Object.keys(e.components).length||e.redirect)}function Li(e){const t=pt(Qs),n=pt(mo),s=tt(()=>{const a=_n(e.to);return t.resolve(a)}),r=tt(()=>{const{matched:a}=s.value,{length:c}=a,u=a[c-1],f=n.matched;if(!u||!f.length)return-1;const h=f.findIndex(An.bind(null,u));if(h>-1)return h;const m=Ui(a[c-2]);return c>1&&Ui(u)===m&&f[f.length-1].path!==m?f.findIndex(An.bind(null,a[c-2])):h}),o=tt(()=>r.value>-1&&Jd(n.params,s.value.params)),i=tt(()=>r.value>-1&&r.value===n.matched.length-1&&Pa(n.params,s.value.params));function l(a={}){if(Gd(a)){const c=t[_n(e.replace)?"replace":"push"](_n(e.to)).catch(Gn);return e.viewTransition&&typeof document<"u"&&"startViewTransition"in document&&document.startViewTransition(()=>c),c}return Promise.resolve()}return{route:s,href:tt(()=>s.value.href),isActive:o,isExactActive:i,navigate:l}}function Kd(e){return e.length===1?e[0]:e}const Wd=Kl({name:"RouterLink",compatConfig:{MODE:3},props:{to:{type:[String,Object],required:!0},replace:Boolean,activeClass:String,exactActiveClass:String,custom:Boolean,ariaCurrentValue:{type:String,default:"page"},viewTransition:Boolean},useLink:Li,setup(e,{slots:t}){const n=At(Li(e)),{options:s}=pt(Qs),r=tt(()=>({[Fi(e.activeClass,s.linkActiveClass,"router-link-active")]:n.isActive,[Fi(e.exactActiveClass,s.linkExactActiveClass,"router-link-exact-active")]:n.isExactActive}));return()=>{const o=t.default&&Kd(t.default(n));return e.custom?o:po("a",{"aria-current":n.isExactActive?e.ariaCurrentValue:null,href:n.href,onClick:n.navigate,class:r.value},o)}}}),zd=Wd;function Gd(e){if(!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)&&!e.defaultPrevented&&!(e.button!==void 0&&e.button!==0)){if(e.currentTarget&&e.currentTarget.getAttribute){const t=e.currentTarget.getAttribute("target");if(/\b_blank\b/i.test(t))return}return e.preventDefault&&e.preventDefault(),!0}}function Jd(e,t){for(const n in t){const s=t[n],r=e[n];if(typeof s=="string"){if(s!==r)return!1}else if(!gt(r)||r.length!==s.length||s.some((o,i)=>o.valueOf()!==r[i].valueOf()))return!1}return!0}function Ui(e){return e?e.aliasOf?e.aliasOf.path:e.path:""}const Fi=(e,t,n)=>e??t??n,Xd=Kl({name:"RouterView",inheritAttrs:!1,props:{name:{type:String,default:"default"},route:Object},compatConfig:{MODE:3},setup(e,{attrs:t,slots:n}){const s=pt(Hr),r=tt(()=>e.route||s.value),o=pt(Ti,0),i=tt(()=>{let c=_n(o);const{matched:u}=r.value;let f;for(;(f=u[c])&&!f.components;)c++;return c}),l=tt(()=>r.value.matched[i.value]);vs(Ti,tt(()=>i.value+1)),vs(Rd,l),vs(Hr,r);const a=Z();return _s(()=>[a.value,l.value,e.name],([c,u,f],[h,m,R])=>{u&&(u.instances[f]=c,m&&m!==u&&c&&c===h&&(u.leaveGuards.size||(u.leaveGuards=m.leaveGuards),u.updateGuards.size||(u.updateGuards=m.updateGuards))),c&&u&&(!m||!An(u,m)||!h)&&(u.enterCallbacks[f]||[]).forEach(C=>C(c))},{flush:"post"}),()=>{const c=r.value,u=e.name,f=l.value,h=f&&f.components[u];if(!h)return Mi(n.default,{Component:h,route:c});const m=f.props[u],R=m?m===!0?c.params:typeof m=="function"?m(c):m:null,P=po(h,ve({},R,t,{onVnodeUnmounted:_=>{_.component.isUnmounted&&(f.instances[u]=null)},ref:a}));return Mi(n.default,{Component:P,route:c})||P}}});function Mi(e,t){if(!e)return null;const n=e(t);return n.length===1?n[0]:n}const Yd=Xd;function Qd(e){const t=Vd(e.routes,e),n=e.parseQuery||Ed,s=e.stringifyQuery||Oi,r=e.history,o=Fn(),i=Fn(),l=Fn(),a=qu(jt);let c=jt;yn&&e.scrollBehavior&&"scrollRestoration"in history&&(history.scrollRestoration="manual");const u=mr.bind(null,y=>""+y),f=mr.bind(null,id),h=mr.bind(null,rs);function m(y,B){let M,X;return Na(y)?(M=t.getRecordMatcher(y),X=B):X=y,t.addRoute(X,M)}function R(y){const B=t.getRecordMatcher(y);B&&t.removeRoute(B)}function C(){return t.getRoutes().map(y=>y.record)}function P(y){return!!t.getRecordMatcher(y)}function _(y,B){if(B=ve({},B||a.value),typeof y=="string"){const v=gr(n,y,B.path),N=t.resolve({path:v.path},B),S=r.createHref(v.fullPath);return ve(v,N,{params:h(N.params),hash:rs(v.hash),redirectedFrom:void 0,href:S})}let M;if(y.path!=null)M=ve({},y,{path:gr(n,y.path,B.path).path});else{const v=ve({},y.params);for(const N in v)v[N]==null&&delete v[N];M=ve({},y,{params:f(v)}),B.params=f(B.params)}const X=t.resolve(M,B),Q=y.hash||"";X.params=u(h(X.params));const p=ud(s,ve({},y,{hash:sd(Q),path:X.path})),g=r.createHref(p);return ve({fullPath:p,hash:Q,query:s===Oi?Sd(y.query):y.query||{}},X,{redirectedFrom:void 0,href:g})}function b(y){return typeof y=="string"?gr(n,y,a.value.path):ve({},y)}function A(y,B){if(c!==y)return On(Ie.NAVIGATION_CANCELLED,{from:B,to:y})}function E(y){return L(y)}function O(y){return E(ve(b(y),{replace:!0}))}function D(y,B){const M=y.matched[y.matched.length-1];if(M&&M.redirect){const{redirect:X}=M;let Q=typeof X=="function"?X(y,B):X;return typeof Q=="string"&&(Q=Q.includes("?")||Q.includes("#")?Q=b(Q):{path:Q},Q.params={}),ve({query:y.query,hash:y.hash,params:Q.path!=null?{}:y.params},Q)}}function L(y,B){const M=c=_(y),X=a.value,Q=y.state,p=y.force,g=y.replace===!0,v=D(M,X);if(v)return L(ve(b(v),{state:typeof v=="object"?ve({},Q,v.state):Q,force:p,replace:g}),B||M);const N=M;N.redirectedFrom=B;let S;return!p&&cd(s,X,M)&&(S=On(Ie.NAVIGATION_DUPLICATED,{to:N,from:X}),re(X,X,!0,!1)),(S?Promise.resolve(S):se(N,X)).catch(T=>Pt(T)?Pt(T,Ie.NAVIGATION_GUARD_REDIRECT)?T:z(T):$(T,N,X)).then(T=>{if(T){if(Pt(T,Ie.NAVIGATION_GUARD_REDIRECT))return L(ve({replace:g},b(T.to),{state:typeof T.to=="object"?ve({},Q,T.to.state):Q,force:p}),B||N)}else T=W(N,X,!0,g,Q);return oe(N,X,T),T})}function ae(y,B){const M=A(y,B);return M?Promise.reject(M):Promise.resolve()}function Y(y){const B=de.values().next().value;return B&&typeof B.runWithContext=="function"?B.runWithContext(y):y()}function se(y,B){let M;const[X,Q,p]=Cd(y,B);M=br(X.reverse(),"beforeRouteLeave",y,B);for(const v of X)v.leaveGuards.forEach(N=>{M.push(Kt(N,y,B))});const g=ae.bind(null,y,B);return M.push(g),w(M).then(()=>{M=[];for(const v of o.list())M.push(Kt(v,y,B));return M.push(g),w(M)}).then(()=>{M=br(Q,"beforeRouteUpdate",y,B);for(const v of Q)v.updateGuards.forEach(N=>{M.push(Kt(N,y,B))});return M.push(g),w(M)}).then(()=>{M=[];for(const v of p)if(v.beforeEnter)if(gt(v.beforeEnter))for(const N of v.beforeEnter)M.push(Kt(N,y,B));else M.push(Kt(v.beforeEnter,y,B));return M.push(g),w(M)}).then(()=>(y.matched.forEach(v=>v.enterCallbacks={}),M=br(p,"beforeRouteEnter",y,B,Y),M.push(g),w(M))).then(()=>{M=[];for(const v of i.list())M.push(Kt(v,y,B));return M.push(g),w(M)}).catch(v=>Pt(v,Ie.NAVIGATION_CANCELLED)?v:Promise.reject(v))}function oe(y,B,M){l.list().forEach(X=>Y(()=>X(y,B,M)))}function W(y,B,M,X,Q){const p=A(y,B);if(p)return p;const g=B===jt,v=yn?history.state:{};M&&(X||g?r.replace(y.fullPath,ve({scroll:g&&v&&v.scroll},Q)):r.push(y.fullPath,Q)),a.value=y,re(y,B,M,g),z()}let ue;function fe(){ue||(ue=r.listen((y,B,M)=>{if(!I.listening)return;const X=_(y),Q=D(X,I.currentRoute.value);if(Q){L(ve(Q,{replace:!0,force:!0}),X).catch(Gn);return}c=X;const p=a.value;yn&&bd(Ai(p.fullPath,M.delta),Ys()),se(X,p).catch(g=>Pt(g,Ie.NAVIGATION_ABORTED|Ie.NAVIGATION_CANCELLED)?g:Pt(g,Ie.NAVIGATION_GUARD_REDIRECT)?(L(ve(b(g.to),{force:!0}),X).then(v=>{Pt(v,Ie.NAVIGATION_ABORTED|Ie.NAVIGATION_DUPLICATED)&&!M.delta&&M.type===Br.pop&&r.go(-1,!1)}).catch(Gn),Promise.reject()):(M.delta&&r.go(-M.delta,!1),$(g,X,p))).then(g=>{g=g||W(X,p,!1),g&&(M.delta&&!Pt(g,Ie.NAVIGATION_CANCELLED)?r.go(-M.delta,!1):M.type===Br.pop&&Pt(g,Ie.NAVIGATION_ABORTED|Ie.NAVIGATION_DUPLICATED)&&r.go(-1,!1)),oe(X,p,g)}).catch(Gn)}))}let Ne=Fn(),me=Fn(),pe;function $(y,B,M){z(y);const X=me.list();return X.length?X.forEach(Q=>Q(y,B,M)):console.error(y),Promise.reject(y)}function k(){return pe&&a.value!==jt?Promise.resolve():new Promise((y,B)=>{Ne.add([y,B])})}function z(y){return pe||(pe=!y,fe(),Ne.list().forEach(([B,M])=>y?M(y):B()),Ne.reset()),y}function re(y,B,M,X){const{scrollBehavior:Q}=e;if(!yn||!Q)return Promise.resolve();const p=!M&&xd(Ai(y.fullPath,0))||(X||!M)&&history.state&&history.state.scroll||null;return io().then(()=>Q(y,B,p)).then(g=>g&&yd(g)).catch(g=>$(g,y,B))}const he=y=>r.go(y);let Oe;const de=new Set,I={currentRoute:a,listening:!0,addRoute:m,removeRoute:R,clearRoutes:t.clearRoutes,hasRoute:P,getRoutes:C,resolve:_,options:e,push:E,replace:O,go:he,back:()=>he(-1),forward:()=>he(1),beforeEach:o.add,beforeResolve:i.add,afterEach:l.add,onError:me.add,isReady:k,install(y){y.component("RouterLink",zd),y.component("RouterView",Yd),y.config.globalProperties.$router=I,Object.defineProperty(y.config.globalProperties,"$route",{enumerable:!0,get:()=>_n(a)}),yn&&!Oe&&a.value===jt&&(Oe=!0,E(r.location).catch(X=>{}));const B={};for(const X in jt)Object.defineProperty(B,X,{get:()=>a.value[X],enumerable:!0});y.provide(Qs,I),y.provide(mo,Cl(B)),y.provide(Hr,a);const M=y.unmount;de.add(y),y.unmount=function(){de.delete(y),de.size<1&&(c=jt,ue&&ue(),ue=null,a.value=jt,Oe=!1,pe=!1),M()}}};function w(y){return y.reduce((B,M)=>B.then(()=>Y(M)),Promise.resolve())}return I}function Zd(){return pt(Qs)}function ep(e){return pt(mo)}const go="sub_store_remote_uri",yo="sub_store_admin_token",bo="sub_store_token_validated";function La(e){const t=(e||"").trim().replace(/\/+$/,"").replace(/\/api$/,"");if(!t)return"";const n=new URL(t);if(!["http:","https:"].includes(n.protocol))throw new Error("Remote URI must use http or https");return n.toString().replace(/\/+$/,"")}function tp(e,t){const n=La(e);n&&t&&(localStorage.setItem(go,n),localStorage.setItem(yo,t),localStorage.setItem(bo,"true"))}function xo(){return localStorage.getItem(go)||""}function Ua(){return localStorage.getItem(yo)||""}function np(){return localStorage.getItem(bo)==="true"}function sp(){localStorage.removeItem(go),localStorage.removeItem(yo),localStorage.removeItem(bo)}async function rp(e,t){if(!e)return!1;try{const n=La(t),s=await fetch(`${n}/api/env`,{headers:{Authorization:`Bearer ${e}`}});return s.ok?(await s.json()).status==="success":!1}catch{return!1}}function op(){return Ua()}function ip(){var e;return xo()||((e=window.SUB_STORE_CONFIG)==null?void 0:e.apiBaseUrl)||""}const lp={class:"min-h-screen flex bg-gray-50"},ap={class:"w-60 bg-gray-900 text-gray-300 flex flex-col fixed inset-y-0 left-0 z-30"},up={class:"flex-1 py-3 overflow-y-auto"},cp={class:"text-base"},fp={class:"flex-1 ml-60 min-h-screen"},dp={class:"px-6 py-5"},pp={__name:"AdminLayout",setup(e){const t=[{to:"/",icon:"📊",label:"概览"},{to:"/sources",icon:"📡",label:"订阅源"},{to:"/collections",icon:"📁",label:"合集"},{to:"/templates",icon:"📋",label:"模板"},{to:"/recycle-bin",icon:"♻️",label:"回收站"},{to:"/tools",icon:"🔧",label:"工具"},{to:"/settings",icon:"⚙️",label:"设置"}];return(n,s)=>{const r=kr("router-link"),o=kr("router-view");return F(),V("div",lp,[d("aside",ap,[s[0]||(s[0]=d("div",{class:"px-5 py-4 border-b border-gray-700"},[d("h1",{class:"text-lg font-bold text-white flex items-center gap-2"},[d("span",{class:"inline-block w-2 h-2 bg-primary-500 rounded-full"}),Wt(" SubStore ")])],-1)),d("nav",up,[(F(),V(we,null,Be(t,i=>Te(r,{key:i.to,to:i.to,class:Fe(["flex items-center gap-3 px-5 py-2.5 text-sm transition-colors",n.$route.path===i.to||i.to!=="/"&&n.$route.path.startsWith(i.to)?"bg-gray-800 text-white border-l-2 border-primary-500":"hover:bg-gray-800/50 border-l-2 border-transparent"])},{default:dt(()=>[d("span",cp,j(i.icon),1),d("span",null,j(i.label),1)]),_:2},1032,["to","class"])),64))])]),d("main",fp,[d("div",dp,[Te(o)])])])}}},hp={class:"min-h-screen bg-gray-50 flex items-center justify-center px-4"},mp={key:0,class:"mt-4 text-sm text-red-600"},gp=["disabled"],yp={__name:"Login",setup(e){const t=ep(),n=Zd(),s=Z(xo()||window.location.origin),r=Z(""),o=Z(!1),i=Z("");async function l(){i.value="",o.value=!0;try{if(!await rp(r.value,s.value)){i.value="远程 URI 或 TOKEN 无效";return}tp(s.value,r.value),n.replace(typeof t.query.redirect=="string"?t.query.redirect:"/")}catch{i.value="远程 URI 格式无效"}finally{o.value=!1}}return(a,c)=>(F(),V("div",hp,[d("form",{class:"w-full max-w-sm bg-white border border-gray-200 rounded-lg p-6 shadow-sm",onSubmit:ct(l,["prevent"])},[c[2]||(c[2]=d("label",{class:"block text-sm font-medium text-gray-700",for:"remote-uri"},"远程 URI",-1)),ye(d("input",{id:"remote-uri","onUpdate:modelValue":c[0]||(c[0]=u=>s.value=u),type:"url",required:"",autocomplete:"url",placeholder:"https://sub-store.example.com",class:"mt-2 w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-primary-500"},null,512),[[De,s.value,void 0,{trim:!0}]]),c[3]||(c[3]=d("label",{class:"block mt-4 text-sm font-medium text-gray-700",for:"token"},"TOKEN",-1)),ye(d("input",{id:"token","onUpdate:modelValue":c[1]||(c[1]=u=>r.value=u),type:"password",required:"",autocomplete:"current-password",class:"mt-2 w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-primary-500"},null,512),[[De,r.value,void 0,{trim:!0}]]),i.value?(F(),V("p",mp,j(i.value),1)):ce("",!0),d("button",{type:"submit",disabled:o.value,class:"mt-6 w-full px-4 py-2 rounded-lg bg-primary-600 text-white text-sm font-medium hover:bg-primary-700 disabled:opacity-60 disabled:cursor-not-allowed"},j(o.value?"登录中...":"登录"),9,gp)],32)]))}},bp={class:"min-h-screen flex items-center justify-center bg-gray-50"},xp={__name:"NotFound",setup(e){return(t,n)=>(F(),V("div",bp,[...n[0]||(n[0]=[d("div",{class:"text-center"},[d("p",{class:"text-7xl font-bold text-gray-300"},"404"),d("p",{class:"mt-4 text-gray-400"},"Page Not Found")],-1)])]))}};function Fa(e,t){return function(){return e.apply(t,arguments)}}const{toString:vp}=Object.prototype,{getPrototypeOf:Tn}=Object,{iterator:cs,toStringTag:Ma}=Symbol,$s=(({hasOwnProperty:e})=>(t,n)=>e.call(t,n))(Object.prototype),os=(e,t)=>{let n=e;const s=[];for(;n!=null&&n!==Object.prototype;){if(s.indexOf(n)!==-1)return!1;if(s.push(n),$s(n,t))return!0;n=Tn(n)}return!1},_p=(e,t)=>e!=null&&os(e,t)?e[t]:void 0,vo=(e=>t=>{const n=vp.call(t);return e[n]||(e[n]=n.slice(8,-1).toLowerCase())})(Object.create(null)),yt=e=>(e=e.toLowerCase(),t=>vo(t)===e),Zs=e=>t=>typeof t===e,{isArray:dn}=Array,Pn=Zs("undefined");function In(e){return e!==null&&!Pn(e)&&e.constructor!==null&&!Pn(e.constructor)&&nt(e.constructor.isBuffer)&&e.constructor.isBuffer(e)}const Va=yt("ArrayBuffer");function wp(e){let t;return typeof ArrayBuffer<"u"&&ArrayBuffer.isView?t=ArrayBuffer.isView(e):t=e&&e.buffer&&Va(e.buffer),t}const Ep=Zs("string"),nt=Zs("function"),Ba=Zs("number"),kn=e=>e!==null&&typeof e=="object",Sp=e=>e===!0||e===!1,Es=e=>{if(!kn(e))return!1;const t=Tn(e);return(t===null||t===Object.prototype||Tn(t)===null)&&!os(e,Ma)&&!os(e,cs)},Rp=e=>{if(!kn(e)||In(e))return!1;try{return Object.keys(e).length===0&&Object.getPrototypeOf(e)===Object.prototype}catch{return!1}},Cp=yt("Date"),Ap=yt("File"),Op=e=>!!(e&&typeof e.uri<"u"),Tp=e=>e&&typeof e.getParts<"u",Pp=yt("Blob"),Np=yt("FileList"),Ip=e=>kn(e)&&nt(e.pipe);function kp(){return typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{}}const Vi=kp(),Bi=typeof Vi.FormData<"u"?Vi.FormData:void 0,$p=e=>{if(!e)return!1;if(Bi&&e instanceof Bi)return!0;const t=Tn(e);if(!t||t===Object.prototype||!nt(e.append))return!1;const n=vo(e);return n==="formdata"||n==="object"&&nt(e.toString)&&e.toString()==="[object FormData]"},Dp=yt("URLSearchParams"),[Lp,Up,Fp,Mp]=["ReadableStream","Request","Response","Headers"].map(yt),Vp=e=>e.trim?e.trim():e.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");function fs(e,t,{allOwnKeys:n=!1}={}){if(e===null||typeof e>"u")return;let s,r;if(typeof e!="object"&&(e=[e]),dn(e))for(s=0,r=e.length;s0;)if(r=n[s],t===r.toLowerCase())return r;return null}const ln=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:global,Ha=e=>!Pn(e)&&e!==ln;function qr(...e){const{caseless:t,skipUndefined:n}=Ha(this)&&this||{},s={},r=(o,i)=>{if(i==="__proto__"||i==="constructor"||i==="prototype")return;const l=t&&typeof i=="string"&&ja(s,i)||i,a=$s(s,l)?s[l]:void 0;Es(a)&&Es(o)?s[l]=qr(a,o):Es(o)?s[l]=qr({},o):dn(o)?s[l]=o.slice():(!n||!Pn(o))&&(s[l]=o)};for(let o=0,i=e.length;o(fs(t,(r,o)=>{n&&nt(r)?Object.defineProperty(e,o,{__proto__:null,value:Fa(r,n),writable:!0,enumerable:!0,configurable:!0}):Object.defineProperty(e,o,{__proto__:null,value:r,writable:!0,enumerable:!0,configurable:!0})},{allOwnKeys:s}),e),jp=e=>(e.charCodeAt(0)===65279&&(e=e.slice(1)),e),Hp=(e,t,n,s)=>{e.prototype=Object.create(t.prototype,s),Object.defineProperty(e.prototype,"constructor",{__proto__:null,value:e,writable:!0,enumerable:!1,configurable:!0}),Object.defineProperty(e,"super",{__proto__:null,value:t.prototype}),n&&Object.assign(e.prototype,n)},qp=(e,t,n,s)=>{let r,o,i;const l={};if(t=t||{},e==null)return t;do{for(r=Object.getOwnPropertyNames(e),o=r.length;o-- >0;)i=r[o],(!s||s(i,e,t))&&!l[i]&&(t[i]=e[i],l[i]=!0);e=n!==!1&&Tn(e)}while(e&&(!n||n(e,t))&&e!==Object.prototype);return t},Kp=(e,t,n)=>{e=String(e),(n===void 0||n>e.length)&&(n=e.length),n-=t.length;const s=e.indexOf(t,n);return s!==-1&&s===n},Wp=e=>{if(!e)return null;if(dn(e))return e;let t=e.length;if(!Ba(t))return null;const n=new Array(t);for(;t-- >0;)n[t]=e[t];return n},zp=(e=>t=>e&&t instanceof e)(typeof Uint8Array<"u"&&Tn(Uint8Array)),Gp=(e,t)=>{const s=(e&&e[cs]).call(e);let r;for(;(r=s.next())&&!r.done;){const o=r.value;t.call(e,o[0],o[1])}},Jp=(e,t)=>{let n;const s=[];for(;(n=e.exec(t))!==null;)s.push(n);return s},Xp=yt("HTMLFormElement"),Yp=e=>e.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,function(n,s,r){return s.toUpperCase()+r}),{propertyIsEnumerable:Qp}=Object.prototype,Zp=yt("RegExp"),qa=(e,t)=>{const n=Object.getOwnPropertyDescriptors(e),s={};fs(n,(r,o)=>{let i;(i=t(r,o,e))!==!1&&(s[o]=i||r)}),Object.defineProperties(e,s)},eh=e=>{qa(e,(t,n)=>{if(nt(e)&&["arguments","caller","callee"].includes(n))return!1;const s=e[n];if(nt(s)){if(t.enumerable=!1,"writable"in t){t.writable=!1;return}t.set||(t.set=()=>{throw Error("Can not rewrite read-only method '"+n+"'")})}})},th=(e,t)=>{const n={},s=r=>{r.forEach(o=>{n[o]=!0})};return dn(e)?s(e):s(String(e).split(t)),n},nh=()=>{},sh=(e,t)=>e!=null&&Number.isFinite(e=+e)?e:t;function rh(e){return!!(e&&nt(e.append)&&e[Ma]==="FormData"&&e[cs])}const oh=e=>{const t=new WeakSet,n=s=>{if(kn(s)){if(t.has(s))return;if(In(s))return s;if(!("toJSON"in s)){t.add(s);const r=dn(s)?[]:{};return fs(s,(o,i)=>{const l=n(o);!Pn(l)&&(r[i]=l)}),t.delete(s),r}}return s};return n(e)},ih=yt("AsyncFunction"),lh=e=>e&&(kn(e)||nt(e))&&nt(e.then)&&nt(e.catch),Ka=((e,t)=>e?setImmediate:t?((n,s)=>(ln.addEventListener("message",({source:r,data:o})=>{r===ln&&o===n&&s.length&&s.shift()()},!1),r=>{s.push(r),ln.postMessage(n,"*")}))(`axios@${Math.random()}`,[]):n=>setTimeout(n))(typeof setImmediate=="function",nt(ln.postMessage)),ah=typeof queueMicrotask<"u"?queueMicrotask.bind(ln):typeof process<"u"&&process.nextTick||Ka,Wa=e=>e!=null&&nt(e[cs]),uh=e=>e!=null&&os(e,cs)&&Wa(e),x={isArray:dn,isArrayBuffer:Va,isBuffer:In,isFormData:$p,isArrayBufferView:wp,isString:Ep,isNumber:Ba,isBoolean:Sp,isObject:kn,isPlainObject:Es,isEmptyObject:Rp,isReadableStream:Lp,isRequest:Up,isResponse:Fp,isHeaders:Mp,isUndefined:Pn,isDate:Cp,isFile:Ap,isReactNativeBlob:Op,isReactNative:Tp,isBlob:Pp,isRegExp:Zp,isFunction:nt,isStream:Ip,isURLSearchParams:Dp,isTypedArray:zp,isFileList:Np,forEach:fs,merge:qr,extend:Bp,trim:Vp,stripBOM:jp,inherits:Hp,toFlatObject:qp,kindOf:vo,kindOfTest:yt,endsWith:Kp,toArray:Wp,forEachEntry:Gp,matchAll:Jp,isHTMLForm:Xp,hasOwnProperty:$s,hasOwnProp:$s,hasOwnInPrototypeChain:os,getSafeProp:_p,reduceDescriptors:qa,freezeMethods:eh,toObjectSet:th,toCamelCase:Yp,noop:nh,toFiniteNumber:sh,findKey:ja,global:ln,isContextDefined:Ha,isSpecCompliantForm:rh,toJSONObject:oh,isAsyncFn:ih,isThenable:lh,setImmediate:Ka,asap:ah,isIterable:Wa,isSafeIterable:uh},ch=x.toObjectSet(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"]),fh=e=>{const t={};let n,s,r;return e&&e.split(` +`).forEach(function(i){r=i.indexOf(":"),n=i.substring(0,r).trim().toLowerCase(),s=i.substring(r+1).trim(),!(!n||t[n]&&ch[n])&&(n==="set-cookie"?t[n]?t[n].push(s):t[n]=[s]:t[n]=t[n]?t[n]+", "+s:s)}),t};function dh(e){let t=0,n=e.length;for(;tt;){const s=e.charCodeAt(n-1);if(s!==9&&s!==32)break;n-=1}return t===0&&n===e.length?e:e.slice(t,n)}const ph=new RegExp("[\\u0000-\\u0008\\u000a-\\u001f\\u007f]+","g"),hh=new RegExp("[^\\u0009\\u0020-\\u007e\\u0080-\\u00ff]+","g");function _o(e,t){return x.isArray(e)?e.map(n=>_o(n,t)):dh(String(e).replace(t,""))}const mh=e=>_o(e,ph),gh=e=>_o(e,hh);function za(e){const t=Object.create(null);return x.forEach(e.toJSON(),(n,s)=>{t[s]=gh(n)}),t}const ji=Symbol("internals");function Mn(e){return e&&String(e).trim().toLowerCase()}function Ss(e){return e===!1||e==null?e:x.isArray(e)?e.map(Ss):mh(String(e))}function yh(e){const t=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let s;for(;s=n.exec(e);)t[s[1]]=s[2];return t}const bh=e=>/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(e.trim());function xr(e,t,n,s,r){if(x.isFunction(s))return s.call(this,t,n);if(r&&(t=n),!!x.isString(t)){if(x.isString(s))return t.indexOf(s)!==-1;if(x.isRegExp(s))return s.test(t)}}function xh(e){return e.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,(t,n,s)=>n.toUpperCase()+s)}function vh(e,t){const n=x.toCamelCase(" "+t);["get","set","has"].forEach(s=>{Object.defineProperty(e,s+n,{__proto__:null,value:function(r,o,i){return this[s].call(this,t,r,o,i)},configurable:!0})})}let Je=class{constructor(t){t&&this.set(t)}set(t,n,s){const r=this;function o(l,a,c){const u=Mn(a);if(!u)return;const f=x.findKey(r,u);(!f||r[f]===void 0||c===!0||c===void 0&&r[f]!==!1)&&(r[f||a]=Ss(l))}const i=(l,a)=>x.forEach(l,(c,u)=>o(c,u,a));if(x.isPlainObject(t)||t instanceof this.constructor)i(t,n);else if(x.isString(t)&&(t=t.trim())&&!bh(t))i(fh(t),n);else if(x.isObject(t)&&x.isSafeIterable(t)){let l=Object.create(null),a,c;for(const u of t){if(!x.isArray(u))throw new TypeError("Object iterator must return a key-value pair");c=u[0],x.hasOwnProp(l,c)?(a=l[c],l[c]=x.isArray(a)?[...a,u[1]]:[a,u[1]]):l[c]=u[1]}i(l,n)}else t!=null&&o(n,t,s);return this}get(t,n){if(t=Mn(t),t){const s=x.findKey(this,t);if(s){const r=this[s];if(!n)return r;if(n===!0)return yh(r);if(x.isFunction(n))return n.call(this,r,s);if(x.isRegExp(n))return n.exec(r);throw new TypeError("parser must be boolean|regexp|function")}}}has(t,n){if(t=Mn(t),t){const s=x.findKey(this,t);return!!(s&&this[s]!==void 0&&(!n||xr(this,this[s],s,n)))}return!1}delete(t,n){const s=this;let r=!1;function o(i){if(i=Mn(i),i){const l=x.findKey(s,i);l&&(!n||xr(s,s[l],l,n))&&(delete s[l],r=!0)}}return x.isArray(t)?t.forEach(o):o(t),r}clear(t){const n=Object.keys(this);let s=n.length,r=!1;for(;s--;){const o=n[s];(!t||xr(this,this[o],o,t,!0))&&(delete this[o],r=!0)}return r}normalize(t){const n=this,s={};return x.forEach(this,(r,o)=>{const i=x.findKey(s,o);if(i){n[i]=Ss(r),delete n[o];return}const l=t?xh(o):String(o).trim();l!==o&&delete n[o],n[l]=Ss(r),s[l]=!0}),this}concat(...t){return this.constructor.concat(this,...t)}toJSON(t){const n=Object.create(null);return x.forEach(this,(s,r)=>{s!=null&&s!==!1&&(n[r]=t&&x.isArray(s)?s.join(", "):s)}),n}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map(([t,n])=>t+": "+n).join(` +`)}getSetCookie(){return this.get("set-cookie")||[]}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(t){return t instanceof this?t:new this(t)}static concat(t,...n){const s=new this(t);return n.forEach(r=>s.set(r)),s}static accessor(t){const s=(this[ji]=this[ji]={accessors:{}}).accessors,r=this.prototype;function o(i){const l=Mn(i);s[l]||(vh(r,i),s[l]=!0)}return x.isArray(t)?t.forEach(o):o(t),this}};Je.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]);x.reduceDescriptors(Je.prototype,({value:e},t)=>{let n=t[0].toUpperCase()+t.slice(1);return{get:()=>e,set(s){this[n]=s}}});x.freezeMethods(Je);const _h="[REDACTED ****]";function wh(e){if(x.hasOwnProp(e,"toJSON"))return!0;let t=Object.getPrototypeOf(e);for(;t&&t!==Object.prototype;){if(x.hasOwnProp(t,"toJSON"))return!0;t=Object.getPrototypeOf(t)}return!1}function Eh(e,t){const n=new Set(t.map(o=>String(o).toLowerCase())),s=[],r=o=>{if(o===null||typeof o!="object"||x.isBuffer(o))return o;if(s.indexOf(o)!==-1)return;o instanceof Je&&(o=o.toJSON()),s.push(o);let i;if(x.isArray(o))i=[],o.forEach((l,a)=>{const c=r(l);x.isUndefined(c)||(i[a]=c)});else{if(!x.isPlainObject(o)&&wh(o))return s.pop(),o;i=Object.create(null);for(const[l,a]of Object.entries(o)){const c=n.has(l.toLowerCase())?_h:r(a);x.isUndefined(c)||(i[l]=c)}}return s.pop(),i};return r(e)}let G=class Ga extends Error{static from(t,n,s,r,o,i){const l=new Ga(t.message,n||t.code,s,r,o);return Object.defineProperty(l,"cause",{__proto__:null,value:t,writable:!0,enumerable:!1,configurable:!0}),l.name=t.name,t.status!=null&&l.status==null&&(l.status=t.status),i&&Object.assign(l,i),l}constructor(t,n,s,r,o){super(t),Object.defineProperty(this,"message",{__proto__:null,value:t,enumerable:!0,writable:!0,configurable:!0}),this.name="AxiosError",this.isAxiosError=!0,n&&(this.code=n),s&&(this.config=s),r&&(this.request=r),o&&(this.response=o,this.status=o.status)}toJSON(){const t=this.config,n=t&&x.hasOwnProp(t,"redact")?t.redact:void 0,s=x.isArray(n)&&n.length>0?Eh(t,n):x.toJSONObject(t);return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:s,code:this.code,status:this.status}}};G.ERR_BAD_OPTION_VALUE="ERR_BAD_OPTION_VALUE";G.ERR_BAD_OPTION="ERR_BAD_OPTION";G.ECONNABORTED="ECONNABORTED";G.ETIMEDOUT="ETIMEDOUT";G.ECONNREFUSED="ECONNREFUSED";G.ERR_NETWORK="ERR_NETWORK";G.ERR_FR_TOO_MANY_REDIRECTS="ERR_FR_TOO_MANY_REDIRECTS";G.ERR_DEPRECATED="ERR_DEPRECATED";G.ERR_BAD_RESPONSE="ERR_BAD_RESPONSE";G.ERR_BAD_REQUEST="ERR_BAD_REQUEST";G.ERR_CANCELED="ERR_CANCELED";G.ERR_NOT_SUPPORT="ERR_NOT_SUPPORT";G.ERR_INVALID_URL="ERR_INVALID_URL";G.ERR_FORM_DATA_DEPTH_EXCEEDED="ERR_FORM_DATA_DEPTH_EXCEEDED";const Sh=null,Ja=100;function Kr(e){return x.isPlainObject(e)||x.isArray(e)}function Xa(e){return x.endsWith(e,"[]")?e.slice(0,-2):e}function vr(e,t,n){return e?e.concat(t).map(function(r,o){return r=Xa(r),!n&&o?"["+r+"]":r}).join(n?".":""):t}function Rh(e){return x.isArray(e)&&!e.some(Kr)}const Ch=x.toFlatObject(x,{},null,function(t){return/^is[A-Z]/.test(t)});function er(e,t,n){if(!x.isObject(e))throw new TypeError("target must be an object");t=t||new FormData,n=x.toFlatObject(n,{metaTokens:!0,dots:!1,indexes:!1},!1,function(b,A){return!x.isUndefined(A[b])});const s=n.metaTokens,r=n.visitor||R,o=n.dots,i=n.indexes,l=n.Blob||typeof Blob<"u"&&Blob,a=n.maxDepth===void 0?Ja:n.maxDepth,c=l&&x.isSpecCompliantForm(t),u=[];if(!x.isFunction(r))throw new TypeError("visitor must be a function");function f(_){if(_===null)return"";if(x.isDate(_))return _.toISOString();if(x.isBoolean(_))return _.toString();if(!c&&x.isBlob(_))throw new G("Blob is not supported. Use a Buffer instead.");if(x.isArrayBuffer(_)||x.isTypedArray(_)){if(c&&typeof l=="function")return new l([_]);if(typeof Buffer<"u")return Buffer.from(_);throw new G("Blob is not supported. Use a Buffer instead.",G.ERR_NOT_SUPPORT)}return _}function h(_){if(_>a)throw new G("Object is too deeply nested ("+_+" levels). Max depth: "+a,G.ERR_FORM_DATA_DEPTH_EXCEEDED)}function m(_,b){if(a===1/0)return JSON.stringify(_);const A=[];return JSON.stringify(_,function(O,D){if(!x.isObject(D))return D;for(;A.length&&A[A.length-1]!==this;)A.pop();return A.push(D),h(b+A.length-1),D})}function R(_,b,A){let E=_;if(x.isReactNative(t)&&x.isReactNativeBlob(_))return t.append(vr(A,b,o),f(_)),!1;if(_&&!A&&typeof _=="object"){if(x.endsWith(b,"{}"))b=s?b:b.slice(0,-2),_=m(_,1);else if(x.isArray(_)&&Rh(_)||(x.isFileList(_)||x.endsWith(b,"[]"))&&(E=x.toArray(_)))return b=Xa(b),E.forEach(function(D,L){!(x.isUndefined(D)||D===null)&&t.append(i===!0?vr([b],L,o):i===null?b:b+"[]",f(D))}),!1}return Kr(_)?!0:(t.append(vr(A,b,o),f(_)),!1)}const C=Object.assign(Ch,{defaultVisitor:R,convertValue:f,isVisitable:Kr});function P(_,b,A=0){if(!x.isUndefined(_)){if(h(A),u.indexOf(_)!==-1)throw new Error("Circular reference detected in "+b.join("."));u.push(_),x.forEach(_,function(O,D){(!(x.isUndefined(O)||O===null)&&r.call(t,O,x.isString(D)?D.trim():D,b,C))===!0&&P(O,b?b.concat(D):[D],A+1)}),u.pop()}}if(!x.isObject(e))throw new TypeError("data must be an object");return P(e),t}function Hi(e){const t={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+"};return encodeURIComponent(e).replace(/[!'()~]|%20/g,function(s){return t[s]})}function wo(e,t){this._pairs=[],e&&er(e,this,t)}const Ya=wo.prototype;Ya.append=function(t,n){this._pairs.push([t,n])};Ya.toString=function(t){const n=t?s=>t.call(this,s,Hi):Hi;return this._pairs.map(function(r){return n(r[0])+"="+n(r[1])},"").join("&")};function Ah(e){return encodeURIComponent(e).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+")}function Qa(e,t,n){if(!t)return e;e=e||"";const s=x.isFunction(n)?{serialize:n}:n,r=x.getSafeProp(s,"encode")||Ah,o=x.getSafeProp(s,"serialize");let i;if(o?i=o(t,s):i=x.isURLSearchParams(t)?t.toString():new wo(t,s).toString(r),i){const l=e.indexOf("#");l!==-1&&(e=e.slice(0,l)),e+=(e.indexOf("?")===-1?"?":"&")+i}return e}class qi{constructor(){this.handlers=[]}use(t,n,s){return this.handlers.push({fulfilled:t,rejected:n,synchronous:s?s.synchronous:!1,runWhen:s?s.runWhen:null}),this.handlers.length-1}eject(t){this.handlers[t]&&(this.handlers[t]=null)}clear(){this.handlers&&(this.handlers=[])}forEach(t){x.forEach(this.handlers,function(s){s!==null&&t(s)})}}const Eo={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1,legacyInterceptorReqResOrdering:!0,advertiseZstdAcceptEncoding:!1,validateStatusUndefinedResolves:!0},Oh=typeof URLSearchParams<"u"?URLSearchParams:wo,Th=typeof FormData<"u"?FormData:null,Ph=typeof Blob<"u"?Blob:null,Nh={isBrowser:!0,classes:{URLSearchParams:Oh,FormData:Th,Blob:Ph},protocols:["http","https","file","blob","url","data"]},So=typeof window<"u"&&typeof document<"u",Wr=typeof navigator=="object"&&navigator||void 0,Ih=So&&(!Wr||["ReactNative","NativeScript","NS"].indexOf(Wr.product)<0),kh=typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope&&typeof self.importScripts=="function",$h=So&&window.location.href||"http://localhost",Dh=Object.freeze(Object.defineProperty({__proto__:null,hasBrowserEnv:So,hasStandardBrowserEnv:Ih,hasStandardBrowserWebWorkerEnv:kh,navigator:Wr,origin:$h},Symbol.toStringTag,{value:"Module"})),je={...Dh,...Nh};function Lh(e,t){return er(e,new je.classes.URLSearchParams,{visitor:function(n,s,r,o){return je.isNode&&x.isBuffer(n)?(this.append(s,n.toString("base64")),!1):o.defaultVisitor.apply(this,arguments)},...t})}const Ki=Ja;function Za(e){if(e>Ki)throw new G("FormData field is too deeply nested ("+e+" levels). Max depth: "+Ki,G.ERR_FORM_DATA_DEPTH_EXCEEDED)}function Uh(e){const t=[],n=/\w+|\[(\w*)]/g;let s;for(;(s=n.exec(e))!==null;)Za(t.length),t.push(s[0]==="[]"?"":s[1]||s[0]);return t}function Fh(e){const t={},n=Object.keys(e);let s;const r=n.length;let o;for(s=0;s=n.length;return i=!i&&x.isArray(r)?r.length:i,a?(x.hasOwnProp(r,i)?r[i]=x.isArray(r[i])?r[i].concat(s):[r[i],s]:r[i]=s,!l):((!x.hasOwnProp(r,i)||!x.isObject(r[i]))&&(r[i]=[]),t(n,s,r[i],o)&&x.isArray(r[i])&&(r[i]=Fh(r[i])),!l)}if(x.isFormData(e)&&x.isFunction(e.entries)){const n={};return x.forEachEntry(e,(s,r)=>{t(Uh(s),r,n,0)}),n}return null}const mn=(e,t)=>e!=null&&x.hasOwnProp(e,t)?e[t]:void 0;function Mh(e,t,n){if(x.isString(e))try{return(t||JSON.parse)(e),x.trim(e)}catch(s){if(s.name!=="SyntaxError")throw s}return(n||JSON.stringify)(e)}const ds={transitional:Eo,adapter:["xhr","http","fetch"],transformRequest:[function(t,n){const s=n.getContentType()||"",r=s.indexOf("application/json")>-1,o=x.isObject(t);if(o&&x.isHTMLForm(t)&&(t=new FormData(t)),x.isFormData(t))return r?JSON.stringify(eu(t)):t;if(x.isArrayBuffer(t)||x.isBuffer(t)||x.isStream(t)||x.isFile(t)||x.isBlob(t)||x.isReadableStream(t))return t;if(x.isArrayBufferView(t))return t.buffer;if(x.isURLSearchParams(t))return n.setContentType("application/x-www-form-urlencoded;charset=utf-8",!1),t.toString();let l;if(o){const a=mn(this,"formSerializer");if(s.indexOf("application/x-www-form-urlencoded")>-1)return Lh(t,a).toString();if((l=x.isFileList(t))||s.indexOf("multipart/form-data")>-1){const c=mn(this,"env"),u=c&&c.FormData;return er(l?{"files[]":t}:t,u&&new u,a)}}return o||r?(n.setContentType("application/json",!1),Mh(t)):t}],transformResponse:[function(t){const n=mn(this,"transitional")||ds.transitional,s=n&&n.forcedJSONParsing,r=mn(this,"responseType"),o=r==="json";if(x.isResponse(t)||x.isReadableStream(t))return t;if(t&&x.isString(t)&&(s&&!r||o)){const l=!(n&&n.silentJSONParsing)&&o;try{return JSON.parse(t,mn(this,"parseReviver"))}catch(a){if(l)throw a.name==="SyntaxError"?G.from(a,G.ERR_BAD_RESPONSE,this,null,mn(this,"response")):a}}return t}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,env:{FormData:je.classes.FormData,Blob:je.classes.Blob},validateStatus:function(t){return t>=200&&t<300},headers:{common:{Accept:"application/json, text/plain, */*","Content-Type":void 0}}};x.forEach(["delete","get","head","post","put","patch","query"],e=>{ds.headers[e]={}});function _r(e,t){const n=this||ds,s=t||n,r=Je.from(s.headers);let o=s.data;return x.forEach(e,function(l){o=l.call(n,o,r.normalize(),t?t.status:void 0)}),r.normalize(),o}function tu(e){return!!(e&&e.__CANCEL__)}let ps=class extends G{constructor(t,n,s){super(t??"canceled",G.ERR_CANCELED,n,s),this.name="CanceledError",this.__CANCEL__=!0}};function nu(e,t,n){const s=n.config.validateStatus;!n.status||!s||s(n.status)?e(n):t(new G("Request failed with status code "+n.status,n.status>=400&&n.status<500?G.ERR_BAD_REQUEST:G.ERR_BAD_RESPONSE,n.config,n.request,n))}function Vh(e){const t=/^([-+\w]{1,25}):(?:\/\/)?/.exec(e);return t&&t[1]||""}function Bh(e,t){e=e||10;const n=new Array(e),s=new Array(e);let r=0,o=0,i;return t=t!==void 0?t:1e3,function(a){const c=Date.now(),u=s[o];i||(i=c),n[r]=a,s[r]=c;let f=o,h=0;for(;f!==r;)h+=n[f++],f=f%e;if(r=(r+1)%e,r===o&&(o=(o+1)%e),c-i{n=u,r=null,o&&(clearTimeout(o),o=null),e(...c)};return[(...c)=>{const u=Date.now(),f=u-n;f>=s?i(c,u):(r=c,o||(o=setTimeout(()=>{o=null,i(r)},s-f)))},()=>r&&i(r)]}const Ds=(e,t,n=3)=>{let s=0;const r=Bh(50,250);return jh(o=>{if(!o||typeof o.loaded!="number")return;const i=o.loaded,l=o.lengthComputable?o.total:void 0,a=l!=null?Math.min(i,l):i,c=Math.max(0,a-s),u=r(c);s=Math.max(s,a);const f={loaded:a,total:l,progress:l?a/l:void 0,bytes:c,rate:u||void 0,estimated:u&&l?(l-a)/u:void 0,event:o,lengthComputable:l!=null,[t?"download":"upload"]:!0};e(f)},n)},Wi=(e,t)=>{const n=e!=null;return[s=>t[0]({lengthComputable:n,total:e,loaded:s}),t[1]]},zi=e=>(...t)=>x.asap(()=>e(...t)),Hh=je.hasStandardBrowserEnv?((e,t)=>n=>(n=new URL(n,je.origin),e.protocol===n.protocol&&e.host===n.host&&(t||e.port===n.port)))(new URL(je.origin),je.navigator&&/(msie|trident)/i.test(je.navigator.userAgent)):()=>!0,qh=je.hasStandardBrowserEnv?{write(e,t,n,s,r,o,i){if(typeof document>"u")return;const l=[`${e}=${encodeURIComponent(t)}`];x.isNumber(n)&&l.push(`expires=${new Date(n).toUTCString()}`),x.isString(s)&&l.push(`path=${s}`),x.isString(r)&&l.push(`domain=${r}`),o===!0&&l.push("secure"),x.isString(i)&&l.push(`SameSite=${i}`),document.cookie=l.join("; ")},read(e){if(typeof document>"u")return null;const t=document.cookie.split(";");for(let n=0;ne instanceof Je?{...e}:e;function pn(e,t){e=e||{},t=t||{};const n=Object.create(null);Object.defineProperty(n,"hasOwnProperty",{__proto__:null,value:Object.prototype.hasOwnProperty,enumerable:!1,writable:!0,configurable:!0});function s(u,f,h,m){return x.isPlainObject(u)&&x.isPlainObject(f)?x.merge.call({caseless:m},u,f):x.isPlainObject(f)?x.merge({},f):x.isArray(f)?f.slice():f}function r(u,f,h,m){if(x.isUndefined(f)){if(!x.isUndefined(u))return s(void 0,u,h,m)}else return s(u,f,h,m)}function o(u,f){if(!x.isUndefined(f))return s(void 0,f)}function i(u,f){if(x.isUndefined(f)){if(!x.isUndefined(u))return s(void 0,u)}else return s(void 0,f)}function l(u){const f=x.hasOwnProp(t,"transitional")?t.transitional:void 0;if(!x.isUndefined(f))if(x.isPlainObject(f)){if(x.hasOwnProp(f,u))return f[u]}else return;const h=x.hasOwnProp(e,"transitional")?e.transitional:void 0;if(x.isPlainObject(h)&&x.hasOwnProp(h,u))return h[u]}function a(u,f,h){if(x.hasOwnProp(t,h))return s(u,f);if(x.hasOwnProp(e,h))return s(void 0,u)}const c={url:o,method:o,data:o,baseURL:i,transformRequest:i,transformResponse:i,paramsSerializer:i,timeout:i,timeoutMessage:i,withCredentials:i,withXSRFToken:i,adapter:i,responseType:i,xsrfCookieName:i,xsrfHeaderName:i,onUploadProgress:i,onDownloadProgress:i,decompress:i,maxContentLength:i,maxBodyLength:i,beforeRedirect:i,transport:i,httpAgent:i,httpsAgent:i,cancelToken:i,socketPath:i,allowedSocketPaths:i,responseEncoding:i,validateStatus:a,headers:(u,f,h)=>r(Ji(u),Ji(f),h,!0)};return x.forEach(Object.keys({...e,...t}),function(f){if(f==="__proto__"||f==="constructor"||f==="prototype")return;const h=x.hasOwnProp(c,f)?c[f]:r,m=x.hasOwnProp(e,f)?e[f]:void 0,R=x.hasOwnProp(t,f)?t[f]:void 0,C=h(m,R,f);x.isUndefined(C)&&h!==a||(n[f]=C)}),x.hasOwnProp(t,"validateStatus")&&x.isUndefined(t.validateStatus)&&l("validateStatusUndefinedResolves")===!1&&(x.hasOwnProp(e,"validateStatus")?n.validateStatus=s(void 0,e.validateStatus):delete n.validateStatus),n}const Yh=["content-type","content-length"];function Qh(e,t,n){if(n!=="content-only"){e.set(t);return}Object.entries(t||{}).forEach(([s,r])=>{Yh.includes(s.toLowerCase())&&e.set(s,r)})}const Zh=e=>encodeURIComponent(e).replace(/%([0-9A-F]{2})/gi,(t,n)=>String.fromCharCode(parseInt(n,16)));function ru(e){const t=pn({},e),n=h=>x.hasOwnProp(t,h)?t[h]:void 0,s=n("data");let r=n("withXSRFToken");const o=n("xsrfHeaderName"),i=n("xsrfCookieName");let l=n("headers");const a=n("auth"),c=n("baseURL"),u=n("allowAbsoluteUrls"),f=n("url");if(t.headers=l=Je.from(l),t.url=Qa(su(c,f,u,t),n("params"),n("paramsSerializer")),a){const h=x.getSafeProp(a,"username")||"",m=x.getSafeProp(a,"password")||"";try{l.set("Authorization","Basic "+btoa(h+":"+(m?Zh(m):"")))}catch(R){throw G.from(R,G.ERR_BAD_OPTION_VALUE,e)}}if(x.isFormData(s)&&(je.hasStandardBrowserEnv||je.hasStandardBrowserWebWorkerEnv||x.isReactNative(s)?l.setContentType(void 0):x.isFunction(s.getHeaders)&&Qh(l,s.getHeaders(),n("formDataHeaderPolicy"))),je.hasStandardBrowserEnv&&(x.isFunction(r)&&(r=r(t)),r===!0||r==null&&Hh(t.url))){const m=o&&i&&qh.read(i);m&&l.set(o,m)}return t}const em=typeof XMLHttpRequest<"u",tm=em&&function(e){return new Promise(function(n,s){const r=ru(e);let o=r.data;const i=Je.from(r.headers).normalize();let{responseType:l,onUploadProgress:a,onDownloadProgress:c}=r,u,f,h,m,R;function C(){m&&m(),R&&R(),r.cancelToken&&r.cancelToken.unsubscribe(u),r.signal&&r.signal.removeEventListener("abort",u)}let P=new XMLHttpRequest;P.open(r.method.toUpperCase(),r.url,!0),P.timeout=r.timeout;function _(){if(!P)return;const A=Je.from("getAllResponseHeaders"in P&&P.getAllResponseHeaders()),O={data:!l||l==="text"||l==="json"?P.responseText:P.response,status:P.status,statusText:P.statusText,headers:A,config:e,request:P};nu(function(L){n(L),C()},function(L){s(L),C()},O),P=null}"onloadend"in P?P.onloadend=_:P.onreadystatechange=function(){!P||P.readyState!==4||P.status===0&&!(P.responseURL&&P.responseURL.startsWith("file:"))||setTimeout(_)},P.onabort=function(){P&&(s(new G("Request aborted",G.ECONNABORTED,e,P)),C(),P=null)},P.onerror=function(E){const O=E&&E.message?E.message:"Network Error",D=new G(O,G.ERR_NETWORK,e,P);D.event=E||null,s(D),C(),P=null},P.ontimeout=function(){let E=r.timeout?"timeout of "+r.timeout+"ms exceeded":"timeout exceeded";const O=r.transitional||Eo;r.timeoutErrorMessage&&(E=r.timeoutErrorMessage),s(new G(E,O.clarifyTimeoutError?G.ETIMEDOUT:G.ECONNABORTED,e,P)),C(),P=null},o===void 0&&i.setContentType(null),"setRequestHeader"in P&&x.forEach(za(i),function(E,O){P.setRequestHeader(O,E)}),x.isUndefined(r.withCredentials)||(P.withCredentials=!!r.withCredentials),l&&l!=="json"&&(P.responseType=r.responseType),c&&([h,R]=Ds(c,!0),P.addEventListener("progress",h)),a&&P.upload&&([f,m]=Ds(a),P.upload.addEventListener("progress",f),P.upload.addEventListener("loadend",m)),(r.cancelToken||r.signal)&&(u=A=>{P&&(s(!A||A.type?new ps(null,e,P):A),P.abort(),C(),P=null)},r.cancelToken&&r.cancelToken.subscribe(u),r.signal&&(r.signal.aborted?u():r.signal.addEventListener("abort",u)));const b=Vh(r.url);if(b&&!je.protocols.includes(b)){s(new G("Unsupported protocol "+b+":",G.ERR_BAD_REQUEST,e)),C();return}P.send(o||null)})},nm=(e,t)=>{if(e=e?e.filter(Boolean):[],!t&&!e.length)return;const n=new AbortController;let s=!1;const r=function(a){if(!s){s=!0,i();const c=a instanceof Error?a:this.reason;n.abort(c instanceof G?c:new ps(c instanceof Error?c.message:c))}};let o=t&&setTimeout(()=>{o=null,r(new G(`timeout of ${t}ms exceeded`,G.ETIMEDOUT))},t);const i=()=>{e&&(o&&clearTimeout(o),o=null,e.forEach(a=>{a.unsubscribe?a.unsubscribe(r):a.removeEventListener("abort",r)}),e=null)};e.forEach(a=>a.addEventListener("abort",r,{once:!0}));const{signal:l}=n;return l.unsubscribe=()=>x.asap(i),l},sm=function*(e,t){let n=e.byteLength;if(n{const r=rm(e,t);let o=0,i,l=a=>{i||(i=!0,s&&s(a))};return new ReadableStream({async pull(a){try{const{done:c,value:u}=await r.next();if(c){l(),a.close();return}let f=u.byteLength;if(n){let h=o+=f;n(h)}a.enqueue(new Uint8Array(u))}catch(c){throw l(c),c}},cancel(a){return l(a),r.return()}},{highWaterMark:2})},Ls=e=>e>=48&&e<=57||e>=65&&e<=70||e>=97&&e<=102,im=(e,t,n)=>t+2m>=2&&s.charCodeAt(m-2)===37&&s.charCodeAt(m-1)===51&&(s.charCodeAt(m)===68||s.charCodeAt(m)===100);c>=0&&(s.charCodeAt(c)===61?(a++,c--):u(c)&&(a++,c-=3)),a===1&&c>=0&&(s.charCodeAt(c)===61||u(c))&&a++;const h=Math.floor(i/4)*3-(a||0);return h>0?h:0}let o=0;for(let i=0,l=s.length;i=55296&&a<=56319&&i+1=56320&&c<=57343?(o+=4,i++):o+=3}else o+=3}return o}const Ro="1.18.1",Yi=64*1024,{isFunction:bs}=x,am=e=>encodeURIComponent(e).replace(/%([0-9A-F]{2})/gi,(t,n)=>String.fromCharCode(parseInt(n,16))),Qi=e=>{if(!x.isString(e))return e;try{return decodeURIComponent(e)}catch{return e}},Zi=(e,...t)=>{try{return!!e(...t)}catch{return!1}},um=e=>{const t=e.indexOf("://");let n=e;return t!==-1&&(n=n.slice(t+3)),n.includes("@")||n.includes(":")},cm=e=>{const t=x.global!==void 0&&x.global!==null?x.global:globalThis,{ReadableStream:n,TextEncoder:s}=t;e=x.merge.call({skipUndefined:!0},{Request:t.Request,Response:t.Response},e);const{fetch:r,Request:o,Response:i}=e,l=r?bs(r):typeof fetch=="function",a=bs(o),c=bs(i);if(!l)return!1;const u=l&&bs(n),f=l&&(typeof s=="function"?(_=>b=>_.encode(b))(new s):async _=>new Uint8Array(await new o(_).arrayBuffer())),h=a&&u&&Zi(()=>{let _=!1;const b=new o(je.origin,{body:new n,method:"POST",get duplex(){return _=!0,"half"}}),A=b.headers.has("Content-Type");return b.body!=null&&b.body.cancel(),_&&!A}),m=c&&u&&Zi(()=>x.isReadableStream(new i("").body)),R={stream:m&&(_=>_.body)};l&&["text","arrayBuffer","blob","formData","stream"].forEach(_=>{!R[_]&&(R[_]=(b,A)=>{let E=b&&b[_];if(E)return E.call(b);throw new G(`Response type '${_}' is not supported`,G.ERR_NOT_SUPPORT,A)})});const C=async _=>{if(_==null)return 0;if(x.isBlob(_))return _.size;if(x.isSpecCompliantForm(_))return(await new o(je.origin,{method:"POST",body:_}).arrayBuffer()).byteLength;if(x.isArrayBufferView(_)||x.isArrayBuffer(_))return _.byteLength;if(x.isURLSearchParams(_)&&(_=_+""),x.isString(_))return(await f(_)).byteLength},P=async(_,b)=>{const A=x.toFiniteNumber(_.getContentLength());return A??C(b)};return async _=>{let{url:b,method:A,data:E,signal:O,cancelToken:D,timeout:L,onDownloadProgress:ae,onUploadProgress:Y,responseType:se,headers:oe,withCredentials:W="same-origin",fetchOptions:ue,maxContentLength:fe,maxBodyLength:Ne}=ru(_);const me=x.isNumber(fe)&&fe>-1,pe=x.isNumber(Ne)&&Ne>-1,$=w=>x.hasOwnProp(_,w)?_[w]:void 0;let k=r||fetch;se=se?(se+"").toLowerCase():"text";let z=nm([O,D&&D.toAbortSignal()],L),re=null;const he=z&&z.unsubscribe&&(()=>{z.unsubscribe()});let Oe,de=null;const I=()=>new G("Request body larger than maxBodyLength limit",G.ERR_BAD_REQUEST,_,re);try{let w;const y=$("auth");if(y){const S=x.getSafeProp(y,"username")||"",T=x.getSafeProp(y,"password")||"";w={username:S,password:T}}if(um(b)){const S=new URL(b,je.origin);if(!w&&(S.username||S.password)){const T=Qi(S.username),K=Qi(S.password);w={username:T,password:K}}(S.username||S.password)&&(S.username="",S.password="",b=S.href)}if(w&&(oe.delete("authorization"),oe.set("Authorization","Basic "+btoa(am((w.username||"")+":"+(w.password||""))))),me&&typeof b=="string"&&b.startsWith("data:")&&lm(b)>fe)throw new G("maxContentLength size of "+fe+" exceeded",G.ERR_BAD_RESPONSE,_,re);if(pe&&A!=="get"&&A!=="head"){const S=await C(E);if(typeof S=="number"&&isFinite(S)&&(Oe=S,S>Ne))throw I()}const B=pe&&(x.isReadableStream(E)||x.isStream(E)),M=(S,T,K)=>Xi(S,Yi,H=>{if(pe&&H>Ne)throw de=I();T&&T(H)},K);if(h&&A!=="get"&&A!=="head"&&(Y||B)){if(Oe=Oe??await P(oe,E),Oe!==0||B){let S=new o(b,{method:"POST",body:E,duplex:"half"}),T;if(x.isFormData(E)&&(T=S.headers.get("content-type"))&&oe.setContentType(T),S.body){const[K,H]=Y&&Wi(Oe,Ds(zi(Y)))||[];E=M(S.body,K,H)}}}else if(B&&!a&&u&&A!=="get"&&A!=="head")E=M(E);else if(B&&a&&!h&&A!=="get"&&A!=="head")throw new G("Stream request bodies are not supported by the current fetch implementation",G.ERR_NOT_SUPPORT,_,re);x.isString(W)||(W=W?"include":"omit");const X=a&&"credentials"in o.prototype;if(x.isFormData(E)){const S=oe.getContentType();S&&/^multipart\/form-data/i.test(S)&&!/boundary=/i.test(S)&&oe.delete("content-type")}oe.set("User-Agent","axios/"+Ro,!1);const Q={...ue,signal:z,method:A.toUpperCase(),headers:za(oe.normalize()),body:E,duplex:"half",credentials:X?W:void 0};re=a&&new o(b,Q);let p=await(a?k(re,ue):k(b,Q));const g=Je.from(p.headers);if(me){const S=x.toFiniteNumber(g.getContentLength());if(S!=null&&S>fe)throw new G("maxContentLength size of "+fe+" exceeded",G.ERR_BAD_RESPONSE,_,re)}const v=m&&(se==="stream"||se==="response");if(m&&p.body&&(ae||me||v&&he)){const S={};["status","statusText","headers"].forEach(ee=>{S[ee]=p[ee]});const T=x.toFiniteNumber(g.getContentLength()),[K,H]=ae&&Wi(T,Ds(zi(ae),!0))||[];let q=0;const U=ee=>{if(me&&(q=ee,q>fe))throw new G("maxContentLength size of "+fe+" exceeded",G.ERR_BAD_RESPONSE,_,re);K&&K(ee)};p=new i(Xi(p.body,Yi,U,()=>{H&&H(),he&&he()}),S)}se=se||"text";let N=await R[x.findKey(R,se)||"text"](p,_);if(me&&!m&&!v){let S;if(N!=null&&(typeof N.byteLength=="number"?S=N.byteLength:typeof N.size=="number"?S=N.size:typeof N=="string"&&(S=typeof s=="function"?new s().encode(N).byteLength:N.length)),typeof S=="number"&&S>fe)throw new G("maxContentLength size of "+fe+" exceeded",G.ERR_BAD_RESPONSE,_,re)}return!v&&he&&he(),await new Promise((S,T)=>{nu(S,T,{data:N,headers:Je.from(p.headers),status:p.status,statusText:p.statusText,config:_,request:re})})}catch(w){if(he&&he(),z&&z.aborted&&z.reason instanceof G){const y=z.reason;throw y.config=_,re&&(y.request=re),w!==y&&Object.defineProperty(y,"cause",{__proto__:null,value:w,writable:!0,enumerable:!1,configurable:!0}),y}if(de)throw re&&!de.request&&(de.request=re),de;if(w instanceof G)throw re&&!w.request&&(w.request=re),w;if(w&&w.name==="TypeError"&&/Load failed|fetch/i.test(w.message)){const y=new G("Network Error",G.ERR_NETWORK,_,re,w&&w.response);throw Object.defineProperty(y,"cause",{__proto__:null,value:w.cause||w,writable:!0,enumerable:!1,configurable:!0}),y}throw G.from(w,w&&w.code,_,re,w&&w.response)}}},fm=new Map,ou=e=>{let t=e&&e.env||{};const{fetch:n,Request:s,Response:r}=t,o=[s,r,n];let i=o.length,l=i,a,c,u=fm;for(;l--;)a=o[l],c=u.get(a),c===void 0&&u.set(a,c=l?new Map:cm(t)),u=c;return c};ou();const Co={http:Sh,xhr:tm,fetch:{get:ou}};x.forEach(Co,(e,t)=>{if(e){try{Object.defineProperty(e,"name",{__proto__:null,value:t})}catch{}Object.defineProperty(e,"adapterName",{__proto__:null,value:t})}});const el=e=>`- ${e}`,dm=e=>x.isFunction(e)||e===null||e===!1;function pm(e,t){e=x.isArray(e)?e:[e];const{length:n}=e;let s,r;const o={};for(let i=0;i`adapter ${a} `+(c===!1?"is not supported by the environment":"is not available in the build"));let l=n?i.length>1?`since : +`+i.map(el).join(` +`):" "+el(i[0]):"as no adapter specified";throw new G("There is no suitable adapter to dispatch the request "+l,G.ERR_NOT_SUPPORT)}return r}const iu={getAdapter:pm,adapters:Co};function wr(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw new ps(null,e)}function tl(e){return wr(e),e.headers=Je.from(e.headers),e.data=_r.call(e,e.transformRequest),["post","put","patch"].indexOf(e.method)!==-1&&e.headers.setContentType("application/x-www-form-urlencoded",!1),iu.getAdapter(e.adapter||ds.adapter,e)(e).then(function(s){wr(e),e.response=s;try{s.data=_r.call(e,e.transformResponse,s)}finally{delete e.response}return s.headers=Je.from(s.headers),s},function(s){if(!tu(s)&&(wr(e),s&&s.response)){e.response=s.response;try{s.response.data=_r.call(e,e.transformResponse,s.response)}finally{delete e.response}s.response.headers=Je.from(s.response.headers)}return Promise.reject(s)})}const tr={};["object","boolean","number","function","string","symbol"].forEach((e,t)=>{tr[e]=function(s){return typeof s===e||"a"+(t<1?"n ":" ")+e}});const nl={};tr.transitional=function(t,n,s){function r(o,i){return"[Axios v"+Ro+"] Transitional option '"+o+"'"+i+(s?". "+s:"")}return(o,i,l)=>{if(t===!1)throw new G(r(i," has been removed"+(n?" in "+n:"")),G.ERR_DEPRECATED);return n&&!nl[i]&&(nl[i]=!0,console.warn(r(i," has been deprecated since v"+n+" and will be removed in the near future"))),t?t(o,i,l):!0}};tr.spelling=function(t){return(n,s)=>(console.warn(`${s} is likely a misspelling of ${t}`),!0)};function hm(e,t,n){if(typeof e!="object"||e===null)throw new G("options must be an object",G.ERR_BAD_OPTION_VALUE);const s=Object.keys(e);let r=s.length;for(;r-- >0;){const o=s[r],i=Object.prototype.hasOwnProperty.call(t,o)?t[o]:void 0;if(i){const l=e[o],a=l===void 0||i(l,o,e);if(a!==!0)throw new G("option "+o+" must be "+a,G.ERR_BAD_OPTION_VALUE);continue}if(n!==!0)throw new G("Unknown option "+o,G.ERR_BAD_OPTION)}}const Rs={assertOptions:hm,validators:tr},qe=Rs.validators;let cn=class{constructor(t){this.defaults=t||{},this.interceptors={request:new qi,response:new qi}}async request(t,n){try{return await this._request(t,n)}catch(s){if(s instanceof Error){let r={};Error.captureStackTrace?Error.captureStackTrace(r):r=new Error;const o=(()=>{if(!r.stack)return"";const i=r.stack.indexOf(` +`);return i===-1?"":r.stack.slice(i+1)})();try{if(!s.stack)s.stack=o;else if(o){const i=o.indexOf(` +`),l=i===-1?-1:o.indexOf(` +`,i+1),a=l===-1?"":o.slice(l+1);String(s.stack).endsWith(a)||(s.stack+=` +`+o)}}catch{}}throw s}}_request(t,n){typeof t=="string"?(n=n||{},n.url=t):n=t||{},n=pn(this.defaults,n);const{transitional:s,paramsSerializer:r,headers:o}=n;s!==void 0&&Rs.assertOptions(s,{silentJSONParsing:qe.transitional(qe.boolean),forcedJSONParsing:qe.transitional(qe.boolean),clarifyTimeoutError:qe.transitional(qe.boolean),legacyInterceptorReqResOrdering:qe.transitional(qe.boolean),advertiseZstdAcceptEncoding:qe.transitional(qe.boolean),validateStatusUndefinedResolves:qe.transitional(qe.boolean)},!1),r!=null&&(x.isFunction(r)?n.paramsSerializer={serialize:r}:Rs.assertOptions(r,{encode:qe.function,serialize:qe.function},!0)),n.allowAbsoluteUrls!==void 0||(this.defaults.allowAbsoluteUrls!==void 0?n.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:n.allowAbsoluteUrls=!0),Rs.assertOptions(n,{baseUrl:qe.spelling("baseURL"),withXsrfToken:qe.spelling("withXSRFToken")},!0),n.method=(n.method||this.defaults.method||"get").toLowerCase();let i=o&&x.merge(o.common,o[n.method]);o&&x.forEach(["delete","get","head","post","put","patch","query","common"],R=>{delete o[R]}),n.headers=Je.concat(i,o);const l=[];let a=!0;this.interceptors.request.forEach(function(C){if(typeof C.runWhen=="function"&&C.runWhen(n)===!1)return;a=a&&C.synchronous;const P=n.transitional||Eo;P&&P.legacyInterceptorReqResOrdering?l.unshift(C.fulfilled,C.rejected):l.push(C.fulfilled,C.rejected)});const c=[];this.interceptors.response.forEach(function(C){c.push(C.fulfilled,C.rejected)});let u,f=0,h;if(!a){const R=[tl.bind(this),void 0];for(R.unshift(...l),R.push(...c),h=R.length,u=Promise.resolve(n);f{if(!s._listeners)return;let o=s._listeners.length;for(;o-- >0;)s._listeners[o](r);s._listeners=null}),this.promise.then=r=>{let o;const i=new Promise(l=>{s.subscribe(l),o=l}).then(r);return i.cancel=function(){s.unsubscribe(o)},i},t(function(o,i,l){s.reason||(s.reason=new ps(o,i,l),n(s.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(t){if(this.reason){t(this.reason);return}this._listeners?this._listeners.push(t):this._listeners=[t]}unsubscribe(t){if(!this._listeners)return;const n=this._listeners.indexOf(t);n!==-1&&this._listeners.splice(n,1)}toAbortSignal(){const t=new AbortController,n=s=>{t.abort(s)};return this.subscribe(n),t.signal.unsubscribe=()=>this.unsubscribe(n),t.signal}static source(){let t;return{token:new lu(function(r){t=r}),cancel:t}}};function gm(e){return function(n){return e.apply(null,n)}}function ym(e){return x.isObject(e)&&e.isAxiosError===!0}const zr={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511,WebServerIsDown:521,ConnectionTimedOut:522,OriginIsUnreachable:523,TimeoutOccurred:524,SslHandshakeFailed:525,InvalidSslCertificate:526};Object.entries(zr).forEach(([e,t])=>{zr[t]=e});function au(e){const t=new cn(e),n=Fa(cn.prototype.request,t);return x.extend(n,cn.prototype,t,{allOwnKeys:!0}),x.extend(n,t,null,{allOwnKeys:!0}),n.create=function(r){return au(pn(e,r))},n}const ke=au(ds);ke.Axios=cn;ke.CanceledError=ps;ke.CancelToken=mm;ke.isCancel=tu;ke.VERSION=Ro;ke.toFormData=er;ke.AxiosError=G;ke.Cancel=ke.CanceledError;ke.all=function(t){return Promise.all(t)};ke.spread=gm;ke.isAxiosError=ym;ke.mergeConfig=pn;ke.AxiosHeaders=Je;ke.formToJSON=e=>eu(x.isHTMLForm(e)?new FormData(e):e);ke.getAdapter=iu.getAdapter;ke.HttpStatusCode=zr;ke.default=ke;const{Axios:y0,AxiosError:b0,CanceledError:x0,isCancel:v0,CancelToken:_0,VERSION:w0,all:E0,Cancel:S0,isAxiosError:R0,spread:C0,toFormData:A0,AxiosHeaders:O0,HttpStatusCode:T0,formToJSON:P0,getAdapter:N0,mergeConfig:I0,create:k0}=ke,be=ke.create({timeout:3e4});be.interceptors.request.use(e=>{e.baseURL=`${ip()}/api`;const t=op();return t&&(e.headers.Authorization=`Bearer ${t}`),e});be.interceptors.response.use(e=>e.data,e=>{var n,s,r,o;((n=e.response)==null?void 0:n.status)===401&&sp();const t=((o=(r=(s=e.response)==null?void 0:s.data)==null?void 0:r.error)==null?void 0:o.message)||e.message||"Request failed";return Promise.reject(new Error(t))});const bm=()=>be.get("/env"),xm=()=>be.get("/settings"),vm=e=>be.patch("/settings",e),_m=()=>be.get("/storage"),wm=e=>be.post("/storage",e),Ao=()=>be.get("/sources"),Em=e=>be.post("/sources",e),Sm=(e,t)=>be.patch(`/sources/${e}`,t),Rm=e=>be.delete(`/sources/${e}`),uu=()=>be.get("/collections"),Cm=e=>be.post("/collections",e),Am=(e,t)=>be.patch(`/collections/${e}`,t),Om=e=>be.delete(`/collections/${e}`),Oo=()=>be.get("/templates"),Tm=e=>be.post("/templates",e),Pm=(e,t)=>be.patch(`/templates/${e}`,t),Nm=e=>be.delete(`/templates/${e}`),Im=()=>be.get("/recycle-bin"),km=e=>be.delete(`/recycle-bin/${e}`),$m=e=>be.post(`/recycle-bin/${e}/restore`),Er=e=>be.post("/preview/source",e),Sr=e=>be.post("/preview/collection",e),Dm=(e,t)=>be.get(`/link/source/${e}`,{params:{}}),Lm=(e,t)=>be.get(`/link/collection/${e}`,{params:{}}),Um=e=>be.get(`/source/flow/${e}`),Fm=e=>be.post("/proxy/parse",e),Mm=e=>be.post("/rule/parse",e),cu=e=>be.post("/utils/proxy-uri",e),Vm=e=>be.post("/utils/node-info",{server:e}),fu=e=>be.post("/utils/egress-info",e),Bm={class:"grid grid-cols-2 lg:grid-cols-4 gap-4 mb-6"},jm={class:"text-sm text-gray-500"},Hm={class:"grid grid-cols-1 lg:grid-cols-2 gap-4"},qm={class:"bg-white rounded-lg p-4 shadow-sm border"},Km={key:0,class:"space-y-1.5 text-sm"},Wm={class:"flex justify-between"},zm={class:"flex justify-between"},Gm={class:"flex justify-between"},Jm={class:"flex justify-between"},Xm={class:"flex justify-between"},Ym={key:1,class:"text-gray-400 text-sm"},Qm={class:"bg-white rounded-lg p-4 shadow-sm border"},Zm={key:0,class:"flex flex-wrap gap-2"},eg={__name:"Dashboard",setup(e){const t=Z(null),n=Z([]),s=Z([]),r=Z([]),o=tt(()=>[{label:"订阅源",value:n.value.length,color:"text-blue-600"},{label:"合集",value:s.value.length,color:"text-purple-600"},{label:"模板",value:r.value.length,color:"text-green-600"}]),i={buildTimeScripts:"脚本引擎",proxyConversion:"代理转换",ruleConversion:"规则转换",recycleBin:"回收站",nodeInfo:"节点信息",surgeMac:"Surge Mac"};return Yt(async()=>{try{const[l,a,c,u]=await Promise.all([bm(),Ao(),uu(),Oo()]);t.value=l.data,n.value=a.data||[],s.value=c.data||[],r.value=u.data||[]}catch(l){console.error("Failed to load dashboard",l)}}),(l,a)=>{var c;return F(),V("div",null,[a[7]||(a[7]=d("h2",{class:"text-xl font-bold mb-5"},"概览",-1)),d("div",Bm,[(F(!0),V(we,null,Be(o.value,u=>(F(),V("div",{key:u.label,class:"bg-white rounded-lg p-4 shadow-sm border"},[d("p",jm,j(u.label),1),d("p",{class:Fe(["text-2xl font-bold mt-1",u.color])},j(u.value),3)]))),128))]),d("div",Hm,[d("div",qm,[a[5]||(a[5]=d("h3",{class:"font-semibold mb-3"},"环境信息",-1)),t.value?(F(),V("div",Km,[d("div",Wm,[a[0]||(a[0]=d("span",{class:"text-gray-500"},"应用",-1)),d("span",null,j(t.value.app),1)]),d("div",zm,[a[1]||(a[1]=d("span",{class:"text-gray-500"},"后端",-1)),d("span",null,j(t.value.backend),1)]),d("div",Gm,[a[2]||(a[2]=d("span",{class:"text-gray-500"},"版本",-1)),d("span",null,j(t.value.version),1)]),d("div",Jm,[a[3]||(a[3]=d("span",{class:"text-gray-500"},"运行时",-1)),d("span",null,j(t.value.runtime),1)]),d("div",Xm,[a[4]||(a[4]=d("span",{class:"text-gray-500"},"存储",-1)),d("span",null,j(t.value.storage),1)])])):(F(),V("div",Ym,"加载中..."))]),d("div",Qm,[a[6]||(a[6]=d("h3",{class:"font-semibold mb-3"},"功能特性",-1)),(c=t.value)!=null&&c.feature?(F(),V("div",Zm,[(F(!0),V(we,null,Be(t.value.feature,(u,f)=>(F(),V("span",{key:f,class:Fe(["px-2 py-1 rounded text-xs",u?"bg-green-100 text-green-700":"bg-gray-100 text-gray-500"])},j(i[f]||f)+": "+j(u?"✓":"✗"),3))),128))])):ce("",!0)])])])}}},tg={key:0,class:"fixed inset-0 z-50 flex items-center justify-center p-4"},ng={class:"relative bg-white rounded-lg shadow-xl w-full max-w-2xl max-h-[85vh] flex flex-col"},sg={class:"flex items-center justify-between px-6 py-3 border-b"},rg={class:"text-base font-semibold text-gray-900"},og={class:"flex-1 overflow-y-auto px-6 py-4"},ig={key:0,class:"px-6 py-3 border-t flex justify-end gap-2"},Us={__name:"Modal",props:{modelValue:Boolean,title:{type:String,default:""}},emits:["update:modelValue"],setup(e){return(t,n)=>(F(),fn(Ml,{to:"body"},[e.modelValue?(F(),V("div",tg,[d("div",{class:"absolute inset-0 bg-black/40",onClick:n[0]||(n[0]=s=>t.$emit("update:modelValue",!1))}),d("div",ng,[d("div",sg,[d("h3",rg,j(e.title),1),d("button",{class:"text-gray-400 hover:text-gray-600 text-xl",onClick:n[1]||(n[1]=s=>t.$emit("update:modelValue",!1))},"×")]),d("div",og,[qo(t.$slots,"default")]),t.$slots.footer?(F(),V("div",ig,[qo(t.$slots,"footer")])):ce("",!0)])])):ce("",!0)]))}},lg={key:0,class:"fixed inset-0 z-[60] flex items-center justify-center p-4"},ag={class:"relative bg-white rounded-lg shadow-xl w-full max-w-sm p-5"},ug={class:"text-base font-semibold text-gray-900 mb-2"},cg={class:"text-sm text-gray-600 mb-4"},fg={class:"flex justify-end gap-2"},nr={__name:"ConfirmDialog",props:{modelValue:Boolean,title:{type:String,default:"确认"},message:{type:String,default:"确定执行此操作?"},confirmText:{type:String,default:"确定"},danger:{type:Boolean,default:!1}},emits:["update:modelValue","confirm"],setup(e){return(t,n)=>(F(),fn(Ml,{to:"body"},[e.modelValue?(F(),V("div",lg,[d("div",{class:"absolute inset-0 bg-black/40",onClick:n[0]||(n[0]=s=>t.$emit("update:modelValue",!1))}),d("div",ag,[d("h3",ug,j(e.title),1),d("p",cg,j(e.message),1),d("div",fg,[d("button",{class:"px-4 py-2 text-sm rounded-lg hover:bg-gray-100",onClick:n[1]||(n[1]=s=>t.$emit("update:modelValue",!1))},"取消"),d("button",{class:Fe(["px-4 py-2 text-sm rounded-lg text-white",e.danger?"bg-red-600 hover:bg-red-700":"bg-primary-600 hover:bg-primary-700"]),onClick:n[2]||(n[2]=s=>t.$emit("confirm"))},j(e.confirmText),3)])])])):ce("",!0)]))}};async function is(e){var n;if((n=navigator.clipboard)!=null&&n.writeText){await navigator.clipboard.writeText(e);return}const t=document.createElement("textarea");t.value=e,t.setAttribute("readonly",""),t.style.position="fixed",t.style.opacity="0",document.body.appendChild(t),t.select();try{if(!document.execCommand("copy"))throw new Error("复制失败")}finally{document.body.removeChild(t)}}const dg={key:0,class:"text-gray-400 text-sm"},pg={key:1,class:"text-gray-400 text-sm py-8 text-center"},hg={key:2,class:"space-y-2"},mg=["onClick"],gg={class:"flex-1 min-w-0"},yg={class:"flex items-center gap-2"},bg={class:"font-medium text-gray-900"},xg={key:0,class:"px-1.5 py-0.5 rounded text-xs bg-purple-100 text-purple-700"},vg={key:1,class:"px-1.5 py-0.5 rounded text-xs bg-red-100 text-red-700"},_g={key:0,class:"text-xs text-gray-500 mt-1"},wg={class:"flex gap-2 mt-1 text-xs text-gray-400"},Eg={key:0},Sg={key:1},Rg={key:1,class:"text-xs text-gray-500 mt-1 truncate"},Cg={class:"flex gap-1 ml-3"},Ag=["disabled","onClick"],Og=["onClick"],Tg=["onClick"],Pg=["onClick"],Ng={key:0,class:"text-gray-400 text-sm py-4 text-center"},Ig={key:1},kg={class:"overflow-x-auto rounded-lg bg-white"},$g={class:"w-full text-left text-xs"},Dg={class:"divide-y divide-gray-100"},Lg={class:"px-3 py-2 text-gray-500"},Ug={class:"px-3 py-2 text-blue-600"},Fg={class:"px-3 py-2 font-mono text-gray-500"},Mg={class:"px-3 py-2 font-mono text-gray-500"},Vg={class:"px-3 py-2 text-gray-500"},Bg={class:"px-3 py-2 text-gray-500"},jg={class:"px-3 py-2 font-mono text-gray-500"},Hg={class:"px-3 py-2 font-mono text-gray-500"},qg={class:"px-3 py-2 font-mono text-gray-500"},Kg={class:"px-3 py-2 text-gray-500"},Wg={class:"px-3 py-2 text-gray-500"},zg={class:"px-3 py-2"},Gg=["onClick"],Jg={key:0,class:"text-xs text-gray-400 mt-2"},Xg={class:"space-y-4"},Yg={class:"grid grid-cols-2 gap-3"},Qg=["disabled"],Zg={class:"flex gap-2"},ey={key:0},ty={key:1},ny={class:"flex items-center gap-2"},sy={class:"mb-2 rounded-lg bg-gray-50 px-3 py-2 text-xs text-gray-500"},ry={class:"mt-2"},oy={class:"mt-2 w-full border-collapse overflow-hidden rounded-lg bg-white text-left"},iy={class:"border border-gray-200 px-2 py-1 text-gray-700"},ly={class:"border border-gray-200 px-2 py-1"},ay=["onUpdate:modelValue"],uy=["value"],cy=["onUpdate:modelValue"],fy=["onUpdate:modelValue"],dy=["onClick"],py={__name:"Sources",setup(e){const t=Z([]),n=Z(!0),s=Z(!1),r=Z(!1),o=Z(""),i=Z(!1),l=Z(null),a=Z(""),c=Z(""),u=At({}),f=At({}),h=Z(null),m=Z({show:!1,title:"",message:"",danger:!1,action:null}),R=["include","exclude","rename","dedupe","sort","delete-field","flag","quick","resolve","custom"],C={include:"包含(include)",exclude:"排除(exclude)",rename:"重命名(rename)",dedupe:"去重(dedupe)",sort:"排序(sort)","delete-field":"删除字段(delete-field)",flag:"旗帜(flag)",quick:"快捷规则(quick)",resolve:"解析域名(resolve)",custom:"自定义(custom)"},P=[{type:"include",label:C.include,help:"只保留 field 匹配 pattern 的节点"},{type:"exclude",label:C.exclude,help:"删除 field 匹配 pattern 的节点"},{type:"rename",label:C.rename,help:"按 pattern 处理名称,简易表单适合清理固定前缀/后缀"},{type:"dedupe",label:C.dedupe,help:"按 field 去重,留空按 name 去重"},{type:"sort",label:C.sort,help:"按名称排序"},{type:"delete-field",label:C["delete-field"],help:"从 field 文本中删除匹配 pattern 的片段"},{type:"flag",label:C.flag,help:"给节点名补充或整理地区旗帜"},{type:"quick",label:C.quick,help:"应用快捷清理规则"},{type:"resolve",label:C.resolve,help:"把 server 域名解析为 IP"},{type:"custom",label:C.custom,help:"高级声明式规则链,适合 API/导入配置使用"}],_=()=>({name:"",alias:"",type:"remote",url:"",content:"",enabled:!0,filters:[]}),b=At(_());function A(I,w="success"){h.value={msg:I,type:w},setTimeout(()=>h.value=null,2500)}function E(I){return I?new Date(I).toLocaleString("zh-CN"):""}function O(I){return I?new Date(I*1e3).toLocaleDateString("zh-CN"):""}function D(I){if(!Number.isFinite(I))return"";const w=["B","KB","MB","GB","TB"];let y=I,B=0;for(;y>=1024&&B=10||B===0?y.toFixed(0):y.toFixed(1)}${w[B]}`}function L(I,...w){for(const y of w){const B=I==null?void 0:I[y];if(B!=null&&B!=="")return B}return"-"}function ae(I){if(I!=null&&I["reality-opts"]||(I==null?void 0:I.security)==="reality")return"reality";const w=L(I,"tls","security");return w===!0?"TLS":w===!1||w==="none"?"-":w}function Y(I){const w=I==null?void 0:I.transport;return typeof w=="string"?w:w!=null&&w.type?w.type:L(I,"network","net")}function se(I){var X,Q,p;const w=f[I.id];if(!w)return"";const y=[];w.planName&&y.push(`套餐: ${w.planName}`);const B=Number(((X=w.usage)==null?void 0:X.upload)||0)+Number(((Q=w.usage)==null?void 0:Q.download)||0),M=Number(w.total||0);return M>0&&y.push(`流量: ${D(B)} / ${D(M)}`),M>B&&y.push(`剩余: ${D(M-B)}`),w.expires&&y.push(`到期: ${O(w.expires)}`),(p=I.meta)!=null&&p.price&&y.push(`计费: ${I.meta.price}${I.meta.billingCycle?`/${I.meta.billingCycle}`:""}`),y.join(" · ")}function oe(I){return{original:(I==null?void 0:I.originalCount)??(Array.isArray(I==null?void 0:I.original)?I.original.length:(I==null?void 0:I.nodes)??0),processed:Array.isArray(I==null?void 0:I.processed)?I.processed.length:0}}function W(I){return{id:I.id,name:I.name,alias:I.alias,type:I.type,url:I.url,content:I.content,filters:I.filters}}function ue(){Object.assign(b,_()),r.value=!1,s.value=!0}function fe(I){Object.assign(b,{name:I.id,alias:I.alias||"",type:I.type||"remote",url:I.url||"",content:I.content||"",enabled:I.enabled!==!1,filters:JSON.parse(JSON.stringify(I.filters||[]))}),r.value=!0,s.value=!0}function Ne(){b.filters.push({type:"include",pattern:"",field:""})}async function me(){try{const I={name:b.name,alias:b.alias,type:b.type,url:b.url,content:b.content,enabled:b.enabled,filters:b.filters.filter(w=>w.type)};r.value?await Sm(b.name,I):await Em(I),s.value=!1,await he(),A(r.value?"已更新":"已创建")}catch(I){A(I.message,"error")}}async function pe(I){m.value={show:!0,title:"删除订阅源",message:`确定删除 "${I.name}"?`,danger:!0,action:async()=>{try{await Rm(I.id),await he(),A("已删除")}catch(w){A(w.message,"error")}}}}async function $(I){if(o.value===I.id){o.value="",l.value=null;return}o.value=I.id,i.value=!0,l.value=null;try{const w=await Er(W(I));l.value=w.data,u[I.id]=oe(w.data)}catch(w){A(w.message,"error"),o.value=""}finally{i.value=!1}}async function k(I){try{const w=await Dm(I.id);await is(w.data.url),A("链接已复制")}catch(w){A(w.message,"error")}}async function z(I){try{const w=await cu(I);await is(w.data.uri),A("节点链接已复制")}catch(w){A(w.message,"error")}}async function re(I){var w,y;if(!a.value){a.value=I.id,c.value="";try{const B=await Er(W(I)),M=((w=B.data)==null?void 0:w.processed)||((y=B.data)==null?void 0:y.original)||[];u[I.id]=oe(B.data),o.value===I.id&&(l.value=B.data);for(let X=0;X(F(),V("div",null,[d("div",{class:"flex items-center justify-between mb-5"},[w[12]||(w[12]=d("h2",{class:"text-xl font-bold"},"订阅源",-1)),d("button",{class:"px-4 py-2 bg-primary-600 text-white rounded-lg text-sm hover:bg-primary-700",onClick:ue},"+ 新建")]),n.value?(F(),V("div",dg,"加载中...")):t.value.length===0?(F(),V("div",pg,"暂无订阅源")):(F(),V("div",hg,[(F(!0),V(we,null,Be(t.value,y=>{var B,M,X;return F(),V("div",{key:y.id,class:"bg-white rounded-lg shadow-sm border overflow-hidden hover:shadow-md transition-shadow"},[d("div",{class:"p-4 flex items-center justify-between cursor-pointer",onClick:Q=>$(y)},[d("div",gg,[d("div",yg,[d("span",bg,j(y.name),1),y.alias?(F(),V("span",xg,j(y.alias),1)):ce("",!0),d("span",{class:Fe(["px-1.5 py-0.5 rounded text-xs",y.type==="remote"?"bg-blue-100 text-blue-700":"bg-gray-100 text-gray-600"])},j(y.type),3),y.enabled?ce("",!0):(F(),V("span",vg,"已禁用"))]),y.type==="local"?(F(),V("p",_g,"(本地内容)")):ce("",!0),d("div",wg,[d("span",null,"原始节点: "+j(((B=u[y.id])==null?void 0:B.original)??"-"),1),d("span",null,"处理后: "+j(((M=u[y.id])==null?void 0:M.processed)??"-"),1),y.alias?(F(),V("span",Eg,"别名: "+j(y.alias),1)):ce("",!0),d("span",null,"过滤器: "+j(((X=y.filters)==null?void 0:X.length)||0),1),y.createdAt?(F(),V("span",Sg,"创建: "+j(E(y.createdAt)),1)):ce("",!0)]),se(y)?(F(),V("p",Rg,j(se(y)),1)):ce("",!0)]),d("div",Cg,[d("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-blue-50 text-blue-600 whitespace-nowrap",disabled:!!a.value,onClick:ct(Q=>re(y),["stop"])},j(a.value===y.id?`探测 ${c.value}`:"探测出口"),9,Ag),d("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-gray-100",onClick:ct(Q=>k(y),["stop"])},"复制链接",8,Og),d("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-blue-50 text-blue-600",onClick:ct(Q=>fe(y),["stop"])},"编辑",8,Tg),d("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-red-50 text-red-600",onClick:ct(Q=>pe(y),["stop"])},"删除",8,Pg)])],8,mg),o.value===y.id?(F(),V("div",{key:0,class:"border-t bg-gray-50",onClick:w[0]||(w[0]=ct(()=>{},["stop"]))},[i.value?(F(),V("div",Ng,"解析中...")):l.value?(F(),V("div",Ig,[d("div",kg,[d("table",$g,[w[13]||(w[13]=d("thead",{class:"sticky top-0 bg-gray-100 text-gray-600"},[d("tr",null,[d("th",{class:"px-3 py-2 font-medium"},"Type"),d("th",{class:"px-3 py-2 font-medium"},"Name"),d("th",{class:"px-3 py-2 font-medium"},"Server"),d("th",{class:"px-3 py-2 font-medium"},"Port"),d("th",{class:"px-3 py-2 font-medium"},"Transport"),d("th",{class:"px-3 py-2 font-medium"},"Tls"),d("th",{class:"px-3 py-2 font-medium"},"Delay"),d("th",{class:"px-3 py-2 font-medium"},"Speed"),d("th",{class:"px-3 py-2 font-medium"},"Egress IP"),d("th",{class:"px-3 py-2 font-medium"},"Country"),d("th",{class:"px-3 py-2 font-medium"},"Region"),d("th",{class:"px-3 py-2 font-medium"},"Link")])],-1)),d("tbody",Dg,[(F(!0),V(we,null,Be(l.value.processed||l.value.original||[],(Q,p)=>(F(),V("tr",{key:p},[d("td",Lg,j(L(Q,"type")),1),d("td",Ug,j(L(Q,"name","remarks")),1),d("td",Fg,j(L(Q,"server","address")),1),d("td",Mg,j(L(Q,"port")),1),d("td",Vg,j(Y(Q)),1),d("td",Bg,j(ae(Q)),1),d("td",jg,j(L(Q,"latencyMs","delay","latency","ping")),1),d("td",Hg,j(L(Q,"speed","downloadSpeed")),1),d("td",qg,j(L(Q,"egressIp")),1),d("td",Kg,j(L(Q,"egressCountry","country")),1),d("td",Wg,j(L(Q,"egressRegion","region")),1),d("td",zg,[d("button",{class:"px-2 py-1 text-xs rounded hover:bg-gray-100 text-blue-600 whitespace-nowrap",onClick:g=>z(Q)},"复制",8,Gg)])]))),128))])])]),(l.value.processed||l.value.original||[]).length===0?(F(),V("p",Jg,"暂无节点")):ce("",!0)])):ce("",!0)])):ce("",!0)])}),128))])),Te(Us,{modelValue:s.value,"onUpdate:modelValue":w[9]||(w[9]=y=>s.value=y),title:r.value?"编辑订阅源":"新建订阅源"},{footer:dt(()=>[d("button",{class:"px-4 py-2 text-sm rounded-lg hover:bg-gray-100",onClick:w[8]||(w[8]=y=>s.value=!1)},"取消"),d("button",{class:"px-4 py-2 bg-primary-600 text-white rounded-lg text-sm hover:bg-primary-700",onClick:me},"保存")]),default:dt(()=>[d("div",Xg,[d("div",Yg,[d("div",null,[w[14]||(w[14]=d("label",{class:"block text-sm font-medium mb-1"},"名称 / ID",-1)),ye(d("input",{"onUpdate:modelValue":w[1]||(w[1]=y=>b.name=y),disabled:r.value,placeholder:"my-sub",class:"w-full px-3 py-2 border rounded-lg text-sm disabled:bg-gray-100"},null,8,Qg),[[De,b.name]]),w[15]||(w[15]=d("p",{class:"text-xs text-gray-400 mt-0.5"},"小写字母、数字、下划线、连字符",-1))]),d("div",null,[w[16]||(w[16]=d("label",{class:"block text-sm font-medium mb-1"},"别名 (Alias)",-1)),ye(d("input",{"onUpdate:modelValue":w[2]||(w[2]=y=>b.alias=y),placeholder:"如:机场A",class:"w-full px-3 py-2 border rounded-lg text-sm"},null,512),[[De,b.alias]]),w[17]||(w[17]=d("p",{class:"text-xs text-gray-400 mt-0.5"},"合集重命名时作为节点标识",-1))])]),d("div",null,[w[20]||(w[20]=d("label",{class:"block text-sm font-medium mb-1"},"类型",-1)),d("div",Zg,[d("label",{class:Fe(["flex-1 flex items-center gap-2 px-3 py-2 border rounded-lg text-sm cursor-pointer",b.type==="remote"?"border-primary-500 bg-primary-50 text-primary-700":"border-gray-200"])},[ye(d("input",{type:"radio","onUpdate:modelValue":w[3]||(w[3]=y=>b.type=y),value:"remote",class:"text-primary-600"},null,512),[[vi,b.type]]),w[18]||(w[18]=d("span",null,"远程 (URL)",-1))],2),d("label",{class:Fe(["flex-1 flex items-center gap-2 px-3 py-2 border rounded-lg text-sm cursor-pointer",b.type==="local"?"border-primary-500 bg-primary-50 text-primary-700":"border-gray-200"])},[ye(d("input",{type:"radio","onUpdate:modelValue":w[4]||(w[4]=y=>b.type=y),value:"local",class:"text-primary-600"},null,512),[[vi,b.type]]),w[19]||(w[19]=d("span",null,"本地 (内容)",-1))],2)])]),b.type==="remote"?(F(),V("div",ey,[w[21]||(w[21]=d("label",{class:"block text-sm font-medium mb-1"},"URL",-1)),ye(d("textarea",{"onUpdate:modelValue":w[5]||(w[5]=y=>b.url=y),rows:"3",placeholder:"https://example.com/sub (多个URL换行)",class:"w-full px-3 py-2 border rounded-lg text-sm font-mono"},null,512),[[De,b.url]])])):ce("",!0),b.type==="local"?(F(),V("div",ty,[w[22]||(w[22]=d("label",{class:"block text-sm font-medium mb-1"},"内容",-1)),ye(d("textarea",{"onUpdate:modelValue":w[6]||(w[6]=y=>b.content=y),rows:"6",placeholder:"ss://... 或 base64 内容",class:"w-full px-3 py-2 border rounded-lg text-sm font-mono"},null,512),[[De,b.content]])])):ce("",!0),d("div",ny,[ye(d("input",{type:"checkbox",id:"src-enabled","onUpdate:modelValue":w[7]||(w[7]=y=>b.enabled=y),class:"rounded"},null,512),[[bn,b.enabled]]),w[23]||(w[23]=d("label",{for:"src-enabled",class:"text-sm"},"启用",-1))]),d("div",null,[d("div",{class:"flex items-center justify-between mb-1"},[w[24]||(w[24]=d("label",{class:"text-sm font-medium"},"过滤器",-1)),d("button",{class:"text-xs text-primary-600 hover:underline",onClick:Ne},"+ 添加")]),d("details",sy,[w[27]||(w[27]=d("summary",{class:"cursor-pointer text-gray-700"},"使用说明",-1)),d("div",ry,[w[26]||(w[26]=d("p",null,"pattern 支持正则;field 留空默认匹配 name。常用字段:name、type、server、port。",-1)),d("table",oy,[w[25]||(w[25]=d("thead",{class:"bg-gray-100 text-gray-700"},[d("tr",null,[d("th",{class:"border border-gray-200 px-2 py-1 font-medium"},"过滤器"),d("th",{class:"border border-gray-200 px-2 py-1 font-medium"},"说明")])],-1)),d("tbody",null,[(F(),V(we,null,Be(P,y=>d("tr",{key:y.type},[d("td",iy,j(y.label),1),d("td",ly,j(y.help),1)])),64))])])])]),(F(!0),V(we,null,Be(b.filters,(y,B)=>(F(),V("div",{key:B,class:"flex gap-1 mb-1.5"},[ye(d("select",{"onUpdate:modelValue":M=>y.type=M,class:"px-2 py-1 border rounded text-xs w-28"},[(F(),V(we,null,Be(R,M=>d("option",{key:M,value:M},j(C[M]||M),9,uy)),64))],8,ay),[[ss,y.type]]),ye(d("input",{"onUpdate:modelValue":M=>y.pattern=M,placeholder:"pattern",class:"flex-1 px-2 py-1 border rounded text-xs"},null,8,cy),[[De,y.pattern]]),ye(d("input",{"onUpdate:modelValue":M=>y.field=M,placeholder:"field",class:"w-24 px-2 py-1 border rounded text-xs"},null,8,fy),[[De,y.field]]),d("button",{class:"px-2 py-1 text-xs text-red-500 hover:bg-red-50 rounded",onClick:M=>b.filters.splice(B,1)},"×",8,dy)]))),128))])])]),_:1},8,["modelValue","title"]),Te(nr,{modelValue:m.value.show,"onUpdate:modelValue":w[10]||(w[10]=y=>m.value.show=y),title:m.value.title,message:m.value.message,danger:m.value.danger,onConfirm:w[11]||(w[11]=y=>{m.value.action(),m.value.show=!1})},null,8,["modelValue","title","message","danger"]),h.value?(F(),V("div",{key:3,class:Fe(["fixed bottom-4 right-4 px-4 py-2 rounded-lg shadow-lg text-sm z-50",h.value.type==="error"?"bg-red-500 text-white":"bg-green-500 text-white"])},j(h.value.msg),3)):ce("",!0)]))}},hy={key:0,class:"text-gray-400 text-sm"},my={key:1,class:"text-gray-400 text-sm py-8 text-center"},gy={key:2,class:"space-y-2"},yy=["onClick"],by={class:"flex-1 min-w-0"},xy={class:"flex items-center gap-2"},vy={class:"font-medium text-gray-900"},_y={key:0,class:"px-1.5 py-0.5 rounded text-xs bg-red-100 text-red-700"},wy={class:"flex gap-3 mt-1 text-xs text-gray-400"},Ey={key:0,class:"text-purple-500"},Sy={key:1},Ry={class:"flex gap-1 ml-3"},Cy=["disabled","onClick"],Ay=["onClick"],Oy=["onClick"],Ty=["onClick"],Py={key:0,class:"text-gray-400 text-sm py-4 text-center"},Ny={key:1},Iy={class:"overflow-x-auto rounded-lg bg-white"},ky={class:"w-full text-left text-xs"},$y={class:"divide-y divide-gray-100"},Dy={class:"px-3 py-2 text-gray-500"},Ly={class:"px-3 py-2 text-blue-600"},Uy={class:"px-3 py-2 font-mono text-gray-500"},Fy={class:"px-3 py-2 font-mono text-gray-500"},My={class:"px-3 py-2 text-gray-500"},Vy={class:"px-3 py-2 text-gray-500"},By={class:"px-3 py-2 font-mono text-gray-500"},jy={class:"px-3 py-2 font-mono text-gray-500"},Hy={class:"px-3 py-2 font-mono text-gray-500"},qy={class:"px-3 py-2 text-gray-500"},Ky={class:"px-3 py-2 text-gray-500"},Wy={class:"px-3 py-2"},zy=["onClick"],Gy={key:0,class:"text-xs text-gray-400 mt-2"},Jy={class:"space-y-4"},Xy=["disabled"],Yy={class:"max-h-32 overflow-y-auto border rounded-lg p-2 space-y-1"},Qy=["value"],Zy={class:"text-xs text-gray-400"},eb={key:0,class:"text-xs text-gray-400 py-1"},tb=["value"],nb={class:"flex items-center gap-4"},sb={class:"flex items-center gap-2 text-sm"},rb={class:"flex items-center gap-2 text-sm"},ob={class:"flex items-center gap-2 text-sm"},ib={key:0,class:"rounded-lg bg-blue-50 px-3 py-2 text-xs text-blue-600"},lb={class:"flex flex-wrap gap-1.5 mt-2"},ab=["onClick"],ub={__name:"Collections",setup(e){const t=Z([]),n=Z([]),s=Z([]),r=Z(!0),o=Z(!1),i=Z(!1),l=Z(""),a=Z(!1),c=Z(null),u=Z(""),f=Z(""),h=Z(null),m=At({}),R=Z({show:!1,title:"",message:"",danger:!1,action:null}),C=[{key:"flag",label:"国旗"},{key:"alias",label:"别名"},{key:"country",label:"国家"},{key:"city",label:"城市"},{key:"index",label:"序号"}],P=()=>({flag:!0,alias:!0,country:!0,city:!0,index:!0}),_=()=>({name:"",sourceIds:[],renameEnabled:!1,renameOptions:P(),templateId:"",ignoreFailed:!0,enabled:!0}),b=At(_());function A($,k="success"){h.value={msg:$,type:k},setTimeout(()=>h.value=null,2500)}function E($,...k){for(const z of k){const re=$==null?void 0:$[z];if(re!=null&&re!=="")return re}return"-"}function O($){if($!=null&&$["reality-opts"]||($==null?void 0:$.security)==="reality")return"reality";const k=E($,"tls","security");return k===!0?"TLS":k===!1||k==="none"?"-":k}function D($){const k=$==null?void 0:$.transport;return typeof k=="string"?k:k!=null&&k.type?k.type:E($,"network","net")}function L($){return{original:($==null?void 0:$.originalCount)??(Array.isArray($==null?void 0:$.original)?$.original.length:($==null?void 0:$.nodes)??0),processed:Array.isArray($==null?void 0:$.processed)?$.processed.length:0}}function ae(){Object.assign(b,_()),i.value=!1,o.value=!0}function Y($){const k=$.renameOptions||{};Object.assign(b,{name:$.id,sourceIds:[...$.sourceIds||[]],renameEnabled:$.renameEnabled===!0,renameOptions:{flag:k.flag!==!1,alias:k.alias!==!1,country:k.country!==!1,city:k.city!==!1,index:k.index!==!1},templateId:$.templateId||"",ignoreFailed:$.ignoreFailed!==!1,enabled:$.enabled!==!1}),i.value=!0,o.value=!0}async function se(){try{const $={...b};i.value?await Am(b.name,$):await Cm($),o.value=!1,await me(),A(i.value?"已更新":"已创建")}catch($){A($.message,"error")}}async function oe($){R.value={show:!0,title:"删除合集",message:`确定删除 "${$.name}"?`,danger:!0,action:async()=>{try{await Om($.id),await me(),A("已删除")}catch(k){A(k.message,"error")}}}}async function W($){try{const k=await Lm($.id);await is(k.data.url),A("链接已复制")}catch(k){A(k.message,"error")}}async function ue($){if(l.value===$.id){l.value="",c.value=null;return}l.value=$.id,a.value=!0,c.value=null;try{const k=await Sr($);c.value=k.data,m[$.id]=L(k.data)}catch(k){A(k.message,"error"),l.value=""}finally{a.value=!1}}async function fe($){try{const k=await cu($);await is(k.data.uri),A("节点链接已复制")}catch(k){A(k.message,"error")}}async function Ne($){var k,z;if(!u.value){u.value=$.id,f.value="";try{const re=await Sr($),he=((k=re.data)==null?void 0:k.processed)||((z=re.data)==null?void 0:z.original)||[];m[$.id]=L(re.data),l.value===$.id&&(c.value=re.data);for(let Oe=0;Oe(F(),V("div",null,[d("div",{class:"flex items-center justify-between mb-5"},[k[11]||(k[11]=d("h2",{class:"text-xl font-bold"},"合集",-1)),d("button",{class:"px-4 py-2 bg-primary-600 text-white rounded-lg text-sm hover:bg-primary-700",onClick:ae},"+ 新建")]),r.value?(F(),V("div",hy,"加载中...")):t.value.length===0?(F(),V("div",my,"暂无合集")):(F(),V("div",gy,[(F(!0),V(we,null,Be(t.value,z=>{var re,he,Oe;return F(),V("div",{key:z.id,class:"bg-white rounded-lg shadow-sm border overflow-hidden hover:shadow-md transition-shadow"},[d("div",{class:"p-4 flex items-center justify-between cursor-pointer",onClick:de=>ue(z)},[d("div",by,[d("div",xy,[d("span",vy,j(z.name),1),z.enabled?ce("",!0):(F(),V("span",_y,"已禁用"))]),d("div",wy,[d("span",null,"原始节点: "+j(((re=m[z.id])==null?void 0:re.original)??"-"),1),d("span",null,"处理后: "+j(((he=m[z.id])==null?void 0:he.processed)??"-"),1),d("span",null,"订阅源: "+j(((Oe=z.sourceIds)==null?void 0:Oe.length)||0),1),z.renameEnabled?(F(),V("span",Ey,"重命名已开启")):ce("",!0),d("span",null,"模板: "+j(z.templateId||"default"),1),z.ignoreFailed?(F(),V("span",Sy,"忽略失败")):ce("",!0)])]),d("div",Ry,[d("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-blue-50 text-blue-600 whitespace-nowrap",disabled:!!u.value,onClick:ct(de=>Ne(z),["stop"])},j(u.value===z.id?`探测 ${f.value}`:"探测出口"),9,Cy),d("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-gray-100",onClick:ct(de=>W(z),["stop"])},"复制链接",8,Ay),d("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-blue-50 text-blue-600",onClick:ct(de=>Y(z),["stop"])},"编辑",8,Oy),d("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-red-50 text-red-600",onClick:ct(de=>oe(z),["stop"])},"删除",8,Ty)])],8,yy),l.value===z.id?(F(),V("div",{key:0,class:"border-t bg-gray-50",onClick:k[0]||(k[0]=ct(()=>{},["stop"]))},[a.value?(F(),V("div",Py,"解析中...")):c.value?(F(),V("div",Ny,[d("div",Iy,[d("table",ky,[k[12]||(k[12]=d("thead",{class:"sticky top-0 bg-gray-100 text-gray-600"},[d("tr",null,[d("th",{class:"px-3 py-2 font-medium"},"Type"),d("th",{class:"px-3 py-2 font-medium"},"Name"),d("th",{class:"px-3 py-2 font-medium"},"Server"),d("th",{class:"px-3 py-2 font-medium"},"Port"),d("th",{class:"px-3 py-2 font-medium"},"Transport"),d("th",{class:"px-3 py-2 font-medium"},"Tls"),d("th",{class:"px-3 py-2 font-medium"},"Delay"),d("th",{class:"px-3 py-2 font-medium"},"Speed"),d("th",{class:"px-3 py-2 font-medium"},"Egress IP"),d("th",{class:"px-3 py-2 font-medium"},"Country"),d("th",{class:"px-3 py-2 font-medium"},"Region"),d("th",{class:"px-3 py-2 font-medium"},"Link")])],-1)),d("tbody",$y,[(F(!0),V(we,null,Be(c.value.processed||c.value.original||[],(de,I)=>(F(),V("tr",{key:I},[d("td",Dy,j(E(de,"type")),1),d("td",Ly,j(E(de,"name","remarks")),1),d("td",Uy,j(E(de,"server","address")),1),d("td",Fy,j(E(de,"port")),1),d("td",My,j(D(de)),1),d("td",Vy,j(O(de)),1),d("td",By,j(E(de,"latencyMs","delay","latency","ping")),1),d("td",jy,j(E(de,"speed","downloadSpeed")),1),d("td",Hy,j(E(de,"egressIp")),1),d("td",qy,j(E(de,"egressCountry","country")),1),d("td",Ky,j(E(de,"egressRegion","region")),1),d("td",Wy,[d("button",{class:"px-2 py-1 text-xs rounded hover:bg-gray-100 text-blue-600 whitespace-nowrap",onClick:w=>fe(de)},"复制",8,zy)])]))),128))])])]),(c.value.processed||c.value.original||[]).length===0?(F(),V("p",Gy,"暂无节点")):ce("",!0)])):ce("",!0)])):ce("",!0)])}),128))])),Te(Us,{modelValue:o.value,"onUpdate:modelValue":k[8]||(k[8]=z=>o.value=z),title:i.value?"编辑合集":"新建合集"},{footer:dt(()=>[d("button",{class:"px-4 py-2 text-sm rounded-lg hover:bg-gray-100",onClick:k[7]||(k[7]=z=>o.value=!1)},"取消"),d("button",{class:"px-4 py-2 bg-primary-600 text-white rounded-lg text-sm hover:bg-primary-700",onClick:se},"保存")]),default:dt(()=>[d("div",Jy,[d("div",null,[k[13]||(k[13]=d("label",{class:"block text-sm font-medium mb-1"},"名称 / ID",-1)),ye(d("input",{"onUpdate:modelValue":k[1]||(k[1]=z=>b.name=z),disabled:i.value,placeholder:"my-collection",class:"w-full px-3 py-2 border rounded-lg text-sm disabled:bg-gray-100"},null,8,Xy),[[De,b.name]])]),d("div",null,[k[14]||(k[14]=d("label",{class:"block text-sm font-medium mb-1"},"订阅源 (多选)",-1)),d("div",Yy,[(F(!0),V(we,null,Be(n.value,z=>(F(),V("label",{key:z.id,class:"flex items-center gap-2 text-sm cursor-pointer hover:bg-gray-50 px-1 py-0.5 rounded"},[ye(d("input",{type:"checkbox",value:z.id,"onUpdate:modelValue":k[2]||(k[2]=re=>b.sourceIds=re),class:"rounded"},null,8,Qy),[[bn,b.sourceIds]]),d("span",null,j(z.name),1),d("span",Zy,"("+j(z.type)+")",1)]))),128)),n.value.length===0?(F(),V("p",eb,"无可用订阅源")):ce("",!0)])]),d("div",null,[k[16]||(k[16]=d("label",{class:"block text-sm font-medium mb-1"},"模板",-1)),ye(d("select",{"onUpdate:modelValue":k[3]||(k[3]=z=>b.templateId=z),class:"w-full px-3 py-2 border rounded-lg text-sm"},[k[15]||(k[15]=d("option",{value:""},"默认",-1)),(F(!0),V(we,null,Be(s.value,z=>(F(),V("option",{key:z.id,value:z.id},j(z.name)+" ("+j(z.target)+")",9,tb))),128))],512),[[ss,b.templateId]])]),d("div",nb,[d("label",sb,[ye(d("input",{type:"checkbox","onUpdate:modelValue":k[4]||(k[4]=z=>b.enabled=z),class:"rounded"},null,512),[[bn,b.enabled]]),k[17]||(k[17]=Wt(" 启用 ",-1))]),d("label",rb,[ye(d("input",{type:"checkbox","onUpdate:modelValue":k[5]||(k[5]=z=>b.ignoreFailed=z),class:"rounded"},null,512),[[bn,b.ignoreFailed]]),k[18]||(k[18]=Wt(" 忽略失败源 ",-1))]),d("label",ob,[ye(d("input",{type:"checkbox","onUpdate:modelValue":k[6]||(k[6]=z=>b.renameEnabled=z),class:"rounded"},null,512),[[bn,b.renameEnabled]]),k[19]||(k[19]=Wt(" 节点重命名 ",-1))])]),b.renameEnabled?(F(),V("div",ib,[k[20]||(k[20]=Wt(" 开启后,所有节点将按以下格式重命名:",-1)),k[21]||(k[21]=d("br",null,null,-1)),k[22]||(k[22]=d("code",{class:"text-blue-800"},"[国旗] [别名] [国家] [城市] [序号]",-1)),k[23]||(k[23]=d("br",null,null,-1)),k[24]||(k[24]=Wt(" 点击下方按钮可切换各字段的显示(默认全开): ",-1)),d("div",lb,[(F(),V(we,null,Be(C,z=>d("button",{type:"button",key:z.key,class:Fe(["px-2.5 py-1 rounded-full text-xs font-medium border transition-colors",b.renameOptions[z.key]?"bg-blue-600 text-white border-blue-600":"bg-white text-gray-500 border-gray-300 hover:border-gray-400"]),onClick:re=>b.renameOptions[z.key]=!b.renameOptions[z.key]},j(z.label),11,ab)),64))])])):ce("",!0)])]),_:1},8,["modelValue","title"]),Te(nr,{modelValue:R.value.show,"onUpdate:modelValue":k[9]||(k[9]=z=>R.value.show=z),title:R.value.title,message:R.value.message,danger:R.value.danger,onConfirm:k[10]||(k[10]=z=>{R.value.action(),R.value.show=!1})},null,8,["modelValue","title","message","danger"]),h.value?(F(),V("div",{key:3,class:Fe(["fixed bottom-4 right-4 px-4 py-2 rounded-lg shadow-lg text-sm z-50",h.value.type==="error"?"bg-red-500 text-white":"bg-green-500 text-white"])},j(h.value.msg),3)):ce("",!0)]))}},cb={key:0,class:"text-gray-400 text-sm"},fb={key:1,class:"text-gray-400 text-sm py-8 text-center"},db={key:2,class:"space-y-2"},pb={class:"flex-1 min-w-0"},hb={class:"flex items-center gap-2"},mb={class:"font-medium text-gray-900"},gb={class:"px-1.5 py-0.5 rounded text-xs bg-purple-100 text-purple-700"},yb={key:0,class:"px-1.5 py-0.5 rounded text-xs bg-gray-100 text-gray-500"},bb={class:"text-xs text-gray-500 mt-1"},xb={key:0,class:"flex gap-1 ml-3"},vb=["onClick"],_b=["onClick"],wb={key:1,class:"flex gap-1 ml-3"},Eb=["onClick"],Sb={class:"space-y-4"},Rb=["disabled"],Cb=["value"],Ab={key:0,class:"text-xs text-red-500 mt-1"},Ob={class:"text-xs font-mono bg-gray-50 p-3 rounded max-h-96 overflow-auto"},Tb={__name:"Templates",setup(e){const t=Z([]),n=Z(!0),s=Z(!1),r=Z(!1),o=Z(!1),i=Z(null),l=Z(null),a=Z({show:!1,title:"",message:"",danger:!1,action:null}),c=["mihomo","stash","surge","surge-mac","surfboard","loon","egern","shadowrocket","qx","sing-box","v2ray","uri","json"],u=()=>({name:"",target:"mihomo",configStr:"{}"}),f=At(u()),h=tt(()=>{try{return JSON.parse(f.configStr),""}catch{return"JSON 格式错误"}});function m(E,O="success"){l.value={msg:E,type:O},setTimeout(()=>l.value=null,2500)}function R(){Object.assign(f,u()),r.value=!1,s.value=!0}function C(E){Object.assign(f,{name:E.id,target:E.target,configStr:JSON.stringify(E.config||{},null,2)}),r.value=!0,s.value=!0}function P(E){i.value=E.config,o.value=!0}async function _(){if(h.value){m(h.value,"error");return}try{const E={name:f.name,target:f.target,config:JSON.parse(f.configStr)};r.value?await Pm(f.name,E):await Tm(E),s.value=!1,await A(),m(r.value?"已更新":"已创建")}catch(E){m(E.message,"error")}}async function b(E){a.value={show:!0,title:"删除模板",message:`确定删除 "${E.name}"?`,danger:!0,action:async()=>{try{await Nm(E.id),await A(),m("已删除")}catch(O){m(O.message,"error")}}}}async function A(){n.value=!0;try{const E=await Oo();t.value=E.data||[]}catch(E){m(E.message,"error")}finally{n.value=!1}}return Yt(A),(E,O)=>(F(),V("div",null,[d("div",{class:"flex items-center justify-between mb-5"},[O[8]||(O[8]=d("h2",{class:"text-xl font-bold"},"模板",-1)),d("button",{class:"px-4 py-2 bg-primary-600 text-white rounded-lg text-sm hover:bg-primary-700",onClick:R},"+ 新建")]),n.value?(F(),V("div",cb,"加载中...")):t.value.length===0?(F(),V("div",fb,"暂无模板")):(F(),V("div",db,[(F(!0),V(we,null,Be(t.value,D=>(F(),V("div",{key:D.id,class:"bg-white rounded-lg p-4 shadow-sm border flex items-center justify-between hover:shadow-md transition-shadow"},[d("div",pb,[d("div",hb,[d("span",mb,j(D.name),1),d("span",gb,j(D.target),1),D.readonly?(F(),V("span",yb,"内置")):ce("",!0)]),d("p",bb,j(Object.keys(D.config||{}).length)+" 个配置项",1)]),D.readonly?(F(),V("div",wb,[d("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-gray-100",onClick:L=>P(D)},"查看",8,Eb)])):(F(),V("div",xb,[d("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-blue-50 text-blue-600",onClick:L=>C(D)},"编辑",8,vb),d("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-red-50 text-red-600",onClick:L=>b(D)},"删除",8,_b)]))]))),128))])),Te(Us,{modelValue:s.value,"onUpdate:modelValue":O[4]||(O[4]=D=>s.value=D),title:r.value?"编辑模板":"新建模板"},{footer:dt(()=>[d("button",{class:"px-4 py-2 text-sm rounded-lg hover:bg-gray-100",onClick:O[3]||(O[3]=D=>s.value=!1)},"取消"),d("button",{class:"px-4 py-2 bg-primary-600 text-white rounded-lg text-sm hover:bg-primary-700",onClick:_},"保存")]),default:dt(()=>[d("div",Sb,[d("div",null,[O[9]||(O[9]=d("label",{class:"block text-sm font-medium mb-1"},"名称 / ID",-1)),ye(d("input",{"onUpdate:modelValue":O[0]||(O[0]=D=>f.name=D),disabled:r.value,placeholder:"my-template",class:"w-full px-3 py-2 border rounded-lg text-sm disabled:bg-gray-100"},null,8,Rb),[[De,f.name]])]),d("div",null,[O[10]||(O[10]=d("label",{class:"block text-sm font-medium mb-1"},"目标平台",-1)),ye(d("select",{"onUpdate:modelValue":O[1]||(O[1]=D=>f.target=D),class:"w-full px-3 py-2 border rounded-lg text-sm"},[(F(),V(we,null,Be(c,D=>d("option",{key:D,value:D},j(D),9,Cb)),64))],512),[[ss,f.target]])]),d("div",null,[O[11]||(O[11]=d("label",{class:"block text-sm font-medium mb-1"},"配置 (JSON)",-1)),ye(d("textarea",{"onUpdate:modelValue":O[2]||(O[2]=D=>f.configStr=D),rows:"12",placeholder:'{"proxy-groups": [], "rules": []}',class:"w-full px-3 py-2 border rounded-lg text-sm font-mono"},null,512),[[De,f.configStr]]),h.value?(F(),V("p",Ab,j(h.value),1)):ce("",!0)])])]),_:1},8,["modelValue","title"]),Te(Us,{modelValue:o.value,"onUpdate:modelValue":O[5]||(O[5]=D=>o.value=D),title:"查看模板配置"},{default:dt(()=>[d("pre",Ob,j(JSON.stringify(i.value,null,2)),1)]),_:1},8,["modelValue"]),Te(nr,{modelValue:a.value.show,"onUpdate:modelValue":O[6]||(O[6]=D=>a.value.show=D),title:a.value.title,message:a.value.message,danger:a.value.danger,onConfirm:O[7]||(O[7]=D=>{a.value.action(),a.value.show=!1})},null,8,["modelValue","title","message","danger"]),l.value?(F(),V("div",{key:3,class:Fe(["fixed bottom-4 right-4 px-4 py-2 rounded-lg shadow-lg text-sm z-50",l.value.type==="error"?"bg-red-500 text-white":"bg-green-500 text-white"])},j(l.value.msg),3)):ce("",!0)]))}},Pb={key:0,class:"text-gray-400 text-sm"},Nb={key:1,class:"text-gray-400 text-sm py-8 text-center"},Ib={key:2,class:"space-y-2"},kb={class:"flex-1 min-w-0"},$b={class:"flex items-center gap-2"},Db={class:"font-medium text-gray-900"},Lb={class:"text-xs text-gray-400 mt-1"},Ub={class:"flex gap-1 ml-3"},Fb=["onClick"],Mb=["onClick"],Vb={__name:"RecycleBin",setup(e){const t=Z([]),n=Z(!0),s=Z(null),r=Z({show:!1,title:"",message:"",danger:!1,confirmText:"确定",action:null});function o(f,h="success"){s.value={msg:f,type:h},setTimeout(()=>s.value=null,2500)}function i(f){return f?new Date(f).toLocaleString("zh-CN"):""}function l(f){return{source:"bg-blue-100 text-blue-700",collection:"bg-purple-100 text-purple-700",template:"bg-green-100 text-green-700"}[f]||"bg-gray-100 text-gray-600"}async function a(f){r.value={show:!0,title:"恢复",message:`恢复 "${f.resourceId}"?`,danger:!1,confirmText:"恢复",action:async()=>{try{await $m(f.id),await u(),o("已恢复")}catch(h){o(h.message,"error")}}}}async function c(f){r.value={show:!0,title:"彻底删除",message:`彻底删除 "${f.resourceId}"?此操作不可撤销!`,danger:!0,confirmText:"彻底删除",action:async()=>{try{await km(f.id),await u(),o("已彻底删除")}catch(h){o(h.message,"error")}}}}async function u(){n.value=!0;try{const f=await Im();t.value=f.data||[]}catch(f){o(f.message,"error")}finally{n.value=!1}}return Yt(u),(f,h)=>(F(),V("div",null,[h[2]||(h[2]=d("h2",{class:"text-xl font-bold mb-5"},"回收站",-1)),n.value?(F(),V("div",Pb,"加载中...")):t.value.length===0?(F(),V("div",Nb,"回收站为空")):(F(),V("div",Ib,[(F(!0),V(we,null,Be(t.value,m=>(F(),V("div",{key:m.id,class:"bg-white rounded-lg p-4 shadow-sm border flex items-center justify-between"},[d("div",kb,[d("div",$b,[d("span",{class:Fe(["px-1.5 py-0.5 rounded text-xs",l(m.resourceType)])},j(m.resourceType),3),d("span",Db,j(m.resourceId),1)]),d("p",Lb,"删除于: "+j(i(m.deletedAt)),1)]),d("div",Ub,[d("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-blue-50 text-blue-600",onClick:R=>a(m)},"恢复",8,Fb),d("button",{class:"px-2.5 py-1 text-xs rounded hover:bg-red-50 text-red-600",onClick:R=>c(m)},"彻底删除",8,Mb)])]))),128))])),Te(nr,{modelValue:r.value.show,"onUpdate:modelValue":h[0]||(h[0]=m=>r.value.show=m),title:r.value.title,message:r.value.message,danger:r.value.danger,confirmText:r.value.confirmText,onConfirm:h[1]||(h[1]=m=>{r.value.action(),r.value.show=!1})},null,8,["modelValue","title","message","danger","confirmText"]),s.value?(F(),V("div",{key:3,class:Fe(["fixed bottom-4 right-4 px-4 py-2 rounded-lg shadow-lg text-sm z-50",s.value.type==="error"?"bg-red-500 text-white":"bg-green-500 text-white"])},j(s.value.msg),3)):ce("",!0)]))}},Bb={class:"bg-white rounded-lg p-4 shadow-sm border mb-4"},jb={class:"flex gap-2 mb-3"},Hb=["value"],qb={class:"flex gap-2 mb-2"},Kb=["disabled"],Wb={key:0,class:"text-xs text-gray-500 mb-2"},zb={class:"bg-white rounded-lg p-4 shadow-sm border mb-4"},Gb={class:"flex gap-2 mb-3"},Jb=["disabled"],Xb={key:0,class:"bg-gray-50 rounded-lg p-3 text-sm space-y-1"},Yb={class:"flex justify-between"},Qb={class:"flex justify-between"},Zb={class:"flex justify-between"},e0={class:"flex justify-between"},t0={key:0,class:"flex justify-between"},n0={class:"bg-white rounded-lg p-4 shadow-sm border"},s0={class:"flex gap-2"},r0={class:"px-4 py-2 bg-gray-600 text-white rounded-lg text-sm hover:bg-gray-700 cursor-pointer"},o0={__name:"Tools",setup(e){const t=["mihomo","stash","surge","surge-mac","surfboard","loon","egern","shadowrocket","qx","sing-box","v2ray","uri","json"],n=["mihomo","surge","loon","qx"],s=Z("proxy"),r=Z("mihomo"),o=Z(""),i=Z(""),l=Z(""),a=Z(!1),c=Z(""),u=Z(null),f=Z(!1),h=Z(null),m=tt(()=>s.value==="proxy"?t:n);function R(E,O="success"){h.value={msg:E,type:O},setTimeout(()=>h.value=null,2500)}async function C(E){try{await is(E),R("已复制")}catch(O){R(O.message,"error")}}async function P(){var E;if(!o.value.trim()){R("请输入内容","error");return}a.value=!0,i.value="",l.value="";try{const D=await(s.value==="proxy"?Fm:Mm)({content:o.value,target:r.value});i.value=D.data.content||D.data.par_res||"",l.value=`解析: ${D.data.parsed||0} · 输出: ${D.data.emitted||0} · 跳过: ${D.data.skipped||0}`,(E=D.data.warnings)!=null&&E.length&&(l.value+=" · ⚠ "+D.data.warnings.join("; ")),R("转换成功")}catch(O){R(O.message,"error")}finally{a.value=!1}}async function _(){f.value=!0,u.value=null;try{const E=await Vm(c.value);u.value=E.data}catch(E){R(E.message,"error")}finally{f.value=!1}}async function b(){try{const E=await _m(),O=new Blob([JSON.stringify(E,null,2)],{type:"application/json"}),D=URL.createObjectURL(O),L=document.createElement("a");L.href=D,L.download=`sub-store-backup-${Date.now()}.json`,L.click(),URL.revokeObjectURL(D),R("已导出")}catch(E){R(E.message,"error")}}async function A(E){var D;const O=(D=E.target.files)==null?void 0:D[0];if(O){try{const L=await O.text(),ae=JSON.parse(L);await wm(ae),R("导入成功")}catch(L){R(L.message,"error")}E.target.value=""}}return(E,O)=>{var D;return F(),V("div",null,[O[16]||(O[16]=d("h2",{class:"text-xl font-bold mb-5"},"工具",-1)),d("div",Bb,[O[7]||(O[7]=d("h3",{class:"font-semibold mb-3"},"转换器",-1)),d("div",jb,[ye(d("select",{"onUpdate:modelValue":O[0]||(O[0]=L=>s.value=L),class:"px-3 py-2 border rounded-lg text-sm"},[...O[6]||(O[6]=[d("option",{value:"proxy"},"代理转换",-1),d("option",{value:"rule"},"规则转换",-1)])],512),[[ss,s.value]]),ye(d("select",{"onUpdate:modelValue":O[1]||(O[1]=L=>r.value=L),class:"px-3 py-2 border rounded-lg text-sm"},[(F(!0),V(we,null,Be(m.value,L=>(F(),V("option",{key:L,value:L},j(L),9,Hb))),128))],512),[[ss,r.value]])]),ye(d("textarea",{"onUpdate:modelValue":O[2]||(O[2]=L=>o.value=L),rows:"5",placeholder:"粘贴订阅内容或规则...",class:"w-full px-3 py-2 border rounded-lg text-sm font-mono mb-2"},null,512),[[De,o.value]]),d("div",qb,[d("button",{class:"px-4 py-2 bg-primary-600 text-white rounded-lg text-sm hover:bg-primary-700",disabled:a.value,onClick:P},j(a.value?"转换中...":"转换"),9,Kb),i.value?(F(),V("button",{key:0,class:"px-4 py-2 text-sm rounded-lg hover:bg-gray-100",onClick:O[3]||(O[3]=L=>C(i.value))},"复制结果")):ce("",!0)]),l.value?(F(),V("p",Wb,j(l.value),1)):ce("",!0),i.value?ye((F(),V("textarea",{key:1,"onUpdate:modelValue":O[4]||(O[4]=L=>i.value=L),rows:"8",readonly:"",class:"w-full px-3 py-2 border rounded-lg text-sm font-mono bg-gray-50"},null,512)),[[De,i.value]]):ce("",!0)]),d("div",zb,[O[13]||(O[13]=d("h3",{class:"font-semibold mb-3"},"节点信息查询",-1)),d("div",Gb,[ye(d("input",{"onUpdate:modelValue":O[5]||(O[5]=L=>c.value=L),placeholder:"服务器地址 / IP",class:"flex-1 px-3 py-2 border rounded-lg text-sm",onKeyup:Ff(_,["enter"])},null,544),[[De,c.value]]),d("button",{class:"px-4 py-2 bg-primary-600 text-white rounded-lg text-sm hover:bg-primary-700",disabled:!c.value||f.value,onClick:_},j(f.value?"查询中...":"查询"),9,Jb)]),u.value?(F(),V("div",Xb,[d("div",Yb,[O[8]||(O[8]=d("span",{class:"text-gray-500"},"IP",-1)),d("span",null,j(u.value.ip),1)]),d("div",Qb,[O[9]||(O[9]=d("span",{class:"text-gray-500"},"国家",-1)),d("span",null,j(u.value.country),1)]),d("div",Zb,[O[10]||(O[10]=d("span",{class:"text-gray-500"},"地区",-1)),d("span",null,j(u.value.region),1)]),d("div",e0,[O[11]||(O[11]=d("span",{class:"text-gray-500"},"城市",-1)),d("span",null,j(u.value.city),1)]),u.value.connection?(F(),V("div",t0,[O[12]||(O[12]=d("span",{class:"text-gray-500"},"ISP",-1)),d("span",null,j(((D=u.value.connection)==null?void 0:D.isp)||"-"),1)])):ce("",!0)])):ce("",!0)]),d("div",n0,[O[15]||(O[15]=d("h3",{class:"font-semibold mb-3"},"数据备份",-1)),d("div",s0,[d("button",{class:"px-4 py-2 bg-green-600 text-white rounded-lg text-sm hover:bg-green-700",onClick:b},"导出全部"),d("label",r0,[O[14]||(O[14]=Wt(" 导入备份 ",-1)),d("input",{type:"file",accept:".json",class:"hidden",onChange:A},null,32)])])]),h.value?(F(),V("div",{key:0,class:Fe(["fixed bottom-4 right-4 px-4 py-2 rounded-lg shadow-lg text-sm z-50",h.value.type==="error"?"bg-red-500 text-white":"bg-green-500 text-white"])},j(h.value.msg),3)):ce("",!0)])}}},i0={key:0,class:"text-gray-400 text-sm"},l0={key:1,class:"space-y-4"},a0={class:"bg-white rounded-lg p-4 shadow-sm border"},u0={class:"space-y-3"},c0={class:"flex items-center gap-2"},f0={class:"bg-white rounded-lg p-4 shadow-sm border"},d0={__name:"Settings",setup(e){const t=Z(null),n=Z(!0),s=Z(null);function r(i,l="success"){s.value={msg:i,type:l},setTimeout(()=>s.value=null,2500)}async function o(){try{await vm(t.value),r("设置已保存")}catch(i){r(i.message,"error")}}return Yt(async()=>{try{const i=await xm();t.value=i.data}catch(i){r(i.message,"error")}finally{n.value=!1}}),(i,l)=>(F(),V("div",null,[l[16]||(l[16]=d("h2",{class:"text-xl font-bold mb-5"},"设置",-1)),n.value?(F(),V("div",i0,"加载中...")):(F(),V("div",l0,[d("div",a0,[l[13]||(l[13]=d("h3",{class:"font-semibold mb-3 text-sm"},"通用",-1)),d("div",u0,[d("div",null,[l[7]||(l[7]=d("label",{class:"block text-sm mb-1"},"默认 User-Agent",-1)),ye(d("input",{"onUpdate:modelValue":l[0]||(l[0]=a=>t.value.defaultUserAgent=a),class:"w-full px-3 py-2 border rounded-lg text-sm"},null,512),[[De,t.value.defaultUserAgent]])]),d("div",null,[l[8]||(l[8]=d("label",{class:"block text-sm mb-1"},"默认流量查询 User-Agent",-1)),ye(d("input",{"onUpdate:modelValue":l[1]||(l[1]=a=>t.value.defaultFlowUserAgent=a),class:"w-full px-3 py-2 border rounded-lg text-sm"},null,512),[[De,t.value.defaultFlowUserAgent]])]),d("div",null,[l[9]||(l[9]=d("label",{class:"block text-sm mb-1"},"请求超时 (ms)",-1)),ye(d("input",{"onUpdate:modelValue":l[2]||(l[2]=a=>t.value.defaultTimeout=a),class:"w-full px-3 py-2 border rounded-lg text-sm"},null,512),[[De,t.value.defaultTimeout]])]),d("div",null,[l[10]||(l[10]=d("label",{class:"block text-sm mb-1"},"后端并发数",-1)),ye(d("input",{"onUpdate:modelValue":l[3]||(l[3]=a=>t.value.backendRequestConcurrency=a),class:"w-full px-3 py-2 border rounded-lg text-sm"},null,512),[[De,t.value.backendRequestConcurrency]])]),d("div",null,[l[11]||(l[11]=d("label",{class:"block text-sm mb-1"},"远程缓存 TTL (秒)",-1)),ye(d("input",{"onUpdate:modelValue":l[4]||(l[4]=a=>t.value.remoteCacheTtl=a),class:"w-full px-3 py-2 border rounded-lg text-sm"},null,512),[[De,t.value.remoteCacheTtl]])]),d("div",c0,[ye(d("input",{type:"checkbox",id:"cache-stale","onUpdate:modelValue":l[5]||(l[5]=a=>t.value.remoteCacheStaleOnError=a),class:"rounded"},null,512),[[bn,t.value.remoteCacheStaleOnError]]),l[12]||(l[12]=d("label",{for:"cache-stale",class:"text-sm"},"缓存过期时仍返回旧数据",-1))])])]),d("div",f0,[l[14]||(l[14]=d("h3",{class:"font-semibold mb-3 text-sm"},"节点信息 API",-1)),ye(d("input",{"onUpdate:modelValue":l[6]||(l[6]=a=>t.value.nodeInfoApiUrl=a),placeholder:"https://ipwho.is/{ip}",class:"w-full px-3 py-2 border rounded-lg text-sm font-mono"},null,512),[[De,t.value.nodeInfoApiUrl]]),l[15]||(l[15]=d("p",{class:"text-xs text-gray-400 mt-1"},"URL 中 {ip} 会被替换为查询的 IP",-1))]),d("button",{class:"px-4 py-2 bg-primary-600 text-white rounded-lg text-sm hover:bg-primary-700",onClick:o},"保存设置")])),s.value?(F(),V("div",{key:2,class:Fe(["fixed bottom-4 right-4 px-4 py-2 rounded-lg shadow-lg text-sm z-50",s.value.type==="error"?"bg-red-500 text-white":"bg-green-500 text-white"])},j(s.value.msg),3)):ce("",!0)]))}},p0=[{path:"/login",name:"login",component:yp,meta:{title:"登录"}},{path:"/",component:pp,children:[{path:"",name:"dashboard",component:eg,meta:{title:"概览"}},{path:"sources",name:"sources",component:py,meta:{title:"订阅源"}},{path:"collections",name:"collections",component:ub,meta:{title:"合集"}},{path:"templates",name:"templates",component:Tb,meta:{title:"模板"}},{path:"recycle-bin",name:"recycle-bin",component:Vb,meta:{title:"回收站"}},{path:"tools",name:"tools",component:o0,meta:{title:"工具"}},{path:"settings",name:"settings",component:d0,meta:{title:"设置"}}]},{path:"/:pathMatch(.*)*",name:"not-found",component:xp}],du=Qd({history:Pd(),routes:p0});du.beforeEach((e,t,n)=>{if(e.name==="login"||e.name==="not-found")return n();const s=xo(),r=Ua(),o=np();if(!s||!r||!o)return n({name:"login",query:{redirect:e.fullPath}});n()});const To=Bf(Wf);To.use(Kf());To.use(du);To.mount("#app"); diff --git a/frontend/dist/assets/index-s7owp4VX.css b/frontend/dist/assets/index-s7owp4VX.css new file mode 100644 index 0000000..da64249 --- /dev/null +++ b/frontend/dist/assets/index-s7owp4VX.css @@ -0,0 +1 @@ +*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.inset-y-0{top:0;bottom:0}.bottom-4{bottom:1rem}.left-0{left:0}.right-4{right:1rem}.top-0{top:0}.z-30{z-index:30}.z-50{z-index:50}.z-\[60\]{z-index:60}.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-5{margin-bottom:1.25rem}.mb-6{margin-bottom:1.5rem}.ml-3{margin-left:.75rem}.ml-60{margin-left:15rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-4{margin-top:1rem}.mt-6{margin-top:1.5rem}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-2{height:.5rem}.max-h-32{max-height:8rem}.max-h-96{max-height:24rem}.max-h-\[85vh\]{max-height:85vh}.min-h-screen{min-height:100vh}.w-2{width:.5rem}.w-24{width:6rem}.w-28{width:7rem}.w-60{width:15rem}.w-full{width:100%}.min-w-0{min-width:0px}.max-w-2xl{max-width:42rem}.max-w-sm{max-width:24rem}.flex-1{flex:1 1 0%}.border-collapse{border-collapse:collapse}.cursor-pointer{cursor:pointer}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.375rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse))}.divide-gray-100>:not([hidden])~:not([hidden]){--tw-divide-opacity: 1;border-color:rgb(243 244 246 / var(--tw-divide-opacity, 1))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-l-2{border-left-width:2px}.border-t{border-top-width:1px}.border-blue-600{--tw-border-opacity: 1;border-color:rgb(37 99 235 / var(--tw-border-opacity, 1))}.border-gray-200{--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1))}.border-gray-300{--tw-border-opacity: 1;border-color:rgb(209 213 219 / var(--tw-border-opacity, 1))}.border-gray-700{--tw-border-opacity: 1;border-color:rgb(55 65 81 / var(--tw-border-opacity, 1))}.border-primary-500{--tw-border-opacity: 1;border-color:rgb(59 130 246 / var(--tw-border-opacity, 1))}.border-transparent{border-color:transparent}.bg-black\/40{background-color:#0006}.bg-blue-100{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1))}.bg-blue-50{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.bg-blue-600{--tw-bg-opacity: 1;background-color:rgb(37 99 235 / var(--tw-bg-opacity, 1))}.bg-gray-100{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.bg-gray-50{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.bg-gray-600{--tw-bg-opacity: 1;background-color:rgb(75 85 99 / var(--tw-bg-opacity, 1))}.bg-gray-800{--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity, 1))}.bg-gray-900{--tw-bg-opacity: 1;background-color:rgb(17 24 39 / var(--tw-bg-opacity, 1))}.bg-green-100{--tw-bg-opacity: 1;background-color:rgb(220 252 231 / var(--tw-bg-opacity, 1))}.bg-green-500{--tw-bg-opacity: 1;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))}.bg-green-600{--tw-bg-opacity: 1;background-color:rgb(22 163 74 / var(--tw-bg-opacity, 1))}.bg-primary-50{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.bg-primary-500{--tw-bg-opacity: 1;background-color:rgb(59 130 246 / var(--tw-bg-opacity, 1))}.bg-primary-600{--tw-bg-opacity: 1;background-color:rgb(37 99 235 / var(--tw-bg-opacity, 1))}.bg-purple-100{--tw-bg-opacity: 1;background-color:rgb(243 232 255 / var(--tw-bg-opacity, 1))}.bg-red-100{--tw-bg-opacity: 1;background-color:rgb(254 226 226 / var(--tw-bg-opacity, 1))}.bg-red-500{--tw-bg-opacity: 1;background-color:rgb(239 68 68 / var(--tw-bg-opacity, 1))}.bg-red-600{--tw-bg-opacity: 1;background-color:rgb(220 38 38 / var(--tw-bg-opacity, 1))}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-5{padding-top:1.25rem;padding-bottom:1.25rem}.py-8{padding-top:2rem;padding-bottom:2rem}.text-left{text-align:left}.text-center{text-align:center}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-7xl{font-size:4.5rem;line-height:1}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.text-blue-600{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.text-blue-700{--tw-text-opacity: 1;color:rgb(29 78 216 / var(--tw-text-opacity, 1))}.text-blue-800{--tw-text-opacity: 1;color:rgb(30 64 175 / var(--tw-text-opacity, 1))}.text-gray-300{--tw-text-opacity: 1;color:rgb(209 213 219 / var(--tw-text-opacity, 1))}.text-gray-400{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.text-gray-500{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}.text-gray-600{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.text-gray-700{--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.text-gray-900{--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}.text-green-600{--tw-text-opacity: 1;color:rgb(22 163 74 / var(--tw-text-opacity, 1))}.text-green-700{--tw-text-opacity: 1;color:rgb(21 128 61 / var(--tw-text-opacity, 1))}.text-primary-600{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.text-primary-700{--tw-text-opacity: 1;color:rgb(29 78 216 / var(--tw-text-opacity, 1))}.text-purple-500{--tw-text-opacity: 1;color:rgb(168 85 247 / var(--tw-text-opacity, 1))}.text-purple-600{--tw-text-opacity: 1;color:rgb(147 51 234 / var(--tw-text-opacity, 1))}.text-purple-700{--tw-text-opacity: 1;color:rgb(126 34 206 / var(--tw-text-opacity, 1))}.text-red-500{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.text-red-600{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.text-red-700{--tw-text-opacity: 1;color:rgb(185 28 28 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-shadow{transition-property:box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:4px}::-webkit-scrollbar-thumb:hover{background:#94a3b8}.fade-enter-active,.fade-leave-active{transition:opacity .2s}.fade-enter-from,.fade-leave-to{opacity:0}.hover\:border-gray-400:hover{--tw-border-opacity: 1;border-color:rgb(156 163 175 / var(--tw-border-opacity, 1))}.hover\:bg-blue-50:hover{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-100:hover{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-50:hover{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-700:hover{--tw-bg-opacity: 1;background-color:rgb(55 65 81 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-800\/50:hover{background-color:#1f293780}.hover\:bg-green-700:hover{--tw-bg-opacity: 1;background-color:rgb(21 128 61 / var(--tw-bg-opacity, 1))}.hover\:bg-primary-700:hover{--tw-bg-opacity: 1;background-color:rgb(29 78 216 / var(--tw-bg-opacity, 1))}.hover\:bg-red-50:hover{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.hover\:bg-red-700:hover{--tw-bg-opacity: 1;background-color:rgb(185 28 28 / var(--tw-bg-opacity, 1))}.hover\:text-gray-600:hover{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.hover\:underline:hover{text-decoration-line:underline}.hover\:shadow-md:hover{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-2:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-primary-500:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity, 1))}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:bg-gray-100:disabled{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.disabled\:opacity-60:disabled{opacity:.6}@media(min-width:1024px){.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}} diff --git a/frontend/dist/index.html b/frontend/dist/index.html index 2534ffb..31ef4bf 100644 --- a/frontend/dist/index.html +++ b/frontend/dist/index.html @@ -5,8 +5,8 @@ Sub-Store - - + +
diff --git a/frontend/src/pages/Collections.vue b/frontend/src/pages/Collections.vue index 7395370..e9e7bc6 100644 --- a/frontend/src/pages/Collections.vue +++ b/frontend/src/pages/Collections.vue @@ -20,7 +20,7 @@ 原始节点: {{ nodeCounts[col.id]?.original ?? '-' }} 处理后: {{ nodeCounts[col.id]?.processed ?? '-' }} 订阅源: {{ col.sourceIds?.length || 0 }} - 过滤器: {{ col.filters?.length || 0 }} + 重命名已开启 模板: {{ col.templateId || 'default' }} 忽略失败 @@ -114,18 +114,23 @@ + -
-
- - -
-
- - - +
+ 开启后,所有节点将按以下格式重命名:
+ [国旗] [别名] [国家] [城市] [序号]
+ 点击下方按钮可切换各字段的显示(默认全开): +
+
@@ -169,8 +174,18 @@ const confirmDialog = ref({ show: false, title: '', message: '', danger: false, const filterTypes = ['include', 'exclude', 'rename', 'dedupe', 'sort', 'delete-field', 'flag', 'quick', 'resolve', 'custom'] +const renameOptionList = [ + { key: 'flag', label: '国旗' }, + { key: 'alias', label: '别名' }, + { key: 'country', label: '国家' }, + { key: 'city', label: '城市' }, + { key: 'index', label: '序号' }, +] + +const defaultRenameOptions = () => ({ flag: true, alias: true, country: true, city: true, index: true }) + const emptyForm = () => ({ - name: '', sourceIds: [], filters: [], templateId: '', ignoreFailed: true, enabled: true + name: '', sourceIds: [], renameEnabled: false, renameOptions: defaultRenameOptions(), templateId: '', ignoreFailed: true, enabled: true }) const form = reactive(emptyForm()) @@ -217,10 +232,18 @@ function openCreate() { } function editCol(col) { + const ro = col.renameOptions || {} Object.assign(form, { name: col.id, sourceIds: [...(col.sourceIds || [])], - filters: JSON.parse(JSON.stringify(col.filters || [])), + renameEnabled: col.renameEnabled === true, + renameOptions: { + flag: ro.flag !== false, + alias: ro.alias !== false, + country: ro.country !== false, + city: ro.city !== false, + index: ro.index !== false, + }, templateId: col.templateId || '', ignoreFailed: col.ignoreFailed !== false, enabled: col.enabled !== false, diff --git a/frontend/src/pages/Sources.vue b/frontend/src/pages/Sources.vue index b842adf..b8c4a43 100644 --- a/frontend/src/pages/Sources.vue +++ b/frontend/src/pages/Sources.vue @@ -14,6 +14,7 @@
{{ src.name }} + {{ src.alias }} {{ src.type }} 已禁用 @@ -22,6 +23,7 @@
原始节点: {{ nodeCounts[src.id]?.original ?? '-' }} 处理后: {{ nodeCounts[src.id]?.processed ?? '-' }} + 别名: {{ src.alias }} 过滤器: {{ src.filters?.length || 0 }} 创建: {{ formatTime(src.createdAt) }}
@@ -87,11 +89,19 @@
-
- - -

仅支持小写字母、数字、下划线、连字符

+
+
+ + +

小写字母、数字、下划线、连字符

+
+
+ + +

合集重命名时作为节点标识

+
@@ -225,7 +235,7 @@ const filterGuides = [ ] const emptyForm = () => ({ - name: '', type: 'remote', url: '', content: '', enabled: true, filters: [] + name: '', alias: '', type: 'remote', url: '', content: '', enabled: true, filters: [] }) const form = reactive(emptyForm()) @@ -305,6 +315,7 @@ function sourcePreviewPayload(src) { return { id: src.id, name: src.name, + alias: src.alias, type: src.type, url: src.url, content: src.content, @@ -321,6 +332,7 @@ function openCreate() { function editSource(src) { Object.assign(form, { name: src.id, + alias: src.alias || '', type: src.type || 'remote', url: src.url || '', content: src.content || '', @@ -339,6 +351,7 @@ async function save() { try { const payload = { name: form.name, + alias: form.alias, type: form.type, url: form.url, content: form.content, diff --git a/go.mod b/go.mod index 3998633..9cbe26a 100644 --- a/go.mod +++ b/go.mod @@ -24,6 +24,7 @@ require ( github.com/mattn/go-isatty v0.0.23 // indirect github.com/mfridman/interpolate v0.0.2 // indirect github.com/ncruces/go-strftime v1.0.0 // indirect + github.com/oschwald/maxminddb-golang v1.13.1 // indirect github.com/pelletier/go-toml/v2 v2.2.4 // indirect github.com/philhofer/fwd v1.2.0 // indirect github.com/pressly/goose/v3 v3.27.3 // indirect diff --git a/go.sum b/go.sum index 1a2757d..24ae1fd 100644 --- a/go.sum +++ b/go.sum @@ -45,6 +45,8 @@ github.com/mfridman/interpolate v0.0.2 h1:pnuTK7MQIxxFz1Gr+rjSIx9u7qVjf5VOoM/u6B github.com/mfridman/interpolate v0.0.2/go.mod h1:p+7uk6oE07mpE/Ik1b8EckO0O4ZXiGAfshKBWLUM9Xg= github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w= github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= +github.com/oschwald/maxminddb-golang v1.13.1 h1:G3wwjdN9JmIK2o/ermkHM+98oX5fS+k5MbwsmL4MRQE= +github.com/oschwald/maxminddb-golang v1.13.1/go.mod h1:K4pgV9N/GcK694KSTmVSDTODk4IsCNThNdTmnaBZ/F8= github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM= diff --git a/internal/database/collection_repo.go b/internal/database/collection_repo.go index 08924ec..17aafa0 100644 --- a/internal/database/collection_repo.go +++ b/internal/database/collection_repo.go @@ -20,21 +20,24 @@ func NewCollectionRepo(db *sqlx.DB) *CollectionRepo { } type collectionRow struct { - ID string `db:"id"` - Name string `db:"name"` - SourceIdsJSON string `db:"source_ids_json"` - FiltersJSON string `db:"filters_json"` - TemplateID string `db:"template_id"` - IgnoreFailed int `db:"ignore_failed"` - Enabled int `db:"enabled"` - MetaJSON string `db:"meta_json"` - CreatedAt int64 `db:"created_at"` - UpdatedAt int64 `db:"updated_at"` + ID string `db:"id"` + Name string `db:"name"` + SourceIdsJSON string `db:"source_ids_json"` + RenameEnabled int `db:"rename_enabled"` + RenameOptionsJSON string `db:"rename_options_json"` + TemplateID string `db:"template_id"` + IgnoreFailed int `db:"ignore_failed"` + Enabled int `db:"enabled"` + MetaJSON string `db:"meta_json"` + CreatedAt int64 `db:"created_at"` + UpdatedAt int64 `db:"updated_at"` } +const collectionColumns = `id, name, source_ids_json, rename_enabled, rename_options_json, template_id, ignore_failed, enabled, meta_json, created_at, updated_at` + func (r *CollectionRepo) List() ([]model.CollectionRecord, error) { var rows []collectionRow - if err := r.db.Select(&rows, "SELECT * FROM collections ORDER BY created_at ASC"); err != nil { + if err := r.db.Select(&rows, `SELECT `+collectionColumns+` FROM collections ORDER BY created_at ASC`); err != nil { return nil, err } result := make([]model.CollectionRecord, 0, len(rows)) @@ -46,7 +49,7 @@ func (r *CollectionRepo) List() ([]model.CollectionRecord, error) { func (r *CollectionRepo) Get(id string) (*model.CollectionRecord, error) { var row collectionRow - if err := r.db.Get(&row, "SELECT * FROM collections WHERE id = ?", id); err != nil { + if err := r.db.Get(&row, `SELECT `+collectionColumns+` FROM collections WHERE id = ?`, id); err != nil { if err == sql.ErrNoRows { return nil, nil } @@ -72,10 +75,6 @@ func (r *CollectionRepo) Upsert(input model.CollectionRecord) (model.CollectionR if sourceIds == nil { sourceIds = []string{} } - filters := input.Filters - if filters == nil { - filters = []model.FilterRule{} - } meta := input.Meta if meta == nil { meta = map[string]any{} @@ -86,31 +85,35 @@ func (r *CollectionRepo) Upsert(input model.CollectionRecord) (model.CollectionR } rec := model.CollectionRecord{ - ID: id, - Name: input.Name, - SourceIds: sourceIds, - Filters: filters, - TemplateId: templateId, - IgnoreFailed: input.IgnoreFailed, - Enabled: input.Enabled, - Meta: meta, - CreatedAt: createdAt, - UpdatedAt: now, + ID: id, + Name: input.Name, + SourceIds: sourceIds, + RenameEnabled: input.RenameEnabled, + RenameOptions: input.RenameOptions, + TemplateId: templateId, + IgnoreFailed: input.IgnoreFailed, + Enabled: input.Enabled, + Meta: meta, + CreatedAt: createdAt, + UpdatedAt: now, } sourceIdsJSON := marshalJSON(rec.SourceIds) - filtersJSON := marshalJSON(rec.Filters) metaJSON := marshalJSON(rec.Meta) + renameOptionsJSON := "" + if rec.RenameOptions != nil { + renameOptionsJSON = marshalJSON(rec.RenameOptions) + } _, err := r.db.Exec( - `INSERT INTO collections (id, name, source_ids_json, filters_json, template_id, ignore_failed, enabled, meta_json, created_at, updated_at) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + `INSERT INTO collections (id, name, source_ids_json, rename_enabled, rename_options_json, template_id, ignore_failed, enabled, meta_json, created_at, updated_at) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(id) DO UPDATE SET name = excluded.name, source_ids_json = excluded.source_ids_json, - filters_json = excluded.filters_json, template_id = excluded.template_id, - ignore_failed = excluded.ignore_failed, enabled = excluded.enabled, - meta_json = excluded.meta_json, updated_at = excluded.updated_at`, - rec.ID, rec.Name, sourceIdsJSON, filtersJSON, rec.TemplateId, boolToInt(rec.IgnoreFailed), boolToInt(rec.Enabled), metaJSON, rec.CreatedAt, rec.UpdatedAt, + rename_enabled = excluded.rename_enabled, rename_options_json = excluded.rename_options_json, + template_id = excluded.template_id, ignore_failed = excluded.ignore_failed, + enabled = excluded.enabled, meta_json = excluded.meta_json, updated_at = excluded.updated_at`, + rec.ID, rec.Name, sourceIdsJSON, boolToInt(rec.RenameEnabled), renameOptionsJSON, rec.TemplateId, boolToInt(rec.IgnoreFailed), boolToInt(rec.Enabled), metaJSON, rec.CreatedAt, rec.UpdatedAt, ) if err != nil { return rec, err @@ -145,16 +148,26 @@ func collectionFromRow(row collectionRow) model.CollectionRecord { if sourceIds == nil { sourceIds = []string{} } + + var renameOptions *model.RenameOptions + if row.RenameOptionsJSON != "" { + var opts model.RenameOptions + if err := json.Unmarshal([]byte(row.RenameOptionsJSON), &opts); err == nil { + renameOptions = &opts + } + } + return model.CollectionRecord{ - ID: row.ID, - Name: row.Name, - SourceIds: sourceIds, - Filters: model.UnmarshalFilterRules(row.FiltersJSON), - TemplateId: row.TemplateID, - IgnoreFailed: row.IgnoreFailed != 0, - Enabled: row.Enabled != 0, - Meta: model.UnmarshalMeta(row.MetaJSON), - CreatedAt: row.CreatedAt, - UpdatedAt: row.UpdatedAt, + ID: row.ID, + Name: row.Name, + SourceIds: sourceIds, + RenameEnabled: row.RenameEnabled != 0, + RenameOptions: renameOptions, + TemplateId: row.TemplateID, + IgnoreFailed: row.IgnoreFailed != 0, + Enabled: row.Enabled != 0, + Meta: model.UnmarshalMeta(row.MetaJSON), + CreatedAt: row.CreatedAt, + UpdatedAt: row.UpdatedAt, } } diff --git a/internal/database/migrations/0004_source_alias_collection_rename.sql b/internal/database/migrations/0004_source_alias_collection_rename.sql new file mode 100644 index 0000000..73b06d0 --- /dev/null +++ b/internal/database/migrations/0004_source_alias_collection_rename.sql @@ -0,0 +1,9 @@ +-- +goose Up +ALTER TABLE sources ADD COLUMN alias TEXT NOT NULL DEFAULT ''; + +-- Collections no longer have filters; they have a rename toggle instead. +ALTER TABLE collections ADD COLUMN rename_enabled INTEGER NOT NULL DEFAULT 0; + +-- +goose Down +-- SQLite does not support DROP COLUMN before 3.35; these columns are harmless +-- if left in place. For a clean rollback, recreate the tables without them. diff --git a/internal/database/migrations/0005_collection_rename_options.sql b/internal/database/migrations/0005_collection_rename_options.sql new file mode 100644 index 0000000..fee058d --- /dev/null +++ b/internal/database/migrations/0005_collection_rename_options.sql @@ -0,0 +1,5 @@ +-- +goose Up +ALTER TABLE collections ADD COLUMN rename_options_json TEXT NOT NULL DEFAULT ''; + +-- +goose Down +-- SQLite does not support DROP COLUMN before 3.35; harmless if left in place. diff --git a/internal/database/repo_extra_test.go b/internal/database/repo_extra_test.go index 74b222e..e3acb25 100644 --- a/internal/database/repo_extra_test.go +++ b/internal/database/repo_extra_test.go @@ -160,7 +160,7 @@ func TestCollectionDelete(t *testing.T) { defer db.Close() repo := NewCollectionRepo(db) repo.Upsert(model.CollectionRecord{ - ID: "col-del", Name: "Del", SourceIds: []string{}, Filters: []model.FilterRule{}, + ID: "col-del", Name: "Del", SourceIds: []string{}, TemplateId: "acl4ssr-mihomo", Meta: map[string]any{}, }) err := repo.Delete("col-del") @@ -179,7 +179,7 @@ func TestCollectionSort(t *testing.T) { repo := NewCollectionRepo(db) for _, id := range []string{"a", "b", "c"} { repo.Upsert(model.CollectionRecord{ - ID: id, Name: id, SourceIds: []string{}, Filters: []model.FilterRule{}, + ID: id, Name: id, SourceIds: []string{}, TemplateId: "acl4ssr-mihomo", Meta: map[string]any{}, }) } @@ -365,7 +365,7 @@ func TestSourceUpsert_AutoId(t *testing.T) { repo := NewSourceRepo(db) rec, err := repo.Upsert(model.SourceRecord{ Name: "My Source", Type: "local", Content: "ss://pass@host:port#name", - Enabled: true, Filters: []model.FilterRule{}, Meta: map[string]any{}, + Enabled: true, Meta: map[string]any{}, }) if err != nil { t.Fatalf("upsert failed: %v", err) @@ -381,7 +381,7 @@ func TestSourceUpsert_DefaultTypeRemote(t *testing.T) { repo := NewSourceRepo(db) repo.Upsert(model.SourceRecord{ ID: "test", Name: "Test", Type: "", URL: "https://example.com/sub", - Enabled: true, Filters: []model.FilterRule{}, Meta: map[string]any{}, + Enabled: true, Meta: map[string]any{}, }) // Read back — sourceFromRow normalizes empty type to "remote" got, _ := repo.Get("test") @@ -455,9 +455,6 @@ func TestCollectionUpsert_Defaults(t *testing.T) { if rec.SourceIds == nil { t.Error("expected non-nil SourceIds") } - if rec.Filters == nil { - t.Error("expected non-nil Filters") - } if rec.Meta == nil { t.Error("expected non-nil Meta") } diff --git a/internal/database/repo_test.go b/internal/database/repo_test.go index 68806d8..1cf9499 100644 --- a/internal/database/repo_test.go +++ b/internal/database/repo_test.go @@ -104,14 +104,14 @@ func TestCollectionCRUD(t *testing.T) { repo := NewCollectionRepo(db) col := model.CollectionRecord{ - ID: "test-col", - Name: "Test Collection", - SourceIds: []string{"src1"}, - Filters: []model.FilterRule{}, - TemplateId: "default", - IgnoreFailed: true, - Enabled: true, - Meta: map[string]any{}, + ID: "test-col", + Name: "Test Collection", + SourceIds: []string{"src1"}, + RenameEnabled: true, + TemplateId: "default", + IgnoreFailed: true, + Enabled: true, + Meta: map[string]any{}, } created, err := repo.Upsert(col) if err != nil { diff --git a/internal/database/source_repo.go b/internal/database/source_repo.go index 5b3a4fc..65b4554 100644 --- a/internal/database/source_repo.go +++ b/internal/database/source_repo.go @@ -21,6 +21,7 @@ func NewSourceRepo(db *sqlx.DB) *SourceRepo { type sourceRow struct { ID string `db:"id"` Name string `db:"name"` + Alias string `db:"alias"` Type string `db:"type"` URL string `db:"url"` Content string `db:"content"` @@ -33,7 +34,7 @@ type sourceRow struct { func (r *SourceRepo) List() ([]model.SourceRecord, error) { var rows []sourceRow - if err := r.db.Select(&rows, "SELECT * FROM sources ORDER BY created_at ASC"); err != nil { + if err := r.db.Select(&rows, `SELECT id, name, alias, type, url, content, enabled, filters_json, meta_json, created_at, updated_at FROM sources ORDER BY created_at ASC`); err != nil { return nil, err } result := make([]model.SourceRecord, 0, len(rows)) @@ -45,7 +46,7 @@ func (r *SourceRepo) List() ([]model.SourceRecord, error) { func (r *SourceRepo) Get(id string) (*model.SourceRecord, error) { var row sourceRow - if err := r.db.Get(&row, "SELECT * FROM sources WHERE id = ?", id); err != nil { + if err := r.db.Get(&row, `SELECT id, name, alias, type, url, content, enabled, filters_json, meta_json, created_at, updated_at FROM sources WHERE id = ?`, id); err != nil { if err == sql.ErrNoRows { return nil, nil } @@ -79,6 +80,7 @@ func (r *SourceRepo) Upsert(input model.SourceRecord) (model.SourceRecord, error rec := model.SourceRecord{ ID: id, Name: input.Name, + Alias: input.Alias, Type: input.Type, URL: input.URL, Content: input.Content, @@ -101,14 +103,14 @@ func (r *SourceRepo) Upsert(input model.SourceRecord) (model.SourceRecord, error } _, err := r.db.Exec( - `INSERT INTO sources (id, name, type, url, content, enabled, filters_json, meta_json, created_at, updated_at) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + `INSERT INTO sources (id, name, alias, type, url, content, enabled, filters_json, meta_json, created_at, updated_at) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(id) DO UPDATE SET - name = excluded.name, type = excluded.type, url = excluded.url, + name = excluded.name, alias = excluded.alias, type = excluded.type, url = excluded.url, content = excluded.content, enabled = excluded.enabled, filters_json = excluded.filters_json, meta_json = excluded.meta_json, updated_at = excluded.updated_at`, - rec.ID, rec.Name, sourceType, rec.URL, rec.Content, enabled, filtersJSON, metaJSON, rec.CreatedAt, rec.UpdatedAt, + rec.ID, rec.Name, rec.Alias, sourceType, rec.URL, rec.Content, enabled, filtersJSON, metaJSON, rec.CreatedAt, rec.UpdatedAt, ) if err != nil { return rec, err @@ -145,6 +147,7 @@ func sourceFromRow(row sourceRow) model.SourceRecord { return model.SourceRecord{ ID: row.ID, Name: row.Name, + Alias: row.Alias, Type: sourceType, URL: row.URL, Content: row.Content, diff --git a/internal/filter/collection_rename.go b/internal/filter/collection_rename.go new file mode 100644 index 0000000..78f0598 --- /dev/null +++ b/internal/filter/collection_rename.go @@ -0,0 +1,147 @@ +package filter + +import ( + "fmt" + "strings" + + "github.com/peterqiu0516/sub-store/internal/model" + "github.com/peterqiu0516/sub-store/internal/util" +) + +// defaultRenameOptions returns the default options (all fields included). +func defaultRenameOptions() model.RenameOptions { + return model.RenameOptions{ + Flag: true, + Alias: true, + Country: true, + City: true, + Index: true, + } +} + +// resolveRenameOptions returns the effective options, applying defaults for +// nil or zero-value fields. +func resolveRenameOptions(opts *model.RenameOptions) model.RenameOptions { + if opts == nil { + return defaultRenameOptions() + } + return *opts +} + +// RenameCollectionNodes renames proxy nodes in the collection-level format: +// +// [emoji country flag] [alias] [country name] [city] [01...100] +// +// The alias is read from each node's "_sourceAlias" field (tagged by the +// subscription service from the source's Alias). Geographic info (flag, +// country, city) is auto-detected from the node's original name and server. +// Nodes are grouped by country+city+alias and numbered sequentially within +// each group, starting at 01. If only one node exists in a group, no number +// is appended. +// +// opts controls which fields are included in the output. A nil opts means all +// fields are included (full default format). +func RenameCollectionNodes(proxies []model.ProxyNode, opts *model.RenameOptions) []model.ProxyNode { + if len(proxies) == 0 { + return proxies + } + + o := resolveRenameOptions(opts) + + type groupKey struct { + alias string + country string + city string + } + + groups := make(map[groupKey]int) + results := make([]model.ProxyNode, len(proxies)) + + // First pass: count group sizes + for i, proxy := range proxies { + if proxy == nil { + results[i] = proxy + continue + } + + name := ToString(proxy["name"]) + alias := ToString(proxy["_sourceAlias"]) + server := ToString(proxy["server"]) + + geo := util.DetectGeoWithServer(name, server) + if geo.CountryName == "" { + results[i] = proxy + continue + } + + key := groupKey{ + alias: alias, + country: geo.CountryCN, + city: geo.CityCN, + } + groups[key]++ + } + + // Second pass: assign names with numbering + counters := make(map[groupKey]int) + for i, proxy := range proxies { + if proxy == nil { + continue + } + + name := ToString(proxy["name"]) + alias := ToString(proxy["_sourceAlias"]) + server := ToString(proxy["server"]) + + geo := util.DetectGeoWithServer(name, server) + if geo.CountryName == "" { + results[i] = proxy + continue + } + + key := groupKey{ + alias: alias, + country: geo.CountryCN, + city: geo.CityCN, + } + + counters[key]++ + total := groups[key] + + // Build name parts based on enabled options + var parts []string + + if o.Flag && geo.Flag != "" { + parts = append(parts, geo.Flag) + } + + if o.Alias && alias != "" { + parts = append(parts, "["+alias+"]") + } + + // Country and city: city is only shown if different from country + if o.Country { + if o.City && geo.CityCN != "" && geo.CityCN != geo.CountryCN { + parts = append(parts, geo.CountryCN, geo.CityCN) + } else { + parts = append(parts, geo.CountryCN) + } + } else if o.City && geo.CityCN != "" && geo.CityCN != geo.CountryCN { + // City enabled but country disabled — show city alone + parts = append(parts, geo.CityCN) + } + + baseName := strings.Join(parts, " ") + + if o.Index && total > 1 { + baseName = fmt.Sprintf("%s %02d", baseName, counters[key]) + } + + next := cloneProxy(proxy) + delete(next, "_sourceAlias") + next["name"] = baseName + results[i] = next + } + + return results +} diff --git a/internal/filter/collection_rename_test.go b/internal/filter/collection_rename_test.go new file mode 100644 index 0000000..4c9cd87 --- /dev/null +++ b/internal/filter/collection_rename_test.go @@ -0,0 +1,255 @@ +package filter + +import ( + "fmt" + "strings" + "testing" + + "github.com/peterqiu0516/sub-store/internal/model" +) + +func TestRenameCollectionNodes_SingleNode(t *testing.T) { + proxies := []model.ProxyNode{ + {"name": "香港 HK 1", "type": "ss", "_sourceAlias": "机场A"}, + } + result := RenameCollectionNodes(proxies, nil) + if len(result) != 1 { + t.Fatalf("expected 1 node, got %d", len(result)) + } + name := result[0]["name"].(string) + if !strings.Contains(name, "🇭🇰") { + t.Errorf("expected flag emoji, got %q", name) + } + if !strings.Contains(name, "[机场A]") { + t.Errorf("expected [alias] with brackets, got %q", name) + } + if !strings.Contains(name, "香港") { + t.Errorf("expected Chinese country name, got %q", name) + } + // 香港 as country == 香港 as city → should only appear once + if strings.Count(name, "香港") > 1 { + t.Errorf("country/city duplicate: %q", name) + } + if _, hasAlias := result[0]["_sourceAlias"]; hasAlias { + t.Error("_sourceAlias should be removed from output") + } +} + +func TestRenameCollectionNodes_MultipleNodes(t *testing.T) { + proxies := []model.ProxyNode{ + {"name": "香港 1", "type": "ss", "_sourceAlias": "机场A"}, + {"name": "香港 2", "type": "ss", "_sourceAlias": "机场A"}, + {"name": "香港 3", "type": "ss", "_sourceAlias": "机场A"}, + } + result := RenameCollectionNodes(proxies, nil) + if len(result) != 3 { + t.Fatalf("expected 3 nodes, got %d", len(result)) + } + // All 3 should be numbered 01, 02, 03 + for i, node := range result { + name := node["name"].(string) + expected := fmt.Sprintf("%02d", i+1) + if !strings.Contains(name, expected) { + t.Errorf("node[%d]: expected number %s in name %q", i, expected, name) + } + } +} + +func TestRenameCollectionNodes_DifferentCountries(t *testing.T) { + proxies := []model.ProxyNode{ + {"name": "香港", "type": "ss", "_sourceAlias": "A"}, + {"name": "东京", "type": "ss", "_sourceAlias": "A"}, + } + result := RenameCollectionNodes(proxies, nil) + if len(result) != 2 { + t.Fatalf("expected 2 nodes, got %d", len(result)) + } + // Different countries → each is single in its group → no number + name0 := result[0]["name"].(string) + name1 := result[1]["name"].(string) + if !strings.Contains(name0, "🇭🇰") { + t.Errorf("node[0] expected HK flag, got %q", name0) + } + if !strings.Contains(name1, "🇯🇵") { + t.Errorf("node[1] expected JP flag, got %q", name1) + } + if !strings.Contains(name0, "香港") { + t.Errorf("node[0] expected 香港, got %q", name0) + } + if !strings.Contains(name1, "日本") { + t.Errorf("node[1] expected 日本, got %q", name1) + } + // Neither should have a number suffix + if strings.HasSuffix(name0, "01") { + t.Errorf("node[0] should not have number, got %q", name0) + } +} + +func TestRenameCollectionNodes_NoAlias(t *testing.T) { + proxies := []model.ProxyNode{ + {"name": "香港 1", "type": "ss"}, + {"name": "香港 2", "type": "ss"}, + } + result := RenameCollectionNodes(proxies, nil) + if len(result) != 2 { + t.Fatalf("expected 2 nodes, got %d", len(result)) + } + for i, node := range result { + name := node["name"].(string) + if !strings.Contains(name, "🇭🇰") { + t.Errorf("node[%d]: expected flag, got %q", i, name) + } + if !strings.Contains(name, "香港") { + t.Errorf("node[%d]: expected Chinese country, got %q", i, name) + } + } +} + +func TestRenameCollectionNodes_UnknownCountry(t *testing.T) { + proxies := []model.ProxyNode{ + {"name": "Unknown Node", "type": "ss", "_sourceAlias": "A"}, + } + result := RenameCollectionNodes(proxies, nil) + if len(result) != 1 { + t.Fatalf("expected 1 node, got %d", len(result)) + } + // Should keep original name + if result[0]["name"] != "Unknown Node" { + t.Errorf("expected original name, got %q", result[0]["name"]) + } +} + +func TestRenameCollectionNodes_CityDetection(t *testing.T) { + proxies := []model.ProxyNode{ + {"name": "洛杉矶 1", "type": "ss", "_sourceAlias": "A"}, + {"name": "洛杉矶 2", "type": "ss", "_sourceAlias": "A"}, + {"name": "纽约 1", "type": "ss", "_sourceAlias": "A"}, + } + result := RenameCollectionNodes(proxies, nil) + if len(result) != 3 { + t.Fatalf("expected 3 nodes, got %d", len(result)) + } + // LA nodes should be numbered 01, 02; NY node 01 + laCount := 0 + nyCount := 0 + for _, node := range result { + name := node["name"].(string) + if strings.Contains(name, "洛杉矶") { + laCount++ + } + if strings.Contains(name, "纽约") { + nyCount++ + } + } + if laCount != 2 { + t.Errorf("expected 2 LA nodes, got %d", laCount) + } + if nyCount != 1 { + t.Errorf("expected 1 NY node, got %d", nyCount) + } +} + +func TestRenameCollectionNodes_Empty(t *testing.T) { + result := RenameCollectionNodes(nil, nil) + if result != nil { + t.Errorf("expected nil for nil input, got %v", result) + } + result = RenameCollectionNodes([]model.ProxyNode{}, nil) + if len(result) != 0 { + t.Errorf("expected empty for empty input, got %d", len(result)) + } +} + +// --- RenameOptions tests --- + +func TestRenameCollectionNodes_DisableFlag(t *testing.T) { + proxies := []model.ProxyNode{ + {"name": "香港 1", "type": "ss", "_sourceAlias": "机场A"}, + } + opts := &model.RenameOptions{Flag: false, Alias: true, Country: true, City: true, Index: true} + result := RenameCollectionNodes(proxies, opts) + name := result[0]["name"].(string) + if strings.Contains(name, "🇭🇰") { + t.Errorf("flag should be disabled, got %q", name) + } + if !strings.Contains(name, "香港") { + t.Errorf("country should be present, got %q", name) + } + if !strings.Contains(name, "[机场A]") { + t.Errorf("alias should be present, got %q", name) + } +} + +func TestRenameCollectionNodes_DisableAlias(t *testing.T) { + proxies := []model.ProxyNode{ + {"name": "香港 1", "type": "ss", "_sourceAlias": "机场A"}, + } + opts := &model.RenameOptions{Flag: true, Alias: false, Country: true, City: true, Index: true} + result := RenameCollectionNodes(proxies, opts) + name := result[0]["name"].(string) + if strings.Contains(name, "[机场A]") { + t.Errorf("alias should be disabled, got %q", name) + } + if !strings.Contains(name, "🇭🇰") { + t.Errorf("flag should be present, got %q", name) + } +} + +func TestRenameCollectionNodes_DisableCountry(t *testing.T) { + proxies := []model.ProxyNode{ + {"name": "洛杉矶 1", "type": "ss", "_sourceAlias": "A"}, + } + opts := &model.RenameOptions{Flag: true, Alias: true, Country: false, City: true, Index: true} + result := RenameCollectionNodes(proxies, opts) + name := result[0]["name"].(string) + // Country name "美国" should not appear + if strings.Contains(name, "美国") { + t.Errorf("country should be disabled, got %q", name) + } + // City "洛杉矶" should still appear + if !strings.Contains(name, "洛杉矶") { + t.Errorf("city should be present, got %q", name) + } +} + +func TestRenameCollectionNodes_DisableIndex(t *testing.T) { + proxies := []model.ProxyNode{ + {"name": "香港 1", "type": "ss", "_sourceAlias": "A"}, + {"name": "香港 2", "type": "ss", "_sourceAlias": "A"}, + } + opts := &model.RenameOptions{Flag: true, Alias: true, Country: true, City: true, Index: false} + result := RenameCollectionNodes(proxies, opts) + for i, node := range result { + name := node["name"].(string) + // Should not contain number suffix + suffix := fmt.Sprintf("%02d", i+1) + if strings.HasSuffix(name, suffix) { + t.Errorf("node[%d]: index should be disabled, got %q", i, name) + } + } +} + +func TestRenameCollectionNodes_OnlyFlagAndIndex(t *testing.T) { + proxies := []model.ProxyNode{ + {"name": "香港 1", "type": "ss", "_sourceAlias": "A"}, + {"name": "香港 2", "type": "ss", "_sourceAlias": "A"}, + } + opts := &model.RenameOptions{Flag: true, Alias: false, Country: false, City: false, Index: true} + result := RenameCollectionNodes(proxies, opts) + for i, node := range result { + name := node["name"].(string) + if !strings.HasPrefix(name, "🇭🇰") { + t.Errorf("node[%d]: should start with flag, got %q", i, name) + } + if strings.Contains(name, "香港") { + t.Errorf("node[%d]: country should not appear, got %q", i, name) + } + if strings.Contains(name, "[A]") { + t.Errorf("node[%d]: alias should not appear, got %q", i, name) + } + expected := fmt.Sprintf("🇭🇰 %02d", i+1) + if name != expected { + t.Errorf("node[%d]: expected %q, got %q", i, expected, name) + } + } +} diff --git a/internal/geoip/download.go b/internal/geoip/download.go new file mode 100644 index 0000000..5ef41a0 --- /dev/null +++ b/internal/geoip/download.go @@ -0,0 +1,96 @@ +package geoip + +import ( + "fmt" + "io" + "net/http" + "os" + "path/filepath" + "time" +) + +const ( + // GeoLite2-City mmdb download sources (tried in order) + // P3TERX/GeoLite.mmdb — GitHub-hosted, updated weekly, direct .mmdb (no tar) + mmdbMirrorURL = "https://raw.githubusercontent.com/P3TERX/GeoLite.mmdb/download/GeoLite2-City.mmdb" + // jsdelivr CDN mirror of the same repo (China-accessible) + mmdbFallbackURL = "https://cdn.jsdelivr.net/gh/P3TERX/GeoLite.mmdb@download/GeoLite2-City.mmdb" + // fastgit mirror (China-accessible) + mmdbFastgitURL = "https://raw.fastgit.org/P3TERX/GeoLite.mmdb/download/GeoLite2-City.mmdb" + + mmdbDownloadTimeout = 120 * time.Second +) + +// DownloadMmdb downloads the GeoLite2-City mmdb file to the given path. +// It tries multiple mirrors in order. +func DownloadMmdb(destPath string) error { + // Ensure parent directory exists + if err := os.MkdirAll(filepath.Dir(destPath), 0755); err != nil { + return fmt.Errorf("create mmdb dir: %w", err) + } + + urls := []string{mmdbMirrorURL, mmdbFallbackURL, mmdbFastgitURL} + var lastErr error + for _, u := range urls { + if err := downloadDirect(destPath, u); err == nil { + return nil + } else { + lastErr = err + } + } + return fmt.Errorf("all download sources failed, last error: %w", lastErr) +} + +func downloadDirect(destPath, url string) error { + client := &http.Client{Timeout: mmdbDownloadTimeout} + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return err + } + req.Header.Set("User-Agent", "sub-store/1.0") + resp, err := client.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return fmt.Errorf("download failed: HTTP %d", resp.StatusCode) + } + out, err := os.Create(destPath) + if err != nil { + return err + } + defer out.Close() + if _, err := io.Copy(out, resp.Body); err != nil { + os.Remove(destPath) + return err + } + // Verify it's a valid mmdb by checking the file size (basic sanity) + if !isValidMmdb(destPath) { + os.Remove(destPath) + return fmt.Errorf("downloaded file is not a valid mmdb") + } + return nil +} + +func isValidMmdb(path string) bool { + f, err := os.Open(path) + if err != nil { + return false + } + defer f.Close() + info, err := f.Stat() + if err != nil { + return false + } + return info.Size() > 1024 +} + +// EnsureMmdb ensures the mmdb file exists, downloading it if needed. +// Returns nil if the file already exists or was downloaded successfully. +func EnsureMmdb(path string) error { + if _, err := os.Stat(path); err == nil { + return nil // already exists + } + return DownloadMmdb(path) +} diff --git a/internal/geoip/geoip.go b/internal/geoip/geoip.go new file mode 100644 index 0000000..9dd46ef --- /dev/null +++ b/internal/geoip/geoip.go @@ -0,0 +1,207 @@ +package geoip + +import ( + "fmt" + "net" + "os" + "path/filepath" + "sync" + + "github.com/oschwald/maxminddb-golang" +) + +// GeoResult holds the geographic lookup result for an IP. +type GeoResult struct { + CountryCode string // ISO 3166-1 alpha-2, e.g. "JP" + CountryName string // English country name, e.g. "Japan" + CountryNameCN string // Chinese country name, e.g. "日本" + CityName string // English city name (may be empty) + CityNameCN string // Chinese city name (may be empty) +} + +var ( + mu sync.Mutex + reader *maxminddb.Reader + loaded bool + mmdbPath string +) + +// countryNameCN maps ISO country codes to Chinese names. +// Covers all 249 ISO 3166-1 countries. +var countryNameCN = map[string]string{ + "AD": "安道尔", "AE": "阿联酋", "AF": "阿富汗", "AG": "安提瓜", "AI": "安圭拉", + "AL": "阿尔巴尼亚", "AM": "亚美尼亚", "AO": "安哥拉", "AQ": "南极洲", "AR": "阿根廷", + "AS": "美属萨摩亚", "AT": "奥地利", "AU": "澳大利亚", "AW": "阿鲁巴", "AX": "奥兰群岛", + "AZ": "阿塞拜疆", "BA": "波黑", "BB": "巴巴多斯", "BD": "孟加拉国", "BE": "比利时", + "BF": "布基纳法索", "BG": "保加利亚", "BH": "巴林", "BI": "布隆迪", "BJ": "贝宁", + "BL": "圣巴泰勒米", "BM": "百慕大", "BN": "文莱", "BO": "玻利维亚", "BQ": "荷兰加勒比", + "BR": "巴西", "BS": "巴哈马", "BT": "不丹", "BV": "布韦岛", "BW": "博茨瓦纳", + "BY": "白俄罗斯", "BZ": "伯利兹", "CA": "加拿大", "CC": "科科斯群岛", "CD": "刚果(金)", + "CF": "中非", "CG": "刚果(布)", "CH": "瑞士", "CI": "科特迪瓦", "CK": "库克群岛", + "CL": "智利", "CM": "喀麦隆", "CN": "中国", "CO": "哥伦比亚", "CR": "哥斯达黎加", + "CU": "古巴", "CV": "佛得角", "CW": "库拉索", "CX": "圣诞岛", "CY": "塞浦路斯", + "CZ": "捷克", "DE": "德国", "DJ": "吉布提", "DK": "丹麦", "DM": "多米尼克", + "DO": "多米尼加", "DZ": "阿尔及利亚", "EC": "厄瓜多尔", "EE": "爱沙尼亚", "EG": "埃及", + "EH": "西撒哈拉", "ER": "厄立特里亚", "ES": "西班牙", "ET": "埃塞俄比亚", "FI": "芬兰", + "FJ": "斐济", "FK": "福克兰群岛", "FM": "密克罗尼西亚", "FO": "法罗群岛", "FR": "法国", + "GA": "加蓬", "GB": "英国", "GD": "格林纳达", "GE": "格鲁吉亚", "GF": "法属圭亚那", + "GG": "根西岛", "GH": "加纳", "GI": "直布罗陀", "GL": "格陵兰", "GM": "冈比亚", + "GN": "几内亚", "GP": "瓜德罗普", "GQ": "赤道几内亚", "GR": "希腊", "GS": "南乔治亚", + "GT": "危地马拉", "GU": "关岛", "GW": "几内亚比绍", "GY": "圭亚那", "HK": "香港", + "HM": "赫德岛", "HN": "洪都拉斯", "HR": "克罗地亚", "HT": "海地", "HU": "匈牙利", + "ID": "印度尼西亚", "IE": "爱尔兰", "IL": "以色列", "IM": "马恩岛", "IN": "印度", + "IO": "英属印度洋领地", "IQ": "伊拉克", "IR": "伊朗", "IS": "冰岛", "IT": "意大利", + "JE": "泽西岛", "JM": "牙买加", "JO": "约旦", "JP": "日本", "KE": "肯尼亚", + "KG": "吉尔吉斯斯坦", "KH": "柬埔寨", "KI": "基里巴斯", "KM": "科摩罗", "KN": "圣基茨", + "KP": "朝鲜", "KR": "韩国", "KW": "科威特", "KY": "开曼群岛", "KZ": "哈萨克斯坦", + "LA": "老挝", "LB": "黎巴嫩", "LC": "圣卢西亚", "LI": "列支敦士登", "LK": "斯里兰卡", + "LR": "利比里亚", "LS": "莱索托", "LT": "立陶宛", "LU": "卢森堡", "LV": "拉脱维亚", + "LY": "利比亚", "MA": "摩洛哥", "MC": "摩纳哥", "MD": "摩尔多瓦", "ME": "黑山", + "MF": "法属圣马丁", "MG": "马达加斯加", "MH": "马绍尔群岛", "MK": "北马其顿", "ML": "马里", + "MM": "缅甸", "MN": "蒙古", "MO": "澳门", "MP": "北马里亚纳", "MQ": "马提尼克", + "MR": "毛里塔尼亚", "MS": "蒙特塞拉特", "MT": "马耳他", "MU": "毛里求斯", "MV": "马尔代夫", + "MW": "马拉维", "MX": "墨西哥", "MY": "马来西亚", "MZ": "莫桑比克", "NA": "纳米比亚", + "NC": "新喀里多尼亚", "NE": "尼日尔", "NF": "诺福克岛", "NG": "尼日利亚", "NI": "尼加拉瓜", + "NL": "荷兰", "NO": "挪威", "NP": "尼泊尔", "NR": "瑙鲁", "NU": "纽埃", + "NZ": "新西兰", "OM": "阿曼", "PA": "巴拿马", "PE": "秘鲁", "PF": "法属波利尼西亚", + "PG": "巴布亚新几内亚", "PH": "菲律宾", "PK": "巴基斯坦", "PL": "波兰", "PM": "圣皮埃尔", + "PN": "皮特凯恩", "PR": "波多黎各", "PS": "巴勒斯坦", "PT": "葡萄牙", "PW": "帕劳", + "PY": "巴拉圭", "QA": "卡塔尔", "RE": "留尼汪", "RO": "罗马尼亚", "RS": "塞尔维亚", + "RU": "俄罗斯", "RW": "卢旺达", "SA": "沙特", "SB": "所罗门群岛", "SC": "塞舌尔", + "SD": "苏丹", "SE": "瑞典", "SG": "新加坡", "SH": "圣赫勒拿", "SI": "斯洛文尼亚", + "SJ": "斯瓦尔巴", "SK": "斯洛伐克", "SL": "塞拉利昂", "SM": "圣马力诺", "SN": "塞内加尔", + "SO": "索马里", "SR": "苏里南", "SS": "南苏丹", "ST": "圣多美", "SV": "萨尔瓦多", + "SX": "圣马丁", "SY": "叙利亚", "SZ": "斯威士兰", "TC": "特克斯群岛", "TD": "乍得", + "TF": "法属南方领地", "TG": "多哥", "TH": "泰国", "TJ": "塔吉克斯坦", "TK": "托克劳", + "TL": "东帝汶", "TM": "土库曼斯坦", "TN": "突尼斯", "TO": "汤加", "TR": "土耳其", + "TT": "特立尼达", "TV": "图瓦卢", "TW": "台湾", "TZ": "坦桑尼亚", "UA": "乌克兰", + "UG": "乌干达", "UM": "美属小群岛", "US": "美国", "UY": "乌拉圭", "UZ": "乌兹别克斯坦", + "VA": "梵蒂冈", "VC": "圣文森特", "VE": "委内瑞拉", "VG": "英属维尔京", "VI": "美属维尔京", + "VN": "越南", "VU": "瓦努阿图", "WF": "瓦利斯", "WS": "萨摩亚", "YE": "也门", + "YT": "马约特", "ZA": "南非", "ZM": "赞比亚", "ZW": "津巴布韦", +} + +// countryCodeToEmoji converts an ISO 3166-1 alpha-2 code to a flag emoji. +func countryCodeToEmoji(code string) string { + if len(code) != 2 { + return "🏳️" + } + c1 := code[0] + c2 := code[1] + if c1 < 'A' || c1 > 'Z' || c2 < 'A' || c2 > 'Z' { + return "🏳️" + } + // Regional indicator symbols: A=0x1F1E6, so subtract 'A' and add 0x1F1E6 + r1 := rune(0x1F1E6) + rune(c1-'A') + r2 := rune(0x1F1E6) + rune(c2-'A') + return string(r1) + string(r2) +} + +// CountryNameCN returns the Chinese name for an ISO country code. +func CountryNameCN(code string) string { + if name, ok := countryNameCN[code]; ok { + return name + } + return "" +} + +// CountryEmoji returns the flag emoji for an ISO country code. +func CountryEmoji(code string) string { + return countryCodeToEmoji(code) +} + +// SetMmdbPath sets the path to the GeoLite2-City mmdb file. +// Must be called before Lookup. +func SetMmdbPath(path string) { + mu.Lock() + defer mu.Unlock() + if mmdbPath != path { + mmdbPath = path + loaded = false + } +} + +// ensureLoaded opens the mmdb reader on first use. +func ensureLoaded() error { + mu.Lock() + defer mu.Unlock() + if loaded { + return nil + } + if mmdbPath == "" { + mmdbPath = filepath.Join("data", "GeoLite2-City.mmdb") + } + if _, err := os.Stat(mmdbPath); err != nil { + return fmt.Errorf("GeoIP database not found at %s: %w", mmdbPath, err) + } + r, err := maxminddb.Open(mmdbPath) + if err != nil { + return fmt.Errorf("failed to open GeoIP database: %w", err) + } + reader = r + loaded = true + return nil +} + +// Lookup returns geographic info for an IP address. +// Returns nil if the database is not available or the IP is not found. +func Lookup(ipStr string) *GeoResult { + if ipStr == "" { + return nil + } + ip := net.ParseIP(ipStr) + if ip == nil { + return nil + } + if err := ensureLoaded(); err != nil { + return nil + } + + var record struct { + Country struct { + IsoCode string `maxminddb:"iso_code"` + Names map[string]string `maxminddb:"names"` + } `maxminddb:"country"` + City struct { + Names map[string]string `maxminddb:"names"` + } `maxminddb:"city"` + } + + if err := reader.Lookup(ip, &record); err != nil { + return nil + } + + code := record.Country.IsoCode + if code == "" { + return nil + } + + result := &GeoResult{ + CountryCode: code, + CountryName: record.Country.Names["en"], + CountryNameCN: record.Country.Names["zh-CN"], + CityName: record.City.Names["en"], + CityNameCN: record.City.Names["zh-CN"], + } + + // Fallback: if zh-CN name is missing from mmdb, use our built-in map + if result.CountryNameCN == "" { + result.CountryNameCN = CountryNameCN(code) + } + + return result +} + +// LookupHost resolves a hostname to its first IP and then looks up geo info. +func LookupHost(host string) *GeoResult { + // If it's already an IP, lookup directly + if ip := net.ParseIP(host); ip != nil { + return Lookup(ip.String()) + } + // Resolve domain + ips, err := net.LookupIP(host) + if err != nil || len(ips) == 0 { + return nil + } + return Lookup(ips[0].String()) +} diff --git a/internal/handler/crud.go b/internal/handler/crud.go index 31eccce..f748c77 100644 --- a/internal/handler/crud.go +++ b/internal/handler/crud.go @@ -436,9 +436,11 @@ func mapToSourceRecord(input map[string]any) model.SourceRecord { } filters := parseFilters(input["filters"]) meta := getMapValue(input["meta"]) + alias := getStringValue(input["alias"]) return model.SourceRecord{ ID: id, Name: orDefault(getStringValue(input["name"]), id), + Alias: alias, Type: sourceType, URL: getStringValue(input["url"]), Content: getStringValue(input["content"]), @@ -455,7 +457,39 @@ func mapToCollectionRecord(input map[string]any) model.CollectionRecord { } id = util.ToId(id) sourceIds := getStringArray(input["sourceIds"]) - filters := parseFilters(input["filters"]) + renameEnabled := false + if v, ok := input["renameEnabled"].(bool); ok { + renameEnabled = v + } + + // Parse rename options (all default to true when renameEnabled is on) + var renameOptions *model.RenameOptions + if opts, ok := input["renameOptions"].(map[string]any); ok { + ro := model.RenameOptions{ + Flag: true, + Alias: true, + Country: true, + City: true, + Index: true, + } + if v, ok := opts["flag"].(bool); ok { + ro.Flag = v + } + if v, ok := opts["alias"].(bool); ok { + ro.Alias = v + } + if v, ok := opts["country"].(bool); ok { + ro.Country = v + } + if v, ok := opts["city"].(bool); ok { + ro.City = v + } + if v, ok := opts["index"].(bool); ok { + ro.Index = v + } + renameOptions = &ro + } + templateId := getStringValue(input["templateId"]) if templateId == "" || templateId == "default" { templateId = template.DefaultTemplateID @@ -470,14 +504,15 @@ func mapToCollectionRecord(input map[string]any) model.CollectionRecord { } meta := getMapValue(input["meta"]) return model.CollectionRecord{ - ID: id, - Name: orDefault(getStringValue(input["name"]), id), - SourceIds: sourceIds, - Filters: filters, - TemplateId: templateId, - IgnoreFailed: ignoreFailed, - Enabled: enabled, - Meta: meta, + ID: id, + Name: orDefault(getStringValue(input["name"]), id), + SourceIds: sourceIds, + RenameEnabled: renameEnabled, + RenameOptions: renameOptions, + TemplateId: templateId, + IgnoreFailed: ignoreFailed, + Enabled: enabled, + Meta: meta, } } @@ -512,6 +547,9 @@ func mergeSource(existing model.SourceRecord, next model.SourceRecord) model.Sou if next.Name != "" { merged.Name = next.Name } + if next.Alias != "" { + merged.Alias = next.Alias + } if next.Type != "" { merged.Type = next.Type } @@ -539,8 +577,9 @@ func mergeCollection(existing model.CollectionRecord, next model.CollectionRecor if next.SourceIds != nil { merged.SourceIds = next.SourceIds } - if next.Filters != nil { - merged.Filters = next.Filters + merged.RenameEnabled = next.RenameEnabled + if next.RenameOptions != nil { + merged.RenameOptions = next.RenameOptions } if next.TemplateId != "" { merged.TemplateId = next.TemplateId diff --git a/internal/handler/egress_info.go b/internal/handler/egress_info.go index a269d5b..42aa46c 100644 --- a/internal/handler/egress_info.go +++ b/internal/handler/egress_info.go @@ -78,7 +78,7 @@ func (d *Deps) HandleEgressInfo(c fiber.Ctx) error { func egressCacheKey(node model.ProxyNode) string { clean := model.ProxyNode{} skip := map[string]bool{ - "id": true, "latencyMs": true, "latencyError": true, + "id": true, "name": true, "latencyMs": true, "latencyError": true, "egressIp": true, "egressCountry": true, "egressRegion": true, "egressError": true, "country": true, "region": true, "city": true, "isp": true, "cached": true, } diff --git a/internal/handler/handler_test.go b/internal/handler/handler_test.go index f7827bf..09cbeea 100644 --- a/internal/handler/handler_test.go +++ b/internal/handler/handler_test.go @@ -255,6 +255,7 @@ func TestValidateSource(t *testing.T) { func TestMapToSourceRecord(t *testing.T) { in := map[string]any{ "name": "My Source!", + "alias": "MyAlias", "type": "local", "url": "https://x.com", "content": "ss://abc", @@ -269,6 +270,9 @@ func TestMapToSourceRecord(t *testing.T) { if rec.Name != "My Source!" { t.Errorf("Name = %q, want %q", rec.Name, "My Source!") } + if rec.Alias != "MyAlias" { + t.Errorf("Alias = %q, want MyAlias", rec.Alias) + } if rec.Type != "local" { t.Errorf("Type = %q, want local", rec.Type) } @@ -300,13 +304,13 @@ func TestMapToSourceRecord(t *testing.T) { func TestMapToCollectionRecord(t *testing.T) { in := map[string]any{ - "name": "My Col", - "sourceIds": []any{"s1", "s2", "", 123}, - "templateId": "default", - "ignoreFailed": false, - "enabled": false, - "meta": map[string]any{"k": "v"}, - "filters": []any{map[string]any{"type": "rename"}}, + "name": "My Col", + "sourceIds": []any{"s1", "s2", "", 123}, + "templateId": "default", + "ignoreFailed": false, + "enabled": false, + "meta": map[string]any{"k": "v"}, + "renameEnabled": true, } rec := mapToCollectionRecord(in) if rec.ID == "" { @@ -327,14 +331,14 @@ func TestMapToCollectionRecord(t *testing.T) { if rec.Enabled { t.Error("expected Enabled=false") } + if !rec.RenameEnabled { + t.Error("expected RenameEnabled=true") + } if rec.Meta["k"] != "v" { t.Errorf("Meta = %v", rec.Meta) } - if len(rec.Filters) != 1 { - t.Errorf("Filters len = %d", len(rec.Filters)) - } - // default ignoreFailed = true + // default ignoreFailed = true, default renameEnabled = false rec2 := mapToCollectionRecord(map[string]any{"id": "c1"}) if !rec2.IgnoreFailed { t.Error("expected default IgnoreFailed=true") @@ -342,6 +346,9 @@ func TestMapToCollectionRecord(t *testing.T) { if !rec2.Enabled { t.Error("expected default Enabled=true") } + if rec2.RenameEnabled { + t.Error("expected default RenameEnabled=false") + } } func TestMapToTemplateRecord(t *testing.T) { @@ -380,11 +387,11 @@ func TestMapToTemplateRecord(t *testing.T) { func TestMergeSource(t *testing.T) { existing := model.SourceRecord{ - ID: "s1", Name: "Old", Type: "local", Content: "old", Enabled: true, + ID: "s1", Name: "Old", Alias: "OldAlias", Type: "local", Content: "old", Enabled: true, Meta: map[string]any{"a": "1"}, } next := model.SourceRecord{ - Name: "New", URL: "https://x.com", Type: "remote", Enabled: false, + Name: "New", Alias: "NewAlias", URL: "https://x.com", Type: "remote", Enabled: false, Filters: []model.FilterRule{{Type: "rename"}}, Meta: map[string]any{"b": "2"}, } @@ -392,6 +399,9 @@ func TestMergeSource(t *testing.T) { if merged.Name != "New" { t.Errorf("Name = %q", merged.Name) } + if merged.Alias != "NewAlias" { + t.Errorf("Alias = %q, want NewAlias", merged.Alias) + } if merged.Type != "remote" { t.Errorf("Type = %q", merged.Type) } @@ -413,6 +423,9 @@ func TestMergeSource(t *testing.T) { if merged2.Name != "Old" { t.Errorf("Name = %q, want Old", merged2.Name) } + if merged2.Alias != "OldAlias" { + t.Errorf("Alias = %q, want OldAlias", merged2.Alias) + } } func TestMergeCollection(t *testing.T) { @@ -422,7 +435,7 @@ func TestMergeCollection(t *testing.T) { } next := model.CollectionRecord{ Name: "New", SourceIds: []string{"s2"}, TemplateId: "t2", - Enabled: false, IgnoreFailed: false, Meta: map[string]any{"b": "2"}, + Enabled: false, IgnoreFailed: false, RenameEnabled: true, Meta: map[string]any{"b": "2"}, } merged := mergeCollection(existing, next) if merged.Name != "New" { @@ -440,6 +453,9 @@ func TestMergeCollection(t *testing.T) { if merged.IgnoreFailed { t.Error("expected IgnoreFailed=false") } + if !merged.RenameEnabled { + t.Error("expected RenameEnabled=true") + } } func TestGetStringValue(t *testing.T) { @@ -999,8 +1015,8 @@ func TestHandleUpdateSettings(t *testing.T) { func TestHandleExportStorage(t *testing.T) { deps := newTestDeps(t) // seed some data - deps.SourceRepo.Upsert(model.SourceRecord{ID: "s1", Name: "S1", Type: "local", Content: "ss://x", Enabled: true, Filters: []model.FilterRule{}, Meta: map[string]any{}}) - deps.CollectionRepo.Upsert(model.CollectionRecord{ID: "c1", Name: "C1", SourceIds: []string{}, Filters: []model.FilterRule{}, TemplateId: template.DefaultTemplateID, IgnoreFailed: true, Enabled: true, Meta: map[string]any{}}) + deps.SourceRepo.Upsert(model.SourceRecord{ID: "s1", Name: "S1", Type: "local", Content: "ss://x", Enabled: true, Meta: map[string]any{}}) + deps.CollectionRepo.Upsert(model.CollectionRecord{ID: "c1", Name: "C1", SourceIds: []string{}, TemplateId: template.DefaultTemplateID, IgnoreFailed: true, Enabled: true, Meta: map[string]any{}}) deps.TemplateRepo.Upsert(model.TemplateRecord{ID: "custom-t", Name: "Custom", Target: "mihomo", Config: map[string]any{"k": "v"}}) app := newApp(deps) @@ -1132,12 +1148,12 @@ func TestSourceCRUDHandlers(t *testing.T) { assertStatus(t, "SortSources bad json", code, 400) // Delete - referenced by collection (create collection referencing source first) - deps.CollectionRepo.Upsert(model.CollectionRecord{ID: "ref-col", Name: "RefCol", SourceIds: []string{"my-src"}, Filters: []model.FilterRule{}, TemplateId: template.DefaultTemplateID, IgnoreFailed: true, Enabled: true, Meta: map[string]any{}}) + deps.CollectionRepo.Upsert(model.CollectionRecord{ID: "ref-col", Name: "RefCol", SourceIds: []string{"my-src"}, TemplateId: template.DefaultTemplateID, IgnoreFailed: true, Enabled: true, Meta: map[string]any{}}) code, _ = doRequest(t, app, "DELETE", "/api/sources/my-src", "", nil) assertStatus(t, "DeleteSource referenced", code, 409) // Delete - remove collection reference, then delete - deps.CollectionRepo.Upsert(model.CollectionRecord{ID: "ref-col", Name: "RefCol", SourceIds: []string{}, Filters: []model.FilterRule{}, TemplateId: template.DefaultTemplateID, IgnoreFailed: true, Enabled: true, Meta: map[string]any{}}) + deps.CollectionRepo.Upsert(model.CollectionRecord{ID: "ref-col", Name: "RefCol", SourceIds: []string{}, TemplateId: template.DefaultTemplateID, IgnoreFailed: true, Enabled: true, Meta: map[string]any{}}) code, body = doRequest(t, app, "DELETE", "/api/sources/my-src", "", nil) assertStatus(t, "DeleteSource", code, 200) data2 := body["data"].(map[string]any) @@ -1258,22 +1274,22 @@ func TestCollectionWithTemplateValidation(t *testing.T) { func TestValidateCollectionMissingTemplate(t *testing.T) { deps := newTestDeps(t) // built-in template is ok - rec := model.CollectionRecord{ID: "c1", TemplateId: "mihomo-basic", Filters: []model.FilterRule{}, Meta: map[string]any{}} + rec := model.CollectionRecord{ID: "c1", TemplateId: "mihomo-basic", Meta: map[string]any{}} if err := deps.validateCollection(rec); err != nil { t.Errorf("builtin template: unexpected err: %v", err) } // missing template - rec2 := model.CollectionRecord{ID: "c2", TemplateId: "no-such", Filters: []model.FilterRule{}, Meta: map[string]any{}} + rec2 := model.CollectionRecord{ID: "c2", TemplateId: "no-such", Meta: map[string]any{}} if err := deps.validateCollection(rec2); err == nil { t.Error("missing template: expected err") } // missing source ref - rec3 := model.CollectionRecord{ID: "c3", SourceIds: []string{"missing"}, Filters: []model.FilterRule{}, Meta: map[string]any{}} + rec3 := model.CollectionRecord{ID: "c3", SourceIds: []string{"missing"}, Meta: map[string]any{}} if err := deps.validateCollection(rec3); err == nil { t.Error("missing source: expected err") } // no sourceIds, no templateId -> ok - rec4 := model.CollectionRecord{ID: "c4", Filters: []model.FilterRule{}, Meta: map[string]any{}} + rec4 := model.CollectionRecord{ID: "c4", Meta: map[string]any{}} if err := deps.validateCollection(rec4); err != nil { t.Errorf("empty collection: unexpected err: %v", err) } @@ -1385,7 +1401,7 @@ func TestRecycleBinHandlers(t *testing.T) { deps := newTestDeps(t) app := newApp(deps) // seed + delete a source to populate recycle bin - deps.SourceRepo.Upsert(model.SourceRecord{ID: "s1", Name: "S1", Type: "local", Content: "ss://x", Enabled: true, Filters: []model.FilterRule{}, Meta: map[string]any{}}) + deps.SourceRepo.Upsert(model.SourceRecord{ID: "s1", Name: "S1", Type: "local", Content: "ss://x", Enabled: true, Meta: map[string]any{}}) code, _ := doRequest(t, app, "DELETE", "/api/sources/s1", "", nil) assertStatus(t, "seed delete", code, 200) @@ -1401,7 +1417,7 @@ func TestRecycleBinHandlers(t *testing.T) { // Get via Restore (409 conflict if source recreated) // First recreate source manually to test conflict path - deps.SourceRepo.Upsert(model.SourceRecord{ID: "s1", Name: "S1", Type: "local", Content: "ss://x", Enabled: true, Filters: []model.FilterRule{}, Meta: map[string]any{}}) + deps.SourceRepo.Upsert(model.SourceRecord{ID: "s1", Name: "S1", Type: "local", Content: "ss://x", Enabled: true, Meta: map[string]any{}}) code, _ = doRequest(t, app, "POST", "/api/recycle-bin/"+entryID+"/restore", "", nil) assertStatus(t, "RestoreRecycleBin conflict", code, 409) // remove the conflicting source so restore can proceed @@ -1425,7 +1441,7 @@ func TestRecycleBinHandlers(t *testing.T) { assertStatus(t, "RestoreRecycleBin not found", code, 404) // Delete entry - seed another - deps.SourceRepo.Upsert(model.SourceRecord{ID: "s2", Name: "S2", Type: "local", Content: "ss://y", Enabled: true, Filters: []model.FilterRule{}, Meta: map[string]any{}}) + deps.SourceRepo.Upsert(model.SourceRecord{ID: "s2", Name: "S2", Type: "local", Content: "ss://y", Enabled: true, Meta: map[string]any{}}) doRequest(t, app, "DELETE", "/api/sources/s2", "", nil) code, body = doRequest(t, app, "GET", "/api/recycle-bin", "", nil) data = body["data"].([]any) @@ -1448,7 +1464,7 @@ func TestRestoreCollectionAndTemplate(t *testing.T) { deps := newTestDeps(t) app := newApp(deps) // seed + delete collection - deps.CollectionRepo.Upsert(model.CollectionRecord{ID: "c1", Name: "C1", Filters: []model.FilterRule{}, TemplateId: template.DefaultTemplateID, IgnoreFailed: true, Enabled: true, Meta: map[string]any{}}) + deps.CollectionRepo.Upsert(model.CollectionRecord{ID: "c1", Name: "C1", TemplateId: template.DefaultTemplateID, IgnoreFailed: true, Enabled: true, Meta: map[string]any{}}) doRequest(t, app, "DELETE", "/api/collections/c1", "", nil) // restore collection code, body := doRequest(t, app, "GET", "/api/recycle-bin", "", nil) @@ -1482,10 +1498,10 @@ func TestRestoreCollectionAndTemplate(t *testing.T) { func TestRestoreCollectionConflict(t *testing.T) { deps := newTestDeps(t) app := newApp(deps) - deps.CollectionRepo.Upsert(model.CollectionRecord{ID: "cc1", Name: "CC1", Filters: []model.FilterRule{}, TemplateId: template.DefaultTemplateID, IgnoreFailed: true, Enabled: true, Meta: map[string]any{}}) + deps.CollectionRepo.Upsert(model.CollectionRecord{ID: "cc1", Name: "CC1", TemplateId: template.DefaultTemplateID, IgnoreFailed: true, Enabled: true, Meta: map[string]any{}}) doRequest(t, app, "DELETE", "/api/collections/cc1", "", nil) // recreate to force conflict - deps.CollectionRepo.Upsert(model.CollectionRecord{ID: "cc1", Name: "CC1", Filters: []model.FilterRule{}, TemplateId: template.DefaultTemplateID, IgnoreFailed: true, Enabled: true, Meta: map[string]any{}}) + deps.CollectionRepo.Upsert(model.CollectionRecord{ID: "cc1", Name: "CC1", TemplateId: template.DefaultTemplateID, IgnoreFailed: true, Enabled: true, Meta: map[string]any{}}) code, body := doRequest(t, app, "GET", "/api/recycle-bin", "", nil) data := body["data"].([]any) var entryID string @@ -1531,7 +1547,7 @@ func TestRestoreUnknownType(t *testing.T) { deps := newTestDeps(t) app := newApp(deps) // Archive a source (which works) then manually update its resourceType to "unknown" - deps.SourceRepo.Upsert(model.SourceRecord{ID: "u1", Name: "U1", Type: "local", Content: "ss://x", Enabled: true, Filters: []model.FilterRule{}, Meta: map[string]any{}}) + deps.SourceRepo.Upsert(model.SourceRecord{ID: "u1", Name: "U1", Type: "local", Content: "ss://x", Enabled: true, Meta: map[string]any{}}) deps.RecycleRepo.ArchiveAndDelete("source", "u1", sourceToMap(model.SourceRecord{ID: "u1", Name: "U1"}), "DELETE FROM sources WHERE id = ?", "u1") // Manually update the resource_type to "unknown" for testing deps.DB.Exec("UPDATE recycle_bin SET resource_type = 'unknown' WHERE resource_id = 'u1'") @@ -1567,8 +1583,8 @@ func TestRestoreUnknownType(t *testing.T) { func TestLinkHandlers(t *testing.T) { deps := newTestDeps(t) app := newApp(deps) - deps.SourceRepo.Upsert(model.SourceRecord{ID: "s1", Name: "S1", Type: "local", Content: "ss://x", Enabled: true, Filters: []model.FilterRule{}, Meta: map[string]any{}}) - deps.CollectionRepo.Upsert(model.CollectionRecord{ID: "c1", Name: "C1", Filters: []model.FilterRule{}, TemplateId: template.DefaultTemplateID, IgnoreFailed: true, Enabled: true, Meta: map[string]any{}}) + deps.SourceRepo.Upsert(model.SourceRecord{ID: "s1", Name: "S1", Type: "local", Content: "ss://x", Enabled: true, Meta: map[string]any{}}) + deps.CollectionRepo.Upsert(model.CollectionRecord{ID: "c1", Name: "C1", TemplateId: template.DefaultTemplateID, IgnoreFailed: true, Enabled: true, Meta: map[string]any{}}) // Link source - found code, body := doRequest(t, app, "GET", "/api/link/source/s1", "", nil) @@ -1614,7 +1630,7 @@ func TestBuildDownloadLinkNoToken(t *testing.T) { deps := newTestDeps(t) deps.Cfg.Auth.DownloadToken = "" // no token app := newApp(deps) - deps.SourceRepo.Upsert(model.SourceRecord{ID: "s1", Name: "S1", Type: "local", Content: "ss://x", Enabled: true, Filters: []model.FilterRule{}, Meta: map[string]any{}}) + deps.SourceRepo.Upsert(model.SourceRecord{ID: "s1", Name: "S1", Type: "local", Content: "ss://x", Enabled: true, Meta: map[string]any{}}) code, body := doRequest(t, app, "GET", "/api/link/source/s1", "", nil) assertStatus(t, "LinkSource no token", code, 200) d := body["data"].(map[string]any) @@ -1783,7 +1799,7 @@ func TestHandleDownloadSourceNotFound(t *testing.T) { code, _ = doRequest(t, app, "GET", "/sources/nope/dl-tok?target=mihomo", "", nil) assertStatus(t, "DownloadSource not found", code, 404) // bad target - deps.SourceRepo.Upsert(model.SourceRecord{ID: "s1", Name: "S1", Type: "local", Content: "ss://x", Enabled: true, Filters: []model.FilterRule{}, Meta: map[string]any{}}) + deps.SourceRepo.Upsert(model.SourceRecord{ID: "s1", Name: "S1", Type: "local", Content: "ss://x", Enabled: true, Meta: map[string]any{}}) code, _ = doRequest(t, app, "GET", "/sources/s1/dl-tok?target=bogus", "", nil) assertStatus(t, "DownloadSource bad target", code, 400) } @@ -1801,7 +1817,7 @@ func TestHandleDownloadCollectionNotFound(t *testing.T) { func TestHandleDownloadSourceLocalSuccess(t *testing.T) { deps := newTestDeps(t) app := newApp(deps) - deps.SourceRepo.Upsert(model.SourceRecord{ID: "s1", Name: "S1", Type: "local", Content: "ss://pass@host:8080#name", Enabled: true, Filters: []model.FilterRule{}, Meta: map[string]any{}}) + deps.SourceRepo.Upsert(model.SourceRecord{ID: "s1", Name: "S1", Type: "local", Content: "ss://pass@host:8080#name", Enabled: true, Meta: map[string]any{}}) code, body := doRequest(t, app, "GET", "/sources/s1/dl-tok?target=json", "", nil) // Should succeed (200) — body contains rendered JSON assertStatus(t, "DownloadSource local", code, 200) @@ -1815,7 +1831,7 @@ func TestHandleDownloadSourceLocalSuccess(t *testing.T) { func TestHandleDownloadSourceDisabled(t *testing.T) { deps := newTestDeps(t) app := newApp(deps) - deps.SourceRepo.Upsert(model.SourceRecord{ID: "s1", Name: "S1", Type: "local", Content: "ss://x", Enabled: false, Filters: []model.FilterRule{}, Meta: map[string]any{}}) + deps.SourceRepo.Upsert(model.SourceRecord{ID: "s1", Name: "S1", Type: "local", Content: "ss://x", Enabled: false, Meta: map[string]any{}}) code, _ := doRequest(t, app, "GET", "/sources/s1/dl-tok?target=json", "", nil) assertStatus(t, "DownloadSource disabled", code, 404) } @@ -1883,7 +1899,7 @@ func TestHandlePreviewCollectionBadJSON(t *testing.T) { func TestHandlePreviewCollectionSuccess(t *testing.T) { deps := newTestDeps(t) app := newApp(deps) - deps.SourceRepo.Upsert(model.SourceRecord{ID: "s1", Name: "S1", Type: "local", Content: "ss://pass@host:8080#name", Enabled: true, Filters: []model.FilterRule{}, Meta: map[string]any{}}) + deps.SourceRepo.Upsert(model.SourceRecord{ID: "s1", Name: "S1", Type: "local", Content: "ss://pass@host:8080#name", Enabled: true, Meta: map[string]any{}}) code, body := doRequest(t, app, "POST", "/api/preview/collection", `{"name":"c1","sourceIds":["s1"]}`, nil) assertStatus(t, "PreviewCollection", code, 200) d := body["data"].(map[string]any) @@ -1910,7 +1926,7 @@ func TestHandleFlowInfoNoFlow(t *testing.T) { deps := newTestDeps(t) app := newApp(deps) // local source has no flow URL -> parseFlowRequest returns nil - deps.SourceRepo.Upsert(model.SourceRecord{ID: "s1", Name: "S1", Type: "local", Content: "ss://x", Enabled: true, Filters: []model.FilterRule{}, Meta: map[string]any{}}) + deps.SourceRepo.Upsert(model.SourceRecord{ID: "s1", Name: "S1", Type: "local", Content: "ss://x", Enabled: true, Meta: map[string]any{}}) code, _ := doRequest(t, app, "GET", "/api/source/flow/s1", "", nil) assertStatus(t, "FlowInfo no flow", code, 400) } @@ -1919,7 +1935,7 @@ func TestHandleFlowInfoWithMetaOnly(t *testing.T) { deps := newTestDeps(t) app := newApp(deps) // source with meta subUserinfo but no remote URL - deps.SourceRepo.Upsert(model.SourceRecord{ID: "s1", Name: "S1", Type: "local", Content: "ss://x", Enabled: true, Filters: []model.FilterRule{}, Meta: map[string]any{"subUserinfo": "upload=100; download=200; total=1000"}}) + deps.SourceRepo.Upsert(model.SourceRecord{ID: "s1", Name: "S1", Type: "local", Content: "ss://x", Enabled: true, Meta: map[string]any{"subUserinfo": "upload=100; download=200; total=1000"}}) code, body := doRequest(t, app, "GET", "/api/source/flow/s1", "", nil) // Flow endpoint may return 200 or 400 depending on whether remote URL is required if code != 200 && code != 400 { diff --git a/internal/model/types.go b/internal/model/types.go index 0cd1217..952e476 100644 --- a/internal/model/types.go +++ b/internal/model/types.go @@ -53,6 +53,7 @@ type CustomRule struct { type SourceRecord struct { ID string `json:"id"` Name string `json:"name"` + Alias string `json:"alias"` Type string `json:"type"` URL string `json:"url"` Content string `json:"content"` @@ -65,16 +66,27 @@ type SourceRecord struct { // CollectionRecord is the full DB record for a subscription collection. type CollectionRecord struct { - ID string `json:"id"` - Name string `json:"name"` - SourceIds []string `json:"sourceIds"` - Filters []FilterRule `json:"filters"` - TemplateId string `json:"templateId"` - IgnoreFailed bool `json:"ignoreFailed"` - Enabled bool `json:"enabled"` - Meta map[string]any `json:"meta"` - CreatedAt int64 `json:"createdAt"` - UpdatedAt int64 `json:"updatedAt"` + ID string `json:"id"` + Name string `json:"name"` + SourceIds []string `json:"sourceIds"` + RenameEnabled bool `json:"renameEnabled"` + RenameOptions *RenameOptions `json:"renameOptions,omitempty"` + TemplateId string `json:"templateId"` + IgnoreFailed bool `json:"ignoreFailed"` + Enabled bool `json:"enabled"` + Meta map[string]any `json:"meta"` + CreatedAt int64 `json:"createdAt"` + UpdatedAt int64 `json:"updatedAt"` +} + +// RenameOptions controls which fields appear in collection-level node renaming. +// All fields default to true (included). When stored as nil, all defaults apply. +type RenameOptions struct { + Flag bool `json:"flag"` // emoji country flag prefix + Alias bool `json:"alias"` // source alias in [brackets] + Country bool `json:"country"` // Chinese country name + City bool `json:"city"` // Chinese city name + Index bool `json:"index"` // sequential number (01, 02, …) } // TemplateRecord is the full DB record for a routing template. diff --git a/internal/render/uri.go b/internal/render/uri.go index a5248b4..ae75fad 100644 --- a/internal/render/uri.go +++ b/internal/render/uri.go @@ -69,7 +69,7 @@ func ToProxyUri(proxy model.ProxyNode) string { url.PathEscape(getString(proxy, "uuid")), server, port, params.Encode(), - url.QueryEscape(name)) + url.PathEscape(name)) case "hysteria2": params := url.Values{} @@ -89,7 +89,7 @@ func ToProxyUri(proxy model.ProxyNode) string { url.PathEscape(getString(proxy, "password")), server, port, params.Encode(), - url.QueryEscape(name)) + url.PathEscape(name)) case "hysteria": params := url.Values{} @@ -118,7 +118,7 @@ func ToProxyUri(proxy model.ProxyNode) string { url.PathEscape(getString(proxy, "auth_str")), server, port, params.Encode(), - url.QueryEscape(name)) + url.PathEscape(name)) case "anytls": params := url.Values{} @@ -135,7 +135,7 @@ func ToProxyUri(proxy model.ProxyNode) string { url.PathEscape(getString(proxy, "password")), server, port, params.Encode(), - url.QueryEscape(name)) + url.PathEscape(name)) case "tuic": params := url.Values{} @@ -162,7 +162,7 @@ func ToProxyUri(proxy model.ProxyNode) string { url.PathEscape(getString(proxy, "password")), server, port, params.Encode(), - url.QueryEscape(name)) + url.PathEscape(name)) case "trojan": params := url.Values{} @@ -176,7 +176,7 @@ func ToProxyUri(proxy model.ProxyNode) string { url.PathEscape(getString(proxy, "password")), server, port, params.Encode(), - url.QueryEscape(name)) + url.PathEscape(name)) case "socks5": params := url.Values{} @@ -208,14 +208,14 @@ func ToProxyUri(proxy model.ProxyNode) string { scheme = "https" } return fmt.Sprintf("%s://%s%s:%d#%s", - scheme, auth, server, port, url.QueryEscape(name)) + scheme, auth, server, port, url.PathEscape(name)) case "ss": userInfo := util.Base64Utf8(fmt.Sprintf("%s:%s@%s:%d", getString(proxy, "cipher"), getString(proxy, "password"), server, port)) - return fmt.Sprintf("ss://%s#%s", userInfo, url.QueryEscape(name)) + return fmt.Sprintf("ss://%s#%s", userInfo, url.PathEscape(name)) case "ssr": main := strings.Join([]string{ @@ -257,7 +257,7 @@ func ToProxyUri(proxy model.ProxyNode) string { url.PathEscape(getString(proxy, "private-key")), server, port, params.Encode(), - url.QueryEscape(name)) + url.PathEscape(name)) case "vmess": wsOpts, _ := proxy["ws-opts"].(map[string]any) diff --git a/internal/service/subscription.go b/internal/service/subscription.go index 4c99909..7b505b3 100644 --- a/internal/service/subscription.go +++ b/internal/service/subscription.go @@ -92,10 +92,25 @@ func loadProxyNodes(ctx context.Context, opts BuildOptions) ([]model.ProxyNode, if filters == nil { filters = []model.FilterRule{} } - return filter.ApplyFilters(nodes, filters, opts.Settings, filter.FilterContext{ + processed := filter.ApplyFilters(nodes, filters, opts.Settings, filter.FilterContext{ TargetPlatform: opts.Target, SourceId: sub.ID, - }), nil + }) + // Tag each node with the source's alias for collection-level renaming + if sub.Alias != "" { + for j := range processed { + if processed[j] == nil { + continue + } + tagged := make(map[string]any, len(processed[j])+1) + for k, v := range processed[j] { + tagged[k] = v + } + tagged["_sourceAlias"] = sub.Alias + processed[j] = tagged + } + } + return processed, nil } } @@ -128,16 +143,9 @@ func loadProxyNodes(ctx context.Context, opts BuildOptions) ([]model.ProxyNode, originalNodes += count } - // Apply collection-level filters - if opts.Collection != nil { - colFilters := opts.Collection.Filters - if colFilters == nil { - colFilters = []model.FilterRule{} - } - allProxies = filter.ApplyFilters(allProxies, colFilters, opts.Settings, filter.FilterContext{ - TargetPlatform: opts.Target, - CollectionId: opts.Collection.ID, - }) + // Apply collection-level rename if enabled + if opts.Collection != nil && opts.Collection.RenameEnabled { + allProxies = filter.RenameCollectionNodes(allProxies, opts.Collection.RenameOptions) } // Ensure unique names diff --git a/internal/service/subscription_test.go b/internal/service/subscription_test.go index b15de7f..7a3ca15 100644 --- a/internal/service/subscription_test.go +++ b/internal/service/subscription_test.go @@ -93,7 +93,6 @@ func TestBuildSubscriptionResult_Collection(t *testing.T) { ID: "col1", Name: "Collection", SourceIds: []string{"src1", "src2"}, - Filters: []model.FilterRule{}, TemplateId: "acl4ssr-mihomo", Enabled: true, Meta: map[string]any{}, @@ -126,7 +125,6 @@ func TestBuildSubscriptionResult_CollectionIgnoreFailed(t *testing.T) { ID: "col1", Name: "Collection", SourceIds: []string{"src1", "src2"}, - Filters: []model.FilterRule{}, TemplateId: "acl4ssr-mihomo", IgnoreFailed: true, Enabled: true, diff --git a/internal/util/flag.go b/internal/util/flag.go index ce13566..dddd781 100644 --- a/internal/util/flag.go +++ b/internal/util/flag.go @@ -1,46 +1,155 @@ package util import ( + "net" "regexp" "strings" + + "github.com/peterqiu0516/sub-store/internal/geoip" ) -// Flag detection rules: [regex, emoji]. +// Flag detection rules: [regex, emoji, countryName, cityExtractor]. // Per review-resolution #16: Go RE2 supports \p{Regional_Indicator} and \uFE0F. -var flagRules []flagRule - -type flagRule struct { - re *regexp.Regexp - emoji string +type geoRule struct { + re *regexp.Regexp + emoji string + countryName string + countryNameCN string + cityPatterns []cityPattern } +type cityPattern struct { + re *regexp.Regexp + name string + nameCN string +} + +var geoRules []geoRule + func init() { rules := []struct { - pattern string - emoji string + pattern string + emoji string + countryName string + countryNameCN string + cities []struct{ pattern, name, nameCN string } }{ - {`香港|港|hong\s*kong|\bhk\b`, "🇭🇰"}, - {`台湾|台灣|taiwan|\btw\b`, "🇹🇼"}, - {`新加坡|狮城|獅城|singapore|\bsg\b`, "🇸🇬"}, - {`日本|东京|東京|大阪|japan|tokyo|osaka|\bjp\b`, "🇯🇵"}, - {`美国|美國|洛杉矶|洛杉磯|纽约|紐約|united\s*states|los\s*angeles|new\s*york|\bus\b|\busa\b`, "🇺🇸"}, - {`英国|英國|伦敦|倫敦|united\s*kingdom|london|\buk\b`, "🇬🇧"}, - {`德国|德國|法兰克福|法蘭克福|germany|frankfurt|\bde\b`, "🇩🇪"}, - {`韩国|韓國|首尔|首爾|korea|seoul|\bkr\b`, "🇰🇷"}, + { + pattern: `香港|港|hong\s*kong|\bhk\b`, + emoji: "🇭🇰", + countryName: "Hong Kong", + countryNameCN: "香港", + cities: []struct{ pattern, name, nameCN string }{ + {`香港|Hong\s*Kong|HK`, "Hong Kong", "香港"}, + }, + }, + { + pattern: `台湾|台灣|taiwan|\btw\b`, + emoji: "🇹🇼", + countryName: "Taiwan", + countryNameCN: "台湾", + cities: []struct{ pattern, name, nameCN string }{ + {`台北|臺北|Taipei`, "Taipei", "台北"}, + {`高雄|Gaoxiong|Kaohsiung`, "Kaohsiung", "高雄"}, + }, + }, + { + pattern: `新加坡|狮城|獅城|singapore|\bsg\b`, + emoji: "🇸🇬", + countryName: "Singapore", + countryNameCN: "新加坡", + cities: []struct{ pattern, name, nameCN string }{ + {`新加坡|Singapore|SG`, "Singapore", "新加坡"}, + }, + }, + { + pattern: `日本|东京|東京|大阪|japan|tokyo|osaka|\bjp\b`, + emoji: "🇯🇵", + countryName: "Japan", + countryNameCN: "日本", + cities: []struct{ pattern, name, nameCN string }{ + {`东京|東京|Tokyo`, "Tokyo", "东京"}, + {`大阪|Osaka`, "Osaka", "大阪"}, + }, + }, + { + pattern: `美国|美國|洛杉矶|洛杉磯|纽约|紐約|united\s*states|los\s*angeles|new\s*york|\bus\b|\busa\b`, + emoji: "🇺🇸", + countryName: "United States", + countryNameCN: "美国", + cities: []struct{ pattern, name, nameCN string }{ + {`洛杉矶|洛杉磯|Los\s*Angeles|LA`, "Los Angeles", "洛杉矶"}, + {`纽约|紐約|New\s*York|NYC`, "New York", "纽约"}, + {`硅谷|Silicon\s*Valley|San\s*Jose|SJC`, "San Jose", "硅谷"}, + {`西雅图|Seattle`, "Seattle", "西雅图"}, + {`芝加哥|Chicago`, "Chicago", "芝加哥"}, + {`达拉斯|Dallas`, "Dallas", "达拉斯"}, + }, + }, + { + pattern: `英国|英國|伦敦|倫敦|united\s*kingdom|london|\buk\b`, + emoji: "🇬🇧", + countryName: "United Kingdom", + countryNameCN: "英国", + cities: []struct{ pattern, name, nameCN string }{ + {`伦敦|倫敦|London`, "London", "伦敦"}, + }, + }, + { + pattern: `德国|德國|法兰克福|法蘭克福|germany|frankfurt|\bde\b`, + emoji: "🇩🇪", + countryName: "Germany", + countryNameCN: "德国", + cities: []struct{ pattern, name, nameCN string }{ + {`法兰克福|法蘭克福|Frankfurt`, "Frankfurt", "法兰克福"}, + }, + }, + { + pattern: `韩国|韓國|首尔|首爾|korea|seoul|\bkr\b`, + emoji: "🇰🇷", + countryName: "South Korea", + countryNameCN: "韩国", + cities: []struct{ pattern, name, nameCN string }{ + {`首尔|首爾|Seoul`, "Seoul", "首尔"}, + }, + }, } for _, r := range rules { re, err := regexp.Compile("(?i)" + r.pattern) if err != nil { continue } - flagRules = append(flagRules, flagRule{re: re, emoji: r.emoji}) + var cps []cityPattern + for _, c := range r.cities { + cre, err := regexp.Compile("(?i)" + c.pattern) + if err != nil { + continue + } + cps = append(cps, cityPattern{re: cre, name: c.name, nameCN: c.nameCN}) + } + geoRules = append(geoRules, geoRule{ + re: re, + emoji: r.emoji, + countryName: r.countryName, + countryNameCN: r.countryNameCN, + cityPatterns: cps, + }) } } +// GeoInfo holds detected geographic information from a proxy name. +type GeoInfo struct { + Flag string // emoji flag + CountryName string // English country name + CountryCN string // Chinese country name + City string // English city name (may be empty) + CityCN string // Chinese city name (may be empty) +} + // DetectFlag returns the flag emoji for a name, or 🏳️ if no match. func DetectFlag(name string) string { text := strings.ToLower(name) - for _, rule := range flagRules { + for _, rule := range geoRules { if rule.re.MatchString(text) { return rule.emoji } @@ -48,6 +157,63 @@ func DetectFlag(name string) string { return "🏳️" } +// DetectGeo returns full geographic info (flag + country + city) from a name. +// It tries GeoIP lookup on the server address first, falling back to +// name-based regex matching. +func DetectGeo(name string) GeoInfo { + return detectGeoFromName(name) +} + +// DetectGeoWithServer returns geographic info by looking up the proxy's +// server address via GeoIP first, falling back to name-based detection. +func DetectGeoWithServer(name, server string) GeoInfo { + // Try GeoIP lookup first + if server != "" { + host := server + // Strip port if present + if h, _, err := net.SplitHostPort(server); err == nil { + host = h + } + if result := geoip.LookupHost(host); result != nil { + return GeoInfo{ + Flag: geoip.CountryEmoji(result.CountryCode), + CountryName: result.CountryName, + CountryCN: result.CountryNameCN, + City: result.CityName, + CityCN: result.CityNameCN, + } + } + } + // Fallback to name-based detection + return detectGeoFromName(name) +} + +// detectGeoFromName does name-based regex matching for geo detection. +func detectGeoFromName(name string) GeoInfo { + text := strings.ToLower(name) + for _, rule := range geoRules { + if rule.re.MatchString(text) { + city := "" + cityCN := "" + for _, cp := range rule.cityPatterns { + if cp.re.MatchString(text) { + city = cp.name + cityCN = cp.nameCN + break + } + } + return GeoInfo{ + Flag: rule.emoji, + CountryName: rule.countryName, + CountryCN: rule.countryNameCN, + City: city, + CityCN: cityCN, + } + } + } + return GeoInfo{} +} + // removeFlagRe matches leading flag emoji sequences and whitespace. // Regional Indicator letters are U+1F1E6–U+1F1FF; ZWJ is U+200D; VS16 is U+FE0F. var removeFlagRe = regexp.MustCompile(`^[\x{1F1E6}-\x{1F1FF}\x{FE0F}\x{200D}\s]+`)