From 42aea1010110a9e7258491ac13714a62b04c2723 Mon Sep 17 00:00:00 2001 From: Blizzard Date: Mon, 5 Oct 2026 11:03:33 +0800 Subject: [PATCH 1/7] Add immediate startup login and loading states for mini program home --- pets-fe/app.js | 37 ++-- pets-fe/components/home-skeleton/index.js | 1 + pets-fe/components/home-skeleton/index.json | 1 + pets-fe/components/home-skeleton/index.wxml | 9 + pets-fe/components/home-skeleton/index.wxss | 73 ++++++++ pets-fe/components/startup-state/index.js | 8 + pets-fe/components/startup-state/index.json | 1 + pets-fe/components/startup-state/index.wxml | 16 ++ pets-fe/components/startup-state/index.wxss | 128 +++++++++++++ pets-fe/pages/home/home.js | 104 ++++++++--- pets-fe/pages/home/home.json | 4 +- pets-fe/pages/home/home.wxml | 23 ++- pets-fe/pages/home/home.wxss | 50 +++++ pets-fe/utils/api.js | 19 +- tests/miniprogram-startup.test.cjs | 193 ++++++++++++++++++++ 15 files changed, 623 insertions(+), 44 deletions(-) create mode 100644 pets-fe/components/home-skeleton/index.js create mode 100644 pets-fe/components/home-skeleton/index.json create mode 100644 pets-fe/components/home-skeleton/index.wxml create mode 100644 pets-fe/components/home-skeleton/index.wxss create mode 100644 pets-fe/components/startup-state/index.js create mode 100644 pets-fe/components/startup-state/index.json create mode 100644 pets-fe/components/startup-state/index.wxml create mode 100644 pets-fe/components/startup-state/index.wxss create mode 100644 tests/miniprogram-startup.test.cjs diff --git a/pets-fe/app.js b/pets-fe/app.js index 8d6cf13..d48a175 100644 --- a/pets-fe/app.js +++ b/pets-fe/app.js @@ -2,22 +2,33 @@ App({ globalData: { token: "", user: null }, onLaunch() { this.globalData.token = wx.getStorageSync("pet_token") || ""; + // Start immediately; pages await the same promise and display failures themselves. + this.login().catch(() => {}); }, async login() { + if (this.loginPromise) return this.loginPromise; if (this.globalData.token) return this.globalData.token; - if (!this.loginPromise) - this.loginPromise = (async () => { - const { request } = require("./utils/api"); - const { code } = await wx.login(); - if (!code) throw new Error("微信登录未取得凭证,请重试"); - const data = await request("/auth/login", "POST", { code }, false); - this.globalData.token = data.token; - this.globalData.user = data.user; - wx.setStorageSync("pet_token", data.token); - return data.token; - })().finally(() => { - this.loginPromise = null; - }); + this.loginPromise = (async () => { + const { request } = require("./utils/api"); + const { code } = await new Promise((resolve, reject) => + wx.login({ + timeout: 10000, + success: resolve, + fail: () => reject(new Error("暂时无法连接微信,请重新连接")), + }), + ); + if (!code) throw new Error("微信登录未取得凭证,请重新连接"); + const data = await request("/auth/login", "POST", { code }, false); + if (!data || typeof data.token !== "string" || !data.token) { + throw new Error("登录未完成,请重新连接"); + } + this.globalData.token = data.token; + this.globalData.user = data.user; + wx.setStorageSync("pet_token", data.token); + return data.token; + })().finally(() => { + this.loginPromise = null; + }); return this.loginPromise; }, }); diff --git a/pets-fe/components/home-skeleton/index.js b/pets-fe/components/home-skeleton/index.js new file mode 100644 index 0000000..b79c512 --- /dev/null +++ b/pets-fe/components/home-skeleton/index.js @@ -0,0 +1 @@ +Component({}); diff --git a/pets-fe/components/home-skeleton/index.json b/pets-fe/components/home-skeleton/index.json new file mode 100644 index 0000000..67f8e03 --- /dev/null +++ b/pets-fe/components/home-skeleton/index.json @@ -0,0 +1 @@ +{ "component": true } diff --git a/pets-fe/components/home-skeleton/index.wxml b/pets-fe/components/home-skeleton/index.wxml new file mode 100644 index 0000000..fc514f1 --- /dev/null +++ b/pets-fe/components/home-skeleton/index.wxml @@ -0,0 +1,9 @@ + + + + + + + + 正在准备今天的小日常… + diff --git a/pets-fe/components/home-skeleton/index.wxss b/pets-fe/components/home-skeleton/index.wxss new file mode 100644 index 0000000..c66e51b --- /dev/null +++ b/pets-fe/components/home-skeleton/index.wxss @@ -0,0 +1,73 @@ +.bone { + background: linear-gradient(100deg, #f3e7dc 20%, #fff8ef 45%, #f3e7dc 70%); + background-size: 220% 100%; + animation: shimmer 1.6s ease-in-out infinite; + border-radius: 15rpx; +} +.hero-placeholder { + position: relative; + min-height: 330rpx; + background: #fff0e2; + border-radius: 38rpx; + padding: 45rpx 35rpx; + box-sizing: border-box; +} +.line { + height: 22rpx; + width: 65%; + margin: 24rpx 0; +} +.short { + width: 25%; +} +.title { + height: 38rpx; + width: 48%; +} +.art { + position: absolute; + right: 35rpx; + top: 62rpx; + width: 170rpx; + height: 190rpx; + border-radius: 40rpx; +} +.heading { + width: 230rpx; + height: 33rpx; + margin: 48rpx 0 28rpx; +} +.card-placeholder { + padding: 28rpx; + background: white; + border-radius: 35rpx; +} +.action { + height: 80rpx; + margin-top: 42rpx; + border-radius: 24rpx; +} +.stats-placeholder { + display: flex; + gap: 14rpx; + margin-top: 20rpx; +} +.stats-placeholder view { + height: 140rpx; + flex: 1; + border-radius: 28rpx; +} +.loading-copy { + text-align: center; + color: #a48d7e; + font-size: 22rpx; + margin-top: 32rpx; +} +@keyframes shimmer { + 0% { + background-position: 100% 0; + } + 100% { + background-position: -100% 0; + } +} diff --git a/pets-fe/components/startup-state/index.js b/pets-fe/components/startup-state/index.js new file mode 100644 index 0000000..d470371 --- /dev/null +++ b/pets-fe/components/startup-state/index.js @@ -0,0 +1,8 @@ +Component({ + properties: { error: String }, + methods: { + retry() { + this.triggerEvent("retry"); + }, + }, +}); diff --git a/pets-fe/components/startup-state/index.json b/pets-fe/components/startup-state/index.json new file mode 100644 index 0000000..67f8e03 --- /dev/null +++ b/pets-fe/components/startup-state/index.json @@ -0,0 +1 @@ +{ "component": true } diff --git a/pets-fe/components/startup-state/index.wxml b/pets-fe/components/startup-state/index.wxml new file mode 100644 index 0000000..16ae6eb --- /dev/null +++ b/pets-fe/components/startup-state/index.wxml @@ -0,0 +1,16 @@ + + + + 肉垫计划 + 给陪伴一个温暖的地方 + + 暂时没能连接 + {{error}} + + + + + 正在准备今天的小日常 + + 陪伴它们的每一天,都值得记录 + diff --git a/pets-fe/components/startup-state/index.wxss b/pets-fe/components/startup-state/index.wxss new file mode 100644 index 0000000..4825c25 --- /dev/null +++ b/pets-fe/components/startup-state/index.wxss @@ -0,0 +1,128 @@ +.startup { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 80; + background: linear-gradient(160deg, #fff9f3, #fff0e2 65%, #f7edf7); + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 60rpx; + box-sizing: border-box; + overflow: hidden; + color: #694c3f; +} +.glow { + position: absolute; + width: 520rpx; + height: 520rpx; + border-radius: 50%; + background: radial-gradient(circle, #ffe1c2, transparent 70%); + top: 18%; + pointer-events: none; +} +.brand-wrap { + position: relative; + animation: breathe 2.4s ease-in-out infinite; +} +.brand { + width: 172rpx; + height: 172rpx; + border-radius: 55rpx; + box-shadow: 0 20rpx 60rpx #bd84551c; +} +.brand-name { + font-size: 45rpx; + font-weight: 600; + letter-spacing: 5rpx; + margin-top: 34rpx; +} +.brand-tagline { + font-size: 23rpx; + color: #9d7965; + margin-top: 14rpx; + letter-spacing: 2rpx; +} +.preparing, +.connection-error { + min-height: 170rpx; + margin-top: 64rpx; + text-align: center; + position: relative; +} +.message { + font-size: 25rpx; + color: #886c5f; +} +.dots { + display: flex; + justify-content: center; + gap: 12rpx; + margin-bottom: 25rpx; +} +.dots view { + width: 10rpx; + height: 10rpx; + border-radius: 50%; + background: #d99a75; + animation: pulse 1.2s ease-in-out infinite; +} +.dots view:nth-child(2) { + animation-delay: 0.15s; +} +.dots view:nth-child(3) { + animation-delay: 0.3s; +} +.error-copy { + font-size: 23rpx; + line-height: 1.8; + color: #9d7965; + margin-top: 15rpx; + max-width: 570rpx; + overflow-wrap: break-word; +} +.retry { + font-size: 25rpx; + background: #b95738; + color: white; + border-radius: 24rpx; + padding: 0 44rpx; + margin-top: 26rpx; + line-height: 82rpx; +} +.retry::after { + border: 0; +} +.failed .brand-wrap { + animation: none; +} +.footer { + position: absolute; + bottom: calc(65rpx + env(safe-area-inset-bottom)); + font-size: 20rpx; + color: #a88c78; + letter-spacing: 1rpx; +} +@keyframes breathe { + 0%, + 100% { + transform: translateY(0) scale(1); + } + 50% { + transform: translateY(-10rpx) scale(1.025); + } +} +@keyframes pulse { + 0%, + 100% { + opacity: 0.35; + transform: scale(0.85); + } + 50% { + opacity: 1; + transform: scale(1.1); + } +} diff --git a/pets-fe/pages/home/home.js b/pets-fe/pages/home/home.js index b801be1..d1b298c 100644 --- a/pets-fe/pages/home/home.js +++ b/pets-fe/pages/home/home.js @@ -14,16 +14,22 @@ Page({ walkCount: 0, name: "铲屎官", loading: true, + ready: false, + phase: "auth", + error: "", }, onShow() { - this.load(); this.updateEnvironmentLabel(); - if (!this.environmentAt || Date.now() - this.environmentAt > 15 * 60 * 1000) { - this.refreshEnvironment(); - } + this.load(); + }, + onUnload() { + this.disposed = true; }, updateEnvironmentLabel() { - this.setData({ headerSubtitle: dateLabel() + " · " + (this.weatherLabel || "轻触获取天气") }); + this.setData({ + headerSubtitle: + dateLabel() + " · " + (this.weatherLabel || "轻触获取天气"), + }); }, async refreshEnvironment(event) { if (this.environmentBusy) return; @@ -31,44 +37,84 @@ Page({ const tapped = !!event; let positioned = false; try { - const settings = await new Promise((resolve, reject) => wx.getSetting({ success: resolve, fail: reject })); + const settings = await new Promise((resolve, reject) => + wx.getSetting({ success: resolve, fail: reject }), + ); if (settings.authSetting["scope.userLocation"] === false) { if (!tapped) throw new Error("location-denied"); - const enabled = await new Promise((resolve, reject) => wx.openSetting({ success: resolve, fail: reject })); - if (!enabled.authSetting["scope.userLocation"]) throw new Error("location-denied"); + const enabled = await new Promise((resolve, reject) => + wx.openSetting({ success: resolve, fail: reject }), + ); + if (!enabled.authSetting["scope.userLocation"]) + throw new Error("location-denied"); } this.weatherLabel = "正在获取天气"; this.updateEnvironmentLabel(); - const point = await new Promise((resolve, reject) => wx.getLocation({ - type: "gcj02", - success: resolve, - fail: reject, - })); + const point = await new Promise((resolve, reject) => + wx.getLocation({ + type: "gcj02", + success: resolve, + fail: reject, + }), + ); positioned = true; - const result = await secure("/environment", "GET", { latitude: point.latitude, longitude: point.longitude }); + const result = await secure("/environment", "GET", { + latitude: point.latitude, + longitude: point.longitude, + }); this.setData({ locationName: result.location_name }); this.weatherLabel = result.weather ? `${result.weather.description} ${result.weather.temperature}°C` : "天气暂不可用"; this.environmentAt = result.weather ? Date.now() : 0; } catch (error) { - const denied = /denied|deny|auth/.test(error.errMsg || error.message || ""); - this.setData({ locationName: positioned ? "位置暂不可用" : denied ? "开启定位" : "定位暂不可用" }); + const denied = /denied|deny|auth/.test( + error.errMsg || error.message || "", + ); + this.setData({ + locationName: positioned + ? "位置暂不可用" + : denied + ? "开启定位" + : "定位暂不可用", + }); this.weatherLabel = denied ? "轻触开启定位" : "轻触重试"; - if (tapped && !denied) wx.showToast({ title: positioned ? "位置和天气获取失败,请重试" : "定位失败,请重试", icon: "none" }); + if (tapped && !denied) + wx.showToast({ + title: positioned ? "位置和天气获取失败,请重试" : "定位失败,请重试", + icon: "none", + }); } finally { this.environmentBusy = false; this.updateEnvironmentLabel(); } }, async load() { + if (this.loadPromise) return this.loadPromise; + this.loadPromise = this.loadHome().finally(() => { + this.loadPromise = null; + }); + return this.loadPromise; + }, + async loadHome() { + this.setData({ + loading: true, + error: "", + phase: this.data.ready ? "data" : "auth", + }); + let authenticated = false; try { + await getApp().login(); + authenticated = true; + if (this.disposed) return; + this.setData({ phase: "data" }); const [pets, tasks, walks, me] = await Promise.all([ secure("/pets"), secure("/tasks"), secure("/walks"), secure("/me"), ]); + if (this.disposed) return; const chosen = wx.getStorageSync("walk_pet_ids") || [], month = localDate().slice(0, 7); this.setData({ @@ -77,14 +123,30 @@ Page({ tasks: tasks.items, walkCount: walks.filter((w) => w.started_at.slice(0, 7) === month) .length, - name: me.nickname || "铲屎官", + name: me.nickname || "毛孩家长", loading: false, + ready: true, + phase: "ready", + }); + // Location permission and weather never hold up the first usable screen. + if ( + !this.environmentAt || + Date.now() - this.environmentAt > 15 * 60 * 1000 + ) { + this.refreshEnvironment(); + } + } catch (error) { + if (this.disposed) return; + this.setData({ + loading: false, + phase: !authenticated && !this.data.ready ? "auth-error" : "data-error", + error: error.message || "暂时没能连接,请稍后重试", }); - } catch (e) { - this.setData({ loading: false }); - toast(e); } }, + addPet() { + wx.navigateTo({ url: "/pages/pet-edit/pet-edit" }); + }, pick(e) { this.setData({ selected: e.detail.selected }); wx.setStorageSync("walk_pet_ids", e.detail.selected); diff --git a/pets-fe/pages/home/home.json b/pets-fe/pages/home/home.json index 2f486b5..07951d1 100644 --- a/pets-fe/pages/home/home.json +++ b/pets-fe/pages/home/home.json @@ -2,6 +2,8 @@ "disableScroll": true, "usingComponents": { "tab-bar": "/components/tab-bar/index", - "pet-picker": "/components/pet-picker/index" + "pet-picker": "/components/pet-picker/index", + "startup-state": "/components/startup-state/index", + "home-skeleton": "/components/home-skeleton/index" } } diff --git a/pets-fe/pages/home/home.wxml b/pets-fe/pages/home/home.wxml index 7aef008..9acbdb1 100644 --- a/pets-fe/pages/home/home.wxml +++ b/pets-fe/pages/home/home.wxml @@ -1,5 +1,16 @@ - + + + + + + 暂时没能准备好首页 + {{error}} + + + + 更新失败,保留上次的日常记录重试 + 正在更新今天的小日常… 今日的主角 @@ -21,9 +32,16 @@ 选择同行的狗狗,一起出门转转。 + + 认识你的第一位毛孩子 + 先建立档案,再一起出门收集小快乐。 + + + 这次带谁?可以多选 + @@ -75,6 +93,7 @@ 今天还没有任务,给狗狗安排一件小事吧 + - + diff --git a/pets-fe/pages/home/home.wxss b/pets-fe/pages/home/home.wxss index 366f3d8..7b5a6a8 100644 --- a/pets-fe/pages/home/home.wxss +++ b/pets-fe/pages/home/home.wxss @@ -157,3 +157,53 @@ .task-main .muted { font-size: 22rpx; } +.home-error { + text-align: center; + padding: 70rpx 35rpx; + display: flex; + align-items: center; + flex-direction: column; + gap: 26rpx; + margin-top: 40rpx; +} +.error-title { + font-size: 30rpx; + font-weight: 600; +} +.home-error .muted { + font-size: 24rpx; + line-height: 1.8; +} +.home-error button { + margin-top: 15rpx; + min-width: 300rpx; +} +.refresh-error { + display: flex; + align-items: center; + justify-content: space-between; + font-size: 22rpx; + background: #fff0e2; + color: #886c5f; + padding: 20rpx 24rpx; + border-radius: 22rpx; + margin-bottom: 20rpx; +} +.refresh-hint { + text-align: center; + font-size: 22rpx; + color: #a48d7e; + margin-bottom: 20rpx; +} +.first-pet { + padding-top: 30rpx; +} +.first-pet-title { + font-size: 27rpx; + font-weight: 600; + margin-bottom: 12rpx; +} +.first-pet .muted { + font-size: 23rpx; + line-height: 1.8; +} diff --git a/pets-fe/utils/api.js b/pets-fe/utils/api.js index 26a5d1f..edd5f8d 100644 --- a/pets-fe/utils/api.js +++ b/pets-fe/utils/api.js @@ -6,23 +6,29 @@ function request(path, method = "GET", data, auth = true) { url: baseURL + path, method, data, + timeout: 15000, header: token && auth ? { Authorization: "Bearer " + token } : {}, success(res) { if (res.data && res.data.code === 0) resolve(res.data.data); else { - if (res.statusCode === 401) { - wx.removeStorageSync("pet_token"); - getApp().globalData.token = ""; - } + if (res.statusCode === 401 && auth) invalidateToken(token); const error = new Error((res.data && res.data.message) || "请求失败"); error.status = res.statusCode; reject(error); } }, - fail: reject, + fail: () => reject(new Error("网络连接失败,请检查网络后重试")), }); }); } +function invalidateToken(usedToken) { + const app = getApp(); + // A late response using the old token must not clear a newly refreshed session. + if (app.globalData.token && app.globalData.token !== usedToken) return; + wx.removeStorageSync("pet_token"); + app.globalData.token = ""; + app.globalData.user = null; +} async function secure(path, method, data) { await getApp().login(); try { @@ -53,6 +59,7 @@ function uploadOnce(path) { else { const error = new Error(body.message || "上传失败"); error.status = res.statusCode; + if (res.statusCode === 401) invalidateToken(token); reject(error); } } catch (e) { @@ -69,8 +76,6 @@ async function upload(path) { return await uploadOnce(path); } catch (error) { if (error.status !== 401) throw error; - wx.removeStorageSync("pet_token"); - getApp().globalData.token = ""; await getApp().login(); return uploadOnce(path); } diff --git a/tests/miniprogram-startup.test.cjs b/tests/miniprogram-startup.test.cjs new file mode 100644 index 0000000..03b7bb0 --- /dev/null +++ b/tests/miniprogram-startup.test.cjs @@ -0,0 +1,193 @@ +const test = require("node:test"); +const assert = require("node:assert/strict"); +const fs = require("node:fs"); +const vm = require("node:vm"); +const tick = () => new Promise((resolve) => setImmediate(resolve)); + +function runtime(cachedToken = "") { + let app; + const storage = new Map(cachedToken ? [["pet_token", cachedToken]] : []); + const requests = [], + logins = []; + const wx = { + getStorageSync: (key) => storage.get(key), + setStorageSync: (key, value) => storage.set(key, value), + removeStorageSync: (key) => storage.delete(key), + login: (options) => logins.push(options), + request: (options) => { + requests.push(options); + if (options.url.endsWith("/auth/login")) + options.success({ + statusCode: 200, + data: { + code: 0, + data: { token: "fresh-token", user: { nickname: "毛孩家长9527" } }, + }, + }); + else if (options.header.Authorization === "Bearer fresh-token") + options.success({ statusCode: 200, data: { code: 0, data: "ok" } }); + }, + }; + const module = { exports: {} }; + vm.runInNewContext(fs.readFileSync("pets-fe/utils/api.js", "utf8"), { + wx, + getApp: () => app, + require: () => ({ baseURL: "https://test.local/api" }), + module, + }); + vm.runInNewContext(fs.readFileSync("pets-fe/app.js", "utf8"), { + wx, + App: (value) => { + app = value; + }, + require: () => module.exports, + }); + return { app, api: module.exports, requests, logins, storage }; +} + +test("启动即登录,多个首页请求共用登录任务并携带 token", async () => { + const r = runtime(); + r.app.onLaunch(); + const pending = [ + r.api.secure("/pets"), + r.api.secure("/tasks"), + r.api.secure("/me"), + ]; + assert.equal(r.logins.length, 1); + assert.equal(r.requests.length, 0); + r.logins[0].success({ code: "wechat-code" }); + assert.deepEqual(await Promise.all(pending), ["ok", "ok", "ok"]); + assert.equal( + r.requests.filter((req) => req.url.endsWith("/auth/login")).length, + 1, + ); + assert.ok( + r.requests + .slice(1) + .every((req) => req.header.Authorization === "Bearer fresh-token"), + ); + assert.equal(r.storage.get("pet_token"), "fresh-token"); +}); + +test("缓存 token 过期时只重新登录一次,延迟的旧 401 不清除新 token", async () => { + const r = runtime("expired"); + r.app.onLaunch(); + const first = r.api.secure("/pets"), + second = r.api.secure("/tasks"); + await tick(); + const old = r.requests.slice(); + assert.equal(old.length, 2); + old[0].success({ statusCode: 401, data: { message: "expired" } }); + await tick(); + assert.equal(r.logins.length, 1); + r.logins[0].success({ code: "new-code" }); + await first; + old[1].success({ statusCode: 401, data: { message: "expired" } }); + await second; + assert.equal(r.app.globalData.token, "fresh-token"); + assert.equal(r.logins.length, 1); +}); + +function home(login, secure) { + let definition; + const wx = { getStorageSync: () => [], navigateTo: () => {} }; + vm.runInNewContext(fs.readFileSync("pets-fe/pages/home/home.js", "utf8"), { + wx, + Date, + getApp: () => ({ login }), + Page: (value) => { + definition = value; + }, + require: (name) => + name.includes("date") + ? { localDate: () => "2026-10-05" } + : { secure, toast: () => {} }, + }); + const page = { + ...definition, + data: { ...definition.data }, + setData(value) { + Object.assign(this.data, value); + }, + }; + page.refreshEnvironment = () => new Promise(() => {}); + return page; +} +function data(path) { + return Promise.resolve( + path === "/pets" || path === "/walks" + ? [] + : path === "/tasks" + ? { items: [] } + : { nickname: "毛孩家长9527" }, + ); +} + +test("登录和数据都准备好才显示首页,天气未完成也能进入", async () => { + let finishLogin, + calls = 0; + const login = new Promise((resolve) => { + finishLogin = resolve; + }); + const page = home( + () => login, + (path) => { + calls++; + return data(path); + }, + ); + const loading = page.load(); + page.load(); + assert.equal(page.data.phase, "auth"); + assert.equal(page.data.ready, false); + assert.equal(calls, 0); + finishLogin("token"); + await loading; + assert.equal(calls, 4); + assert.equal(page.data.ready, true); + assert.equal(page.data.loading, false); + assert.equal(page.data.phase, "ready"); + assert.equal(page.data.pets.length, 0); +}); + +test("首次登录失败可重试,失败期间不请求业务数据", async () => { + let attempts = 0, + calls = 0; + const page = home( + async () => { + if (++attempts === 1) throw new Error("无法连接"); + return "token"; + }, + (path) => { + calls++; + return data(path); + }, + ); + await page.load(); + assert.equal(page.data.phase, "auth-error"); + assert.equal(page.data.ready, false); + assert.equal(calls, 0); + await page.load(); + assert.equal(page.data.ready, true); + assert.equal(page.data.error, ""); +}); + +test("首页请求失败不显示空数据状态,刷新失败保留已有记录", async () => { + let fail = true; + const page = home( + async () => "token", + (path) => (fail ? Promise.reject(new Error("网络异常")) : data(path)), + ); + await page.load(); + assert.equal(page.data.phase, "data-error"); + assert.equal(page.data.ready, false); + fail = false; + await page.load(); + assert.equal(page.data.ready, true); + page.setData({ pets: [{ id: "existing" }] }); + fail = true; + await page.load(); + assert.equal(page.data.ready, true); + assert.equal(page.data.pets[0].id, "existing"); + assert.equal(page.data.error, "网络异常"); +}); -- 2.54.0 From f0ee63e642f526def70e475d172b994ba7b99bee Mon Sep 17 00:00:00 2001 From: Blizzard Date: Mon, 5 Oct 2026 11:08:11 +0800 Subject: [PATCH 2/7] Cache home location and weather across page navigation --- pets-fe/pages/home/home.js | 82 +++++++++---------------- pets-fe/utils/environment.js | 85 ++++++++++++++++++++++++++ tests/miniprogram-environment.test.cjs | 84 +++++++++++++++++++++++++ tests/miniprogram-smoke.test.cjs | 3 + tests/miniprogram-startup.test.cjs | 8 ++- 5 files changed, 205 insertions(+), 57 deletions(-) create mode 100644 pets-fe/utils/environment.js create mode 100644 tests/miniprogram-environment.test.cjs diff --git a/pets-fe/pages/home/home.js b/pets-fe/pages/home/home.js index d1b298c..2a9a98f 100644 --- a/pets-fe/pages/home/home.js +++ b/pets-fe/pages/home/home.js @@ -1,5 +1,6 @@ const { secure, toast } = require("../../utils/api"); const { localDate } = require("../../utils/date"); +const environment = require("../../utils/environment"); function dateLabel() { const now = new Date(); return `${now.getMonth() + 1}月${now.getDate()}日 周${"日一二三四五六"[now.getDay()]}`; @@ -19,7 +20,7 @@ Page({ error: "", }, onShow() { - this.updateEnvironmentLabel(); + this.applyEnvironment(environment.cached()); this.load(); }, onUnload() { @@ -31,62 +32,40 @@ Page({ dateLabel() + " · " + (this.weatherLabel || "轻触获取天气"), }); }, + applyEnvironment(value) { + if (this.disposed) return; + if (value) { + this.weatherLabel = value.weatherLabel; + this.setData({ locationName: value.locationName }); + } + this.updateEnvironmentLabel(); + }, async refreshEnvironment(event) { if (this.environmentBusy) return; this.environmentBusy = true; const tapped = !!event; - let positioned = false; - try { - const settings = await new Promise((resolve, reject) => - wx.getSetting({ success: resolve, fail: reject }), - ); - if (settings.authSetting["scope.userLocation"] === false) { - if (!tapped) throw new Error("location-denied"); - const enabled = await new Promise((resolve, reject) => - wx.openSetting({ success: resolve, fail: reject }), - ); - if (!enabled.authSetting["scope.userLocation"]) - throw new Error("location-denied"); - } + const cached = environment.cached(); + if (!cached) { this.weatherLabel = "正在获取天气"; this.updateEnvironmentLabel(); - const point = await new Promise((resolve, reject) => - wx.getLocation({ - type: "gcj02", - success: resolve, - fail: reject, - }), - ); - positioned = true; - const result = await secure("/environment", "GET", { - latitude: point.latitude, - longitude: point.longitude, - }); - this.setData({ locationName: result.location_name }); - this.weatherLabel = result.weather - ? `${result.weather.description} ${result.weather.temperature}°C` - : "天气暂不可用"; - this.environmentAt = result.weather ? Date.now() : 0; + } + try { + this.applyEnvironment(await environment.refresh(tapped)); } catch (error) { - const denied = /denied|deny|auth/.test( - error.errMsg || error.message || "", - ); - this.setData({ - locationName: positioned - ? "位置暂不可用" - : denied - ? "开启定位" - : "定位暂不可用", - }); - this.weatherLabel = denied ? "轻触开启定位" : "轻触重试"; - if (tapped && !denied) - wx.showToast({ - title: positioned ? "位置和天气获取失败,请重试" : "定位失败,请重试", - icon: "none", - }); + if (this.disposed) return; + if (cached) { + this.applyEnvironment(cached); + } else { + const denied = /denied|deny|auth/.test( + error.errMsg || error.message || "", + ); + this.setData({ locationName: denied ? "开启定位" : "定位暂不可用" }); + this.weatherLabel = denied ? "轻触开启定位" : "轻触重试"; + this.updateEnvironmentLabel(); + } + if (tapped) toast(error); } finally { this.environmentBusy = false; - this.updateEnvironmentLabel(); } }, async load() { @@ -129,12 +108,7 @@ Page({ phase: "ready", }); // Location permission and weather never hold up the first usable screen. - if ( - !this.environmentAt || - Date.now() - this.environmentAt > 15 * 60 * 1000 - ) { - this.refreshEnvironment(); - } + this.refreshEnvironment(); } catch (error) { if (this.disposed) return; this.setData({ diff --git a/pets-fe/utils/environment.js b/pets-fe/utils/environment.js new file mode 100644 index 0000000..7a6cedc --- /dev/null +++ b/pets-fe/utils/environment.js @@ -0,0 +1,85 @@ +const { secure } = require("./api"); + +const STORAGE_KEY = "pet_environment_v1"; +let value; +let attempted = false; +let pending; +let failure; + +function cached() { + if (value === undefined) { + const saved = wx.getStorageSync(STORAGE_KEY); + value = + saved && + typeof saved.locationName === "string" && + typeof saved.weatherLabel === "string" && + Number.isFinite(saved.updatedAt) + ? saved + : null; + } + return value; +} + +async function fetchEnvironment(tapped) { + const settings = await new Promise((resolve, reject) => + wx.getSetting({ success: resolve, fail: reject }), + ); + if (settings.authSetting["scope.userLocation"] === false) { + if (!tapped) throw new Error("location-denied"); + const enabled = await new Promise((resolve, reject) => + wx.openSetting({ success: resolve, fail: reject }), + ); + if (!enabled.authSetting["scope.userLocation"]) + throw new Error("location-denied"); + } + const point = await new Promise((resolve, reject) => + wx.getLocation({ type: "gcj02", success: resolve, fail: reject }), + ); + const result = await secure("/environment", "GET", { + latitude: point.latitude, + longitude: point.longitude, + }); + if (!result || !result.location_name) + throw new Error("位置和天气获取失败,请重试"); + const previous = cached(); + value = { + locationName: result.location_name, + weatherLabel: result.weather + ? `${result.weather.description} ${result.weather.temperature}°C` + : previous && previous.locationName === result.location_name + ? previous.weatherLabel + : "天气暂不可用", + updatedAt: Date.now(), + }; + // Store display data only; precise coordinates are not persisted here. + try { + wx.setStorageSync(STORAGE_KEY, value); + } catch (_) {} + return value; +} + +function refresh(tapped = false) { + if (pending) return pending; + // Module lifetime follows the app, including recreated pages and warm resumes. + // Failed automatic attempts also wait for a tap or the next cold start. + if (attempted && !tapped) + return failure ? Promise.reject(failure) : Promise.resolve(cached()); + attempted = true; + pending = fetchEnvironment(tapped) + .then( + (result) => { + failure = null; + return result; + }, + (error) => { + failure = error; + throw error; + }, + ) + .finally(() => { + pending = null; + }); + return pending; +} + +module.exports = { cached, refresh }; diff --git a/tests/miniprogram-environment.test.cjs b/tests/miniprogram-environment.test.cjs new file mode 100644 index 0000000..afd7ab8 --- /dev/null +++ b/tests/miniprogram-environment.test.cjs @@ -0,0 +1,84 @@ +const test = require("node:test"); +const assert = require("node:assert/strict"); +const fs = require("node:fs"); +const vm = require("node:vm"); + +function runtime(storage = new Map()) { + const counts = { location: 0, request: 0 }; + let fail = false; + let release; + const module = { exports: {} }; + vm.runInNewContext(fs.readFileSync("pets-fe/utils/environment.js", "utf8"), { + module, + wx: { + getStorageSync: (key) => storage.get(key), + setStorageSync: (key, value) => storage.set(key, value), + getSetting: (opts) => opts.success({ authSetting: {} }), + getLocation: (opts) => { + counts.location++; + opts.success({ latitude: 25, longitude: 102 }); + }, + }, + require: () => ({ + secure: async () => { + counts.request++; + if (fail) throw new Error("offline"); + if (release) await release; + return { + location_name: "昆明市 · 五华区", + weather: { description: "晴", temperature: "22" }, + }; + }, + }), + }); + return { + api: module.exports, + counts, + storage, + fail: () => { + fail = true; + }, + hold: (promise) => { + release = promise; + }, + }; +} + +test("页面重建与返回复用同一轮天气请求,点击可以刷新", async () => { + const r = runtime(); + let finish; + r.hold( + new Promise((resolve) => { + finish = resolve; + }), + ); + const first = r.api.refresh(); + assert.equal(r.api.refresh(), first); + finish(); + await first; + await r.api.refresh(); + await r.api.refresh(); + assert.equal(r.counts.location, 1); + assert.equal(r.counts.request, 1); + await r.api.refresh(true); + assert.equal(r.counts.request, 2); + assert.equal(r.api.cached().weatherLabel, "晴 22°C"); + const saved = r.storage.get("pet_environment_v1"); + assert.equal("latitude" in saved, false); + assert.equal("longitude" in saved, false); +}); + +test("冷启动先读取上次缓存,再请求一次;失败保留缓存且不会返回就重试", async () => { + const previous = runtime(); + await previous.api.refresh(); + const next = runtime(previous.storage); + assert.equal(next.api.cached().locationName, "昆明市 · 五华区"); + assert.equal(next.counts.request, 0); + next.fail(); + await assert.rejects(next.api.refresh(), /offline/); + await assert.rejects(next.api.refresh(), /offline/); + assert.equal(next.counts.request, 1); + assert.equal(next.api.cached().weatherLabel, "晴 22°C"); + await assert.rejects(next.api.refresh(true), /offline/); + assert.equal(next.counts.request, 2); +}); diff --git a/tests/miniprogram-smoke.test.cjs b/tests/miniprogram-smoke.test.cjs index 7d342a4..34bfec5 100644 --- a/tests/miniprogram-smoke.test.cjs +++ b/tests/miniprogram-smoke.test.cjs @@ -5,6 +5,9 @@ const path = require("node:path"); const apiPath = require.resolve("../pets-fe/utils/api"); function page(name, secure, wx = {}) { + // Each test represents a fresh app session; page navigation within a test + // still shares the environment module. + delete require.cache[require.resolve("../pets-fe/utils/environment")]; global.wx = { getStorageSync: () => [], setStorageSync: () => {}, diff --git a/tests/miniprogram-startup.test.cjs b/tests/miniprogram-startup.test.cjs index 03b7bb0..7edbd5a 100644 --- a/tests/miniprogram-startup.test.cjs +++ b/tests/miniprogram-startup.test.cjs @@ -99,9 +99,11 @@ function home(login, secure) { definition = value; }, require: (name) => - name.includes("date") - ? { localDate: () => "2026-10-05" } - : { secure, toast: () => {} }, + name.includes("environment") + ? { cached: () => null } + : name.includes("date") + ? { localDate: () => "2026-10-05" } + : { secure, toast: () => {} }, }); const page = { ...definition, -- 2.54.0 From cb4ffa13e97e56878e2775ed4dd92ffca5ba6889 Mon Sep 17 00:00:00 2001 From: Blizzard Date: Mon, 5 Oct 2026 11:32:32 +0800 Subject: [PATCH 3/7] Add one-way task completion and exportable pet identity cards --- pets-be/internal/httpapi/server.go | 1 + pets-be/internal/httpapi/tasks.go | 86 +++++++-- pets-be/internal/httpapi/tasks_test.go | 91 ++++++++++ pets-fe/app.wxss | 43 ++++- pets-fe/components/pet-id-card/index.js | 42 +++++ pets-fe/components/pet-id-card/index.json | 4 + pets-fe/components/pet-id-card/index.wxml | 10 ++ pets-fe/components/pet-id-card/index.wxss | 164 +++++++++++++++++ pets-fe/pages/home/home.js | 27 +-- pets-fe/pages/home/home.wxml | 11 +- pets-fe/pages/pet-edit/pet-edit.wxss | 22 +++ pets-fe/pages/pets/pets.js | 2 +- pets-fe/pages/pets/pets.json | 3 +- pets-fe/pages/pets/pets.wxml | 26 +-- pets-fe/pages/pets/pets.wxss | 37 ---- pets-fe/pages/tasks/tasks.js | 48 +++-- pets-fe/pages/tasks/tasks.wxml | 11 +- pets-fe/utils/pet-card.js | 207 ++++++++++++++++++++++ pets-fe/utils/task-completion.js | 73 ++++++++ tests/miniprogram-completion.test.cjs | 104 +++++++++++ tests/miniprogram-pet-card.test.cjs | 104 +++++++++++ 21 files changed, 999 insertions(+), 117 deletions(-) create mode 100644 pets-be/internal/httpapi/tasks_test.go create mode 100644 pets-fe/components/pet-id-card/index.js create mode 100644 pets-fe/components/pet-id-card/index.json create mode 100644 pets-fe/components/pet-id-card/index.wxml create mode 100644 pets-fe/components/pet-id-card/index.wxss create mode 100644 pets-fe/utils/pet-card.js create mode 100644 pets-fe/utils/task-completion.js create mode 100644 tests/miniprogram-completion.test.cjs create mode 100644 tests/miniprogram-pet-card.test.cjs diff --git a/pets-be/internal/httpapi/server.go b/pets-be/internal/httpapi/server.go index 005bd8e..ffd253c 100644 --- a/pets-be/internal/httpapi/server.go +++ b/pets-be/internal/httpapi/server.go @@ -54,6 +54,7 @@ func (a *API) Register(r *gin.Engine) { user.PUT("/tasks/:id", a.updateTask) user.DELETE("/tasks/:id", a.deleteTask) user.PUT("/tasks/:id/completion", a.setTaskCompletion) + user.PUT("/tasks/completions", a.completeTasks) user.GET("/walks", a.listWalks) user.POST("/walks", a.startWalk) user.GET("/walks/:id", a.getWalk) diff --git a/pets-be/internal/httpapi/tasks.go b/pets-be/internal/httpapi/tasks.go index 0cf2bfe..226483a 100644 --- a/pets-be/internal/httpapi/tasks.go +++ b/pets-be/internal/httpapi/tasks.go @@ -8,6 +8,7 @@ import ( "github.com/gin-gonic/gin" "gorm.io/gorm" + "gorm.io/gorm/clause" "github.com/sundynix/pets-be/internal/model" ) @@ -179,11 +180,6 @@ func (a *API) deleteTask(c *gin.Context) { } func (a *API) setTaskCompletion(c *gin.Context) { - var task model.CareTask - if !validID(c.Param("id")) || a.db.Where("id = ? AND user_id = ?", c.Param("id"), actor(c)).First(&task).Error != nil { - fail(c, http.StatusNotFound, "任务不存在") - return - } var in struct { Date string `json:"date" binding:"required"` Completed bool `json:"completed"` @@ -192,20 +188,82 @@ func (a *API) setTaskCompletion(c *gin.Context) { fail(c, http.StatusBadRequest, "完成状态参数无效") return } + if !in.Completed { + fail(c, http.StatusBadRequest, "已完成的任务不能取消完成") + return + } + var task model.CareTask + if !validID(c.Param("id")) || a.db.Where("id = ? AND user_id = ?", c.Param("id"), actor(c)).First(&task).Error != nil { + fail(c, http.StatusNotFound, "任务不存在") + return + } date, err := parseDay(in.Date) if err != nil || !due(task, date) { fail(c, http.StatusBadRequest, "该日期没有这项任务") return } - if in.Completed { - item := model.TaskCompletion{TaskID: task.ID, UserID: actor(c), Date: date, CompletedAt: time.Now()} - if err := a.db.Where("task_id = ? AND date = ?", task.ID, date).FirstOrCreate(&item).Error; err != nil { - fail(c, http.StatusInternalServerError, "保存完成状态失败") - return - } - } else if err := a.db.Where("task_id = ? AND date = ?", task.ID, date).Delete(&model.TaskCompletion{}).Error; err != nil { - fail(c, http.StatusInternalServerError, "取消完成失败") + item := model.TaskCompletion{TaskID: task.ID, UserID: actor(c), Date: date, CompletedAt: time.Now()} + if err := a.db.Clauses(clause.OnConflict{Columns: []clause.Column{{Name: "task_id"}, {Name: "date"}}, DoNothing: true}).Create(&item).Error; err != nil { + fail(c, http.StatusInternalServerError, "保存完成状态失败") return } - ok(c, gin.H{"id": task.ID, "date": in.Date, "completed": in.Completed}) + ok(c, gin.H{"id": task.ID, "date": in.Date, "completed": true}) +} + +// Complete the displayed tasks atomically, allowing safe retries and concurrent taps. +func (a *API) completeTasks(c *gin.Context) { + var in struct { + Date string `json:"date" binding:"required"` + TaskIDs []string `json:"task_ids" binding:"required,min=1,max=200"` + } + if c.ShouldBindJSON(&in) != nil { + fail(c, http.StatusBadRequest, "请选择 1 至 200 项任务") + return + } + date, err := parseDay(in.Date) + if err != nil { + fail(c, http.StatusBadRequest, "日期格式应为 YYYY-MM-DD") + return + } + ids := make([]string, 0, len(in.TaskIDs)) + seen := map[string]bool{} + for _, id := range in.TaskIDs { + if !validID(id) { + fail(c, http.StatusBadRequest, "任务 ID 无效") + return + } + if !seen[id] { + ids = append(ids, id) + seen[id] = true + } + } + invalid := false + err = a.db.Transaction(func(tx *gorm.DB) error { + var tasks []model.CareTask + if err := tx.Clauses(clause.Locking{Strength: "UPDATE"}).Where("id IN ? AND user_id = ?", ids, actor(c)).Order("id").Find(&tasks).Error; err != nil { + return err + } + if len(tasks) != len(ids) { + invalid = true + return gorm.ErrRecordNotFound + } + items := make([]model.TaskCompletion, 0, len(tasks)) + for _, task := range tasks { + if !due(task, date) { + invalid = true + return gorm.ErrRecordNotFound + } + items = append(items, model.TaskCompletion{TaskID: task.ID, UserID: actor(c), Date: date, CompletedAt: time.Now()}) + } + return tx.Clauses(clause.OnConflict{Columns: []clause.Column{{Name: "task_id"}, {Name: "date"}}, DoNothing: true}).Create(&items).Error + }) + if err != nil { + if invalid { + fail(c, http.StatusBadRequest, "包含不存在或该日期无需完成的任务") + } else { + fail(c, http.StatusInternalServerError, "完成任务失败,请重试") + } + return + } + ok(c, gin.H{"task_ids": ids, "date": in.Date, "completed": true}) } diff --git a/pets-be/internal/httpapi/tasks_test.go b/pets-be/internal/httpapi/tasks_test.go new file mode 100644 index 0000000..6813d78 --- /dev/null +++ b/pets-be/internal/httpapi/tasks_test.go @@ -0,0 +1,91 @@ +package httpapi + +import ( + "bytes" + "encoding/json" + "net/http" + "net/http/httptest" + "os" + "testing" + + "github.com/gin-gonic/gin" + "github.com/google/uuid" + "github.com/sundynix/pets-be/internal/config" + "github.com/sundynix/pets-be/internal/database" + "github.com/sundynix/pets-be/internal/model" +) + +func TestTaskCompletionCannotBeUndone(t *testing.T) { + gin.SetMode(gin.TestMode) + rec := httptest.NewRecorder() + c, _ := gin.CreateTestContext(rec) + c.Request = httptest.NewRequest(http.MethodPut, "/completion", bytes.NewBufferString(`{"date":"2026-10-05","completed":false}`)) + api := New(nil, nil, &config.Config{}) + api.setTaskCompletion(c) + if rec.Code != http.StatusBadRequest { + t.Fatalf("undo status %d", rec.Code) + } +} + +// All fixtures and writes are rolled back, including inner batch transactions. +func TestTaskCompletionPostgres(t *testing.T) { + if os.Getenv("PETS_ADMIN_INTEGRATION") != "1" { + t.Skip("PostgreSQL integration disabled") + } + cfg, err := config.Load() + if err != nil { + t.Fatal(err) + } + db, err := database.Open(cfg.Postgres, true) + if err != nil { + t.Fatal(err) + } + sqlDB, _ := db.DB() + defer sqlDB.Close() + tx := db.Begin() + if tx.Error != nil { + t.Fatal(tx.Error) + } + defer tx.Rollback() + user := model.User{OpenID: "completion-test:" + uuid.NewString(), Nickname: "测试家长"} + if err := tx.Create(&user).Error; err != nil { + t.Fatal(err) + } + pet := model.Pet{UserID: user.ID, Name: "测试毛孩", Species: "dog", Gender: "male"} + if err := tx.Create(&pet).Error; err != nil { + t.Fatal(err) + } + tasks := []model.CareTask{{UserID: user.ID, PetID: pet.ID, Title: "喝水", Category: "water", TimeOfDay: "08:00", RepeatRule: "daily"}, {UserID: user.ID, PetID: pet.ID, Title: "喂食", Category: "food", TimeOfDay: "09:00", RepeatRule: "daily"}} + if err := tx.Create(&tasks).Error; err != nil { + t.Fatal(err) + } + api := New(tx, nil, cfg) + call := func(ids []string) int { + t.Helper() + body, _ := json.Marshal(gin.H{"date": "2026-10-05", "task_ids": ids}) + rec := httptest.NewRecorder() + c, _ := gin.CreateTestContext(rec) + c.Set("actor_id", user.ID) + c.Request = httptest.NewRequest(http.MethodPut, "/tasks/completions", bytes.NewReader(body)) + api.completeTasks(c) + return rec.Code + } + if status := call([]string{tasks[0].ID, uuid.NewString()}); status != 400 { + t.Fatalf("invalid batch status %d", status) + } + var count int64 + tx.Model(&model.TaskCompletion{}).Where("user_id = ?", user.ID).Count(&count) + if count != 0 { + t.Fatal("invalid batch partially completed") + } + ids := []string{tasks[0].ID, tasks[1].ID} + for range 2 { + if status := call(ids); status != 200 { + t.Fatalf("batch status %d", status) + } + } + tx.Model(&model.TaskCompletion{}).Where("user_id = ?", user.ID).Count(&count) + if count != 2 { + t.Fatalf("retry duplicated completions: %d", count) + } +} diff --git a/pets-fe/app.wxss b/pets-fe/app.wxss index dcb90c1..7d4ed68 100644 --- a/pets-fe/app.wxss +++ b/pets-fe/app.wxss @@ -3,7 +3,8 @@ page { overflow: hidden; background: #fff9f3; color: #604a40; - font-family: ui-rounded, "Hiragino Maru Gothic ProN", "PingFang SC", sans-serif; + font-family: + ui-rounded, "Hiragino Maru Gothic ProN", "PingFang SC", sans-serif; font-size: 28rpx; line-height: 1.5; } @@ -112,3 +113,43 @@ button::after { .field textarea { height: 170rpx; } + +.completion-toolbar { + display: flex; + align-items: center; + justify-content: space-between; + gap: 18rpx; + margin: 8rpx 0 20rpx; + font-size: 23rpx; + color: #886c5f; +} +.finish-all { + margin: 0; + padding: 12rpx 22rpx; + background: #fff0e2; + color: #b95738; + font-size: 24rpx; + line-height: 1.4; + border-radius: 99rpx; +} +.all-done { + color: #b95738; +} +.task-completed .check { + animation: completion-pop 0.35s ease-out; +} +.task-completed .task-name, +.task-completed .info strong { + color: #9d8779; +} +@keyframes completion-pop { + 0% { + transform: scale(0.7); + } + 60% { + transform: scale(1.18); + } + 100% { + transform: scale(1); + } +} diff --git a/pets-fe/components/pet-id-card/index.js b/pets-fe/components/pet-id-card/index.js new file mode 100644 index 0000000..a7f8ab2 --- /dev/null +++ b/pets-fe/components/pet-id-card/index.js @@ -0,0 +1,42 @@ +const { profile, renderCard, saveToAlbum } = require("../../utils/pet-card"); +const { toast } = require("../../utils/api"); +Component({ + properties: { pet: { type: Object, value: {} } }, + data: { card: {}, saving: false }, + observers: { + pet(value) { + this.setData({ card: profile(value || {}) }); + }, + }, + methods: { + edit() { + this.triggerEvent("edit", { id: this.data.pet.id }); + }, + async generate() { + const canvas = await new Promise((resolve, reject) => + this.createSelectorQuery() + .select("#card-canvas") + .fields({ node: true, size: true }) + .exec((result) => + result[0] && result[0].node + ? resolve(result[0].node) + : reject(new Error("卡片还未准备好,请重试")), + ), + ); + return renderCard(canvas, this.data.pet); + }, + async save() { + if (this.data.saving) return; + this.setData({ saving: true }); + try { + const path = await this.generate(); + if (await saveToAlbum(path)) + wx.showToast({ title: "身份卡已保存到相册", icon: "success" }); + } catch (error) { + toast(error); + } finally { + this.setData({ saving: false }); + } + }, + }, +}); diff --git a/pets-fe/components/pet-id-card/index.json b/pets-fe/components/pet-id-card/index.json new file mode 100644 index 0000000..9173e85 --- /dev/null +++ b/pets-fe/components/pet-id-card/index.json @@ -0,0 +1,4 @@ +{ + "component": true, + "usingComponents": { "app-icon": "/components/app-icon/index" } +} diff --git a/pets-fe/components/pet-id-card/index.wxml b/pets-fe/components/pet-id-card/index.wxml new file mode 100644 index 0000000..dc1c817 --- /dev/null +++ b/pets-fe/components/pet-id-card/index.wxml @@ -0,0 +1,10 @@ + + 肉垫计划PAWPRINT ID毛孩身份卡 + + + {{card.name}}{{card.breed||'品种未填写'}} · {{card.genderLabel}}生日{{card.birthday}}体重{{card.weightLabel}}毛色{{card.coat||'未填写'}} + + 陪伴编号{{card.cardNumber}}把陪伴,认真记下来 + + + diff --git a/pets-fe/components/pet-id-card/index.wxss b/pets-fe/components/pet-id-card/index.wxss new file mode 100644 index 0000000..f0f2a1e --- /dev/null +++ b/pets-fe/components/pet-id-card/index.wxss @@ -0,0 +1,164 @@ +:host { + display: block; + margin-bottom: 30rpx; +} +.identity { + position: relative; + overflow: hidden; + border-radius: 28rpx; + border: 1rpx solid #ead8ca; + padding: 25rpx; + background: linear-gradient(125deg, #fff3e5, #f0e9f8); + box-shadow: 0 14rpx 35rpx #79543a0b; + color: #604a40; +} +.id-top { + display: flex; + align-items: center; + justify-content: space-between; + padding-bottom: 20rpx; + border-bottom: 1rpx solid #dfcdbf; +} +.brand { + display: flex; + gap: 9rpx; + align-items: center; +} +.brand image { + width: 44rpx; + height: 44rpx; +} +.brand-name, +.brand-en { + display: block; +} +.brand-name { + font-size: 18rpx; + font-weight: 600; + color: #795a4b; +} +.brand-en { + font-size: 11rpx; + letter-spacing: 2rpx; + color: #a48d7e; +} +.id-title { + font-size: 23rpx; + letter-spacing: 3rpx; + font-weight: 600; +} +.id-body { + display: flex; + gap: 24rpx; + padding: 24rpx 0; +} +.portrait { + width: 166rpx; + height: 180rpx; + flex: none; + border: 6rpx solid #fffaf4; + border-radius: 18rpx; + overflow: hidden; + background: #fffaf4; + display: flex; + align-items: center; + justify-content: center; +} +.portrait image { + width: 100%; + height: 100%; +} +.details { + flex: 1; + min-width: 0; +} +.pet-name { + display: block; + font-size: 34rpx; + font-weight: 600; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.breed { + display: block; + font-size: 21rpx; + color: #886c5f; + margin: 2rpx 0 12rpx; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.facts { + display: flex; + gap: 22rpx; +} +.facts > view { + flex: 1; + min-width: 0; +} +.label { + display: block; + font-size: 17rpx; + color: #a48d7e; +} +.value { + display: block; + font-size: 21rpx; + font-weight: 500; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.coat { + margin-top: 9rpx; +} +.id-bottom { + border-top: 1rpx solid #dfcdbf; + padding-top: 15rpx; + display: flex; + align-items: flex-end; + justify-content: space-between; + gap: 10rpx; +} +.number { + display: block; + font-size: 18rpx; + letter-spacing: 1rpx; + color: #795a4b; +} +.motto { + font-size: 16rpx; + color: #886c5f; + max-width: 200rpx; + text-align: right; +} +.card-actions { + display: flex; + justify-content: flex-end; + gap: 16rpx; + margin-top: 12rpx; +} +.card-actions button { + margin: 0; + padding: 9rpx 20rpx; + border: 1rpx solid #ead8ca; + border-radius: 99rpx; + background: #fffaf4; + color: #886c5f; + font-size: 22rpx; + line-height: 1.5; +} +.card-actions .save { + background: #fff0e2; + color: #b95738; + border-color: #f1d6c4; +} +.export-canvas { + position: fixed; + left: -2000px; + top: 0; + width: 600px; + height: 380px; + pointer-events: none; +} diff --git a/pets-fe/pages/home/home.js b/pets-fe/pages/home/home.js index 2a9a98f..65b4190 100644 --- a/pets-fe/pages/home/home.js +++ b/pets-fe/pages/home/home.js @@ -1,4 +1,5 @@ -const { secure, toast } = require("../../utils/api"); +const completion = require("../../utils/task-completion"); +const { secure } = require("../../utils/api"); const { localDate } = require("../../utils/date"); const environment = require("../../utils/environment"); function dateLabel() { @@ -12,6 +13,9 @@ Page({ pets: [], selected: [], tasks: [], + taskBusyIds: [], + completingAll: false, + undoneCount: 0, walkCount: 0, name: "铲屎官", loading: true, @@ -100,6 +104,7 @@ Page({ pets, selected: chosen.filter((id) => pets.some((p) => p.id === id)), tasks: tasks.items, + undoneCount: tasks.items.filter((t) => !t.completed).length, walkCount: walks.filter((w) => w.started_at.slice(0, 7) === month) .length, name: me.nickname || "毛孩家长", @@ -138,17 +143,13 @@ Page({ goWalks() { wx.navigateTo({ url: "/pages/walk-records/walk-records" }); }, - async complete(e) { - const id = e.currentTarget.dataset.id, - task = this.data.tasks.find((t) => t.id === id); - try { - await secure("/tasks/" + id + "/completion", "PUT", { - date: localDate(), - completed: !task.completed, - }); - await this.load(); - } catch (err) { - toast(err); - } + complete(e) { + return completion.complete( + this, + this.data.tasks.find((t) => t.id === e.currentTarget.dataset.id), + ); + }, + completeAll() { + return completion.completeAll(this); }, }); diff --git a/pets-fe/pages/home/home.wxml b/pets-fe/pages/home/home.wxml index 9acbdb1..c3cffff 100644 --- a/pets-fe/pages/home/home.wxml +++ b/pets-fe/pages/home/home.wxml @@ -70,23 +70,28 @@ 今天要做的事 全部任务 › + + {{undoneCount ? '还有 '+undoneCount+' 项小事' : '这一份日常,已全部照顾好'}} + + 全部完成 + - {{item.completed?'✓':''}} + {{item.completed?'✓':taskBusyIds[0]===item.id?'…':''}} {{item.title}} - {{item.time_of_day}} + {{item.time_of_day}} · {{item.completed?'已完成':taskBusyIds[0]===item.id?'正在记录…':'点击完成'}} diff --git a/pets-fe/pages/pet-edit/pet-edit.wxss b/pets-fe/pages/pet-edit/pet-edit.wxss index 3c90e94..5ef0497 100644 --- a/pets-fe/pages/pet-edit/pet-edit.wxss +++ b/pets-fe/pages/pet-edit/pet-edit.wxss @@ -48,3 +48,25 @@ font-size: 24rpx; margin-top: 20rpx; } + +.field input { + height: 104rpx; + min-height: 104rpx; + padding: 0 26rpx; + line-height: normal; +} +.picker { + min-height: 104rpx; + padding: 30rpx 26rpx; +} +.field radio-group { + min-height: 104rpx; + padding: 26rpx; +} +.field textarea { + height: 210rpx; + padding: 26rpx; +} +.field { + margin: 28rpx 0; +} diff --git a/pets-fe/pages/pets/pets.js b/pets-fe/pages/pets/pets.js index f1738ce..af8fae1 100644 --- a/pets-fe/pages/pets/pets.js +++ b/pets-fe/pages/pets/pets.js @@ -16,7 +16,7 @@ Page({ }, edit(e) { wx.navigateTo({ - url: "/pages/pet-edit/pet-edit?id=" + e.currentTarget.dataset.id, + url: "/pages/pet-edit/pet-edit?id=" + e.detail.id, }); }, }); diff --git a/pets-fe/pages/pets/pets.json b/pets-fe/pages/pets/pets.json index e2b624a..b1a77fb 100644 --- a/pets-fe/pages/pets/pets.json +++ b/pets-fe/pages/pets/pets.json @@ -1,6 +1,7 @@ { "disableScroll": true, "usingComponents": { - "tab-bar": "/components/tab-bar/index" + "tab-bar": "/components/tab-bar/index", + "pet-id-card": "/components/pet-id-card/index" } } diff --git a/pets-fe/pages/pets/pets.wxml b/pets-fe/pages/pets/pets.wxml index 96d6659..bb4af51 100644 --- a/pets-fe/pages/pets/pets.wxml +++ b/pets-fe/pages/pets/pets.wxml @@ -11,31 +11,7 @@ 宠物档案 · {{pets.length}} + 添加 - - - - - - - {{item.name}} - - {{item.breed||'小可爱'}} · - {{item.gender==='male'?'男孩':item.gender==='female'?'女孩':'未知'}} - - 体重 {{item.weight_kg||'—'}} kg - - › - + 给第一只狗狗建个档案吧 diff --git a/pets-fe/pages/pets/pets.wxss b/pets-fe/pages/pets/pets.wxss index b1ab14d..4ee1e29 100644 --- a/pets-fe/pages/pets/pets.wxss +++ b/pets-fe/pages/pets/pets.wxss @@ -33,43 +33,6 @@ font-weight: 600; color: #b95738; } -.pet { - display: flex; - align-items: center; - gap: 22rpx; -} -.pet-avatar { - width: 125rpx; - height: 125rpx; - flex: none; - border-radius: 28rpx; - background: #f1d2a3; - display: grid; - place-items: center; - font-size: 63rpx; - overflow: hidden; -} -.pet-avatar image { - width: 100%; - height: 100%; -} -.pet-info { - display: flex; - flex-direction: column; - gap: 6rpx; - flex: 1; -} -.pet-info strong { - font-size: 32rpx; -} -.pet-info text { - font-size: 23rpx; - color: #886c5f; -} -.arrow { - font-size: 42rpx; - color: #886c5f; -} .add-button { margin-top: 25rpx; } diff --git a/pets-fe/pages/tasks/tasks.js b/pets-fe/pages/tasks/tasks.js index 3aad5ac..7d54472 100644 --- a/pets-fe/pages/tasks/tasks.js +++ b/pets-fe/pages/tasks/tasks.js @@ -1,9 +1,13 @@ +const completion = require("../../utils/task-completion"); const { secure, toast } = require("../../utils/api"); const { localDate, shiftDate } = require("../../utils/date"); Page({ data: { pets: [], tasks: [], + taskBusyIds: [], + completingAll: false, + undoneCount: 0, date: localDate(), showForm: false, editingId: "", @@ -33,23 +37,21 @@ Page({ this.setData({ pets, tasks, + undoneCount: tasks.filter((t) => !t.completed).length, done: tasks.filter((t) => t.completed).length, }); } catch (e) { toast(e); } }, - async toggle(e) { - const t = this.data.tasks[e.currentTarget.dataset.index]; - try { - await secure("/tasks/" + t.id + "/completion", "PUT", { - date: this.data.date, - completed: !t.completed, - }); - await this.load(); - } catch (err) { - toast(err); - } + toggle(e) { + return completion.complete( + this, + this.data.tasks[e.currentTarget.dataset.index], + ); + }, + completeAll() { + return completion.completeAll(this); }, open() { if (!this.data.pets.length) { @@ -83,10 +85,14 @@ Page({ }); }, changeDay(e) { - this.setData({ date: shiftDate(this.data.date, Number(e.currentTarget.dataset.days)) }); + if (this.data.completingAll || this.data.taskBusyIds.length) return; + this.setData({ + date: shiftDate(this.data.date, Number(e.currentTarget.dataset.days)), + }); this.load(); }, showToday() { + if (this.data.completingAll || this.data.taskBusyIds.length) return; this.setData({ date: localDate() }); this.load(); }, @@ -113,13 +119,17 @@ Page({ } this.setData({ saving: true }); try { - await secure(this.data.editingId ? "/tasks/" + this.data.editingId : "/tasks", this.data.editingId ? "PUT" : "POST", { - pet_id: this.data.pets[this.data.petIndex].id, - title: this.data.title.trim(), - category: this.data.category, - time_of_day: this.data.time_of_day, - repeat_rule: this.data.repeat_rule, - }); + await secure( + this.data.editingId ? "/tasks/" + this.data.editingId : "/tasks", + this.data.editingId ? "PUT" : "POST", + { + pet_id: this.data.pets[this.data.petIndex].id, + title: this.data.title.trim(), + category: this.data.category, + time_of_day: this.data.time_of_day, + repeat_rule: this.data.repeat_rule, + }, + ); this.setData({ showForm: false, editingId: "" }); await this.load(); } catch (e) { diff --git a/pets-fe/pages/tasks/tasks.wxml b/pets-fe/pages/tasks/tasks.wxml index d92a094..a5c4e47 100644 --- a/pets-fe/pages/tasks/tasks.wxml +++ b/pets-fe/pages/tasks/tasks.wxml @@ -19,14 +19,19 @@ 回到今天 后一天 › + + {{undoneCount ? '还有 '+undoneCount+' 项小事' : '这一份日常,已全部照顾好'}} + + 全部完成 + - + - {{item.completed?'✓':''}} + {{item.completed?'✓':taskBusyIds[0]===item.id?'…':''}} @@ -37,7 +42,7 @@ {{item.petName}} · {{item.time_of_day}} · {{item.repeat_rule==='daily'?'每天':item.repeat_rule==='weekdays'?'工作日':'周末'}} - 点此编辑 + {{item.completed?'已完成 · 点此编辑任务':taskBusyIds[0]===item.id?'正在记录…':'点击左侧完成 · 点此编辑'}} × diff --git a/pets-fe/utils/pet-card.js b/pets-fe/utils/pet-card.js new file mode 100644 index 0000000..7ef0ddf --- /dev/null +++ b/pets-fe/utils/pet-card.js @@ -0,0 +1,207 @@ +function profile(pet) { + return { + ...pet, + genderLabel: + pet.gender === "male" + ? "男孩" + : pet.gender === "female" + ? "女孩" + : "未填写", + birthday: pet.birth_date ? pet.birth_date.slice(0, 10) : "未填写", + weightLabel: pet.weight_kg ? `${pet.weight_kg} kg` : "未填写", + cardNumber: + "PET-" + (pet.id || "").replace(/-/g, "").slice(0, 12).toUpperCase(), + }; +} + +function round(ctx, x, y, w, h, r) { + ctx.beginPath(); + ctx.moveTo(x + r, y); + ctx.arcTo(x + w, y, x + w, y + h, r); + ctx.arcTo(x + w, y + h, x, y + h, r); + ctx.arcTo(x, y + h, x, y, r); + ctx.arcTo(x, y, x + w, y, r); + ctx.closePath(); +} +function text(ctx, value, x, y, size, color, width, bold = false) { + ctx.font = `${bold ? "600 " : ""}${size}px sans-serif`; + ctx.fillStyle = color; + let label = String(value || "未填写"); + if (width && ctx.measureText(label).width > width) { + while (label && ctx.measureText(label + "…").width > width) + label = label.slice(0, -1); + label += "…"; + } + ctx.fillText(label, x, y); +} +function image(canvas, path) { + return new Promise((resolve, reject) => { + const img = canvas.createImage(); + img.onload = () => resolve(img); + img.onerror = () => reject(new Error("照片加载失败,请重试")); + img.src = path; + }); +} +async function renderCard(canvas, pet) { + const p = profile(pet); + canvas.width = 1200; + canvas.height = 760; + const ctx = canvas.getContext("2d"); + ctx.clearRect(0, 0, 1200, 760); + const gradient = ctx.createLinearGradient(0, 0, 1200, 760); + gradient.addColorStop(0, "#fff3e5"); + gradient.addColorStop(1, "#f0e9f8"); + ctx.fillStyle = gradient; + round(ctx, 0, 0, 1200, 760, 48); + ctx.fill(); + ctx.save(); + round(ctx, 0, 0, 1200, 760, 48); + ctx.clip(); + ctx.fillStyle = "#ffffff66"; + ctx.beginPath(); + ctx.arc(1080, 140, 180, 0, Math.PI * 2); + ctx.fill(); + ctx.beginPath(); + ctx.arc(1020, 700, 210, 0, Math.PI * 2); + ctx.fill(); + ctx.restore(); + ctx.strokeStyle = "#e9d6c7"; + ctx.lineWidth = 2; + round(ctx, 20, 20, 1160, 720, 34); + ctx.stroke(); + const logo = await image(canvas, "/assets/logo-corgi-v2.png"); + ctx.drawImage(logo, 54, 52, 70, 70); + text(ctx, "肉垫计划", 140, 82, 27, "#795a4b", 220, true); + text(ctx, "PAWPRINT ID", 140, 113, 18, "#a48d7e", 220); + text(ctx, "毛孩身份卡", 842, 103, 38, "#604a40", 300, true); + ctx.strokeStyle = "#dfcdbf"; + ctx.beginPath(); + ctx.moveTo(54, 155); + ctx.lineTo(1146, 155); + ctx.stroke(); + ctx.fillStyle = "#fffaf4"; + round(ctx, 58, 200, 310, 340, 28); + ctx.fill(); + if (p.avatar_url) { + const info = await new Promise((resolve, reject) => + wx.getImageInfo({ + src: p.avatar_url, + success: resolve, + fail: () => reject(new Error("照片下载失败,请检查网络后重试")), + }), + ); + const photo = await image(canvas, info.path); + ctx.save(); + round(ctx, 70, 212, 286, 316, 20); + ctx.clip(); + // Aspect fill, with a centered crop matching the card's portrait window. + const ratio = 286 / 316; + const sw = Math.min(photo.width, photo.height * ratio), + sh = sw / ratio; + ctx.drawImage( + photo, + (photo.width - sw) / 2, + (photo.height - sh) / 2, + sw, + sh, + 70, + 212, + 286, + 316, + ); + ctx.restore(); + } else { + ctx.fillStyle = "#d18b67"; + ctx.beginPath(); + ctx.ellipse(213, 399, 53, 42, 0, 0, Math.PI * 2); + ctx.fill(); + for (const [x, y, r] of [ + [145, 335, 20], + [188, 309, 22], + [235, 309, 22], + [278, 335, 20], + ]) { + ctx.beginPath(); + ctx.arc(x, y, r, 0, Math.PI * 2); + ctx.fill(); + } + text(ctx, "等待一张可爱照片", 114, 491, 23, "#9b7966", 230); + } + text(ctx, p.name, 410, 250, 58, "#604a40", 700, true); + text( + ctx, + `${p.breed || "品种未填写"} · ${p.genderLabel}`, + 412, + 298, + 28, + "#886c5f", + 700, + ); + const fields = [ + ["生日", p.birthday, 412, 368], + ["体重", p.weightLabel, 805, 368], + ["毛色", p.coat || "未填写", 412, 465], + ]; + for (const [label, value, x, y] of fields) { + text(ctx, label, x, y, 23, "#a48d7e", 290); + text( + ctx, + value, + x, + y + 43, + 31, + "#604a40", + x === 412 && y === 465 ? 680 : 300, + true, + ); + } + ctx.strokeStyle = "#dfcdbf"; + ctx.beginPath(); + ctx.moveTo(54, 585); + ctx.lineTo(1146, 585); + ctx.stroke(); + text(ctx, "陪伴编号", 58, 635, 20, "#a48d7e", 200); + text(ctx, p.cardNumber, 58, 676, 29, "#795a4b", 650, true); + text(ctx, "每一位家人,都值得被好好照顾", 650, 669, 24, "#886c5f", 490); + return new Promise((resolve, reject) => + wx.canvasToTempFilePath({ + canvas, + fileType: "png", + success: (res) => resolve(res.tempFilePath), + fail: () => reject(new Error("档案图片生成失败,请重试")), + }), + ); +} +async function saveToAlbum(filePath) { + try { + await new Promise((resolve, reject) => + wx.saveImageToPhotosAlbum({ filePath, success: resolve, fail: reject }), + ); + } catch (error) { + if (/cancel/.test(error.errMsg || "")) return false; + const settings = await new Promise((resolve, reject) => + wx.getSetting({ success: resolve, fail: reject }), + ); + if (settings.authSetting["scope.writePhotosAlbum"] !== false) + throw new Error("保存失败,请在真机上重试"); + const confirm = await wx.showModal({ + title: "允许保存档案卡", + content: "需要相册权限,将这张毛孩身份卡保存到你的手机。", + confirmText: "去设置", + }); + if (!confirm.confirm) return false; + const enabled = await new Promise((resolve, reject) => + wx.openSetting({ success: resolve, fail: reject }), + ); + if (!enabled.authSetting["scope.writePhotosAlbum"]) return false; + await new Promise((resolve, reject) => + wx.saveImageToPhotosAlbum({ + filePath, + success: resolve, + fail: () => reject(new Error("保存失败,请重试")), + }), + ); + } + return true; +} +module.exports = { profile, renderCard, saveToAlbum }; diff --git a/pets-fe/utils/task-completion.js b/pets-fe/utils/task-completion.js new file mode 100644 index 0000000..730f734 --- /dev/null +++ b/pets-fe/utils/task-completion.js @@ -0,0 +1,73 @@ +const { secure, toast } = require("./api"); +const { localDate } = require("./date"); + +function apply(page, ids) { + const tasks = page.data.tasks.map((task) => + ids.includes(task.id) ? { ...task, completed: true } : task, + ); + page.setData({ + tasks, + done: tasks.filter((t) => t.completed).length, + undoneCount: tasks.filter((t) => !t.completed).length, + }); + if (wx.vibrateShort) wx.vibrateShort({ type: "light", fail() {} }); +} + +async function complete(page, task) { + if ( + !task || + task.completed || + page.data.completingAll || + page.data.taskBusyIds.length + ) + return; + const date = page.data.date || localDate(); + page.setData({ taskBusyIds: [task.id] }); + try { + await secure("/tasks/" + task.id + "/completion", "PUT", { + date, + completed: true, + }); + if (page.data.date && page.data.date !== date) return; + apply(page, [task.id]); + wx.showToast({ title: "照顾好了,记下一份陪伴", icon: "success" }); + } catch (error) { + toast(error); + } finally { + page.setData({ taskBusyIds: [] }); + } +} + +async function completeAll(page) { + if (page.data.completingAll || page.data.taskBusyIds.length) return; + const tasks = page.data.tasks.filter((t) => !t.completed); + if (!tasks.length) return; + const date = page.data.date || localDate(); + page.setData({ completingAll: true }); + try { + const confirmation = await wx.showModal({ + title: "都照顾好了吗?", + content: `将 ${date} 的 ${tasks.length} 项待办记为完成,完成后不能撤销。`, + confirmText: "全部完成", + confirmColor: "#b95738", + }); + if (!confirmation.confirm) return; + // The API accepts bounded batches; avoid partial completion of larger lists. + if (tasks.length > 200) throw new Error("任务较多,请分项完成后再试"); + await secure("/tasks/completions", "PUT", { + date, + task_ids: tasks.map((t) => t.id), + }); + if (page.data.date && page.data.date !== date) return; + apply( + page, + tasks.map((t) => t.id), + ); + wx.showToast({ title: "日常照顾全部完成", icon: "success" }); + } catch (error) { + toast(error); + } finally { + page.setData({ completingAll: false }); + } +} +module.exports = { complete, completeAll }; diff --git a/tests/miniprogram-completion.test.cjs b/tests/miniprogram-completion.test.cjs new file mode 100644 index 0000000..9ca58d3 --- /dev/null +++ b/tests/miniprogram-completion.test.cjs @@ -0,0 +1,104 @@ +const test = require("node:test"); +const assert = require("node:assert/strict"); +const fs = require("node:fs"); +const vm = require("node:vm"); + +function runtime() { + const calls = [], + notices = []; + let confirm = true, + failure = false, + release; + const module = { exports: {} }; + vm.runInNewContext( + fs.readFileSync("pets-fe/utils/task-completion.js", "utf8"), + { + module, + require: (name) => + name.includes("date") + ? { localDate: () => "2026-10-05" } + : { + secure: async (...args) => { + calls.push(args); + if (release) await release; + if (failure) throw new Error("offline"); + }, + toast: (error) => notices.push(error.message), + }, + wx: { + showModal: async () => ({ confirm }), + showToast: (opts) => notices.push(opts.title), + vibrateShort() {}, + }, + }, + ); + const page = { + data: { + tasks: [ + { id: "a", completed: false }, + { id: "b", completed: true }, + ], + taskBusyIds: [], + completingAll: false, + }, + setData(value) { + Object.assign(this.data, value); + }, + }; + return { + api: module.exports, + page, + calls, + notices, + cancel: () => { + confirm = false; + }, + fail: () => { + failure = true; + }, + hold: (p) => { + release = p; + }, + }; +} +test("完成即时更新且不能撤销,快速重复点击只发送一次", async () => { + const r = runtime(); + let release; + r.hold( + new Promise((resolve) => { + release = resolve; + }), + ); + const action = r.api.complete(r.page, r.page.data.tasks[0]); + await r.api.complete(r.page, r.page.data.tasks[0]); + assert.equal(r.calls.length, 1); + release(); + await action; + assert.equal(r.page.data.tasks[0].completed, true); + assert.equal(r.page.data.undoneCount, 0); + await r.api.complete(r.page, r.page.data.tasks[0]); + assert.equal(r.calls.length, 1); + assert.equal(r.calls[0][2].completed, true); +}); +test("一键完成只发送未完成项,确认取消不发送请求", async () => { + const r = runtime(); + r.cancel(); + await r.api.completeAll(r.page); + assert.equal(r.calls.length, 0); + assert.equal(r.page.data.completingAll, false); + const s = runtime(); + await s.api.completeAll(s.page); + assert.equal(s.calls[0][0], "/tasks/completions"); + assert.equal(JSON.stringify(s.calls[0][2].task_ids), '["a"]'); + assert.equal(s.page.data.done, 2); +}); +test("完成请求失败保留待办,释放按钮可重试", async () => { + const r = runtime(); + r.fail(); + await r.api.completeAll(r.page); + assert.equal(r.page.data.tasks[0].completed, false); + assert.equal(r.page.data.completingAll, false); + await r.api.complete(r.page, r.page.data.tasks[0]); + assert.equal(r.page.data.taskBusyIds.length, 0); + assert.equal(r.page.data.tasks[0].completed, false); +}); diff --git a/tests/miniprogram-pet-card.test.cjs b/tests/miniprogram-pet-card.test.cjs new file mode 100644 index 0000000..b6104e2 --- /dev/null +++ b/tests/miniprogram-pet-card.test.cjs @@ -0,0 +1,104 @@ +const test = require("node:test"); +const assert = require("node:assert/strict"); +const fs = require("node:fs"); +const vm = require("node:vm"); +function library(wx) { + const module = { exports: {} }; + vm.runInNewContext(fs.readFileSync("pets-fe/utils/pet-card.js", "utf8"), { + wx, + module, + }); + return module.exports; +} + +test("保存卡片被拒绝授权后,确认去设置并授权则重试同一图片", async () => { + const saves = []; + const api = library({ + saveImageToPhotosAlbum(options) { + saves.push(options.filePath); + if (saves.length === 1) options.fail({ errMsg: "auth deny" }); + else options.success(); + }, + getSetting: (options) => + options.success({ authSetting: { "scope.writePhotosAlbum": false } }), + showModal: async () => ({ confirm: true }), + openSetting: (options) => + options.success({ authSetting: { "scope.writePhotosAlbum": true } }), + }); + assert.equal(await api.saveToAlbum("/tmp/card.png"), true); + assert.deepEqual(saves, ["/tmp/card.png", "/tmp/card.png"]); +}); +test("拒绝开启相册权限不报告保存成功,也不重复保存", async () => { + let saves = 0; + const api = library({ + saveImageToPhotosAlbum: (options) => { + saves++; + options.fail({ errMsg: "auth deny" }); + }, + getSetting: (options) => + options.success({ authSetting: { "scope.writePhotosAlbum": false } }), + showModal: async () => ({ confirm: false }), + }); + assert.equal(await api.saveToAlbum("/tmp/card.png"), false); + assert.equal(saves, 1); +}); +test("导出等待照片读取后生成 PNG,远程照片失败不会导出错误头像", async () => { + let exported = 0, + imageOptions; + const ctx = new Proxy( + {}, + { + get(target, key) { + if (key === "measureText") + return (text) => ({ width: text.length * 10 }); + if (key === "createLinearGradient") + return () => ({ addColorStop() {} }); + return () => {}; + }, + set() { + return true; + }, + }, + ); + const canvas = { + getContext: () => ctx, + createImage() { + const img = { width: 200, height: 300 }; + Object.defineProperty(img, "src", { + set() { + queueMicrotask(() => img.onload()); + }, + }); + return img; + }, + }; + const api = library({ + getImageInfo: (options) => { + imageOptions = options; + }, + canvasToTempFilePath: (options) => { + exported++; + assert.equal(options.fileType, "png"); + options.success({ tempFilePath: "/tmp/card.png" }); + }, + }); + const waiting = api.renderCard(canvas, { + id: "1234", + name: "毛孩", + avatar_url: "https://s3.test/pet.png", + }); + await new Promise((resolve) => setImmediate(resolve)); + assert.equal(exported, 0); + imageOptions.success({ path: "/tmp/photo.png" }); + assert.equal(await waiting, "/tmp/card.png"); + assert.equal(canvas.width, 1200); + assert.equal(canvas.height, 760); + const failed = api.renderCard(canvas, { + name: "毛孩", + avatar_url: "https://s3.test/missing.png", + }); + await new Promise((resolve) => setImmediate(resolve)); + imageOptions.fail(); + await assert.rejects(failed, /照片下载失败/); + assert.equal(exported, 1); +}); -- 2.54.0 From b1439b0fe5a2d34a05d0faccb751df6207eef34e Mon Sep 17 00:00:00 2001 From: Blizzard Date: Mon, 5 Oct 2026 11:38:15 +0800 Subject: [PATCH 4/7] Move pet card actions into menu and use circular brand logos --- .../admin/dist/assets/index-7B3h3Yq6.css | 1 + .../admin/dist/assets/index-B39ofd9P.css | 1 - .../{index-DkKuSusU.js => index-BOnBpy-T.js} | 0 pets-be/internal/admin/dist/brand-icon.svg | 1 + pets-be/internal/admin/dist/index.html | 6 +-- pets-be/web/admin/index.html | 2 +- pets-be/web/admin/public/brand-icon.svg | 1 + pets-be/web/admin/src/index.css | 12 +++-- pets-fe/components/pet-id-card/index.js | 13 ++++++ pets-fe/components/pet-id-card/index.wxml | 5 +- pets-fe/components/pet-id-card/index.wxss | 46 ++++++++++++------- pets-fe/utils/pet-card.js | 10 ++++ 12 files changed, 69 insertions(+), 29 deletions(-) create mode 100644 pets-be/internal/admin/dist/assets/index-7B3h3Yq6.css delete mode 100644 pets-be/internal/admin/dist/assets/index-B39ofd9P.css rename pets-be/internal/admin/dist/assets/{index-DkKuSusU.js => index-BOnBpy-T.js} (100%) create mode 100644 pets-be/internal/admin/dist/brand-icon.svg create mode 100644 pets-be/web/admin/public/brand-icon.svg diff --git a/pets-be/internal/admin/dist/assets/index-7B3h3Yq6.css b/pets-be/internal/admin/dist/assets/index-7B3h3Yq6.css new file mode 100644 index 0000000..ff26b52 --- /dev/null +++ b/pets-be/internal/admin/dist/assets/index-7B3h3Yq6.css @@ -0,0 +1 @@ +*,:before,:after,::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:#3b82f680;--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:0 solid #e5e7eb}:before,:after{--tw-content:""}html,:host{-webkit-text-size-adjust:100%;tab-size:4;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}body{line-height:inherit;margin:0}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;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-feature-settings:normal;font-variation-settings:normal;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-feature-settings:inherit;font-variation-settings:inherit;font-family: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:#0000;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button{height:auto}::-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{margin:0;padding:0;list-style:none}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder{opacity:1;color:#9ca3af}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{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.sr-only{clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{inset:0}.left-1\/2{left:50%}.right-4{right:1rem}.top-1\/2{top:50%}.top-4{top:1rem}.z-50{z-index:50}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.h-10{height:2.5rem}.h-4{height:1rem}.h-8{height:2rem}.h-9{height:2.25rem}.w-4{width:1rem}.w-9{width:2.25rem}.w-full{width:100%}.max-w-lg{max-width:32rem}.caption-bottom{caption-side:bottom}.-translate-x-1\/2{--tw-translate-x:-50%;transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-1\/2{--tw-translate-y:-50%;transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:1s linear infinite spin}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-center{justify-content:center}.gap-2{gap:.5rem}.gap-4{gap:1rem}.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))}.overflow-auto{overflow:auto}.whitespace-nowrap{white-space:nowrap}.rounded-full{border-radius:9999px}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-input{border-color:hsl(var(--input))}.border-transparent{border-color:#0000}.bg-amber-100{--tw-bg-opacity:1;background-color:rgb(254 243 199/var(--tw-bg-opacity,1))}.bg-black\/40{background-color:#0006}.bg-card{background-color:hsl(var(--card))}.bg-destructive{background-color:hsl(var(--destructive))}.bg-destructive\/15{background-color:hsl(var(--destructive) / .15)}.bg-emerald-100{--tw-bg-opacity:1;background-color:rgb(209 250 229/var(--tw-bg-opacity,1))}.bg-muted{background-color:hsl(var(--muted))}.bg-primary{background-color:hsl(var(--primary))}.bg-primary\/15{background-color:hsl(var(--primary) / .15)}.bg-secondary{background-color:hsl(var(--secondary))}.p-3{padding:.75rem}.p-6{padding:1.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-8{padding-left:2rem;padding-right:2rem}.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}.pt-0{padding-top:0}.text-left{text-align:left}.align-middle{vertical-align:middle}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-medium{font-weight:500}.font-semibold{font-weight:600}.leading-none{line-height:1}.tracking-tight{letter-spacing:-.025em}.text-amber-700{--tw-text-opacity:1;color:rgb(180 83 9/var(--tw-text-opacity,1))}.text-card-foreground{color:hsl(var(--card-foreground))}.text-destructive{color:hsl(var(--destructive))}.text-destructive-foreground{color:hsl(var(--destructive-foreground))}.text-emerald-700{--tw-text-opacity:1;color:rgb(4 120 87/var(--tw-text-opacity,1))}.text-foreground{color:hsl(var(--foreground))}.text-muted-foreground{color:hsl(var(--muted-foreground))}.text-primary{color:hsl(var(--primary))}.text-primary-foreground{color:hsl(var(--primary-foreground))}.text-secondary-foreground{color:hsl(var(--secondary-foreground))}.underline-offset-4{text-underline-offset:4px}.opacity-70{opacity:.7}.shadow{--tw-shadow:0 1px 3px 0 #0000001a, 0 1px 2px -1px #0000001a;--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px 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-lg{--tw-shadow:0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a;--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 #0000000d;--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)}.outline{outline-style:solid}.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-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}:root{--background:30 100% 98%;--foreground:20 20% 30%;--card:0 0% 100%;--card-foreground:20 20% 30%;--primary:15 54% 47%;--primary-foreground:0 0% 100%;--secondary:30 100% 94%;--secondary-foreground:20 20% 30%;--muted:30 38% 96%;--muted-foreground:23 16% 46%;--accent:30 100% 94%;--accent-foreground:20 20% 30%;--destructive:0 60% 48%;--destructive-foreground:0 0% 100%;--border:27 36% 88%;--input:27 36% 85%;--ring:15 54% 47%;--radius:.85rem}*{box-sizing:border-box;border-color:hsl(var(--border))}body{color:#604a40;background:#fff9f3;margin:0;font-family:ui-rounded,Hiragino Maru Gothic ProN,PingFang SC,system-ui,sans-serif;font-size:14px}button,input,select{font:inherit}button:focus-visible,a:focus-visible,select:focus-visible{outline-offset:3px;outline:2px solid #b95738}h1,h2,h3,p{margin:0}button{cursor:pointer}button:disabled{cursor:default}strong{font-weight:600}.app-shell{min-height:100vh}.sidebar{z-index:20;background:#fffefd;border-right:1px solid #ece2d8;flex-direction:column;width:238px;padding:28px 16px;display:flex;position:fixed;inset:0 auto 0 0}.brand{align-items:center;gap:12px;padding:0 12px 32px;display:flex}.brand img{border:3px solid #fffaf4;border-radius:50%;width:48px;height:48px;box-shadow:0 0 0 1px #ead8ca}.brand strong{letter-spacing:1px;font-size:20px;display:block}.brand small{color:#9d8779;letter-spacing:2px;margin-top:4px;font-size:9px;display:block}.side-caption{color:#9d8779;letter-spacing:1px;margin-bottom:14px;padding:0 15px;font-size:11px}.sidebar nav{gap:7px;display:grid}.nav-item{color:#886c5f;text-align:left;background:0 0;border:none;border-radius:13px;align-items:center;gap:12px;min-height:46px;padding:13px 15px;display:flex}.nav-item:hover{background:#fff5eb}.nav-item.active{color:#b95738;background:#ffeadc;font-weight:600}.nav-dot{background:#b95738;border-radius:50%;width:5px;height:5px;margin-left:auto}.side-note{color:#9b7057;background:#fff6ed;border-radius:18px;margin-top:auto;margin-bottom:24px;padding:22px 18px;font-size:12px;line-height:1.9}.side-note svg{color:#d9956e;margin-bottom:8px}.side-bottom{border-top:1px solid #f0e8e0;justify-content:space-between;align-items:center;padding-top:20px;display:flex}.admin-indicator{color:#886c5f;padding-left:9px;font-size:12px}.content{max-width:1780px;margin-left:238px;padding:32px 38px 24px}.topbar{justify-content:space-between;align-items:center;gap:16px;margin-bottom:26px;display:flex}.eyebrow{color:#9d7965;letter-spacing:1.8px;margin-bottom:9px;font-size:10px;font-weight:600}.topbar h1{letter-spacing:1px;font-size:27px;font-weight:600}.topbar-actions{align-items:center;gap:14px;display:flex}.today-date{color:#9d8779;font-size:12px}.mobile-logout{display:none}.welcome{background:linear-gradient(110deg,#fff0dd,#ffdec7);border:1px solid #ffeadb;border-radius:24px;justify-content:space-between;align-items:center;min-height:180px;padding:32px 36px;display:flex;overflow:hidden}.welcome h2{color:#694c3f;margin:10px 0 13px;font-size:25px;font-weight:600}.welcome p:not(.eyebrow){color:#98745d;font-size:13px}.welcome img{border:5px solid #fffaf4;border-radius:50%;width:116px;height:116px;transform:rotate(-8deg);box-shadow:0 8px 30px #a5623615}.stat-grid{grid-template-columns:repeat(6,minmax(0,1fr));gap:14px;margin:22px 0;display:grid}.stat-card,.panel{background:#fff;border:1px solid #ece2d8;border-radius:19px;box-shadow:0 6px 28px #604a4004}.stat-card{text-align:left;padding:18px;transition:transform .2s,border-color .2s}.stat-card:hover{border-color:#ddb699;transform:translateY(-3px)}.stat-top{color:#bca89c;justify-content:space-between;align-items:center;margin-bottom:15px;display:flex}.stat-icon{color:#b95738;background:#fff0e2;border-radius:12px;place-items:center;width:38px;height:38px;display:grid}.tint-pets .stat-icon,.tint-tasks .stat-icon{color:#977eae;background:#f1eaf8}.tint-walks .stat-icon,.tint-files .stat-icon{color:#7d96b6;background:#edf2fb}.stat-card>span{color:#886c5f;font-size:12px}.stat-card strong{margin:6px 0;font-size:30px;display:block}.stat-card small{color:#a48d7e;white-space:nowrap;font-size:10px}.overview-grid{grid-template-columns:1.6fr 1fr;gap:20px;display:grid}.panel-heading{justify-content:space-between;align-items:center;padding:24px 25px 0;display:flex}.panel-heading h2,.records-heading h2{font-size:17px;font-weight:600}.panel-heading p,.records-heading p{color:#a18a7c;margin-top:7px;font-size:12px}.panel-heading>svg{color:#c6a28c}.bar-chart{align-items:flex-end;gap:18px;height:232px;padding:28px 26px;display:flex}.chart-column{flex-direction:column;flex:1;align-items:center;gap:8px;min-width:0;height:100%;display:flex}.chart-column>span{color:#9d7965;font-size:12px}.bar-space{flex:1;align-items:flex-end;width:100%;max-width:42px;display:flex}.chart-bar{background:linear-gradient(#f2bc94,#d88760);border-radius:7px 7px 2px 2px;width:100%;transition:height .3s}.chart-column small{color:#a48d7e;font-size:11px}.today dl{margin:0;padding:12px 25px 20px}.today dl>div{border-bottom:1px solid #f2eae4;justify-content:space-between;align-items:center;padding:14px 0;display:flex}.today dl>div:last-child{border:0}.today dt{color:#886c5f;font-size:12px}.today dd{margin:0;font-size:21px}.today dd small{color:#a48d7e;margin-left:5px;font-size:11px}.summary-strip{background:#fff5eb;border:1px dashed #e6d2c2;border-radius:15px;gap:28px;margin-top:20px;padding:18px 22px;display:flex}.summary-strip>div{color:#9d7965;align-items:center;gap:9px;font-size:12px;display:flex}.summary-strip strong{color:#604a40;margin-left:8px}.records{overflow:hidden}.records-heading{justify-content:space-between;align-items:center;padding:24px 26px 16px;display:flex}.per-page{color:#9d7965;background:#fff6ed;border:1px solid #f4e6d8;border-radius:8px;padding:5px 10px;font-size:11px}.toolbar{flex-wrap:wrap;align-items:center;gap:12px;padding:0 26px 22px;display:flex}.search-form{flex:1;align-items:center;gap:8px;max-width:490px;display:flex;position:relative}.search-form>svg{pointer-events:none;color:#a48d7e;position:absolute;left:12px}.search-form input{border-radius:10px;min-width:140px;padding-left:36px}.toolbar select{color:#886c5f;background:#fff;border:1px solid #e6d9cf;border-radius:10px;height:36px;padding:8px 30px 8px 12px;font-size:12px}table{min-width:760px}thead{background:#fffaf6}th{white-space:nowrap;padding:13px 18px!important;font-size:12px!important}td{max-width:360px;font-size:12px;padding:15px 18px!important}td small{color:#a48d7e;margin-top:5px;font-size:10px;display:block}td strong{display:block}.identity{align-items:center;gap:10px;min-width:0;display:flex}.identity strong{color:#604a40;font-size:13px}.identity small{text-overflow:ellipsis;white-space:nowrap;color:#a48d7e;max-width:185px;margin-top:5px;font-size:10px;display:block;overflow:hidden}.avatar{color:#c58d6a;background:#fff1e4;border-radius:12px;flex:none;place-items:center;width:38px;height:38px;display:grid;overflow:hidden}.avatar img{-o-object-fit:cover;object-fit:cover;width:100%;height:100%}.mono{font-family:ui-monospace,SFMono-Regular,monospace}.pet-tags{flex-wrap:wrap;gap:5px;max-width:250px;display:flex}.pet-tags>span{color:#9d6a4e;background:#fff3e8;border-radius:7px;align-items:center;gap:4px;padding:4px 7px;font-size:11px;display:flex}.row-actions{white-space:nowrap;align-items:center;gap:5px;display:flex}.tree-toggle{color:#ad826b;background:#fffaf6;border:1px solid #f0e4da;border-radius:8px;place-items:center;width:28px;height:28px;display:grid}.text-action{color:#b95738;background:0 0;border:none;padding:0}.tree-row td{background:#fffcf9;padding:0 20px 16px 56px!important}.pet-tree{border-left:2px solid #ecd8c8;padding:14px 18px 5px}.tree-heading{color:#9d7965;align-items:center;gap:7px;margin-bottom:14px;font-size:12px;display:flex}.tree-heading strong{display:inline}.tree-heading>span{color:#b29a89;margin-left:auto;font-size:10px}.pet-tree-grid{grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:10px;display:grid}.pet-tree-card{text-align:left;background:#fff;border:1px solid #f0e2d6;border-radius:12px;justify-content:space-between;align-items:center;gap:12px;padding:13px 14px;display:flex}.pet-tree-card:hover{background:#fffaf6;border-color:#deb697}.pet-tree-card .identity{flex:1}.pet-tree-card>svg{color:#bfa390}.pet-tree-card .identity small{font-family:inherit}.tree-message{color:#a48d7e;align-items:center;gap:10px;padding:12px 0;font-size:12px;display:flex}.pagination{color:#9d8779;border-top:1px solid #f0e7df;justify-content:space-between;align-items:center;gap:16px;padding:18px 25px;font-size:12px;display:flex}.pagination>div{align-items:center;gap:15px;display:flex}.pagination button{border-radius:9px}.empty{color:#a48d7e;text-align:center;flex-direction:column;justify-content:center;align-items:center;gap:12px;min-height:230px;padding:35px 20px;display:flex}.empty svg{color:#c9ae9a}.empty h3{color:#8e7160;font-size:15px;font-weight:500}.empty p{font-size:12px;line-height:1.8}.empty.compact{min-height:150px}.error-banner,.notice{color:#a04b31;background:#fff0e7;border:1px solid #f0d7c9;border-radius:12px;justify-content:space-between;align-items:center;gap:12px;margin-bottom:18px;padding:12px 15px;font-size:12px;display:flex}.notice{color:#806499;background:#f5f0fb;border-color:#e6dcef;justify-content:flex-start}.notice button{color:inherit;background:0 0;border:none;margin-left:auto}.error-text{color:#a04b31}.page-footer{text-align:center;color:#b49c8b;letter-spacing:1px;padding:24px 0 5px;font-size:10px}.detail-dialog{width:calc(100% - 32px);max-width:700px;max-height:85vh;overflow:auto;border-radius:22px!important;padding:26px!important}.detail-summary{border-bottom:1px solid #f0e7df;justify-content:space-between;align-items:center;gap:10px;padding:14px 0;display:flex}.detail-summary .identity small{max-width:330px}.detail-grid{grid-template-columns:1fr 1fr;gap:20px;margin:7px 0;display:grid}.detail-grid>div{min-width:0}.detail-grid dt{color:#a48d7e;margin-bottom:7px;font-size:11px}.detail-grid dd{overflow-wrap:anywhere;white-space:pre-wrap;margin:0;font-size:13px;line-height:1.8}.dialog-actions{justify-content:flex-end;gap:10px;margin-top:10px;display:flex}.confirm-copy{color:#886c5f;font-size:13px;line-height:1.9}.track{background:#fffaf5;border:1px solid #eee0d4;border-radius:16px;padding:14px}.track svg{border-radius:10px;width:100%;display:block}.track p{color:#a48d7e;text-align:center;padding-top:10px;font-size:10px}.file-preview{-o-object-fit:contain;object-fit:contain;background:#fff8f0;border-radius:12px;width:100%;max-height:260px}.file-link{color:#b95738;align-items:center;gap:5px;font-size:12px;display:flex}.file-name{text-overflow:ellipsis;white-space:nowrap;max-width:220px;overflow:hidden}.login-page{background:radial-gradient(at 15% 20%,#ffead4,#0000 50%),radial-gradient(at 95% 90%,#f1eaf8,#0000 45%),#fff9f3;justify-content:center;align-items:center;gap:100px;min-height:100vh;padding:40px;display:flex}.login-story{max-width:480px}.login-story>img{border:4px solid #fffaf4;border-radius:50%;width:94px;height:94px;margin-bottom:30px;transform:rotate(-6deg);box-shadow:0 12px 40px #aa683219}.login-story h1{letter-spacing:2px;font-size:42px;font-weight:600;line-height:1.55}.login-story>p:not(.eyebrow){color:#a0816a;margin-top:20px;font-size:14px;line-height:1.9}.story-tags{gap:20px;margin-top:40px;display:flex}.story-tags>span{color:#b28d72;align-items:center;gap:7px;font-size:12px;display:flex}.login-card{background:#fff;border:1px solid #eee1d6;border-radius:27px;width:400px;padding:35px;box-shadow:0 20px 80px #98694b0b}.login-mark{color:#c07851;background:#fff0e2;border-radius:16px;place-items:center;width:48px;height:48px;margin-bottom:24px;display:grid}.login-card h2{font-size:26px;font-weight:600}.muted{color:#a18a7c;margin:10px 0 28px;font-size:12px;line-height:1.8}.login-card label{color:#8e7160;margin:17px 0 8px;font-size:12px;display:block}.login-card input{border-radius:11px;height:42px}.login-submit{border-radius:11px;height:42px;margin-top:25px}.login-footnote{text-align:center;color:#baa392;margin-top:25px;font-size:10px;display:block}.login-card .error-banner{margin-top:16px;margin-bottom:0;line-height:1.7}@media (width>=1550px){.content{padding-left:52px;padding-right:52px}}@media (width<=1240px){.stat-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.sidebar{width:210px}.content{margin-left:210px;padding:26px}.today-date{display:none}.overview-grid{grid-template-columns:1.4fr 1fr}.login-page{gap:55px}.login-story h1{font-size:35px}}@media (width<=880px){.sidebar{width:76px;padding:22px 9px}.content{margin-left:76px;padding:24px 20px}.brand{padding:0 3px 28px}.brand img{width:45px;height:45px}.brand>div,.side-caption,.nav-item>span,.side-note,.side-bottom{display:none}.nav-item{justify-content:center;padding:13px 0}.mobile-logout{display:inline-flex}.overview-grid{grid-template-columns:1fr}.summary-strip{flex-wrap:wrap;gap:15px}.welcome{min-height:170px;padding:26px}.welcome h2{font-size:22px}.welcome img{width:85px;height:85px}.login-page{gap:35px}.login-story h1{font-size:28px}.story-tags{flex-wrap:wrap;gap:12px}.login-card{width:360px;padding:28px}}@media (width<=620px){.sidebar{width:60px;padding:20px 6px}.brand{padding:0 0 22px}.brand img{width:40px;height:40px}.content{margin-left:60px;padding:20px 12px}.topbar h1{font-size:22px}.topbar-actions{gap:5px}.topbar-actions>button{padding:8px;font-size:11px}.eyebrow{letter-spacing:1px;font-size:9px}.welcome{padding:22px}.welcome img{display:none}.welcome h2{font-size:20px}.stat-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}.stat-card{padding:15px}.toolbar{padding:0 14px 18px}.records-heading{padding:22px 15px 18px}.records-heading p{max-width:170px;line-height:1.8}.search-form{flex-basis:100%;max-width:none}.pagination{flex-direction:column;align-items:flex-start;gap:13px;padding:16px 12px}.pagination>div{justify-content:space-between;width:100%}.detail-grid{grid-template-columns:1fr}.detail-summary .identity small{max-width:190px}.login-page{flex-direction:column;gap:22px;padding:25px}.login-story{width:min(400px,100%)}.login-story>img{border-radius:50%;width:54px;height:54px;margin:0 0 10px}.login-story h1{font-size:25px;line-height:1.7}.login-story h1 br,.login-story>p:not(.eyebrow),.story-tags{display:none}.login-card{width:min(400px,100%);padding:28px}.bar-chart{gap:10px;padding-left:20px;padding-right:20px}}.placeholder\:text-muted-foreground::placeholder{color:hsl(var(--muted-foreground))}.hover\:bg-accent:hover{background-color:hsl(var(--accent))}.hover\:bg-destructive\/90:hover{background-color:hsl(var(--destructive) / .9)}.hover\:bg-muted\/50:hover{background-color:hsl(var(--muted) / .5)}.hover\:bg-primary\/90:hover{background-color:hsl(var(--primary) / .9)}.hover\:bg-secondary\/80:hover{background-color:hsl(var(--secondary) / .8)}.hover\:text-accent-foreground:hover{color:hsl(var(--accent-foreground))}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}.focus-visible\:outline-none:focus-visible{outline-offset:2px;outline:2px solid #0000}.focus-visible\:ring-2:focus-visible{--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-visible\:ring-ring:focus-visible{--tw-ring-color:hsl(var(--ring))}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.\[\&_tr\:last-child\]\:border-0 tr:last-child{border-width:0}.\[\&_tr\]\:border-b tr{border-bottom-width:1px} diff --git a/pets-be/internal/admin/dist/assets/index-B39ofd9P.css b/pets-be/internal/admin/dist/assets/index-B39ofd9P.css deleted file mode 100644 index a02abbd..0000000 --- a/pets-be/internal/admin/dist/assets/index-B39ofd9P.css +++ /dev/null @@ -1 +0,0 @@ -*,:before,:after,::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:#3b82f680;--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:0 solid #e5e7eb}:before,:after{--tw-content:""}html,:host{-webkit-text-size-adjust:100%;tab-size:4;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}body{line-height:inherit;margin:0}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;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-feature-settings:normal;font-variation-settings:normal;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-feature-settings:inherit;font-variation-settings:inherit;font-family: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:#0000;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button{height:auto}::-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{margin:0;padding:0;list-style:none}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder{opacity:1;color:#9ca3af}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{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.sr-only{clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{inset:0}.left-1\/2{left:50%}.right-4{right:1rem}.top-1\/2{top:50%}.top-4{top:1rem}.z-50{z-index:50}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.h-10{height:2.5rem}.h-4{height:1rem}.h-8{height:2rem}.h-9{height:2.25rem}.w-4{width:1rem}.w-9{width:2.25rem}.w-full{width:100%}.max-w-lg{max-width:32rem}.caption-bottom{caption-side:bottom}.-translate-x-1\/2{--tw-translate-x:-50%;transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-1\/2{--tw-translate-y:-50%;transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:1s linear infinite spin}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-center{justify-content:center}.gap-2{gap:.5rem}.gap-4{gap:1rem}.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))}.overflow-auto{overflow:auto}.whitespace-nowrap{white-space:nowrap}.rounded-full{border-radius:9999px}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-input{border-color:hsl(var(--input))}.border-transparent{border-color:#0000}.bg-amber-100{--tw-bg-opacity:1;background-color:rgb(254 243 199/var(--tw-bg-opacity,1))}.bg-black\/40{background-color:#0006}.bg-card{background-color:hsl(var(--card))}.bg-destructive{background-color:hsl(var(--destructive))}.bg-destructive\/15{background-color:hsl(var(--destructive) / .15)}.bg-emerald-100{--tw-bg-opacity:1;background-color:rgb(209 250 229/var(--tw-bg-opacity,1))}.bg-muted{background-color:hsl(var(--muted))}.bg-primary{background-color:hsl(var(--primary))}.bg-primary\/15{background-color:hsl(var(--primary) / .15)}.bg-secondary{background-color:hsl(var(--secondary))}.p-3{padding:.75rem}.p-6{padding:1.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-8{padding-left:2rem;padding-right:2rem}.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}.pt-0{padding-top:0}.text-left{text-align:left}.align-middle{vertical-align:middle}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-medium{font-weight:500}.font-semibold{font-weight:600}.leading-none{line-height:1}.tracking-tight{letter-spacing:-.025em}.text-amber-700{--tw-text-opacity:1;color:rgb(180 83 9/var(--tw-text-opacity,1))}.text-card-foreground{color:hsl(var(--card-foreground))}.text-destructive{color:hsl(var(--destructive))}.text-destructive-foreground{color:hsl(var(--destructive-foreground))}.text-emerald-700{--tw-text-opacity:1;color:rgb(4 120 87/var(--tw-text-opacity,1))}.text-foreground{color:hsl(var(--foreground))}.text-muted-foreground{color:hsl(var(--muted-foreground))}.text-primary{color:hsl(var(--primary))}.text-primary-foreground{color:hsl(var(--primary-foreground))}.text-secondary-foreground{color:hsl(var(--secondary-foreground))}.underline-offset-4{text-underline-offset:4px}.opacity-70{opacity:.7}.shadow{--tw-shadow:0 1px 3px 0 #0000001a, 0 1px 2px -1px #0000001a;--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px 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-lg{--tw-shadow:0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a;--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 #0000000d;--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)}.outline{outline-style:solid}.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-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}:root{--background:30 100% 98%;--foreground:20 20% 30%;--card:0 0% 100%;--card-foreground:20 20% 30%;--primary:15 54% 47%;--primary-foreground:0 0% 100%;--secondary:30 100% 94%;--secondary-foreground:20 20% 30%;--muted:30 38% 96%;--muted-foreground:23 16% 46%;--accent:30 100% 94%;--accent-foreground:20 20% 30%;--destructive:0 60% 48%;--destructive-foreground:0 0% 100%;--border:27 36% 88%;--input:27 36% 85%;--ring:15 54% 47%;--radius:.85rem}*{box-sizing:border-box;border-color:hsl(var(--border))}body{color:#604a40;background:#fff9f3;margin:0;font-family:ui-rounded,Hiragino Maru Gothic ProN,PingFang SC,system-ui,sans-serif;font-size:14px}button,input,select{font:inherit}button:focus-visible,a:focus-visible,select:focus-visible{outline-offset:3px;outline:2px solid #b95738}h1,h2,h3,p{margin:0}button{cursor:pointer}button:disabled{cursor:default}strong{font-weight:600}.app-shell{min-height:100vh}.sidebar{z-index:20;background:#fffefd;border-right:1px solid #ece2d8;flex-direction:column;width:238px;padding:28px 16px;display:flex;position:fixed;inset:0 auto 0 0}.brand{align-items:center;gap:12px;padding:0 12px 32px;display:flex}.brand img{border-radius:17px;width:48px;height:48px}.brand strong{letter-spacing:1px;font-size:20px;display:block}.brand small{color:#9d8779;letter-spacing:2px;margin-top:4px;font-size:9px;display:block}.side-caption{color:#9d8779;letter-spacing:1px;margin-bottom:14px;padding:0 15px;font-size:11px}.sidebar nav{gap:7px;display:grid}.nav-item{color:#886c5f;text-align:left;background:0 0;border:none;border-radius:13px;align-items:center;gap:12px;min-height:46px;padding:13px 15px;display:flex}.nav-item:hover{background:#fff5eb}.nav-item.active{color:#b95738;background:#ffeadc;font-weight:600}.nav-dot{background:#b95738;border-radius:50%;width:5px;height:5px;margin-left:auto}.side-note{color:#9b7057;background:#fff6ed;border-radius:18px;margin-top:auto;margin-bottom:24px;padding:22px 18px;font-size:12px;line-height:1.9}.side-note svg{color:#d9956e;margin-bottom:8px}.side-bottom{border-top:1px solid #f0e8e0;justify-content:space-between;align-items:center;padding-top:20px;display:flex}.admin-indicator{color:#886c5f;padding-left:9px;font-size:12px}.content{max-width:1780px;margin-left:238px;padding:32px 38px 24px}.topbar{justify-content:space-between;align-items:center;gap:16px;margin-bottom:26px;display:flex}.eyebrow{color:#9d7965;letter-spacing:1.8px;margin-bottom:9px;font-size:10px;font-weight:600}.topbar h1{letter-spacing:1px;font-size:27px;font-weight:600}.topbar-actions{align-items:center;gap:14px;display:flex}.today-date{color:#9d8779;font-size:12px}.mobile-logout{display:none}.welcome{background:linear-gradient(110deg,#fff0dd,#ffdec7);border:1px solid #ffeadb;border-radius:24px;justify-content:space-between;align-items:center;min-height:180px;padding:32px 36px;display:flex;overflow:hidden}.welcome h2{color:#694c3f;margin:10px 0 13px;font-size:25px;font-weight:600}.welcome p:not(.eyebrow){color:#98745d;font-size:13px}.welcome img{border-radius:32px;width:116px;height:116px;transform:rotate(-8deg);box-shadow:0 8px 30px #a5623615}.stat-grid{grid-template-columns:repeat(6,minmax(0,1fr));gap:14px;margin:22px 0;display:grid}.stat-card,.panel{background:#fff;border:1px solid #ece2d8;border-radius:19px;box-shadow:0 6px 28px #604a4004}.stat-card{text-align:left;padding:18px;transition:transform .2s,border-color .2s}.stat-card:hover{border-color:#ddb699;transform:translateY(-3px)}.stat-top{color:#bca89c;justify-content:space-between;align-items:center;margin-bottom:15px;display:flex}.stat-icon{color:#b95738;background:#fff0e2;border-radius:12px;place-items:center;width:38px;height:38px;display:grid}.tint-pets .stat-icon,.tint-tasks .stat-icon{color:#977eae;background:#f1eaf8}.tint-walks .stat-icon,.tint-files .stat-icon{color:#7d96b6;background:#edf2fb}.stat-card>span{color:#886c5f;font-size:12px}.stat-card strong{margin:6px 0;font-size:30px;display:block}.stat-card small{color:#a48d7e;white-space:nowrap;font-size:10px}.overview-grid{grid-template-columns:1.6fr 1fr;gap:20px;display:grid}.panel-heading{justify-content:space-between;align-items:center;padding:24px 25px 0;display:flex}.panel-heading h2,.records-heading h2{font-size:17px;font-weight:600}.panel-heading p,.records-heading p{color:#a18a7c;margin-top:7px;font-size:12px}.panel-heading>svg{color:#c6a28c}.bar-chart{align-items:flex-end;gap:18px;height:232px;padding:28px 26px;display:flex}.chart-column{flex-direction:column;flex:1;align-items:center;gap:8px;min-width:0;height:100%;display:flex}.chart-column>span{color:#9d7965;font-size:12px}.bar-space{flex:1;align-items:flex-end;width:100%;max-width:42px;display:flex}.chart-bar{background:linear-gradient(#f2bc94,#d88760);border-radius:7px 7px 2px 2px;width:100%;transition:height .3s}.chart-column small{color:#a48d7e;font-size:11px}.today dl{margin:0;padding:12px 25px 20px}.today dl>div{border-bottom:1px solid #f2eae4;justify-content:space-between;align-items:center;padding:14px 0;display:flex}.today dl>div:last-child{border:0}.today dt{color:#886c5f;font-size:12px}.today dd{margin:0;font-size:21px}.today dd small{color:#a48d7e;margin-left:5px;font-size:11px}.summary-strip{background:#fff5eb;border:1px dashed #e6d2c2;border-radius:15px;gap:28px;margin-top:20px;padding:18px 22px;display:flex}.summary-strip>div{color:#9d7965;align-items:center;gap:9px;font-size:12px;display:flex}.summary-strip strong{color:#604a40;margin-left:8px}.records{overflow:hidden}.records-heading{justify-content:space-between;align-items:center;padding:24px 26px 16px;display:flex}.per-page{color:#9d7965;background:#fff6ed;border:1px solid #f4e6d8;border-radius:8px;padding:5px 10px;font-size:11px}.toolbar{flex-wrap:wrap;align-items:center;gap:12px;padding:0 26px 22px;display:flex}.search-form{flex:1;align-items:center;gap:8px;max-width:490px;display:flex;position:relative}.search-form>svg{pointer-events:none;color:#a48d7e;position:absolute;left:12px}.search-form input{border-radius:10px;min-width:140px;padding-left:36px}.toolbar select{color:#886c5f;background:#fff;border:1px solid #e6d9cf;border-radius:10px;height:36px;padding:8px 30px 8px 12px;font-size:12px}table{min-width:760px}thead{background:#fffaf6}th{white-space:nowrap;padding:13px 18px!important;font-size:12px!important}td{max-width:360px;font-size:12px;padding:15px 18px!important}td small{color:#a48d7e;margin-top:5px;font-size:10px;display:block}td strong{display:block}.identity{align-items:center;gap:10px;min-width:0;display:flex}.identity strong{color:#604a40;font-size:13px}.identity small{text-overflow:ellipsis;white-space:nowrap;color:#a48d7e;max-width:185px;margin-top:5px;font-size:10px;display:block;overflow:hidden}.avatar{color:#c58d6a;background:#fff1e4;border-radius:12px;flex:none;place-items:center;width:38px;height:38px;display:grid;overflow:hidden}.avatar img{-o-object-fit:cover;object-fit:cover;width:100%;height:100%}.mono{font-family:ui-monospace,SFMono-Regular,monospace}.pet-tags{flex-wrap:wrap;gap:5px;max-width:250px;display:flex}.pet-tags>span{color:#9d6a4e;background:#fff3e8;border-radius:7px;align-items:center;gap:4px;padding:4px 7px;font-size:11px;display:flex}.row-actions{white-space:nowrap;align-items:center;gap:5px;display:flex}.tree-toggle{color:#ad826b;background:#fffaf6;border:1px solid #f0e4da;border-radius:8px;place-items:center;width:28px;height:28px;display:grid}.text-action{color:#b95738;background:0 0;border:none;padding:0}.tree-row td{background:#fffcf9;padding:0 20px 16px 56px!important}.pet-tree{border-left:2px solid #ecd8c8;padding:14px 18px 5px}.tree-heading{color:#9d7965;align-items:center;gap:7px;margin-bottom:14px;font-size:12px;display:flex}.tree-heading strong{display:inline}.tree-heading>span{color:#b29a89;margin-left:auto;font-size:10px}.pet-tree-grid{grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:10px;display:grid}.pet-tree-card{text-align:left;background:#fff;border:1px solid #f0e2d6;border-radius:12px;justify-content:space-between;align-items:center;gap:12px;padding:13px 14px;display:flex}.pet-tree-card:hover{background:#fffaf6;border-color:#deb697}.pet-tree-card .identity{flex:1}.pet-tree-card>svg{color:#bfa390}.pet-tree-card .identity small{font-family:inherit}.tree-message{color:#a48d7e;align-items:center;gap:10px;padding:12px 0;font-size:12px;display:flex}.pagination{color:#9d8779;border-top:1px solid #f0e7df;justify-content:space-between;align-items:center;gap:16px;padding:18px 25px;font-size:12px;display:flex}.pagination>div{align-items:center;gap:15px;display:flex}.pagination button{border-radius:9px}.empty{color:#a48d7e;text-align:center;flex-direction:column;justify-content:center;align-items:center;gap:12px;min-height:230px;padding:35px 20px;display:flex}.empty svg{color:#c9ae9a}.empty h3{color:#8e7160;font-size:15px;font-weight:500}.empty p{font-size:12px;line-height:1.8}.empty.compact{min-height:150px}.error-banner,.notice{color:#a04b31;background:#fff0e7;border:1px solid #f0d7c9;border-radius:12px;justify-content:space-between;align-items:center;gap:12px;margin-bottom:18px;padding:12px 15px;font-size:12px;display:flex}.notice{color:#806499;background:#f5f0fb;border-color:#e6dcef;justify-content:flex-start}.notice button{color:inherit;background:0 0;border:none;margin-left:auto}.error-text{color:#a04b31}.page-footer{text-align:center;color:#b49c8b;letter-spacing:1px;padding:24px 0 5px;font-size:10px}.detail-dialog{width:calc(100% - 32px);max-width:700px;max-height:85vh;overflow:auto;border-radius:22px!important;padding:26px!important}.detail-summary{border-bottom:1px solid #f0e7df;justify-content:space-between;align-items:center;gap:10px;padding:14px 0;display:flex}.detail-summary .identity small{max-width:330px}.detail-grid{grid-template-columns:1fr 1fr;gap:20px;margin:7px 0;display:grid}.detail-grid>div{min-width:0}.detail-grid dt{color:#a48d7e;margin-bottom:7px;font-size:11px}.detail-grid dd{overflow-wrap:anywhere;white-space:pre-wrap;margin:0;font-size:13px;line-height:1.8}.dialog-actions{justify-content:flex-end;gap:10px;margin-top:10px;display:flex}.confirm-copy{color:#886c5f;font-size:13px;line-height:1.9}.track{background:#fffaf5;border:1px solid #eee0d4;border-radius:16px;padding:14px}.track svg{border-radius:10px;width:100%;display:block}.track p{color:#a48d7e;text-align:center;padding-top:10px;font-size:10px}.file-preview{-o-object-fit:contain;object-fit:contain;background:#fff8f0;border-radius:12px;width:100%;max-height:260px}.file-link{color:#b95738;align-items:center;gap:5px;font-size:12px;display:flex}.file-name{text-overflow:ellipsis;white-space:nowrap;max-width:220px;overflow:hidden}.login-page{background:radial-gradient(at 15% 20%,#ffead4,#0000 50%),radial-gradient(at 95% 90%,#f1eaf8,#0000 45%),#fff9f3;justify-content:center;align-items:center;gap:100px;min-height:100vh;padding:40px;display:flex}.login-story{max-width:480px}.login-story>img{border-radius:28px;width:94px;height:94px;margin-bottom:30px;transform:rotate(-6deg);box-shadow:0 12px 40px #aa683219}.login-story h1{letter-spacing:2px;font-size:42px;font-weight:600;line-height:1.55}.login-story>p:not(.eyebrow){color:#a0816a;margin-top:20px;font-size:14px;line-height:1.9}.story-tags{gap:20px;margin-top:40px;display:flex}.story-tags>span{color:#b28d72;align-items:center;gap:7px;font-size:12px;display:flex}.login-card{background:#fff;border:1px solid #eee1d6;border-radius:27px;width:400px;padding:35px;box-shadow:0 20px 80px #98694b0b}.login-mark{color:#c07851;background:#fff0e2;border-radius:16px;place-items:center;width:48px;height:48px;margin-bottom:24px;display:grid}.login-card h2{font-size:26px;font-weight:600}.muted{color:#a18a7c;margin:10px 0 28px;font-size:12px;line-height:1.8}.login-card label{color:#8e7160;margin:17px 0 8px;font-size:12px;display:block}.login-card input{border-radius:11px;height:42px}.login-submit{border-radius:11px;height:42px;margin-top:25px}.login-footnote{text-align:center;color:#baa392;margin-top:25px;font-size:10px;display:block}.login-card .error-banner{margin-top:16px;margin-bottom:0;line-height:1.7}@media (width>=1550px){.content{padding-left:52px;padding-right:52px}}@media (width<=1240px){.stat-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.sidebar{width:210px}.content{margin-left:210px;padding:26px}.today-date{display:none}.overview-grid{grid-template-columns:1.4fr 1fr}.login-page{gap:55px}.login-story h1{font-size:35px}}@media (width<=880px){.sidebar{width:76px;padding:22px 9px}.content{margin-left:76px;padding:24px 20px}.brand{padding:0 3px 28px}.brand img{width:45px;height:45px}.brand>div,.side-caption,.nav-item>span,.side-note,.side-bottom{display:none}.nav-item{justify-content:center;padding:13px 0}.mobile-logout{display:inline-flex}.overview-grid{grid-template-columns:1fr}.summary-strip{flex-wrap:wrap;gap:15px}.welcome{min-height:170px;padding:26px}.welcome h2{font-size:22px}.welcome img{width:85px;height:85px}.login-page{gap:35px}.login-story h1{font-size:28px}.story-tags{flex-wrap:wrap;gap:12px}.login-card{width:360px;padding:28px}}@media (width<=620px){.sidebar{width:60px;padding:20px 6px}.brand{padding:0 0 22px}.brand img{width:40px;height:40px}.content{margin-left:60px;padding:20px 12px}.topbar h1{font-size:22px}.topbar-actions{gap:5px}.topbar-actions>button{padding:8px;font-size:11px}.eyebrow{letter-spacing:1px;font-size:9px}.welcome{padding:22px}.welcome img{display:none}.welcome h2{font-size:20px}.stat-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}.stat-card{padding:15px}.toolbar{padding:0 14px 18px}.records-heading{padding:22px 15px 18px}.records-heading p{max-width:170px;line-height:1.8}.search-form{flex-basis:100%;max-width:none}.pagination{flex-direction:column;align-items:flex-start;gap:13px;padding:16px 12px}.pagination>div{justify-content:space-between;width:100%}.detail-grid{grid-template-columns:1fr}.detail-summary .identity small{max-width:190px}.login-page{flex-direction:column;gap:22px;padding:25px}.login-story{width:min(400px,100%)}.login-story>img{border-radius:17px;width:54px;height:54px;margin:0 0 10px}.login-story h1{font-size:25px;line-height:1.7}.login-story h1 br,.login-story>p:not(.eyebrow),.story-tags{display:none}.login-card{width:min(400px,100%);padding:28px}.bar-chart{gap:10px;padding-left:20px;padding-right:20px}}.placeholder\:text-muted-foreground::placeholder{color:hsl(var(--muted-foreground))}.hover\:bg-accent:hover{background-color:hsl(var(--accent))}.hover\:bg-destructive\/90:hover{background-color:hsl(var(--destructive) / .9)}.hover\:bg-muted\/50:hover{background-color:hsl(var(--muted) / .5)}.hover\:bg-primary\/90:hover{background-color:hsl(var(--primary) / .9)}.hover\:bg-secondary\/80:hover{background-color:hsl(var(--secondary) / .8)}.hover\:text-accent-foreground:hover{color:hsl(var(--accent-foreground))}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}.focus-visible\:outline-none:focus-visible{outline-offset:2px;outline:2px solid #0000}.focus-visible\:ring-2:focus-visible{--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-visible\:ring-ring:focus-visible{--tw-ring-color:hsl(var(--ring))}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.\[\&_tr\:last-child\]\:border-0 tr:last-child{border-width:0}.\[\&_tr\]\:border-b tr{border-bottom-width:1px} diff --git a/pets-be/internal/admin/dist/assets/index-DkKuSusU.js b/pets-be/internal/admin/dist/assets/index-BOnBpy-T.js similarity index 100% rename from pets-be/internal/admin/dist/assets/index-DkKuSusU.js rename to pets-be/internal/admin/dist/assets/index-BOnBpy-T.js diff --git a/pets-be/internal/admin/dist/brand-icon.svg b/pets-be/internal/admin/dist/brand-icon.svg new file mode 100644 index 0000000..02947f9 --- /dev/null +++ b/pets-be/internal/admin/dist/brand-icon.svg @@ -0,0 +1 @@ + diff --git a/pets-be/internal/admin/dist/index.html b/pets-be/internal/admin/dist/index.html index e4bfd39..a0286c4 100644 --- a/pets-be/internal/admin/dist/index.html +++ b/pets-be/internal/admin/dist/index.html @@ -2,11 +2,11 @@ - + 肉垫计划 · 管理后台 - - + +
diff --git a/pets-be/web/admin/index.html b/pets-be/web/admin/index.html index aed6626..cdd647c 100644 --- a/pets-be/web/admin/index.html +++ b/pets-be/web/admin/index.html @@ -2,7 +2,7 @@ - + 肉垫计划 · 管理后台 diff --git a/pets-be/web/admin/public/brand-icon.svg b/pets-be/web/admin/public/brand-icon.svg new file mode 100644 index 0000000..02947f9 --- /dev/null +++ b/pets-be/web/admin/public/brand-icon.svg @@ -0,0 +1 @@ + diff --git a/pets-be/web/admin/src/index.css b/pets-be/web/admin/src/index.css index 3063e47..1632082 100644 --- a/pets-be/web/admin/src/index.css +++ b/pets-be/web/admin/src/index.css @@ -83,7 +83,9 @@ strong { .brand img { width: 48px; height: 48px; - border-radius: 17px; + border-radius: 50%; + border: 3px solid #fffaf4; + box-shadow: 0 0 0 1px #ead8ca; } .brand strong { display: block; @@ -221,7 +223,8 @@ strong { .welcome img { width: 116px; height: 116px; - border-radius: 32px; + border-radius: 50%; + border: 5px solid #fffaf4; transform: rotate(-8deg); box-shadow: 0 8px 30px #a5623615; } @@ -798,7 +801,8 @@ td strong { .login-story > img { width: 94px; height: 94px; - border-radius: 28px; + border-radius: 50%; + border: 4px solid #fffaf4; box-shadow: 0 12px 40px #aa683219; margin-bottom: 30px; transform: rotate(-6deg); @@ -1062,7 +1066,7 @@ td strong { .login-story > img { width: 54px; height: 54px; - border-radius: 17px; + border-radius: 50%; margin: 0 0 10px; } .login-story h1 { diff --git a/pets-fe/components/pet-id-card/index.js b/pets-fe/components/pet-id-card/index.js index a7f8ab2..9185d40 100644 --- a/pets-fe/components/pet-id-card/index.js +++ b/pets-fe/components/pet-id-card/index.js @@ -9,6 +9,19 @@ Component({ }, }, methods: { + async more() { + if (this.data.saving) return; + try { + const result = await wx.showActionSheet({ + itemList: ["编辑档案", "保存身份卡到相册"], + itemColor: "#795a4b", + }); + if (result.tapIndex === 0) this.edit(); + else if (result.tapIndex === 1) await this.save(); + } catch (error) { + if (!/cancel/.test(error.errMsg || "")) toast(error); + } + }, edit() { this.triggerEvent("edit", { id: this.data.pet.id }); }, diff --git a/pets-fe/components/pet-id-card/index.wxml b/pets-fe/components/pet-id-card/index.wxml index dc1c817..09e1635 100644 --- a/pets-fe/components/pet-id-card/index.wxml +++ b/pets-fe/components/pet-id-card/index.wxml @@ -1,10 +1,9 @@ - 肉垫计划PAWPRINT ID毛孩身份卡 + 肉垫计划PAWPRINT ID毛孩身份卡 {{card.name}}{{card.breed||'品种未填写'}} · {{card.genderLabel}}生日{{card.birthday}}体重{{card.weightLabel}}毛色{{card.coat||'未填写'}} - 陪伴编号{{card.cardNumber}}把陪伴,认真记下来 + 陪伴编号{{card.cardNumber}}{{saving?'正在生成身份卡…':'把陪伴,认真记下来'}} - diff --git a/pets-fe/components/pet-id-card/index.wxss b/pets-fe/components/pet-id-card/index.wxss index f0f2a1e..ea8d0e9 100644 --- a/pets-fe/components/pet-id-card/index.wxss +++ b/pets-fe/components/pet-id-card/index.wxss @@ -27,6 +27,9 @@ .brand image { width: 44rpx; height: 44rpx; + border-radius: 50%; + border: 3rpx solid #fffaf4; + box-shadow: 0 0 0 1rpx #dfcdbf; } .brand-name, .brand-en { @@ -133,26 +136,35 @@ max-width: 200rpx; text-align: right; } -.card-actions { +.id-heading { display: flex; - justify-content: flex-end; - gap: 16rpx; - margin-top: 12rpx; + align-items: center; + gap: 14rpx; } -.card-actions button { - margin: 0; - padding: 9rpx 20rpx; - border: 1rpx solid #ead8ca; - border-radius: 99rpx; - background: #fffaf4; - color: #886c5f; - font-size: 22rpx; - line-height: 1.5; +.more { + display: flex; + align-items: center; + justify-content: center; + gap: 5rpx; + margin: -10rpx -10rpx -10rpx 0; + width: 60rpx; + height: 60rpx; + padding: 0; + background: transparent; + border-radius: 50%; } -.card-actions .save { - background: #fff0e2; - color: #b95738; - border-color: #f1d6c4; +.more::after { + border: 0; +} +.more view { + width: 5rpx; + height: 5rpx; + border-radius: 50%; + background: #9d8779; +} +.more[disabled] { + opacity: 0.4; + background: transparent; } .export-canvas { position: fixed; diff --git a/pets-fe/utils/pet-card.js b/pets-fe/utils/pet-card.js index 7ef0ddf..06dd8ab 100644 --- a/pets-fe/utils/pet-card.js +++ b/pets-fe/utils/pet-card.js @@ -70,7 +70,17 @@ async function renderCard(canvas, pet) { round(ctx, 20, 20, 1160, 720, 34); ctx.stroke(); const logo = await image(canvas, "/assets/logo-corgi-v2.png"); + ctx.save(); + ctx.beginPath(); + ctx.arc(89, 87, 35, 0, Math.PI * 2); + ctx.clip(); ctx.drawImage(logo, 54, 52, 70, 70); + ctx.restore(); + ctx.strokeStyle = "#fffaf4"; + ctx.lineWidth = 5; + ctx.beginPath(); + ctx.arc(89, 87, 35, 0, Math.PI * 2); + ctx.stroke(); text(ctx, "肉垫计划", 140, 82, 27, "#795a4b", 220, true); text(ctx, "PAWPRINT ID", 140, 113, 18, "#a48d7e", 220); text(ctx, "毛孩身份卡", 842, 103, 38, "#604a40", 300, true); -- 2.54.0 From d6cb582ffe0c736aa068787118a1bbb423aaa940 Mon Sep 17 00:00:00 2001 From: Blizzard Date: Mon, 5 Oct 2026 11:43:10 +0800 Subject: [PATCH 5/7] Rename home tab to daily and add calendar sunshine icon --- pets-fe/components/tab-bar/index.js | 2 +- pets-fe/components/tab-bar/index.wxml | 10 ++-- pets-fe/components/tab-bar/index.wxss | 69 ++++++++++++++++----------- 3 files changed, 48 insertions(+), 33 deletions(-) diff --git a/pets-fe/components/tab-bar/index.js b/pets-fe/components/tab-bar/index.js index ffbb88a..a4676fc 100644 --- a/pets-fe/components/tab-bar/index.js +++ b/pets-fe/components/tab-bar/index.js @@ -1,5 +1,5 @@ const tabs = [ - { path: "/pages/home/home", label: "首页", key: "home" }, + { path: "/pages/home/home", label: "日常", key: "daily" }, { path: "/pages/meetups/meetups", label: "约遛", key: "meetups" }, { path: "/pages/walk/walk", label: "遛狗", key: "walk" }, { path: "/pages/tasks/tasks", label: "任务", key: "tasks" }, diff --git a/pets-fe/components/tab-bar/index.wxml b/pets-fe/components/tab-bar/index.wxml index c2a82f7..01b1ab7 100644 --- a/pets-fe/components/tab-bar/index.wxml +++ b/pets-fe/components/tab-bar/index.wxml @@ -18,10 +18,12 @@
- - - - + + + + + + diff --git a/pets-fe/components/tab-bar/index.wxss b/pets-fe/components/tab-bar/index.wxss index a0b1664..d439fa1 100644 --- a/pets-fe/components/tab-bar/index.wxss +++ b/pets-fe/components/tab-bar/index.wxss @@ -50,44 +50,57 @@ border-radius: 50%; background: #df936a; } -.home-icon { +.daily-icon { position: relative; - width: 42rpx; - height: 42rpx; + width: 39rpx; + height: 37rpx; + margin-top: 5rpx; + border: 3rpx solid currentColor; + border-radius: 9rpx; } -.home-roof { +.calendar-ring { position: absolute; - top: 3rpx; - left: 10rpx; - width: 25rpx; - height: 25rpx; - border-left: 4rpx solid currentColor; - border-top: 4rpx solid currentColor; + top: -8rpx; + width: 3rpx; + height: 11rpx; border-radius: 3rpx; - transform: rotate(45deg); + background: currentColor; } -.home-body { +.ring-left { left: 7rpx; } +.ring-right { right: 7rpx; } +.calendar-divider { + position: absolute; + top: 7rpx; + left: 0; + right: 0; + border-top: 3rpx solid currentColor; +} +.daily-rays { position: absolute; left: 6rpx; - right: 6rpx; - bottom: 1rpx; - height: 24rpx; - border-left: 4rpx solid currentColor; - border-right: 4rpx solid currentColor; - border-bottom: 4rpx solid currentColor; - border-radius: 0 0 5rpx 5rpx; + top: 12rpx; + width: 21rpx; + height: 21rpx; } -.home-door { +.daily-rays::before, .daily-rays::after { + content: ""; position: absolute; - left: 18rpx; - bottom: 2rpx; - width: 10rpx; - height: 15rpx; - border-left: 3rpx solid currentColor; - border-right: 3rpx solid currentColor; - border-top: 3rpx solid currentColor; - border-radius: 5rpx 5rpx 0 0; + border-radius: 2rpx; + background: currentColor; } +.daily-rays::before { left: 9rpx; top: 0; width: 3rpx; height: 21rpx; } +.daily-rays::after { left: 0; top: 9rpx; width: 21rpx; height: 3rpx; } +.daily-sun { + position: absolute; + left: 10rpx; + top: 16rpx; + width: 13rpx; + height: 13rpx; + border: 3rpx solid currentColor; + border-radius: 50%; + background: #fff; +} +.active .daily-sun { background: #fff0e2; } .friends-icon { position: relative; width: 48rpx; -- 2.54.0 From 607d709100e34f610743dd7cefe596515aaa6fbf Mon Sep 17 00:00:00 2001 From: Blizzard Date: Mon, 5 Oct 2026 12:01:37 +0800 Subject: [PATCH 6/7] Avoid reloading tasks when already viewing today --- pets-fe/pages/tasks/tasks.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pets-fe/pages/tasks/tasks.js b/pets-fe/pages/tasks/tasks.js index 7d54472..568fe3f 100644 --- a/pets-fe/pages/tasks/tasks.js +++ b/pets-fe/pages/tasks/tasks.js @@ -93,7 +93,9 @@ Page({ }, showToday() { if (this.data.completingAll || this.data.taskBusyIds.length) return; - this.setData({ date: localDate() }); + const today = localDate(); + if (this.data.date === today) return; + this.setData({ date: today }); this.load(); }, field(e) { -- 2.54.0 From 9d7cf720a5293fc9c9f3637cd41f27e675559c00 Mon Sep 17 00:00:00 2001 From: Blizzard Date: Mon, 5 Oct 2026 13:38:24 +0800 Subject: [PATCH 7/7] feat: add multi-source breed encyclopedia and two-hour refresh sessions --- deploy/.env.example | 2 + deploy/docker-compose.yml | 2 + pets-be/README.md | 18 +- pets-be/cmd/seedbreeds/main.go | 36 + pets-be/configs/config.example.yaml | 3 +- pets-be/configs/config.yaml | 2 + pets-be/go.mod | 1 + pets-be/go.sum | 2 + .../admin/dist/assets/index-BOnBpy-T.js | 57 - ...{index-7B3h3Yq6.css => index-CkSlqiFn.css} | 2 +- .../admin/dist/assets/index-N2FSM0pD.js | 59 + pets-be/internal/admin/dist/index.html | 4 +- pets-be/internal/admin/embed_test.go | 3 + pets-be/internal/breeds/README.md | 33 + pets-be/internal/breeds/breeds.go | 102 + pets-be/internal/breeds/breeds_test.go | 59 + pets-be/internal/breeds/data.json | 3429 +++ pets-be/internal/breeds/enrichment.go | 100 + pets-be/internal/breeds/enrichment.json | 19162 ++++++++++++++++ pets-be/internal/breeds/rkc_facts.json | 114 + pets-be/internal/config/config.go | 11 +- pets-be/internal/database/database.go | 4 + pets-be/internal/httpapi/auth.go | 10 +- pets-be/internal/httpapi/breeds.go | 219 + .../internal/httpapi/breeds_refresh_test.go | 269 + pets-be/internal/httpapi/files.go | 2 +- pets-be/internal/httpapi/pets.go | 25 +- pets-be/internal/httpapi/refresh.go | 139 + pets-be/internal/httpapi/server.go | 38 +- pets-be/internal/model/models.go | 56 +- pets-be/scripts/collect_breed_facts.py | 204 + pets-be/web/admin/package-lock.json | 58 + pets-be/web/admin/package.json | 1 + pets-be/web/admin/src/App.tsx | 38 +- .../web/admin/src/components/admin/Breeds.tsx | 660 + .../web/admin/src/components/admin/format.ts | 3 +- pets-be/web/admin/src/index.css | 25 + pets-be/web/admin/src/lib/api.ts | 211 +- pets-be/web/admin/src/main.tsx | 8 +- pets-fe/README.md | 2 + pets-fe/app.js | 31 +- pets-fe/app.json | 5 +- pets-fe/components/breed-picker/index.js | 88 + pets-fe/components/breed-picker/index.json | 1 + pets-fe/components/breed-picker/index.wxml | 27 + pets-fe/components/breed-picker/index.wxss | 30 + pets-fe/components/meetup-panel/index.js | 143 + .../meetup-panel/index.json} | 3 +- .../meetup-panel/index.wxml} | 8 +- .../meetup-panel/index.wxss} | 0 pets-fe/components/tab-bar/index.js | 4 +- pets-fe/components/tab-bar/index.wxml | 5 +- pets-fe/components/tab-bar/index.wxss | 29 +- pets-fe/pages/breed-detail/breed-detail.js | 85 + pets-fe/pages/breed-detail/breed-detail.json | 1 + pets-fe/pages/breed-detail/breed-detail.wxml | 14 + pets-fe/pages/breed-detail/breed-detail.wxss | 30 + pets-fe/pages/knowledge/knowledge.js | 50 + pets-fe/pages/knowledge/knowledge.json | 1 + pets-fe/pages/knowledge/knowledge.wxml | 12 + pets-fe/pages/knowledge/knowledge.wxss | 25 + pets-fe/pages/meetups/meetups.js | 108 - pets-fe/pages/pet-edit/pet-edit.js | 5 + pets-fe/pages/pet-edit/pet-edit.json | 4 +- pets-fe/pages/pet-edit/pet-edit.wxml | 2 +- pets-fe/pages/walk/walk.js | 5 + pets-fe/pages/walk/walk.json | 3 +- pets-fe/pages/walk/walk.wxml | 4 +- pets-fe/pages/walk/walk.wxss | 5 + pets-fe/utils/breeds.js | 46 + tests/admin-refresh.test.cjs | 34 + tests/miniprogram-breeds-refresh.test.cjs | 51 + tests/miniprogram-smoke.test.cjs | 3 +- 73 files changed, 25771 insertions(+), 264 deletions(-) create mode 100644 pets-be/cmd/seedbreeds/main.go delete mode 100644 pets-be/internal/admin/dist/assets/index-BOnBpy-T.js rename pets-be/internal/admin/dist/assets/{index-7B3h3Yq6.css => index-CkSlqiFn.css} (88%) create mode 100644 pets-be/internal/admin/dist/assets/index-N2FSM0pD.js create mode 100644 pets-be/internal/breeds/README.md create mode 100644 pets-be/internal/breeds/breeds.go create mode 100644 pets-be/internal/breeds/breeds_test.go create mode 100644 pets-be/internal/breeds/data.json create mode 100644 pets-be/internal/breeds/enrichment.go create mode 100644 pets-be/internal/breeds/enrichment.json create mode 100644 pets-be/internal/breeds/rkc_facts.json create mode 100644 pets-be/internal/httpapi/breeds.go create mode 100644 pets-be/internal/httpapi/breeds_refresh_test.go create mode 100644 pets-be/internal/httpapi/refresh.go create mode 100644 pets-be/scripts/collect_breed_facts.py create mode 100644 pets-be/web/admin/src/components/admin/Breeds.tsx create mode 100644 pets-fe/components/breed-picker/index.js create mode 100644 pets-fe/components/breed-picker/index.json create mode 100644 pets-fe/components/breed-picker/index.wxml create mode 100644 pets-fe/components/breed-picker/index.wxss create mode 100644 pets-fe/components/meetup-panel/index.js rename pets-fe/{pages/meetups/meetups.json => components/meetup-panel/index.json} (53%) rename pets-fe/{pages/meetups/meetups.wxml => components/meetup-panel/index.wxml} (93%) rename pets-fe/{pages/meetups/meetups.wxss => components/meetup-panel/index.wxss} (100%) create mode 100644 pets-fe/pages/breed-detail/breed-detail.js create mode 100644 pets-fe/pages/breed-detail/breed-detail.json create mode 100644 pets-fe/pages/breed-detail/breed-detail.wxml create mode 100644 pets-fe/pages/breed-detail/breed-detail.wxss create mode 100644 pets-fe/pages/knowledge/knowledge.js create mode 100644 pets-fe/pages/knowledge/knowledge.json create mode 100644 pets-fe/pages/knowledge/knowledge.wxml create mode 100644 pets-fe/pages/knowledge/knowledge.wxss delete mode 100644 pets-fe/pages/meetups/meetups.js create mode 100644 pets-fe/utils/breeds.js create mode 100644 tests/admin-refresh.test.cjs create mode 100644 tests/miniprogram-breeds-refresh.test.cjs diff --git a/deploy/.env.example b/deploy/.env.example index 92a96f5..70beac0 100644 --- a/deploy/.env.example +++ b/deploy/.env.example @@ -11,6 +11,8 @@ MINIO_SECRET_KEY=sundynix MINIO_BUCKET=sundynix-pet MINIO_USE_SSL=true +JWT_EXPIRE_HOURS=2 +JWT_REFRESH_HOURS=2 JWT_SECRET= WECHAT_APP_ID=wx52dfc635739a9c19 WECHAT_APP_SECRET= diff --git a/deploy/docker-compose.yml b/deploy/docker-compose.yml index c40c4d1..88f2eb9 100644 --- a/deploy/docker-compose.yml +++ b/deploy/docker-compose.yml @@ -20,6 +20,8 @@ services: PETS_MINIO_BUCKET: ${MINIO_BUCKET:-sundynix-pet} PETS_MINIO_USE_SSL: ${MINIO_USE_SSL:-true} PETS_JWT_SECRET: ${JWT_SECRET:?} + PETS_JWT_EXPIRE_HOURS: ${JWT_EXPIRE_HOURS:-2} + PETS_JWT_REFRESH_HOURS: ${JWT_REFRESH_HOURS:-2} PETS_WECHAT_APP_ID: ${WECHAT_APP_ID:?} PETS_WECHAT_APP_SECRET: ${WECHAT_APP_SECRET:?} PETS_AUTH_DEV_LOGIN: "false" diff --git a/pets-be/README.md b/pets-be/README.md index 529d376..0bee2e7 100644 --- a/pets-be/README.md +++ b/pets-be/README.md @@ -15,7 +15,7 @@ ## 本地启动 -1. `cp configs/config.example.yaml configs/config.yaml`,设置 PostgreSQL、MinIO、JWT 和微信参数。配置文件不进入 Git。 +1. `cp configs/config.example.yaml configs/config.yaml`,设置 PostgreSQL、MinIO、JWT 和微信参数。 2. `cd web/admin && npm ci && npm run build`。 3. 若数据库还不存在,在 `pets-be` 目录执行一次 `go run ./cmd/dbinit`。 4. 执行 `go run ./cmd/server`。 @@ -33,3 +33,19 @@ GORM 使用 `sundynix_` 表前缀、单数 snake_case 表名和字段名,例 ## 部署 `../deploy/docker-compose.yml` 使用外部 PostgreSQL 和 MinIO;把 `../deploy/.env.example` 复制为 `.env` 后设置凭据。`pet.sundynix.cn` 用于业务 API;`s3.sundynix.cn` 用于文件上传和图片直链。URL 由 MinIO endpoint、bucket 和 object key 拼接,在上传时写入文件表,格式为 `https://s3.sundynix.cn/sundynix-pet/`。`res.sundynix.cn/browser/...` 是 MinIO 控制台页面,不能作为图片直链。 + +## 管理端路由与犬种百科 + +菜单使用独立路由:`/admin/overview`、`/admin/users`、`/admin/pets`、`/admin/breeds`、`/admin/walks`、`/admin/meetups`、`/admin/tasks`、`/admin/files`;登录页 `/admin/login`。根路径自动进入工作台或登录页;Go 的 SPA 回退支持刷新和直达链接。业务接口仍在 `/api`,无需额外 API 前缀。 + +犬种目录自动导入 350 项(CKU 去重 347 项,另补充三种实用分类),按名称拼音 A–Z 排序。选品种使用 `breed_id`,手动填写保留 `breed` 名称并清空 `breed_id`。后台提供新增、编辑、启用、停用、搜索及每页十条分页。停用品种不影响已有宠物档案。 + +CKU 当前返回完整详情的 88 个犬种已整理基本资料、简短改写介绍和来源链接;另三项补充分类提供原创介绍。资料缺失时显示待补充,后台可以编辑百科字段。图片与长篇犬种标准未转载。 + +## 登录刷新 + +管理端和小程序的访问 token、refresh token 都为 **2 小时**。请求前发现不足一分钟即刷新;401 也会尝试刷新并仅重试一次。刷新凭证每次轮换,数据库只存 SHA-256 摘要;两个角色的凭证不能混用,停用账号、过期及退出会话都不能继续刷新。后台退出会撤销会话和其访问 token。 + +刷新成功后,两种凭证重新计时两小时;超过两小时未使用则重新登录。小程序自动重新微信登录,管理端回到登录页并保留原目标路由。并发接口共用刷新请求,支持 Web Locks 的浏览器还会跨标签页串行刷新;网络失败保留凭证以便重试。 + +接口:`POST /api/auth/refresh`、`POST /api/admin/refresh`,请求体为 `{ "refresh_token": "..." }`。登录与刷新响应包含 `token`、`refresh_token`、`expires_in: 7200`、`expires_at`、`refresh_expires_at`(Unix 秒)。旧七天 token 会要求重新登录。时长按业务约束固定两小时,旧环境变量不会把期限拉长。 diff --git a/pets-be/cmd/seedbreeds/main.go b/pets-be/cmd/seedbreeds/main.go new file mode 100644 index 0000000..8442342 --- /dev/null +++ b/pets-be/cmd/seedbreeds/main.go @@ -0,0 +1,36 @@ +// seedbreeds imports the embedded CKU breed catalog without overwriting administrator edits. +package main + +import ( + "github.com/sundynix/pets-be/internal/breeds" + "github.com/sundynix/pets-be/internal/config" + "github.com/sundynix/pets-be/internal/database" + "github.com/sundynix/pets-be/internal/model" + "log" +) + +func main() { + cfg, err := config.Load() + if err != nil { + log.Fatal(err) + } + db, err := database.Open(cfg.Postgres, true) + if err != nil { + log.Fatal(err) + } + // Only the schema needed by these features, leaving unrelated application records intact. + if err := db.AutoMigrate(&model.Breed{}, &model.BreedReference{}, &model.Pet{}, &model.RefreshSession{}); err != nil { + log.Fatal(err) + } + added, err := breeds.Seed(db) + if err != nil { + log.Fatal(err) + } + var total int64 + if err := db.Model(&model.Breed{}).Count(&total).Error; err != nil { + log.Fatal(err) + } + var sources int64 + db.Model(&model.BreedReference{}).Count(&sources) + log.Printf("breed catalog imported: added=%d total=%d references=%d", added, total, sources) +} diff --git a/pets-be/configs/config.example.yaml b/pets-be/configs/config.example.yaml index 8c9f4cc..78b71dc 100644 --- a/pets-be/configs/config.example.yaml +++ b/pets-be/configs/config.example.yaml @@ -19,7 +19,8 @@ minio: jwt: secret: "" # 用 PETS_JWT_SECRET 注入 - expire_hours: 168 + expire_hours: 2 + refresh_hours: 2 wechat: app_id: "" diff --git a/pets-be/configs/config.yaml b/pets-be/configs/config.yaml index 6a1a66c..4f70d38 100644 --- a/pets-be/configs/config.yaml +++ b/pets-be/configs/config.yaml @@ -18,6 +18,8 @@ minio: use_ssl: true jwt: + expire_hours: 2 + refresh_hours: 2 secret: kFdKDNCXpyJO2W+htdxobhHNzUIYuwcaZV94aJbIGHQ= # 生产用 PETS_JWT_SECRET 覆盖 wechat: diff --git a/pets-be/go.mod b/pets-be/go.mod index 8ac2fc2..c349e45 100644 --- a/pets-be/go.mod +++ b/pets-be/go.mod @@ -7,6 +7,7 @@ require ( github.com/golang-jwt/jwt/v5 v5.3.1 github.com/google/uuid v1.6.0 github.com/minio/minio-go/v7 v7.2.1 + github.com/mozillazg/go-pinyin v0.21.0 github.com/spf13/viper v1.21.0 golang.org/x/crypto v0.53.0 gorm.io/driver/postgres v1.6.0 diff --git a/pets-be/go.sum b/pets-be/go.sum index e8b48d7..531ef8d 100644 --- a/pets-be/go.sum +++ b/pets-be/go.sum @@ -86,6 +86,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/mozillazg/go-pinyin v0.21.0 h1:Wo8/NT45z7P3er/9YSLHA3/kjZzbLz5hR7i+jGeIGao= +github.com/mozillazg/go-pinyin v0.21.0/go.mod h1:iR4EnMMRXkfpFVV5FMi4FNB6wGq9NV6uDWbUuPhP4Yc= github.com/pelletier/go-toml/v2 v2.3.1 h1:MYEvvGnQjeNkRF1qUuGolNtNExTDwct51yp7olPtrEc= github.com/pelletier/go-toml/v2 v2.3.1/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM= diff --git a/pets-be/internal/admin/dist/assets/index-BOnBpy-T.js b/pets-be/internal/admin/dist/assets/index-BOnBpy-T.js deleted file mode 100644 index b1b2ff8..0000000 --- a/pets-be/internal/admin/dist/assets/index-BOnBpy-T.js +++ /dev/null @@ -1,57 +0,0 @@ -var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),s=(e,n)=>{let r={};for(var i in e)t(r,i,{get:e[i],enumerable:!0});return n||t(r,Symbol.toStringTag,{value:`Module`}),r},c=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;li[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},l=(n,r,a)=>(a=n==null?{}:e(i(n)),c(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),e.crossOrigin===`use-credentials`?t.credentials=`include`:e.crossOrigin===`anonymous`?t.credentials=`omit`:t.credentials=`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var u=o((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.portal`),r=Symbol.for(`react.fragment`),i=Symbol.for(`react.strict_mode`),a=Symbol.for(`react.profiler`),o=Symbol.for(`react.consumer`),s=Symbol.for(`react.context`),c=Symbol.for(`react.forward_ref`),l=Symbol.for(`react.suspense`),u=Symbol.for(`react.memo`),d=Symbol.for(`react.lazy`),f=Symbol.for(`react.activity`),p=Symbol.iterator;function m(e){return typeof e!=`object`||!e?null:(e=p&&e[p]||e[`@@iterator`],typeof e==`function`?e:null)}var h={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},g=Object.assign,_={};function v(e,t,n){this.props=e,this.context=t,this.refs=_,this.updater=n||h}v.prototype.isReactComponent={},v.prototype.setState=function(e,t){if(typeof e!=`object`&&typeof e!=`function`&&e!=null)throw Error(`takes an object of state variables to update or a function which returns an object of state variables.`);this.updater.enqueueSetState(this,e,t,`setState`)},v.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,`forceUpdate`)};function y(){}y.prototype=v.prototype;function b(e,t,n){this.props=e,this.context=t,this.refs=_,this.updater=n||h}var x=b.prototype=new y;x.constructor=b,g(x,v.prototype),x.isPureReactComponent=!0;var S=Array.isArray;function C(){}var w={H:null,A:null,T:null,S:null},T=Object.prototype.hasOwnProperty;function ee(e,n,r){var i=r.ref;return{$$typeof:t,type:e,key:n,ref:i===void 0?null:i,props:r}}function te(e,t){return ee(e.type,t,e.props)}function ne(e){return typeof e==`object`&&!!e&&e.$$typeof===t}function E(e){var t={"=":`=0`,":":`=2`};return`$`+e.replace(/[=:]/g,function(e){return t[e]})}var re=/\/+/g;function D(e,t){return typeof e==`object`&&e&&e.key!=null?E(``+e.key):t.toString(36)}function O(e){switch(e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason;default:switch(typeof e.status==`string`?e.then(C,C):(e.status=`pending`,e.then(function(t){e.status===`pending`&&(e.status=`fulfilled`,e.value=t)},function(t){e.status===`pending`&&(e.status=`rejected`,e.reason=t)})),e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason}}throw e}function ie(e,r,i,a,o){var s=typeof e;(s===`undefined`||s===`boolean`)&&(e=null);var c=!1;if(e===null)c=!0;else switch(s){case`bigint`:case`string`:case`number`:c=!0;break;case`object`:switch(e.$$typeof){case t:case n:c=!0;break;case d:return c=e._init,ie(c(e._payload),r,i,a,o)}}if(c)return o=o(e),c=a===``?`.`+D(e,0):a,S(o)?(i=``,c!=null&&(i=c.replace(re,`$&/`)+`/`),ie(o,r,i,``,function(e){return e})):o!=null&&(ne(o)&&(o=te(o,i+(o.key==null||e&&e.key===o.key?``:(``+o.key).replace(re,`$&/`)+`/`)+c)),r.push(o)),1;c=0;var l=a===``?`.`:a+`:`;if(S(e))for(var u=0;u{t.exports=u()})),f=o((e=>{function t(e,t){var n=e.length;e.push(t);a:for(;0>>1,a=e[r];if(0>>1;ri(c,n))li(u,c)?(e[r]=u,e[l]=n,r=l):(e[r]=c,e[s]=n,r=s);else if(li(u,n))e[r]=u,e[l]=n,r=l;else break a}}return t}function i(e,t){var n=e.sortIndex-t.sortIndex;return n===0?e.id-t.id:n}if(e.unstable_now=void 0,typeof performance==`object`&&typeof performance.now==`function`){var a=performance;e.unstable_now=function(){return a.now()}}else{var o=Date,s=o.now();e.unstable_now=function(){return o.now()-s}}var c=[],l=[],u=1,d=null,f=3,p=!1,m=!1,h=!1,g=!1,_=typeof setTimeout==`function`?setTimeout:null,v=typeof clearTimeout==`function`?clearTimeout:null,y=typeof setImmediate<`u`?setImmediate:null;function b(e){for(var i=n(l);i!==null;){if(i.callback===null)r(l);else if(i.startTime<=e)r(l),i.sortIndex=i.expirationTime,t(c,i);else break;i=n(l)}}function x(e){if(h=!1,b(e),!m)if(n(c)!==null)m=!0,S||(S=!0,ne());else{var t=n(l);t!==null&&D(x,t.startTime-e)}}var S=!1,C=-1,w=5,T=-1;function ee(){return g?!0:!(e.unstable_now()-Tt&&ee());){var o=d.callback;if(typeof o==`function`){d.callback=null,f=d.priorityLevel;var s=o(d.expirationTime<=t);if(t=e.unstable_now(),typeof s==`function`){d.callback=s,b(t),i=!0;break b}d===n(c)&&r(c),b(t)}else r(c);d=n(c)}if(d!==null)i=!0;else{var u=n(l);u!==null&&D(x,u.startTime-t),i=!1}}break a}finally{d=null,f=a,p=!1}i=void 0}}finally{i?ne():S=!1}}}var ne;if(typeof y==`function`)ne=function(){y(te)};else if(typeof MessageChannel<`u`){var E=new MessageChannel,re=E.port2;E.port1.onmessage=te,ne=function(){re.postMessage(null)}}else ne=function(){_(te,0)};function D(t,n){C=_(function(){t(e.unstable_now())},n)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(e){e.callback=null},e.unstable_forceFrameRate=function(e){0>e||125o?(r.sortIndex=a,t(l,r),n(c)===null&&r===n(l)&&(h?(v(C),C=-1):h=!0,D(x,a-o))):(r.sortIndex=s,t(c,r),m||p||(m=!0,S||(S=!0,ne()))),r},e.unstable_shouldYield=ee,e.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}})),p=o(((e,t)=>{t.exports=f()})),m=o((e=>{var t=d();function n(e){var t=`https://react.dev/errors/`+e;if(1{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=m()})),g=o((e=>{var t=p(),n=d(),r=h();function i(e){var t=`https://react.dev/errors/`+e;if(1le||(e.current=ce[le],ce[le]=null,le--)}function N(e,t){le++,ce[le]=e.current,e.current=t}var ue=j(null),de=j(null),fe=j(null),pe=j(null);function me(e,t){switch(N(fe,t),N(de,e),N(ue,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?Vd(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)t=Vd(t),e=Hd(t,e);else switch(e){case`svg`:e=1;break;case`math`:e=2;break;default:e=0}}M(ue),N(ue,e)}function he(){M(ue),M(de),M(fe)}function ge(e){e.memoizedState!==null&&N(pe,e);var t=ue.current,n=Hd(t,e.type);t!==n&&(N(de,e),N(ue,n))}function _e(e){de.current===e&&(M(ue),M(de)),pe.current===e&&(M(pe),Qf._currentValue=se)}var ve,ye;function be(e){if(ve===void 0)try{throw Error()}catch(e){var t=e.stack.trim().match(/\n( *(at )?)/);ve=t&&t[1]||``,ye=-1)`:-1i||c[r]!==l[i]){var u=` -`+c[r].replace(` at new `,` at `);return e.displayName&&u.includes(``)&&(u=u.replace(``,e.displayName)),u}while(1<=r&&0<=i);break}}}finally{xe=!1,Error.prepareStackTrace=n}return(n=e?e.displayName||e.name:``)?be(n):``}function Ce(e,t){switch(e.tag){case 26:case 27:case 5:return be(e.type);case 16:return be(`Lazy`);case 13:return e.child!==t&&t!==null?be(`Suspense Fallback`):be(`Suspense`);case 19:return be(`SuspenseList`);case 0:case 15:return Se(e.type,!1);case 11:return Se(e.type.render,!1);case 1:return Se(e.type,!0);case 31:return be(`Activity`);default:return``}}function we(e){try{var t=``,n=null;do t+=Ce(e,n),n=e,e=e.return;while(e);return t}catch(e){return` -Error generating stack: `+e.message+` -`+e.stack}}var Te=Object.prototype.hasOwnProperty,Ee=t.unstable_scheduleCallback,De=t.unstable_cancelCallback,Oe=t.unstable_shouldYield,ke=t.unstable_requestPaint,Ae=t.unstable_now,je=t.unstable_getCurrentPriorityLevel,Me=t.unstable_ImmediatePriority,Ne=t.unstable_UserBlockingPriority,Pe=t.unstable_NormalPriority,Fe=t.unstable_LowPriority,Ie=t.unstable_IdlePriority,Le=t.log,Re=t.unstable_setDisableYieldValue,ze=null,Be=null;function Ve(e){if(typeof Le==`function`&&Re(e),Be&&typeof Be.setStrictMode==`function`)try{Be.setStrictMode(ze,e)}catch{}}var He=Math.clz32?Math.clz32:Ge,Ue=Math.log,We=Math.LN2;function Ge(e){return e>>>=0,e===0?32:31-(Ue(e)/We|0)|0}var Ke=256,qe=262144,Je=4194304;function Ye(e){var t=e&42;if(t!==0)return t;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return e&261888;case 262144:case 524288:case 1048576:case 2097152:return e&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return e&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function Xe(e,t,n){var r=e.pendingLanes;if(r===0)return 0;var i=0,a=e.suspendedLanes,o=e.pingedLanes;e=e.warmLanes;var s=r&134217727;return s===0?(s=r&~a,s===0?o===0?n||(n=r&~e,n!==0&&(i=Ye(n))):i=Ye(o):i=Ye(s)):(r=s&~a,r===0?(o&=s,o===0?n||(n=s&~e,n!==0&&(i=Ye(n))):i=Ye(o)):i=Ye(r)),i===0?0:t!==0&&t!==i&&(t&a)===0&&(a=i&-i,n=t&-t,a>=n||a===32&&n&4194048)?t:i}function Ze(e,t){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)===0}function Qe(e,t){switch(e){case 1:case 2:case 4:case 8:case 64:return t+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function $e(){var e=Je;return Je<<=1,!(Je&62914560)&&(Je=4194304),e}function et(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function tt(e,t){e.pendingLanes|=t,t!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function nt(e,t,n,r,i,a){var o=e.pendingLanes;e.pendingLanes=n,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=n,e.entangledLanes&=n,e.errorRecoveryDisabledLanes&=n,e.shellSuspendCounter=0;var s=e.entanglements,c=e.expirationTimes,l=e.hiddenUpdates;for(n=o&~n;0`u`||window.document===void 0||window.document.createElement===void 0),dn=!1;if(un)try{var fn={};Object.defineProperty(fn,"passive",{get:function(){dn=!0}}),window.addEventListener(`test`,fn,fn),window.removeEventListener(`test`,fn,fn)}catch{dn=!1}var pn=null,mn=null,hn=null;function gn(){if(hn)return hn;var e,t=mn,n=t.length,r,i=`value`in pn?pn.value:pn.textContent,a=i.length;for(e=0;e=Jn),Zn=` `,Qn=!1;function $n(e,t){switch(e){case`keyup`:return Kn.indexOf(t.keyCode)!==-1;case`keydown`:return t.keyCode!==229;case`keypress`:case`mousedown`:case`focusout`:return!0;default:return!1}}function er(e){return e=e.detail,typeof e==`object`&&`data`in e?e.data:null}var tr=!1;function nr(e,t){switch(e){case`compositionend`:return er(t);case`keypress`:return t.which===32?(Qn=!0,Zn):null;case`textInput`:return e=t.data,e===Zn&&Qn?null:e;default:return null}}function rr(e,t){if(tr)return e===`compositionend`||!qn&&$n(e,t)?(e=gn(),hn=mn=pn=null,tr=!1,e):null;switch(e){case`paste`:return null;case`keypress`:if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:n,offset:t-e};e=r}a:{for(;n;){if(n.nextSibling){n=n.nextSibling;break a}n=n.parentNode}n=void 0}n=Tr(n)}}function Dr(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?Dr(e,t.parentNode):`contains`in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function Or(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var t=zt(e.document);t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href==`string`}catch{n=!1}if(n)e=t.contentWindow;else break;t=zt(e.document)}return t}function kr(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t===`input`&&(e.type===`text`||e.type===`search`||e.type===`tel`||e.type===`url`||e.type===`password`)||t===`textarea`||e.contentEditable===`true`)}var Ar=un&&`documentMode`in document&&11>=document.documentMode,jr=null,Mr=null,Nr=null,Pr=!1;function Fr(e,t,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;Pr||jr==null||jr!==zt(r)||(r=jr,`selectionStart`in r&&kr(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),Nr&&wr(Nr,r)||(Nr=r,r=Ed(Mr,`onSelect`),0>=o,i-=o,Di=1<<32-He(t)+i|n<h?(g=d,d=null):g=d.sibling;var _=p(i,d,s[h],c);if(_===null){d===null&&(d=g);break}e&&d&&_.alternate===null&&t(i,d),a=o(_,a,h),u===null?l=_:u.sibling=_,u=_,d=g}if(h===s.length)return n(i,d),z&&ki(i,h),l;if(d===null){for(;hg?(_=h,h=null):_=h.sibling;var y=p(a,h,v.value,l);if(y===null){h===null&&(h=_);break}e&&h&&y.alternate===null&&t(a,h),s=o(y,s,g),d===null?u=y:d.sibling=y,d=y,h=_}if(v.done)return n(a,h),z&&ki(a,g),u;if(h===null){for(;!v.done;g++,v=c.next())v=f(a,v.value,l),v!==null&&(s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return z&&ki(a,g),u}for(h=r(h);!v.done;g++,v=c.next())v=m(h,a,g,v.value,l),v!==null&&(e&&v.alternate!==null&&h.delete(v.key===null?g:v.key),s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return e&&h.forEach(function(e){return t(a,e)}),z&&ki(a,g),u}function b(e,r,o,c){if(typeof o==`object`&&o&&o.type===y&&o.key===null&&(o=o.props.children),typeof o==`object`&&o){switch(o.$$typeof){case _:a:{for(var l=o.key;r!==null;){if(r.key===l){if(l=o.type,l===y){if(r.tag===7){n(e,r.sibling),c=a(r,o.props.children),c.return=e,e=c;break a}}else if(r.elementType===l||typeof l==`object`&&l&&l.$$typeof===ne&&Oa(l)===r.type){n(e,r.sibling),c=a(r,o.props),Fa(c,o),c.return=e,e=c;break a}n(e,r);break}else t(e,r);r=r.sibling}o.type===y?(c=mi(o.props.children,e.mode,c,o.key),c.return=e,e=c):(c=pi(o.type,o.key,o.props,null,e.mode,c),Fa(c,o),c.return=e,e=c)}return s(e);case v:a:{for(l=o.key;r!==null;){if(r.key===l)if(r.tag===4&&r.stateNode.containerInfo===o.containerInfo&&r.stateNode.implementation===o.implementation){n(e,r.sibling),c=a(r,o.children||[]),c.return=e,e=c;break a}else{n(e,r);break}else t(e,r);r=r.sibling}c=_i(o,e.mode,c),c.return=e,e=c}return s(e);case ne:return o=Oa(o),b(e,r,o,c)}if(oe(o))return h(e,r,o,c);if(O(o)){if(l=O(o),typeof l!=`function`)throw Error(i(150));return o=l.call(o),g(e,r,o,c)}if(typeof o.then==`function`)return b(e,r,Pa(o),c);if(o.$$typeof===C)return b(e,r,na(e,o),c);Ia(e,o)}return typeof o==`string`&&o!==``||typeof o==`number`||typeof o==`bigint`?(o=``+o,r!==null&&r.tag===6?(n(e,r.sibling),c=a(r,o),c.return=e,e=c):(n(e,r),c=hi(o,e.mode,c),c.return=e,e=c),s(e)):n(e,r)}return function(e,t,n,r){try{Na=0;var i=b(e,t,n,r);return Ma=null,i}catch(t){if(t===Sa||t===wa)throw t;var a=li(29,t,null,e.mode);return a.lanes=r,a.return=e,a}}}var Ra=La(!0),za=La(!1),Ba=!1;function Va(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function Ha(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,callbacks:null})}function Ua(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function Wa(e,t,n){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,K&2){var i=r.pending;return i===null?t.next=t:(t.next=i.next,i.next=t),r.pending=t,t=oi(e),ai(e,null,n),t}return ni(e,r,t,n),oi(e)}function Ga(e,t,n){if(t=t.updateQueue,t!==null&&(t=t.shared,n&4194048)){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,it(e,n)}}function Ka(e,t){var n=e.updateQueue,r=e.alternate;if(r!==null&&(r=r.updateQueue,n===r)){var i=null,a=null;if(n=n.firstBaseUpdate,n!==null){do{var o={lane:n.lane,tag:n.tag,payload:n.payload,callback:null,next:null};a===null?i=a=o:a=a.next=o,n=n.next}while(n!==null);a===null?i=a=t:a=a.next=t}else i=a=t;n={baseState:r.baseState,firstBaseUpdate:i,lastBaseUpdate:a,shared:r.shared,callbacks:r.callbacks},e.updateQueue=n;return}e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}var qa=!1;function Ja(){if(qa){var e=pa;if(e!==null)throw e}}function Ya(e,t,n,r){qa=!1;var i=e.updateQueue;Ba=!1;var a=i.firstBaseUpdate,o=i.lastBaseUpdate,s=i.shared.pending;if(s!==null){i.shared.pending=null;var c=s,l=c.next;c.next=null,o===null?a=l:o.next=l,o=c;var u=e.alternate;u!==null&&(u=u.updateQueue,s=u.lastBaseUpdate,s!==o&&(s===null?u.firstBaseUpdate=l:s.next=l,u.lastBaseUpdate=c))}if(a!==null){var d=i.baseState;o=0,u=l=c=null,s=a;do{var f=s.lane&-536870913,p=f!==s.lane;if(p?(Y&f)===f:(r&f)===f){f!==0&&f===fa&&(qa=!0),u!==null&&(u=u.next={lane:0,tag:s.tag,payload:s.payload,callback:null,next:null});a:{var h=e,g=s;f=t;var _=n;switch(g.tag){case 1:if(h=g.payload,typeof h==`function`){d=h.call(_,d,f);break a}d=h;break a;case 3:h.flags=h.flags&-65537|128;case 0:if(h=g.payload,f=typeof h==`function`?h.call(_,d,f):h,f==null)break a;d=m({},d,f);break a;case 2:Ba=!0}}f=s.callback,f!==null&&(e.flags|=64,p&&(e.flags|=8192),p=i.callbacks,p===null?i.callbacks=[f]:p.push(f))}else p={lane:f,tag:s.tag,payload:s.payload,callback:s.callback,next:null},u===null?(l=u=p,c=d):u=u.next=p,o|=f;if(s=s.next,s===null){if(s=i.shared.pending,s===null)break;p=s,s=p.next,p.next=null,i.lastBaseUpdate=p,i.shared.pending=null}}while(1);u===null&&(c=d),i.baseState=c,i.firstBaseUpdate=l,i.lastBaseUpdate=u,a===null&&(i.shared.lanes=0),Gl|=o,e.lanes=o,e.memoizedState=d}}function Xa(e,t){if(typeof e!=`function`)throw Error(i(191,e));e.call(t)}function Za(e,t){var n=e.callbacks;if(n!==null)for(e.callbacks=null,e=0;ea?a:8;var o=k.T,s={};k.T=s,Ps(e,!1,t,n);try{var c=i(),l=k.S;l!==null&&l(s,c),typeof c==`object`&&c&&typeof c.then==`function`?Ns(e,t,ga(c,r),pu(e)):Ns(e,t,r,pu(e))}catch(n){Ns(e,t,{then:function(){},status:`rejected`,reason:n},pu())}finally{A.p=a,o!==null&&s.types!==null&&(o.types=s.types),k.T=o}}function Cs(){}function ws(e,t,n,r){if(e.tag!==5)throw Error(i(476));var a=Ts(e).queue;Ss(e,a,t,se,n===null?Cs:function(){return Es(e),n(r)})}function Ts(e){var t=e.memoizedState;if(t!==null)return t;t={memoizedState:se,baseState:se,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Io,lastRenderedState:se},next:null};var n={};return t.next={memoizedState:n,baseState:n,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Io,lastRenderedState:n},next:null},e.memoizedState=t,e=e.alternate,e!==null&&(e.memoizedState=t),t}function Es(e){var t=Ts(e);t.next===null&&(t=e.alternate.memoizedState),Ns(e,t.next.queue,{},pu())}function Ds(){return ta(Qf)}function Os(){return jo().memoizedState}function ks(){return jo().memoizedState}function As(e){for(var t=e.return;t!==null;){switch(t.tag){case 24:case 3:var n=pu();e=Ua(n);var r=Wa(t,e,n);r!==null&&(hu(r,t,n),Ga(r,t,n)),t={cache:ca()},e.payload=t;return}t=t.return}}function js(e,t,n){var r=pu();n={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null},Fs(e)?Is(t,n):(n=ri(e,t,n,r),n!==null&&(hu(n,e,r),Ls(n,t,r)))}function Ms(e,t,n){Ns(e,t,n,pu())}function Ns(e,t,n,r){var i={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null};if(Fs(e))Is(t,i);else{var a=e.alternate;if(e.lanes===0&&(a===null||a.lanes===0)&&(a=t.lastRenderedReducer,a!==null))try{var o=t.lastRenderedState,s=a(o,n);if(i.hasEagerState=!0,i.eagerState=s,Cr(s,o))return ni(e,t,i,0),q===null&&ti(),!1}catch{}if(n=ri(e,t,i,r),n!==null)return hu(n,e,r),Ls(n,t,r),!0}return!1}function Ps(e,t,n,r){if(r={lane:2,revertLane:dd(),gesture:null,action:r,hasEagerState:!1,eagerState:null,next:null},Fs(e)){if(t)throw Error(i(479))}else t=ri(e,n,r,2),t!==null&&hu(t,e,2)}function Fs(e){var t=e.alternate;return e===B||t!==null&&t===B}function Is(e,t){go=ho=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function Ls(e,t,n){if(n&4194048){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,it(e,n)}}var Rs={readContext:ta,use:Po,useCallback:So,useContext:So,useEffect:So,useImperativeHandle:So,useLayoutEffect:So,useInsertionEffect:So,useMemo:So,useReducer:So,useRef:So,useState:So,useDebugValue:So,useDeferredValue:So,useTransition:So,useSyncExternalStore:So,useId:So,useHostTransitionStatus:So,useFormState:So,useActionState:So,useOptimistic:So,useMemoCache:So,useCacheRefresh:So};Rs.useEffectEvent=So;var zs={readContext:ta,use:Po,useCallback:function(e,t){return Ao().memoizedState=[e,t===void 0?null:t],e},useContext:ta,useEffect:ls,useImperativeHandle:function(e,t,n){n=n==null?null:n.concat([e]),ss(4194308,4,hs.bind(null,t,e),n)},useLayoutEffect:function(e,t){return ss(4194308,4,e,t)},useInsertionEffect:function(e,t){ss(4,2,e,t)},useMemo:function(e,t){var n=Ao();t=t===void 0?null:t;var r=e();if(_o){Ve(!0);try{e()}finally{Ve(!1)}}return n.memoizedState=[r,t],r},useReducer:function(e,t,n){var r=Ao();if(n!==void 0){var i=n(t);if(_o){Ve(!0);try{n(t)}finally{Ve(!1)}}}else i=t;return r.memoizedState=r.baseState=i,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:i},r.queue=e,e=e.dispatch=js.bind(null,B,e),[r.memoizedState,e]},useRef:function(e){var t=Ao();return e={current:e},t.memoizedState=e},useState:function(e){e=Ko(e);var t=e.queue,n=Ms.bind(null,B,t);return t.dispatch=n,[e.memoizedState,n]},useDebugValue:_s,useDeferredValue:function(e,t){return bs(Ao(),e,t)},useTransition:function(){var e=Ko(!1);return e=Ss.bind(null,B,e.queue,!0,!1),Ao().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,t,n){var r=B,a=Ao();if(z){if(n===void 0)throw Error(i(407));n=n()}else{if(n=t(),q===null)throw Error(i(349));Y&127||Vo(r,t,n)}a.memoizedState=n;var o={value:n,getSnapshot:t};return a.queue=o,ls(Uo.bind(null,r,o,e),[e]),r.flags|=2048,as(9,{destroy:void 0},Ho.bind(null,r,o,n,t),null),n},useId:function(){var e=Ao(),t=q.identifierPrefix;if(z){var n=Oi,r=Di;n=(r&~(1<<32-He(r)-1)).toString(32)+n,t=`_`+t+`R_`+n,n=vo++,0<\/script>`,o=o.removeChild(o.firstChild);break;case`select`:o=typeof r.is==`string`?s.createElement(`select`,{is:r.is}):s.createElement(`select`),r.multiple?o.multiple=!0:r.size&&(o.size=r.size);break;default:o=typeof r.is==`string`?s.createElement(a,{is:r.is}):s.createElement(a)}}o[dt]=t,o[ft]=r;a:for(s=t.child;s!==null;){if(s.tag===5||s.tag===6)o.appendChild(s.stateNode);else if(s.tag!==4&&s.tag!==27&&s.child!==null){s.child.return=s,s=s.child;continue}if(s===t)break a;for(;s.sibling===null;){if(s.return===null||s.return===t)break a;s=s.return}s.sibling.return=s.return,s=s.sibling}t.stateNode=o;a:switch(Pd(o,a,r),a){case`button`:case`input`:case`select`:case`textarea`:r=!!r.autoFocus;break a;case`img`:r=!0;break a;default:r=!1}r&&Nc(t)}}return W(t),Pc(t,t.type,e===null?null:e.memoizedProps,t.pendingProps,n),null;case 6:if(e&&t.stateNode!=null)e.memoizedProps!==r&&Nc(t);else{if(typeof r!=`string`&&t.stateNode===null)throw Error(i(166));if(e=fe.current,Vi(t)){if(e=t.stateNode,n=t.memoizedProps,r=null,a=Pi,a!==null)switch(a.tag){case 27:case 5:r=a.memoizedProps}e[dt]=t,e=!!(e.nodeValue===n||r!==null&&!0===r.suppressHydrationWarning||Md(e.nodeValue,n)),e||Ri(t,!0)}else e=Bd(e).createTextNode(r),e[dt]=t,t.stateNode=e}return W(t),null;case 31:if(n=t.memoizedState,e===null||e.memoizedState!==null){if(r=Vi(t),n!==null){if(e===null){if(!r)throw Error(i(318));if(e=t.memoizedState,e=e===null?null:e.dehydrated,!e)throw Error(i(557));e[dt]=t}else Hi(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;W(t),e=!1}else n=Ui(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=n),e=!0;if(!e)return t.flags&256?(lo(t),t):(lo(t),null);if(t.flags&128)throw Error(i(558))}return W(t),null;case 13:if(r=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(a=Vi(t),r!==null&&r.dehydrated!==null){if(e===null){if(!a)throw Error(i(318));if(a=t.memoizedState,a=a===null?null:a.dehydrated,!a)throw Error(i(317));a[dt]=t}else Hi(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;W(t),a=!1}else a=Ui(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=a),a=!0;if(!a)return t.flags&256?(lo(t),t):(lo(t),null)}return lo(t),t.flags&128?(t.lanes=n,t):(n=r!==null,e=e!==null&&e.memoizedState!==null,n&&(r=t.child,a=null,r.alternate!==null&&r.alternate.memoizedState!==null&&r.alternate.memoizedState.cachePool!==null&&(a=r.alternate.memoizedState.cachePool.pool),o=null,r.memoizedState!==null&&r.memoizedState.cachePool!==null&&(o=r.memoizedState.cachePool.pool),o!==a&&(r.flags|=2048)),n!==e&&n&&(t.child.flags|=8192),Ic(t,t.updateQueue),W(t),null);case 4:return he(),e===null&&Sd(t.stateNode.containerInfo),W(t),null;case 10:return Yi(t.type),W(t),null;case 19:if(M(uo),r=t.memoizedState,r===null)return W(t),null;if(a=(t.flags&128)!=0,o=r.rendering,o===null)if(a)Lc(r,!1);else{if(Wl!==0||e!==null&&e.flags&128)for(e=t.child;e!==null;){if(o=fo(e),o!==null){for(t.flags|=128,Lc(r,!1),e=o.updateQueue,t.updateQueue=e,Ic(t,e),t.subtreeFlags=0,e=n,n=t.child;n!==null;)fi(n,e),n=n.sibling;return N(uo,uo.current&1|2),z&&ki(t,r.treeForkCount),t.child}e=e.sibling}r.tail!==null&&Ae()>tu&&(t.flags|=128,a=!0,Lc(r,!1),t.lanes=4194304)}else{if(!a)if(e=fo(o),e!==null){if(t.flags|=128,a=!0,e=e.updateQueue,t.updateQueue=e,Ic(t,e),Lc(r,!0),r.tail===null&&r.tailMode===`hidden`&&!o.alternate&&!z)return W(t),null}else 2*Ae()-r.renderingStartTime>tu&&n!==536870912&&(t.flags|=128,a=!0,Lc(r,!1),t.lanes=4194304);r.isBackwards?(o.sibling=t.child,t.child=o):(e=r.last,e===null?t.child=o:e.sibling=o,r.last=o)}return r.tail===null?(W(t),null):(e=r.tail,r.rendering=e,r.tail=e.sibling,r.renderingStartTime=Ae(),e.sibling=null,n=uo.current,N(uo,a?n&1|2:n&1),z&&ki(t,r.treeForkCount),e);case 22:case 23:return lo(t),no(),r=t.memoizedState!==null,e===null?r&&(t.flags|=8192):e.memoizedState!==null!==r&&(t.flags|=8192),r?n&536870912&&!(t.flags&128)&&(W(t),t.subtreeFlags&6&&(t.flags|=8192)):W(t),n=t.updateQueue,n!==null&&Ic(t,n.retryQueue),n=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(n=e.memoizedState.cachePool.pool),r=null,t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(r=t.memoizedState.cachePool.pool),r!==n&&(t.flags|=2048),e!==null&&M(va),null;case 24:return n=null,e!==null&&(n=e.memoizedState.cache),t.memoizedState.cache!==n&&(t.flags|=2048),Yi(sa),W(t),null;case 25:return null;case 30:return null}throw Error(i(156,t.tag))}function zc(e,t){switch(Mi(t),t.tag){case 1:return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return Yi(sa),he(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 26:case 27:case 5:return _e(t),null;case 31:if(t.memoizedState!==null){if(lo(t),t.alternate===null)throw Error(i(340));Hi()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 13:if(lo(t),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(i(340));Hi()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return M(uo),null;case 4:return he(),null;case 10:return Yi(t.type),null;case 22:case 23:return lo(t),no(),e!==null&&M(va),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 24:return Yi(sa),null;case 25:return null;default:return null}}function Bc(e,t){switch(Mi(t),t.tag){case 3:Yi(sa),he();break;case 26:case 27:case 5:_e(t);break;case 4:he();break;case 31:t.memoizedState!==null&&lo(t);break;case 13:lo(t);break;case 19:M(uo);break;case 10:Yi(t.type);break;case 22:case 23:lo(t),no(),e!==null&&M(va);break;case 24:Yi(sa)}}function Vc(e,t){try{var n=t.updateQueue,r=n===null?null:n.lastEffect;if(r!==null){var i=r.next;n=i;do{if((n.tag&e)===e){r=void 0;var a=n.create,o=n.inst;r=a(),o.destroy=r}n=n.next}while(n!==i)}}catch(e){Z(t,t.return,e)}}function Hc(e,t,n){try{var r=t.updateQueue,i=r===null?null:r.lastEffect;if(i!==null){var a=i.next;r=a;do{if((r.tag&e)===e){var o=r.inst,s=o.destroy;if(s!==void 0){o.destroy=void 0,i=t;var c=n,l=s;try{l()}catch(e){Z(i,c,e)}}}r=r.next}while(r!==a)}}catch(e){Z(t,t.return,e)}}function Uc(e){var t=e.updateQueue;if(t!==null){var n=e.stateNode;try{Za(t,n)}catch(t){Z(e,e.return,t)}}}function Wc(e,t,n){n.props=Ks(e.type,e.memoizedProps),n.state=e.memoizedState;try{n.componentWillUnmount()}catch(n){Z(e,t,n)}}function Gc(e,t){try{var n=e.ref;if(n!==null){switch(e.tag){case 26:case 27:case 5:var r=e.stateNode;break;case 30:r=e.stateNode;break;default:r=e.stateNode}typeof n==`function`?e.refCleanup=n(r):n.current=r}}catch(n){Z(e,t,n)}}function Kc(e,t){var n=e.ref,r=e.refCleanup;if(n!==null)if(typeof r==`function`)try{r()}catch(n){Z(e,t,n)}finally{e.refCleanup=null,e=e.alternate,e!=null&&(e.refCleanup=null)}else if(typeof n==`function`)try{n(null)}catch(n){Z(e,t,n)}else n.current=null}function qc(e){var t=e.type,n=e.memoizedProps,r=e.stateNode;try{a:switch(t){case`button`:case`input`:case`select`:case`textarea`:n.autoFocus&&r.focus();break a;case`img`:n.src?r.src=n.src:n.srcSet&&(r.srcset=n.srcSet)}}catch(t){Z(e,e.return,t)}}function Jc(e,t,n){try{var r=e.stateNode;Fd(r,e.type,n,t),r[ft]=t}catch(t){Z(e,e.return,t)}}function Yc(e){return e.tag===5||e.tag===3||e.tag===26||e.tag===27&&Zd(e.type)||e.tag===4}function Xc(e){a:for(;;){for(;e.sibling===null;){if(e.return===null||Yc(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.tag===27&&Zd(e.type)||e.flags&2||e.child===null||e.tag===4)continue a;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function Zc(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?(n.nodeType===9?n.body:n.nodeName===`HTML`?n.ownerDocument.body:n).insertBefore(e,t):(t=n.nodeType===9?n.body:n.nodeName===`HTML`?n.ownerDocument.body:n,t.appendChild(e),n=n._reactRootContainer,n!=null||t.onclick!==null||(t.onclick=tn));else if(r!==4&&(r===27&&Zd(e.type)&&(n=e.stateNode,t=null),e=e.child,e!==null))for(Zc(e,t,n),e=e.sibling;e!==null;)Zc(e,t,n),e=e.sibling}function Qc(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(r!==4&&(r===27&&Zd(e.type)&&(n=e.stateNode),e=e.child,e!==null))for(Qc(e,t,n),e=e.sibling;e!==null;)Qc(e,t,n),e=e.sibling}function $c(e){var t=e.stateNode,n=e.memoizedProps;try{for(var r=e.type,i=t.attributes;i.length;)t.removeAttributeNode(i[0]);Pd(t,r,n),t[dt]=e,t[ft]=n}catch(t){Z(e,e.return,t)}}var el=!1,G=!1,tl=!1,nl=typeof WeakSet==`function`?WeakSet:Set,rl=null;function il(e,t){if(e=e.containerInfo,Rd=sp,e=Or(e),kr(e)){if(`selectionStart`in e)var n={start:e.selectionStart,end:e.selectionEnd};else a:{n=(n=e.ownerDocument)&&n.defaultView||window;var r=n.getSelection&&n.getSelection();if(r&&r.rangeCount!==0){n=r.anchorNode;var a=r.anchorOffset,o=r.focusNode;r=r.focusOffset;try{n.nodeType,o.nodeType}catch{n=null;break a}var s=0,c=-1,l=-1,u=0,d=0,f=e,p=null;b:for(;;){for(var m;f!==n||a!==0&&f.nodeType!==3||(c=s+a),f!==o||r!==0&&f.nodeType!==3||(l=s+r),f.nodeType===3&&(s+=f.nodeValue.length),(m=f.firstChild)!==null;)p=f,f=m;for(;;){if(f===e)break b;if(p===n&&++u===a&&(c=s),p===o&&++d===r&&(l=s),(m=f.nextSibling)!==null)break;f=p,p=f.parentNode}f=m}n=c===-1||l===-1?null:{start:c,end:l}}else n=null}n||={start:0,end:0}}else n=null;for(zd={focusedElem:e,selectionRange:n},sp=!1,rl=t;rl!==null;)if(t=rl,e=t.child,t.subtreeFlags&1028&&e!==null)e.return=t,rl=e;else for(;rl!==null;){switch(t=rl,o=t.alternate,e=t.flags,t.tag){case 0:if(e&4&&(e=t.updateQueue,e=e===null?null:e.events,e!==null))for(n=0;n title`))),Pd(o,r,n),o[dt]=e,wt(o),r=o;break a;case`link`:var s=Vf(`link`,`href`,a).get(r+(n.href||``));if(s){for(var c=0;cg&&(o=g,g=h,h=o);var _=Er(s,h),v=Er(s,g);if(_&&v&&(p.rangeCount!==1||p.anchorNode!==_.node||p.anchorOffset!==_.offset||p.focusNode!==v.node||p.focusOffset!==v.offset)){var y=d.createRange();y.setStart(_.node,_.offset),p.removeAllRanges(),h>g?(p.addRange(y),p.extend(v.node,v.offset)):(y.setEnd(v.node,v.offset),p.addRange(y))}}}}for(d=[],p=s;p=p.parentNode;)p.nodeType===1&&d.push({element:p,left:p.scrollLeft,top:p.scrollTop});for(typeof s.focus==`function`&&s.focus(),s=0;sn?32:n,k.T=null,n=lu,lu=null;var o=au,s=su;if(iu=0,ou=au=null,su=0,K&6)throw Error(i(331));var c=K;if(K|=4,Pl(o.current),El(o,o.current,s,n),K=c,id(0,!1),Be&&typeof Be.onPostCommitFiberRoot==`function`)try{Be.onPostCommitFiberRoot(ze,o)}catch{}return!0}finally{A.p=a,k.T=r,Vu(e,t)}}function Wu(e,t,n){t=yi(n,t),t=Qs(e.stateNode,t,2),e=Wa(e,t,2),e!==null&&(tt(e,2),rd(e))}function Z(e,t,n){if(e.tag===3)Wu(e,e,n);else for(;t!==null;){if(t.tag===3){Wu(t,e,n);break}else if(t.tag===1){var r=t.stateNode;if(typeof t.type.getDerivedStateFromError==`function`||typeof r.componentDidCatch==`function`&&(ru===null||!ru.has(r))){e=yi(n,e),n=$s(2),r=Wa(t,n,2),r!==null&&(ec(n,r,t,e),tt(r,2),rd(r));break}}t=t.return}}function Gu(e,t,n){var r=e.pingCache;if(r===null){r=e.pingCache=new Rl;var i=new Set;r.set(t,i)}else i=r.get(t),i===void 0&&(i=new Set,r.set(t,i));i.has(n)||(Hl=!0,i.add(n),e=Ku.bind(null,e,t,n),t.then(e,e))}function Ku(e,t,n){var r=e.pingCache;r!==null&&r.delete(t),e.pingedLanes|=e.suspendedLanes&n,e.warmLanes&=~n,q===e&&(Y&n)===n&&(Wl===4||Wl===3&&(Y&62914560)===Y&&300>Ae()-$l?!(K&2)&&Su(e,0):ql|=n,Yl===Y&&(Yl=0)),rd(e)}function qu(e,t){t===0&&(t=$e()),e=ii(e,t),e!==null&&(tt(e,t),rd(e))}function Ju(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),qu(e,n)}function Yu(e,t){var n=0;switch(e.tag){case 31:case 13:var r=e.stateNode,a=e.memoizedState;a!==null&&(n=a.retryLane);break;case 19:r=e.stateNode;break;case 22:r=e.stateNode._retryCache;break;default:throw Error(i(314))}r!==null&&r.delete(t),qu(e,n)}function Xu(e,t){return Ee(e,t)}var Zu=null,Qu=null,$u=!1,ed=!1,td=!1,nd=0;function rd(e){e!==Qu&&e.next===null&&(Qu===null?Zu=Qu=e:Qu=Qu.next=e),ed=!0,$u||($u=!0,ud())}function id(e,t){if(!td&&ed){td=!0;do for(var n=!1,r=Zu;r!==null;){if(!t)if(e!==0){var i=r.pendingLanes;if(i===0)var a=0;else{var o=r.suspendedLanes,s=r.pingedLanes;a=(1<<31-He(42|e)+1)-1,a&=i&~(o&~s),a=a&201326741?a&201326741|1:a?a|2:0}a!==0&&(n=!0,ld(r,a))}else a=Y,a=Xe(r,r===q?a:0,r.cancelPendingCommit!==null||r.timeoutHandle!==-1),!(a&3)||Ze(r,a)||(n=!0,ld(r,a));r=r.next}while(n);td=!1}}function ad(){od()}function od(){ed=$u=!1;var e=0;nd!==0&&Gd()&&(e=nd);for(var t=Ae(),n=null,r=Zu;r!==null;){var i=r.next,a=sd(r,t);a===0?(r.next=null,n===null?Zu=i:n.next=i,i===null&&(Qu=n)):(n=r,(e!==0||a&3)&&(ed=!0)),r=i}iu!==0&&iu!==5||id(e,!1),nd!==0&&(nd=0)}function sd(e,t){for(var n=e.suspendedLanes,r=e.pingedLanes,i=e.expirationTimes,a=e.pendingLanes&-62914561;0s)break;var u=c.transferSize,d=c.initiatorType;u&&Id(d)&&(c=c.responseEnd,o+=u*(c`u`?null:document;function xf(e,t,n){var r=bf;if(r&&typeof t==`string`&&t){var i=Vt(t);i=`link[rel="`+e+`"][href="`+i+`"]`,typeof n==`string`&&(i+=`[crossorigin="`+n+`"]`),hf.has(i)||(hf.add(i),e={rel:e,crossOrigin:n,href:t},r.querySelector(i)===null&&(t=r.createElement(`link`),Pd(t,`link`,e),wt(t),r.head.appendChild(t)))}}function Sf(e){_f.D(e),xf(`dns-prefetch`,e,null)}function Cf(e,t){_f.C(e,t),xf(`preconnect`,e,t)}function wf(e,t,n){_f.L(e,t,n);var r=bf;if(r&&e&&t){var i=`link[rel="preload"][as="`+Vt(t)+`"]`;t===`image`&&n&&n.imageSrcSet?(i+=`[imagesrcset="`+Vt(n.imageSrcSet)+`"]`,typeof n.imageSizes==`string`&&(i+=`[imagesizes="`+Vt(n.imageSizes)+`"]`)):i+=`[href="`+Vt(e)+`"]`;var a=i;switch(t){case`style`:a=Af(e);break;case`script`:a=Pf(e)}mf.has(a)||(e=m({rel:`preload`,href:t===`image`&&n&&n.imageSrcSet?void 0:e,as:t},n),mf.set(a,e),r.querySelector(i)!==null||t===`style`&&r.querySelector(jf(a))||t===`script`&&r.querySelector(Ff(a))||(t=r.createElement(`link`),Pd(t,`link`,e),wt(t),r.head.appendChild(t)))}}function Tf(e,t){_f.m(e,t);var n=bf;if(n&&e){var r=t&&typeof t.as==`string`?t.as:`script`,i=`link[rel="modulepreload"][as="`+Vt(r)+`"][href="`+Vt(e)+`"]`,a=i;switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:a=Pf(e)}if(!mf.has(a)&&(e=m({rel:`modulepreload`,href:e},t),mf.set(a,e),n.querySelector(i)===null)){switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:if(n.querySelector(Ff(a)))return}r=n.createElement(`link`),Pd(r,`link`,e),wt(r),n.head.appendChild(r)}}}function Ef(e,t,n){_f.S(e,t,n);var r=bf;if(r&&e){var i=Ct(r).hoistableStyles,a=Af(e);t||=`default`;var o=i.get(a);if(!o){var s={loading:0,preload:null};if(o=r.querySelector(jf(a)))s.loading=5;else{e=m({rel:`stylesheet`,href:e,"data-precedence":t},n),(n=mf.get(a))&&Rf(e,n);var c=o=r.createElement(`link`);wt(c),Pd(c,`link`,e),c._p=new Promise(function(e,t){c.onload=e,c.onerror=t}),c.addEventListener(`load`,function(){s.loading|=1}),c.addEventListener(`error`,function(){s.loading|=2}),s.loading|=4,Lf(o,t,r)}o={type:`stylesheet`,instance:o,count:1,state:s},i.set(a,o)}}}function Df(e,t){_f.X(e,t);var n=bf;if(n&&e){var r=Ct(n).hoistableScripts,i=Pf(e),a=r.get(i);a||(a=n.querySelector(Ff(i)),a||(e=m({src:e,async:!0},t),(t=mf.get(i))&&zf(e,t),a=n.createElement(`script`),wt(a),Pd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function Of(e,t){_f.M(e,t);var n=bf;if(n&&e){var r=Ct(n).hoistableScripts,i=Pf(e),a=r.get(i);a||(a=n.querySelector(Ff(i)),a||(e=m({src:e,async:!0,type:`module`},t),(t=mf.get(i))&&zf(e,t),a=n.createElement(`script`),wt(a),Pd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function kf(e,t,n,r){var a=(a=fe.current)?gf(a):null;if(!a)throw Error(i(446));switch(e){case`meta`:case`title`:return null;case`style`:return typeof n.precedence==`string`&&typeof n.href==`string`?(t=Af(n.href),n=Ct(a).hoistableStyles,r=n.get(t),r||(r={type:`style`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};case`link`:if(n.rel===`stylesheet`&&typeof n.href==`string`&&typeof n.precedence==`string`){e=Af(n.href);var o=Ct(a).hoistableStyles,s=o.get(e);if(s||(a=a.ownerDocument||a,s={type:`stylesheet`,instance:null,count:0,state:{loading:0,preload:null}},o.set(e,s),(o=a.querySelector(jf(e)))&&!o._p&&(s.instance=o,s.state.loading=5),mf.has(e)||(n={rel:`preload`,as:`style`,href:n.href,crossOrigin:n.crossOrigin,integrity:n.integrity,media:n.media,hrefLang:n.hrefLang,referrerPolicy:n.referrerPolicy},mf.set(e,n),o||Nf(a,e,n,s.state))),t&&r===null)throw Error(i(528,``));return s}if(t&&r!==null)throw Error(i(529,``));return null;case`script`:return t=n.async,n=n.src,typeof n==`string`&&t&&typeof t!=`function`&&typeof t!=`symbol`?(t=Pf(n),n=Ct(a).hoistableScripts,r=n.get(t),r||(r={type:`script`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};default:throw Error(i(444,e))}}function Af(e){return`href="`+Vt(e)+`"`}function jf(e){return`link[rel="stylesheet"][`+e+`]`}function Mf(e){return m({},e,{"data-precedence":e.precedence,precedence:null})}function Nf(e,t,n,r){e.querySelector(`link[rel="preload"][as="style"][`+t+`]`)?r.loading=1:(t=e.createElement(`link`),r.preload=t,t.addEventListener(`load`,function(){return r.loading|=1}),t.addEventListener(`error`,function(){return r.loading|=2}),Pd(t,`link`,n),wt(t),e.head.appendChild(t))}function Pf(e){return`[src="`+Vt(e)+`"]`}function Ff(e){return`script[async]`+e}function If(e,t,n){if(t.count++,t.instance===null)switch(t.type){case`style`:var r=e.querySelector(`style[data-href~="`+Vt(n.href)+`"]`);if(r)return t.instance=r,wt(r),r;var a=m({},n,{"data-href":n.href,"data-precedence":n.precedence,href:null,precedence:null});return r=(e.ownerDocument||e).createElement(`style`),wt(r),Pd(r,`style`,a),Lf(r,n.precedence,e),t.instance=r;case`stylesheet`:a=Af(n.href);var o=e.querySelector(jf(a));if(o)return t.state.loading|=4,t.instance=o,wt(o),o;r=Mf(n),(a=mf.get(a))&&Rf(r,a),o=(e.ownerDocument||e).createElement(`link`),wt(o);var s=o;return s._p=new Promise(function(e,t){s.onload=e,s.onerror=t}),Pd(o,`link`,r),t.state.loading|=4,Lf(o,n.precedence,e),t.instance=o;case`script`:return o=Pf(n.src),(a=e.querySelector(Ff(o)))?(t.instance=a,wt(a),a):(r=n,(a=mf.get(o))&&(r=m({},n),zf(r,a)),e=e.ownerDocument||e,a=e.createElement(`script`),wt(a),Pd(a,`link`,r),e.head.appendChild(a),t.instance=a);case`void`:return null;default:throw Error(i(443,t.type))}else t.type===`stylesheet`&&!(t.state.loading&4)&&(r=t.instance,t.state.loading|=4,Lf(r,n.precedence,e));return t.instance}function Lf(e,t,n){for(var r=n.querySelectorAll(`link[rel="stylesheet"][data-precedence],style[data-precedence]`),i=r.length?r[r.length-1]:null,a=i,o=0;o title`):null)}function Uf(e,t,n){if(n===1||t.itemProp!=null)return!1;switch(e){case`meta`:case`title`:return!0;case`style`:if(typeof t.precedence!=`string`||typeof t.href!=`string`||t.href===``)break;return!0;case`link`:if(typeof t.rel!=`string`||typeof t.href!=`string`||t.href===``||t.onLoad||t.onError)break;switch(t.rel){case`stylesheet`:return e=t.disabled,typeof t.precedence==`string`&&e==null;default:return!0}case`script`:if(t.async&&typeof t.async!=`function`&&typeof t.async!=`symbol`&&!t.onLoad&&!t.onError&&t.src&&typeof t.src==`string`)return!0}return!1}function Wf(e){return!(e.type===`stylesheet`&&!(e.state.loading&3))}function Gf(e,t,n,r){if(n.type===`stylesheet`&&(typeof r.media!=`string`||!1!==matchMedia(r.media).matches)&&!(n.state.loading&4)){if(n.instance===null){var i=Af(r.href),a=t.querySelector(jf(i));if(a){t=a._p,typeof t==`object`&&t&&typeof t.then==`function`&&(e.count++,e=Jf.bind(e),t.then(e,e)),n.state.loading|=4,n.instance=a,wt(a);return}a=t.ownerDocument||t,r=Mf(r),(i=mf.get(i))&&Rf(r,i),a=a.createElement(`link`),wt(a);var o=a;o._p=new Promise(function(e,t){o.onload=e,o.onerror=t}),Pd(a,`link`,r),n.instance=a}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(n,t),(t=n.state.preload)&&!(n.state.loading&3)&&(e.count++,n=Jf.bind(e),t.addEventListener(`load`,n),t.addEventListener(`error`,n))}}var Kf=0;function qf(e,t){return e.stylesheets&&e.count===0&&Xf(e,e.stylesheets),0Kf?50:800)+t);return e.unsuspend=n,function(){e.unsuspend=null,clearTimeout(r),clearTimeout(i)}}:null}function Jf(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)Xf(this,this.stylesheets);else if(this.unsuspend){var e=this.unsuspend;this.unsuspend=null,e()}}}var Yf=null;function Xf(e,t){e.stylesheets=null,e.unsuspend!==null&&(e.count++,Yf=new Map,t.forEach(Zf,e),Yf=null,Jf.call(e))}function Zf(e,t){if(!(t.state.loading&4)){var n=Yf.get(e);if(n)var r=n.get(null);else{n=new Map,Yf.set(e,n);for(var i=e.querySelectorAll(`link[data-precedence],style[data-precedence]`),a=0;a{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=g()})),v=l(d(),1),y=_(),b=(...e)=>e.filter((e,t,n)=>!!e&&e.trim()!==``&&n.indexOf(e)===t).join(` `).trim(),x=e=>e.replace(/([a-z0-9])([A-Z])/g,`$1-$2`).toLowerCase(),S=e=>e.replace(/^([A-Z])|[\s-_]+(\w)/g,(e,t,n)=>n?n.toUpperCase():t.toLowerCase()),C=e=>{let t=S(e);return t.charAt(0).toUpperCase()+t.slice(1)},w={xmlns:`http://www.w3.org/2000/svg`,width:24,height:24,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:2,strokeLinecap:`round`,strokeLinejoin:`round`},T=e=>{for(let t in e)if(t.startsWith(`aria-`)||t===`role`||t===`title`)return!0;return!1},ee=(0,v.createContext)({}),te=()=>(0,v.useContext)(ee),ne=(0,v.forwardRef)(({color:e,size:t,strokeWidth:n,absoluteStrokeWidth:r,className:i=``,children:a,iconNode:o,...s},c)=>{let{size:l=24,strokeWidth:u=2,absoluteStrokeWidth:d=!1,color:f=`currentColor`,className:p=``}=te()??{},m=r??d?Number(n??u)*24/Number(t??l):n??u;return(0,v.createElement)(`svg`,{ref:c,...w,width:t??l??w.width,height:t??l??w.height,stroke:e??f,strokeWidth:m,className:b(`lucide`,p,i),...!a&&!T(s)&&{"aria-hidden":`true`},...s},[...o.map(([e,t])=>(0,v.createElement)(e,t)),...Array.isArray(a)?a:[a]])}),E=(e,t)=>{let n=(0,v.forwardRef)(({className:n,...r},i)=>(0,v.createElement)(ne,{ref:i,iconNode:t,className:b(`lucide-${x(C(e))}`,`lucide-${e}`,n),...r}));return n.displayName=C(e),n},re=E(`arrow-up-right`,[[`path`,{d:`M7 7h10v10`,key:`1tivn9`}],[`path`,{d:`M7 17 17 7`,key:`1vkiza`}]]),D=E(`calendar-days`,[[`path`,{d:`M8 2v4`,key:`1cmpym`}],[`path`,{d:`M16 2v4`,key:`4m81vk`}],[`rect`,{width:`18`,height:`18`,x:`3`,y:`4`,rx:`2`,key:`1hopcy`}],[`path`,{d:`M3 10h18`,key:`8toen8`}],[`path`,{d:`M8 14h.01`,key:`6423bh`}],[`path`,{d:`M12 14h.01`,key:`1etili`}],[`path`,{d:`M16 14h.01`,key:`1gbofw`}],[`path`,{d:`M8 18h.01`,key:`lrp35t`}],[`path`,{d:`M12 18h.01`,key:`mhygvu`}],[`path`,{d:`M16 18h.01`,key:`kzsmim`}]]),O=E(`check-check`,[[`path`,{d:`M18 6 7 17l-5-5`,key:`116fxf`}],[`path`,{d:`m22 10-7.5 7.5L13 16`,key:`ke71qq`}]]),ie=E(`chevron-down`,[[`path`,{d:`m6 9 6 6 6-6`,key:`qrunsl`}]]),ae=E(`chevron-left`,[[`path`,{d:`m15 18-6-6 6-6`,key:`1wnfg3`}]]),oe=E(`chevron-right`,[[`path`,{d:`m9 18 6-6-6-6`,key:`mthhwq`}]]),k=E(`external-link`,[[`path`,{d:`M15 3h6v6`,key:`1q9fwt`}],[`path`,{d:`M10 14 21 3`,key:`gplh6r`}],[`path`,{d:`M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6`,key:`a6xqqp`}]]),A=E(`files`,[[`path`,{d:`M15 2h-4a2 2 0 0 0-2 2v11a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V8`,key:`14sh0y`}],[`path`,{d:`M16.706 2.706A2.4 2.4 0 0 0 15 2v5a1 1 0 0 0 1 1h5a2.4 2.4 0 0 0-.706-1.706z`,key:`1970lx`}],[`path`,{d:`M5 7a2 2 0 0 0-2 2v11a2 2 0 0 0 2 2h8a2 2 0 0 0 1.732-1`,key:`l4dndm`}]]),se=E(`inbox`,[[`polyline`,{points:`22 12 16 12 14 15 10 15 8 12 2 12`,key:`o97t9d`}],[`path`,{d:`M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z`,key:`oot6mr`}]]),ce=E(`layout-dashboard`,[[`rect`,{width:`7`,height:`9`,x:`3`,y:`3`,rx:`1`,key:`10lvy0`}],[`rect`,{width:`7`,height:`5`,x:`14`,y:`3`,rx:`1`,key:`16une8`}],[`rect`,{width:`7`,height:`9`,x:`14`,y:`12`,rx:`1`,key:`1hutg5`}],[`rect`,{width:`7`,height:`5`,x:`3`,y:`16`,rx:`1`,key:`ldoo1y`}]]),le=E(`loader-circle`,[[`path`,{d:`M21 12a9 9 0 1 1-6.219-8.56`,key:`13zald`}]]),j=E(`log-out`,[[`path`,{d:`m16 17 5-5-5-5`,key:`1bji2h`}],[`path`,{d:`M21 12H9`,key:`dn1m92`}],[`path`,{d:`M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4`,key:`1uf3rs`}]]),M=E(`paw-print`,[[`circle`,{cx:`11`,cy:`4`,r:`2`,key:`vol9p0`}],[`circle`,{cx:`18`,cy:`8`,r:`2`,key:`17gozi`}],[`circle`,{cx:`20`,cy:`16`,r:`2`,key:`1v9bxh`}],[`path`,{d:`M9 10a5 5 0 0 1 5 5v3.5a3.5 3.5 0 0 1-6.84 1.045Q6.52 17.48 4.46 16.84A3.5 3.5 0 0 1 5.5 10Z`,key:`1ydw1z`}]]),N=E(`refresh-cw`,[[`path`,{d:`M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8`,key:`v9h5vc`}],[`path`,{d:`M21 3v5h-5`,key:`1q7to0`}],[`path`,{d:`M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16`,key:`3uifl3`}],[`path`,{d:`M8 16H3v5`,key:`1cv678`}]]),ue=E(`route`,[[`circle`,{cx:`6`,cy:`19`,r:`3`,key:`1kj8tv`}],[`path`,{d:`M9 19h8.5a3.5 3.5 0 0 0 0-7h-11a3.5 3.5 0 0 1 0-7H15`,key:`1d8sl`}],[`circle`,{cx:`18`,cy:`5`,r:`3`,key:`gq8acd`}]]),de=E(`search`,[[`path`,{d:`m21 21-4.34-4.34`,key:`14j7rj`}],[`circle`,{cx:`11`,cy:`11`,r:`8`,key:`4ej97u`}]]),fe=E(`user-round`,[[`circle`,{cx:`12`,cy:`8`,r:`5`,key:`1hypcn`}],[`path`,{d:`M20 21a8 8 0 0 0-16 0`,key:`rfgkzh`}]]),pe=E(`users`,[[`path`,{d:`M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2`,key:`1yyitq`}],[`path`,{d:`M16 3.128a4 4 0 0 1 0 7.744`,key:`16gr8j`}],[`path`,{d:`M22 21v-2a4 4 0 0 0-3-3.87`,key:`kshegd`}],[`circle`,{cx:`9`,cy:`7`,r:`4`,key:`nufk8`}]]),me=E(`x`,[[`path`,{d:`M18 6 6 18`,key:`1bl5f8`}],[`path`,{d:`m6 6 12 12`,key:`d8bk6v`}]]);function he(e,t){if(typeof e==`function`)return e(t);e!=null&&(e.current=t)}function ge(...e){return t=>{let n=!1,r=e.map(e=>{let r=he(e,t);return!n&&typeof r==`function`&&(n=!0),r});if(n)return()=>{for(let t=0;t{let{children:r,...i}=t,a=null,o=!1,s=[];Ee(r)&&typeof Ae==`function`&&(r=Ae(r._payload)),v.Children.forEach(r,e=>{if(we(e)){o=!0;let t=e,n=`child`in t.props?t.props.child:t.props.children;Ee(n)&&typeof Ae==`function`&&(n=Ae(n._payload)),a=xe(t,n),s.push(a?.props?.children)}else s.push(e)}),a?a=v.cloneElement(a,void 0,s):!o&&v.Children.count(r)===1&&v.isValidElement(r)&&(a=r);let c=a?Ce(a):void 0,l=_e(n,c);if(!a){if(r||r===0)throw Error(o?ke(e):Oe(e));return r}let u=Se(i,a.props??{});return a.type!==v.Fragment&&(u.ref=n?l:c),v.cloneElement(a,u)});return t.displayName=`${e}.Slot`,t}var ye=ve(`Slot`),be=Symbol.for(`radix.slottable`),xe=(e,t)=>{if(`child`in e.props){let t=e.props.child;return v.isValidElement(t)?v.cloneElement(t,void 0,e.props.children(t.props.children)):null}return v.isValidElement(t)?t:null};function Se(e,t){let n={...t};for(let r in t){let i=e[r],a=t[r];/^on[A-Z]/.test(r)?i&&a?n[r]=(...e)=>{let t=a(...e);return i(...e),t}:i&&(n[r]=i):r===`style`?n[r]={...i,...a}:r===`className`&&(n[r]=[i,a].filter(Boolean).join(` `))}return{...e,...n}}function Ce(e){let t=Object.getOwnPropertyDescriptor(e.props,`ref`)?.get,n=t&&`isReactWarning`in t&&t.isReactWarning;return n?e.ref:(t=Object.getOwnPropertyDescriptor(e,`ref`)?.get,n=t&&`isReactWarning`in t&&t.isReactWarning,n?e.props.ref:e.props.ref||e.ref)}function we(e){return v.isValidElement(e)&&typeof e.type==`function`&&`__radixId`in e.type&&e.type.__radixId===be}var Te=Symbol.for(`react.lazy`);function Ee(e){return typeof e==`object`&&!!e&&`$$typeof`in e&&e.$$typeof===Te&&`_payload`in e&&De(e._payload)}function De(e){return typeof e==`object`&&!!e&&`then`in e}var Oe=e=>`${e} failed to slot onto its children. Expected a single React element child or \`Slottable\`.`,ke=e=>`${e} failed to slot onto its \`Slottable\`. Expected \`Slottable\` to receive a single React element child.`,Ae=v.use;function je(e){var t,n,r=``;if(typeof e==`string`||typeof e==`number`)r+=e;else if(typeof e==`object`)if(Array.isArray(e)){var i=e.length;for(t=0;ttypeof e==`boolean`?`${e}`:e===0?`0`:e,Pe=Me,Fe=(e,t)=>n=>{if(t?.variants==null)return Pe(e,n?.class,n?.className);let{variants:r,defaultVariants:i}=t,a=Object.keys(r).map(e=>{let t=n?.[e],a=i?.[e];if(t===null)return null;let o=Ne(t)||Ne(a);return r[e][o]}),o=n&&Object.entries(n).reduce((e,t)=>{let[n,r]=t;return r===void 0||(e[n]=r),e},{});return Pe(e,a,t?.compoundVariants?.reduce((e,t)=>{let{class:n,className:r,...a}=t;return Object.entries(a).every(e=>{let[t,n]=e;return Array.isArray(n)?n.includes({...i,...o}[t]):{...i,...o}[t]===n})?[...e,n,r]:e},[]),n?.class,n?.className)},Ie=(e,t)=>{let n=Array(e.length+t.length);for(let t=0;t({classGroupId:e,validator:t}),Re=(e=new Map,t=null,n)=>({nextPart:e,validators:t,classGroupId:n}),ze=`-`,Be=[],Ve=`arbitrary..`,He=e=>{let t=Ge(e),{conflictingClassGroups:n,conflictingClassGroupModifiers:r}=e;return{getClassGroupId:e=>{if(e.startsWith(`[`)&&e.endsWith(`]`))return We(e);let n=e.split(ze);return Ue(n,+(n[0]===``&&n.length>1),t)},getConflictingClassGroupIds:(e,t)=>{if(t){let t=r[e],i=n[e];return t?i?Ie(i,t):t:i||Be}return n[e]||Be}}},Ue=(e,t,n)=>{if(e.length-t===0)return n.classGroupId;let r=e[t],i=n.nextPart.get(r);if(i){let n=Ue(e,t+1,i);if(n)return n}let a=n.validators;if(a===null)return;let o=t===0?e.join(ze):e.slice(t).join(ze),s=a.length;for(let e=0;ee.slice(1,-1).indexOf(`:`)===-1?void 0:(()=>{let t=e.slice(1,-1),n=t.indexOf(`:`),r=t.slice(0,n);return r?Ve+r:void 0})(),Ge=e=>{let{theme:t,classGroups:n}=e;return Ke(n,t)},Ke=(e,t)=>{let n=Re();for(let r in e){let i=e[r];qe(i,n,r,t)}return n},qe=(e,t,n,r)=>{let i=e.length;for(let a=0;a{if(typeof e==`string`){Ye(e,t,n);return}if(typeof e==`function`){Xe(e,t,n,r);return}Ze(e,t,n,r)},Ye=(e,t,n)=>{let r=e===``?t:Qe(t,e);r.classGroupId=n},Xe=(e,t,n,r)=>{if($e(e)){qe(e(r),t,n,r);return}t.validators===null&&(t.validators=[]),t.validators.push(Le(n,e))},Ze=(e,t,n,r)=>{let i=Object.entries(e),a=i.length;for(let e=0;e{let n=e,r=t.split(ze),i=r.length;for(let e=0;e`isThemeGetter`in e&&e.isThemeGetter===!0,et=e=>{if(e<1)return{get:()=>void 0,set:()=>{}};let t=0,n=Object.create(null),r=Object.create(null),i=(i,a)=>{n[i]=a,t++,t>e&&(t=0,r=n,n=Object.create(null))};return{get(e){let t=n[e];if(t!==void 0)return t;if((t=r[e])!==void 0)return i(e,t),t},set(e,t){e in n?n[e]=t:i(e,t)}}},tt=`!`,nt=`:`,rt=[],it=(e,t,n,r,i)=>({modifiers:e,hasImportantModifier:t,baseClassName:n,maybePostfixModifierPosition:r,isExternal:i}),at=e=>{let{prefix:t,experimentalParseClassName:n}=e,r=e=>{let t=[],n=0,r=0,i=0,a,o=e.length;for(let s=0;si?a-i:void 0;return it(t,l,c,u)};if(t){let e=t+nt,n=r;r=t=>t.startsWith(e)?n(t.slice(e.length)):it(rt,!1,t,void 0,!0)}if(n){let e=r;r=t=>n({className:t,parseClassName:e})}return r},ot=e=>{let t=new Map;return e.orderSensitiveModifiers.forEach((e,n)=>{t.set(e,1e6+n)}),e=>{let n=[],r=[];for(let i=0;i0&&(r.sort(),n.push(...r),r=[]),n.push(a)):r.push(a)}return r.length>0&&(r.sort(),n.push(...r)),n}},st=e=>({cache:et(e.cacheSize),parseClassName:at(e),sortModifiers:ot(e),postfixLookupClassGroupIds:ct(e),...He(e)}),ct=e=>{let t=Object.create(null),n=e.postfixLookupClassGroups;if(n)for(let e=0;e{let{parseClassName:n,getClassGroupId:r,getConflictingClassGroupIds:i,sortModifiers:a,postfixLookupClassGroupIds:o}=t,s=[],c=e.trim().split(lt),l=``;for(let e=c.length-1;e>=0;--e){let t=c[e],{isExternal:u,modifiers:d,hasImportantModifier:f,baseClassName:p,maybePostfixModifierPosition:m}=n(t);if(u){l=t+(l.length>0?` `+l:l);continue}let h=!!m,g;if(h){g=r(p.substring(0,m));let e=g&&o[g]?r(p):void 0;e&&e!==g&&(g=e,h=!1)}else g=r(p);if(!g){if(!h){l=t+(l.length>0?` `+l:l);continue}if(g=r(p),!g){l=t+(l.length>0?` `+l:l);continue}h=!1}let _=d.length===0?``:d.length===1?d[0]:a(d).join(`:`),v=f?_+tt:_,y=v+g;if(s.indexOf(y)>-1)continue;s.push(y);let b=i(g,h);for(let e=0;e0?` `+l:l)}return l},dt=(...e)=>{let t=0,n,r,i=``;for(;t{if(typeof e==`string`)return e;let t,n=``;for(let r=0;r{let n,r,i,a,o=o=>(n=st(t.reduce((e,t)=>t(e),e())),r=n.cache.get,i=n.cache.set,a=s,s(o)),s=e=>{let t=r(e);if(t)return t;let a=ut(e,n);return i(e,a),a};return a=o,(...e)=>a(dt(...e))},mt=[],ht=e=>{let t=t=>t[e]||mt;return t.isThemeGetter=!0,t},gt=/^\[(?:(\w[\w-]*):)?(.+)\]$/i,_t=/^\((?:(\w[\w-]*):)?(.+)\)$/i,vt=/^\d+(?:\.\d+)?\/\d+(?:\.\d+)?$/,yt=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,bt=/\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/,xt=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,St=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,Ct=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,wt=e=>vt.test(e),P=e=>!!e&&!Number.isNaN(Number(e)),Tt=e=>!!e&&Number.isInteger(Number(e)),Et=e=>e.endsWith(`%`)&&P(e.slice(0,-1)),Dt=e=>yt.test(e),Ot=()=>!0,kt=e=>bt.test(e)&&!xt.test(e),At=()=>!1,jt=e=>St.test(e),Mt=e=>Ct.test(e),Nt=e=>!F(e)&&!I(e),Pt=e=>e.startsWith(`@container`)&&(e[10]===`/`&&e[11]!==void 0||e[11]===`s`&&e[16]!==void 0&&e.startsWith(`-size/`,10)||e[11]===`n`&&e[18]!==void 0&&e.startsWith(`-normal/`,10)),Ft=e=>Xt(e,en,At),F=e=>gt.test(e),It=e=>Xt(e,tn,kt),Lt=e=>Xt(e,nn,P),Rt=e=>Xt(e,an,Ot),zt=e=>Xt(e,rn,At),Bt=e=>Xt(e,Qt,At),Vt=e=>Xt(e,$t,Mt),Ht=e=>Xt(e,on,jt),I=e=>_t.test(e),Ut=e=>Zt(e,tn),Wt=e=>Zt(e,rn),Gt=e=>Zt(e,Qt),Kt=e=>Zt(e,en),qt=e=>Zt(e,$t),Jt=e=>Zt(e,on,!0),Yt=e=>Zt(e,an,!0),Xt=(e,t,n)=>{let r=gt.exec(e);return r?r[1]?t(r[1]):n(r[2]):!1},Zt=(e,t,n=!1)=>{let r=_t.exec(e);return r?r[1]?t(r[1]):n:!1},Qt=e=>e===`position`||e===`percentage`,$t=e=>e===`image`||e===`url`,en=e=>e===`length`||e===`size`||e===`bg-size`,tn=e=>e===`length`,nn=e=>e===`number`,rn=e=>e===`family-name`,an=e=>e===`number`||e===`weight`,on=e=>e===`shadow`,sn=pt(()=>{let e=ht(`color`),t=ht(`font`),n=ht(`text`),r=ht(`font-weight`),i=ht(`tracking`),a=ht(`leading`),o=ht(`breakpoint`),s=ht(`container`),c=ht(`spacing`),l=ht(`radius`),u=ht(`shadow`),d=ht(`inset-shadow`),f=ht(`text-shadow`),p=ht(`drop-shadow`),m=ht(`blur`),h=ht(`perspective`),g=ht(`aspect`),_=ht(`ease`),v=ht(`animate`),y=()=>[`auto`,`avoid`,`all`,`avoid-page`,`page`,`left`,`right`,`column`],b=()=>[`center`,`top`,`bottom`,`left`,`right`,`top-left`,`left-top`,`top-right`,`right-top`,`bottom-right`,`right-bottom`,`bottom-left`,`left-bottom`],x=()=>[...b(),I,F],S=()=>[`auto`,`hidden`,`clip`,`visible`,`scroll`],C=()=>[`auto`,`contain`,`none`],w=()=>[I,F,c],T=()=>[wt,`full`,`auto`,...w()],ee=()=>[Tt,`none`,`subgrid`,I,F],te=()=>[`auto`,{span:[`full`,Tt,I,F]},Tt,I,F],ne=()=>[Tt,`auto`,I,F],E=()=>[`auto`,`min`,`max`,`fr`,I,F],re=()=>[`start`,`end`,`center`,`between`,`around`,`evenly`,`stretch`,`baseline`,`center-safe`,`end-safe`],D=()=>[`start`,`end`,`center`,`stretch`,`center-safe`,`end-safe`],O=()=>[`auto`,...w()],ie=()=>[wt,`auto`,`full`,`dvw`,`dvh`,`lvw`,`lvh`,`svw`,`svh`,`min`,`max`,`fit`,...w()],ae=()=>[wt,`screen`,`full`,`dvw`,`lvw`,`svw`,`min`,`max`,`fit`,...w()],oe=()=>[wt,`screen`,`full`,`lh`,`dvh`,`lvh`,`svh`,`min`,`max`,`fit`,...w()],k=()=>[e,I,F],A=()=>[...b(),Gt,Bt,{position:[I,F]}],se=()=>[`no-repeat`,{repeat:[``,`x`,`y`,`space`,`round`]}],ce=()=>[`auto`,`cover`,`contain`,Kt,Ft,{size:[I,F]}],le=()=>[Et,Ut,It],j=()=>[``,`none`,`full`,l,I,F],M=()=>[``,P,Ut,It],N=()=>[`solid`,`dashed`,`dotted`,`double`],ue=()=>[`normal`,`multiply`,`screen`,`overlay`,`darken`,`lighten`,`color-dodge`,`color-burn`,`hard-light`,`soft-light`,`difference`,`exclusion`,`hue`,`saturation`,`color`,`luminosity`],de=()=>[P,Et,Gt,Bt],fe=()=>[``,`none`,m,I,F],pe=()=>[`none`,P,I,F],me=()=>[`none`,P,I,F],he=()=>[P,I,F],ge=()=>[wt,`full`,...w()];return{cacheSize:500,theme:{animate:[`spin`,`ping`,`pulse`,`bounce`],aspect:[`video`],blur:[Dt],breakpoint:[Dt],color:[Ot],container:[Dt],"drop-shadow":[Dt],ease:[`in`,`out`,`in-out`],font:[Nt],"font-weight":[`thin`,`extralight`,`light`,`normal`,`medium`,`semibold`,`bold`,`extrabold`,`black`],"inset-shadow":[Dt],leading:[`none`,`tight`,`snug`,`normal`,`relaxed`,`loose`],perspective:[`dramatic`,`near`,`normal`,`midrange`,`distant`,`none`],radius:[Dt],shadow:[Dt],spacing:[`px`,P],text:[Dt],"text-shadow":[Dt],tracking:[`tighter`,`tight`,`normal`,`wide`,`wider`,`widest`]},classGroups:{aspect:[{aspect:[`auto`,`square`,wt,F,I,g]}],container:[`container`],"container-type":[{"@container":[``,`normal`,`size`,I,F]}],"container-named":[Pt],columns:[{columns:[P,F,I,s]}],"break-after":[{"break-after":y()}],"break-before":[{"break-before":y()}],"break-inside":[{"break-inside":[`auto`,`avoid`,`avoid-page`,`avoid-column`]}],"box-decoration":[{"box-decoration":[`slice`,`clone`]}],box:[{box:[`border`,`content`]}],display:[`block`,`inline-block`,`inline`,`flex`,`inline-flex`,`table`,`inline-table`,`table-caption`,`table-cell`,`table-column`,`table-column-group`,`table-footer-group`,`table-header-group`,`table-row-group`,`table-row`,`flow-root`,`grid`,`inline-grid`,`contents`,`list-item`,`hidden`],sr:[`sr-only`,`not-sr-only`],float:[{float:[`right`,`left`,`none`,`start`,`end`]}],clear:[{clear:[`left`,`right`,`both`,`none`,`start`,`end`]}],isolation:[`isolate`,`isolation-auto`],"object-fit":[{object:[`contain`,`cover`,`fill`,`none`,`scale-down`]}],"object-position":[{object:x()}],overflow:[{overflow:S()}],"overflow-x":[{"overflow-x":S()}],"overflow-y":[{"overflow-y":S()}],overscroll:[{overscroll:C()}],"overscroll-x":[{"overscroll-x":C()}],"overscroll-y":[{"overscroll-y":C()}],position:[`static`,`fixed`,`absolute`,`relative`,`sticky`],inset:[{inset:T()}],"inset-x":[{"inset-x":T()}],"inset-y":[{"inset-y":T()}],start:[{"inset-s":T(),start:T()}],end:[{"inset-e":T(),end:T()}],"inset-bs":[{"inset-bs":T()}],"inset-be":[{"inset-be":T()}],top:[{top:T()}],right:[{right:T()}],bottom:[{bottom:T()}],left:[{left:T()}],visibility:[`visible`,`invisible`,`collapse`],z:[{z:[Tt,`auto`,I,F]}],basis:[{basis:[wt,`full`,`auto`,s,...w()]}],"flex-direction":[{flex:[`row`,`row-reverse`,`col`,`col-reverse`]}],"flex-wrap":[{flex:[`nowrap`,`wrap`,`wrap-reverse`]}],flex:[{flex:[P,wt,`auto`,`initial`,`none`,F]}],grow:[{grow:[``,P,I,F]}],shrink:[{shrink:[``,P,I,F]}],order:[{order:[Tt,`first`,`last`,`none`,I,F]}],"grid-cols":[{"grid-cols":ee()}],"col-start-end":[{col:te()}],"col-start":[{"col-start":ne()}],"col-end":[{"col-end":ne()}],"grid-rows":[{"grid-rows":ee()}],"row-start-end":[{row:te()}],"row-start":[{"row-start":ne()}],"row-end":[{"row-end":ne()}],"grid-flow":[{"grid-flow":[`row`,`col`,`dense`,`row-dense`,`col-dense`]}],"auto-cols":[{"auto-cols":E()}],"auto-rows":[{"auto-rows":E()}],gap:[{gap:w()}],"gap-x":[{"gap-x":w()}],"gap-y":[{"gap-y":w()}],"justify-content":[{justify:[...re(),`normal`]}],"justify-items":[{"justify-items":[...D(),`normal`]}],"justify-self":[{"justify-self":[`auto`,...D()]}],"align-content":[{content:[`normal`,...re()]}],"align-items":[{items:[...D(),{baseline:[``,`last`]}]}],"align-self":[{self:[`auto`,...D(),{baseline:[``,`last`]}]}],"place-content":[{"place-content":re()}],"place-items":[{"place-items":[...D(),`baseline`]}],"place-self":[{"place-self":[`auto`,...D()]}],p:[{p:w()}],px:[{px:w()}],py:[{py:w()}],ps:[{ps:w()}],pe:[{pe:w()}],pbs:[{pbs:w()}],pbe:[{pbe:w()}],pt:[{pt:w()}],pr:[{pr:w()}],pb:[{pb:w()}],pl:[{pl:w()}],m:[{m:O()}],mx:[{mx:O()}],my:[{my:O()}],ms:[{ms:O()}],me:[{me:O()}],mbs:[{mbs:O()}],mbe:[{mbe:O()}],mt:[{mt:O()}],mr:[{mr:O()}],mb:[{mb:O()}],ml:[{ml:O()}],"space-x":[{"space-x":w()}],"space-x-reverse":[`space-x-reverse`],"space-y":[{"space-y":w()}],"space-y-reverse":[`space-y-reverse`],size:[{size:ie()}],"inline-size":[{inline:[`auto`,...ae()]}],"min-inline-size":[{"min-inline":[`auto`,...ae()]}],"max-inline-size":[{"max-inline":[`none`,...ae()]}],"block-size":[{block:[`auto`,...oe()]}],"min-block-size":[{"min-block":[`auto`,...oe()]}],"max-block-size":[{"max-block":[`none`,...oe()]}],w:[{w:[s,`screen`,...ie()]}],"min-w":[{"min-w":[s,`screen`,`none`,...ie()]}],"max-w":[{"max-w":[s,`screen`,`none`,`prose`,{screen:[o]},...ie()]}],h:[{h:[`screen`,`lh`,...ie()]}],"min-h":[{"min-h":[`screen`,`lh`,`none`,...ie()]}],"max-h":[{"max-h":[`screen`,`lh`,...ie()]}],"font-size":[{text:[`base`,n,Ut,It]}],"font-smoothing":[`antialiased`,`subpixel-antialiased`],"font-style":[`italic`,`not-italic`],"font-weight":[{font:[r,Yt,Rt]}],"font-stretch":[{"font-stretch":[`ultra-condensed`,`extra-condensed`,`condensed`,`semi-condensed`,`normal`,`semi-expanded`,`expanded`,`extra-expanded`,`ultra-expanded`,Et,F]}],"font-family":[{font:[Wt,zt,t]}],"font-features":[{"font-features":[F]}],"fvn-normal":[`normal-nums`],"fvn-ordinal":[`ordinal`],"fvn-slashed-zero":[`slashed-zero`],"fvn-figure":[`lining-nums`,`oldstyle-nums`],"fvn-spacing":[`proportional-nums`,`tabular-nums`],"fvn-fraction":[`diagonal-fractions`,`stacked-fractions`],tracking:[{tracking:[i,I,F]}],"line-clamp":[{"line-clamp":[P,`none`,I,Lt]}],leading:[{leading:[a,...w()]}],"list-image":[{"list-image":[`none`,I,F]}],"list-style-position":[{list:[`inside`,`outside`]}],"list-style-type":[{list:[`disc`,`decimal`,`none`,I,F]}],"text-alignment":[{text:[`left`,`center`,`right`,`justify`,`start`,`end`]}],"placeholder-color":[{placeholder:k()}],"text-color":[{text:k()}],"text-decoration":[`underline`,`overline`,`line-through`,`no-underline`],"text-decoration-style":[{decoration:[...N(),`wavy`]}],"text-decoration-thickness":[{decoration:[P,`from-font`,`auto`,I,It]}],"text-decoration-color":[{decoration:k()}],"underline-offset":[{"underline-offset":[P,`auto`,I,F]}],"text-transform":[`uppercase`,`lowercase`,`capitalize`,`normal-case`],"text-overflow":[`truncate`,`text-ellipsis`,`text-clip`],"text-wrap":[{text:[`wrap`,`nowrap`,`balance`,`pretty`]}],indent:[{indent:w()}],"tab-size":[{tab:[Tt,I,F]}],"vertical-align":[{align:[`baseline`,`top`,`middle`,`bottom`,`text-top`,`text-bottom`,`sub`,`super`,I,F]}],whitespace:[{whitespace:[`normal`,`nowrap`,`pre`,`pre-line`,`pre-wrap`,`break-spaces`]}],break:[{break:[`normal`,`words`,`all`,`keep`]}],wrap:[{wrap:[`break-word`,`anywhere`,`normal`]}],hyphens:[{hyphens:[`none`,`manual`,`auto`]}],content:[{content:[`none`,I,F]}],"bg-attachment":[{bg:[`fixed`,`local`,`scroll`]}],"bg-clip":[{"bg-clip":[`border`,`padding`,`content`,`text`]}],"bg-origin":[{"bg-origin":[`border`,`padding`,`content`]}],"bg-position":[{bg:A()}],"bg-repeat":[{bg:se()}],"bg-size":[{bg:ce()}],"bg-image":[{bg:[`none`,{linear:[{to:[`t`,`tr`,`r`,`br`,`b`,`bl`,`l`,`tl`]},Tt,I,F],radial:[``,I,F],conic:[Tt,I,F]},qt,Vt]}],"bg-color":[{bg:k()}],"gradient-from-pos":[{from:le()}],"gradient-via-pos":[{via:le()}],"gradient-to-pos":[{to:le()}],"gradient-from":[{from:k()}],"gradient-via":[{via:k()}],"gradient-to":[{to:k()}],rounded:[{rounded:j()}],"rounded-s":[{"rounded-s":j()}],"rounded-e":[{"rounded-e":j()}],"rounded-t":[{"rounded-t":j()}],"rounded-r":[{"rounded-r":j()}],"rounded-b":[{"rounded-b":j()}],"rounded-l":[{"rounded-l":j()}],"rounded-ss":[{"rounded-ss":j()}],"rounded-se":[{"rounded-se":j()}],"rounded-ee":[{"rounded-ee":j()}],"rounded-es":[{"rounded-es":j()}],"rounded-tl":[{"rounded-tl":j()}],"rounded-tr":[{"rounded-tr":j()}],"rounded-br":[{"rounded-br":j()}],"rounded-bl":[{"rounded-bl":j()}],"border-w":[{border:M()}],"border-w-x":[{"border-x":M()}],"border-w-y":[{"border-y":M()}],"border-w-s":[{"border-s":M()}],"border-w-e":[{"border-e":M()}],"border-w-bs":[{"border-bs":M()}],"border-w-be":[{"border-be":M()}],"border-w-t":[{"border-t":M()}],"border-w-r":[{"border-r":M()}],"border-w-b":[{"border-b":M()}],"border-w-l":[{"border-l":M()}],"divide-x":[{"divide-x":M()}],"divide-x-reverse":[`divide-x-reverse`],"divide-y":[{"divide-y":M()}],"divide-y-reverse":[`divide-y-reverse`],"border-style":[{border:[...N(),`hidden`,`none`]}],"divide-style":[{divide:[...N(),`hidden`,`none`]}],"border-color":[{border:k()}],"border-color-x":[{"border-x":k()}],"border-color-y":[{"border-y":k()}],"border-color-s":[{"border-s":k()}],"border-color-e":[{"border-e":k()}],"border-color-bs":[{"border-bs":k()}],"border-color-be":[{"border-be":k()}],"border-color-t":[{"border-t":k()}],"border-color-r":[{"border-r":k()}],"border-color-b":[{"border-b":k()}],"border-color-l":[{"border-l":k()}],"divide-color":[{divide:k()}],"outline-style":[{outline:[...N(),`none`,`hidden`]}],"outline-offset":[{"outline-offset":[P,I,F]}],"outline-w":[{outline:[``,P,Ut,It]}],"outline-color":[{outline:k()}],shadow:[{shadow:[``,`none`,u,Jt,Ht]}],"shadow-color":[{shadow:k()}],"inset-shadow":[{"inset-shadow":[`none`,d,Jt,Ht]}],"inset-shadow-color":[{"inset-shadow":k()}],"ring-w":[{ring:M()}],"ring-w-inset":[`ring-inset`],"ring-color":[{ring:k()}],"ring-offset-w":[{"ring-offset":[P,It]}],"ring-offset-color":[{"ring-offset":k()}],"inset-ring-w":[{"inset-ring":M()}],"inset-ring-color":[{"inset-ring":k()}],"text-shadow":[{"text-shadow":[`none`,f,Jt,Ht]}],"text-shadow-color":[{"text-shadow":k()}],opacity:[{opacity:[P,I,F]}],"mix-blend":[{"mix-blend":[...ue(),`plus-darker`,`plus-lighter`]}],"bg-blend":[{"bg-blend":ue()}],"mask-clip":[{"mask-clip":[`border`,`padding`,`content`,`fill`,`stroke`,`view`]},`mask-no-clip`],"mask-composite":[{mask:[`add`,`subtract`,`intersect`,`exclude`]}],"mask-image-linear-pos":[{"mask-linear":[P]}],"mask-image-linear-from-pos":[{"mask-linear-from":de()}],"mask-image-linear-to-pos":[{"mask-linear-to":de()}],"mask-image-linear-from-color":[{"mask-linear-from":k()}],"mask-image-linear-to-color":[{"mask-linear-to":k()}],"mask-image-t-from-pos":[{"mask-t-from":de()}],"mask-image-t-to-pos":[{"mask-t-to":de()}],"mask-image-t-from-color":[{"mask-t-from":k()}],"mask-image-t-to-color":[{"mask-t-to":k()}],"mask-image-r-from-pos":[{"mask-r-from":de()}],"mask-image-r-to-pos":[{"mask-r-to":de()}],"mask-image-r-from-color":[{"mask-r-from":k()}],"mask-image-r-to-color":[{"mask-r-to":k()}],"mask-image-b-from-pos":[{"mask-b-from":de()}],"mask-image-b-to-pos":[{"mask-b-to":de()}],"mask-image-b-from-color":[{"mask-b-from":k()}],"mask-image-b-to-color":[{"mask-b-to":k()}],"mask-image-l-from-pos":[{"mask-l-from":de()}],"mask-image-l-to-pos":[{"mask-l-to":de()}],"mask-image-l-from-color":[{"mask-l-from":k()}],"mask-image-l-to-color":[{"mask-l-to":k()}],"mask-image-x-from-pos":[{"mask-x-from":de()}],"mask-image-x-to-pos":[{"mask-x-to":de()}],"mask-image-x-from-color":[{"mask-x-from":k()}],"mask-image-x-to-color":[{"mask-x-to":k()}],"mask-image-y-from-pos":[{"mask-y-from":de()}],"mask-image-y-to-pos":[{"mask-y-to":de()}],"mask-image-y-from-color":[{"mask-y-from":k()}],"mask-image-y-to-color":[{"mask-y-to":k()}],"mask-image-radial":[{"mask-radial":[I,F]}],"mask-image-radial-from-pos":[{"mask-radial-from":de()}],"mask-image-radial-to-pos":[{"mask-radial-to":de()}],"mask-image-radial-from-color":[{"mask-radial-from":k()}],"mask-image-radial-to-color":[{"mask-radial-to":k()}],"mask-image-radial-shape":[{"mask-radial":[`circle`,`ellipse`]}],"mask-image-radial-size":[{"mask-radial":[{closest:[`side`,`corner`],farthest:[`side`,`corner`]}]}],"mask-image-radial-pos":[{"mask-radial-at":b()}],"mask-image-conic-pos":[{"mask-conic":[P]}],"mask-image-conic-from-pos":[{"mask-conic-from":de()}],"mask-image-conic-to-pos":[{"mask-conic-to":de()}],"mask-image-conic-from-color":[{"mask-conic-from":k()}],"mask-image-conic-to-color":[{"mask-conic-to":k()}],"mask-mode":[{mask:[`alpha`,`luminance`,`match`]}],"mask-origin":[{"mask-origin":[`border`,`padding`,`content`,`fill`,`stroke`,`view`]}],"mask-position":[{mask:A()}],"mask-repeat":[{mask:se()}],"mask-size":[{mask:ce()}],"mask-type":[{"mask-type":[`alpha`,`luminance`]}],"mask-image":[{mask:[`none`,I,F]}],filter:[{filter:[``,`none`,I,F]}],blur:[{blur:fe()}],brightness:[{brightness:[P,I,F]}],contrast:[{contrast:[P,I,F]}],"drop-shadow":[{"drop-shadow":[``,`none`,p,Jt,Ht]}],"drop-shadow-color":[{"drop-shadow":k()}],grayscale:[{grayscale:[``,P,I,F]}],"hue-rotate":[{"hue-rotate":[P,I,F]}],invert:[{invert:[``,P,I,F]}],saturate:[{saturate:[P,I,F]}],sepia:[{sepia:[``,P,I,F]}],"backdrop-filter":[{"backdrop-filter":[``,`none`,I,F]}],"backdrop-blur":[{"backdrop-blur":fe()}],"backdrop-brightness":[{"backdrop-brightness":[P,I,F]}],"backdrop-contrast":[{"backdrop-contrast":[P,I,F]}],"backdrop-grayscale":[{"backdrop-grayscale":[``,P,I,F]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[P,I,F]}],"backdrop-invert":[{"backdrop-invert":[``,P,I,F]}],"backdrop-opacity":[{"backdrop-opacity":[P,I,F]}],"backdrop-saturate":[{"backdrop-saturate":[P,I,F]}],"backdrop-sepia":[{"backdrop-sepia":[``,P,I,F]}],"border-collapse":[{border:[`collapse`,`separate`]}],"border-spacing":[{"border-spacing":w()}],"border-spacing-x":[{"border-spacing-x":w()}],"border-spacing-y":[{"border-spacing-y":w()}],"table-layout":[{table:[`auto`,`fixed`]}],caption:[{caption:[`top`,`bottom`]}],transition:[{transition:[``,`all`,`colors`,`opacity`,`shadow`,`transform`,`none`,I,F]}],"transition-behavior":[{transition:[`normal`,`discrete`]}],duration:[{duration:[P,`initial`,I,F]}],ease:[{ease:[`linear`,`initial`,_,I,F]}],delay:[{delay:[P,I,F]}],animate:[{animate:[`none`,v,I,F]}],backface:[{backface:[`hidden`,`visible`]}],perspective:[{perspective:[h,I,F]}],"perspective-origin":[{"perspective-origin":x()}],rotate:[{rotate:pe()}],"rotate-x":[{"rotate-x":pe()}],"rotate-y":[{"rotate-y":pe()}],"rotate-z":[{"rotate-z":pe()}],scale:[{scale:me()}],"scale-x":[{"scale-x":me()}],"scale-y":[{"scale-y":me()}],"scale-z":[{"scale-z":me()}],"scale-3d":[`scale-3d`],skew:[{skew:he()}],"skew-x":[{"skew-x":he()}],"skew-y":[{"skew-y":he()}],transform:[{transform:[I,F,``,`none`,`gpu`,`cpu`]}],"transform-origin":[{origin:x()}],"transform-style":[{transform:[`3d`,`flat`]}],translate:[{translate:ge()}],"translate-x":[{"translate-x":ge()}],"translate-y":[{"translate-y":ge()}],"translate-z":[{"translate-z":ge()}],"translate-none":[`translate-none`],zoom:[{zoom:[Tt,I,F]}],accent:[{accent:k()}],appearance:[{appearance:[`none`,`auto`]}],"caret-color":[{caret:k()}],"color-scheme":[{scheme:[`normal`,`dark`,`light`,`light-dark`,`only-dark`,`only-light`]}],cursor:[{cursor:[`auto`,`default`,`pointer`,`wait`,`text`,`move`,`help`,`not-allowed`,`none`,`context-menu`,`progress`,`cell`,`crosshair`,`vertical-text`,`alias`,`copy`,`no-drop`,`grab`,`grabbing`,`all-scroll`,`col-resize`,`row-resize`,`n-resize`,`e-resize`,`s-resize`,`w-resize`,`ne-resize`,`nw-resize`,`se-resize`,`sw-resize`,`ew-resize`,`ns-resize`,`nesw-resize`,`nwse-resize`,`zoom-in`,`zoom-out`,I,F]}],"field-sizing":[{"field-sizing":[`fixed`,`content`]}],"pointer-events":[{"pointer-events":[`auto`,`none`]}],resize:[{resize:[`none`,``,`y`,`x`]}],"scroll-behavior":[{scroll:[`auto`,`smooth`]}],"scrollbar-thumb-color":[{"scrollbar-thumb":k()}],"scrollbar-track-color":[{"scrollbar-track":k()}],"scrollbar-gutter":[{"scrollbar-gutter":[`auto`,`stable`,`both`]}],"scrollbar-w":[{scrollbar:[`auto`,`thin`,`none`]}],"scroll-m":[{"scroll-m":w()}],"scroll-mx":[{"scroll-mx":w()}],"scroll-my":[{"scroll-my":w()}],"scroll-ms":[{"scroll-ms":w()}],"scroll-me":[{"scroll-me":w()}],"scroll-mbs":[{"scroll-mbs":w()}],"scroll-mbe":[{"scroll-mbe":w()}],"scroll-mt":[{"scroll-mt":w()}],"scroll-mr":[{"scroll-mr":w()}],"scroll-mb":[{"scroll-mb":w()}],"scroll-ml":[{"scroll-ml":w()}],"scroll-p":[{"scroll-p":w()}],"scroll-px":[{"scroll-px":w()}],"scroll-py":[{"scroll-py":w()}],"scroll-ps":[{"scroll-ps":w()}],"scroll-pe":[{"scroll-pe":w()}],"scroll-pbs":[{"scroll-pbs":w()}],"scroll-pbe":[{"scroll-pbe":w()}],"scroll-pt":[{"scroll-pt":w()}],"scroll-pr":[{"scroll-pr":w()}],"scroll-pb":[{"scroll-pb":w()}],"scroll-pl":[{"scroll-pl":w()}],"snap-align":[{snap:[`start`,`end`,`center`,`align-none`]}],"snap-stop":[{snap:[`normal`,`always`]}],"snap-type":[{snap:[`none`,`x`,`y`,`both`]}],"snap-strictness":[{snap:[`mandatory`,`proximity`]}],touch:[{touch:[`auto`,`none`,`manipulation`]}],"touch-x":[{"touch-pan":[`x`,`left`,`right`]}],"touch-y":[{"touch-pan":[`y`,`up`,`down`]}],"touch-pz":[`touch-pinch-zoom`],select:[{select:[`none`,`text`,`all`,`auto`]}],"will-change":[{"will-change":[`auto`,`scroll`,`contents`,`transform`,I,F]}],fill:[{fill:[`none`,...k()]}],"stroke-w":[{stroke:[P,Ut,It,Lt]}],stroke:[{stroke:[`none`,...k()]}],"forced-color-adjust":[{"forced-color-adjust":[`auto`,`none`]}]},conflictingClassGroups:{"container-named":[`container-type`],overflow:[`overflow-x`,`overflow-y`],overscroll:[`overscroll-x`,`overscroll-y`],inset:[`inset-x`,`inset-y`,`inset-bs`,`inset-be`,`start`,`end`,`top`,`right`,`bottom`,`left`],"inset-x":[`right`,`left`],"inset-y":[`top`,`bottom`],flex:[`basis`,`grow`,`shrink`],gap:[`gap-x`,`gap-y`],p:[`px`,`py`,`ps`,`pe`,`pbs`,`pbe`,`pt`,`pr`,`pb`,`pl`],px:[`pr`,`pl`],py:[`pt`,`pb`],m:[`mx`,`my`,`ms`,`me`,`mbs`,`mbe`,`mt`,`mr`,`mb`,`ml`],mx:[`mr`,`ml`],my:[`mt`,`mb`],size:[`w`,`h`],"font-size":[`leading`],"fvn-normal":[`fvn-ordinal`,`fvn-slashed-zero`,`fvn-figure`,`fvn-spacing`,`fvn-fraction`],"fvn-ordinal":[`fvn-normal`],"fvn-slashed-zero":[`fvn-normal`],"fvn-figure":[`fvn-normal`],"fvn-spacing":[`fvn-normal`],"fvn-fraction":[`fvn-normal`],"line-clamp":[`display`,`overflow`],rounded:[`rounded-s`,`rounded-e`,`rounded-t`,`rounded-r`,`rounded-b`,`rounded-l`,`rounded-ss`,`rounded-se`,`rounded-ee`,`rounded-es`,`rounded-tl`,`rounded-tr`,`rounded-br`,`rounded-bl`],"rounded-s":[`rounded-ss`,`rounded-es`],"rounded-e":[`rounded-se`,`rounded-ee`],"rounded-t":[`rounded-tl`,`rounded-tr`],"rounded-r":[`rounded-tr`,`rounded-br`],"rounded-b":[`rounded-br`,`rounded-bl`],"rounded-l":[`rounded-tl`,`rounded-bl`],"border-spacing":[`border-spacing-x`,`border-spacing-y`],"border-w":[`border-w-x`,`border-w-y`,`border-w-s`,`border-w-e`,`border-w-bs`,`border-w-be`,`border-w-t`,`border-w-r`,`border-w-b`,`border-w-l`],"border-w-x":[`border-w-r`,`border-w-l`],"border-w-y":[`border-w-t`,`border-w-b`],"border-color":[`border-color-x`,`border-color-y`,`border-color-s`,`border-color-e`,`border-color-bs`,`border-color-be`,`border-color-t`,`border-color-r`,`border-color-b`,`border-color-l`],"border-color-x":[`border-color-r`,`border-color-l`],"border-color-y":[`border-color-t`,`border-color-b`],translate:[`translate-x`,`translate-y`,`translate-none`],"translate-none":[`translate`,`translate-x`,`translate-y`,`translate-z`],"scroll-m":[`scroll-mx`,`scroll-my`,`scroll-ms`,`scroll-me`,`scroll-mbs`,`scroll-mbe`,`scroll-mt`,`scroll-mr`,`scroll-mb`,`scroll-ml`],"scroll-mx":[`scroll-mr`,`scroll-ml`],"scroll-my":[`scroll-mt`,`scroll-mb`],"scroll-p":[`scroll-px`,`scroll-py`,`scroll-ps`,`scroll-pe`,`scroll-pbs`,`scroll-pbe`,`scroll-pt`,`scroll-pr`,`scroll-pb`,`scroll-pl`],"scroll-px":[`scroll-pr`,`scroll-pl`],"scroll-py":[`scroll-pt`,`scroll-pb`],touch:[`touch-x`,`touch-y`,`touch-pz`],"touch-x":[`touch`],"touch-y":[`touch`],"touch-pz":[`touch`]},conflictingClassGroupModifiers:{"font-size":[`leading`]},postfixLookupClassGroups:[`container-type`],orderSensitiveModifiers:[`*`,`**`,`after`,`backdrop`,`before`,`details-content`,`file`,`first-letter`,`first-line`,`marker`,`placeholder`,`selection`]}});function cn(...e){return sn(Me(e))}var ln=o((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.fragment`);function r(e,n,r){var i=null;if(r!==void 0&&(i=``+r),n.key!==void 0&&(i=``+n.key),`key`in n)for(var a in r={},n)a!==`key`&&(r[a]=n[a]);else r=n;return n=r.ref,{$$typeof:t,type:e,key:i,ref:n===void 0?null:n,props:r}}e.Fragment=n,e.jsx=r,e.jsxs=r})),L=o(((e,t)=>{t.exports=ln()}))(),un=Fe(`inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50`,{variants:{variant:{default:`bg-primary text-primary-foreground hover:bg-primary/90 shadow`,destructive:`bg-destructive text-destructive-foreground hover:bg-destructive/90`,outline:`border border-input bg-card hover:bg-accent hover:text-accent-foreground`,secondary:`bg-secondary text-secondary-foreground hover:bg-secondary/80`,ghost:`hover:bg-accent hover:text-accent-foreground`,link:`text-primary underline-offset-4 hover:underline`},size:{default:`h-9 px-4 py-2`,sm:`h-8 rounded-md px-3 text-xs`,lg:`h-10 rounded-md px-8`,icon:`h-9 w-9`}},defaultVariants:{variant:`default`,size:`default`}}),dn=v.forwardRef(({className:e,variant:t,size:n,asChild:r=!1,...i},a)=>(0,L.jsx)(r?ye:`button`,{className:cn(un({variant:t,size:n,className:e})),ref:a,...i}));dn.displayName=`Button`;var fn=v.forwardRef(({className:e,type:t,...n},r)=>(0,L.jsx)(`input`,{type:t,ref:r,className:cn(`flex h-9 w-full rounded-md border border-input bg-card px-3 py-1 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50`,e),...n}));fn.displayName=`Input`,typeof window<`u`&&window.document&&window.document.createElement;function pn(e,t,{checkForDefaultPrevented:n=!0}={}){return function(r){if(e?.(r),n===!1||!r.defaultPrevented)return t?.(r)}}function mn(e,t=[]){let n=[];function r(t,r){let i=v.createContext(r);i.displayName=t+`Context`;let a=n.length;n=[...n,r];let o=t=>{let{scope:n,children:r,...o}=t,s=n?.[e]?.[a]||i,c=v.useMemo(()=>o,Object.values(o));return(0,L.jsx)(s.Provider,{value:c,children:r})};o.displayName=t+`Provider`;function s(n,o){let s=o?.[e]?.[a]||i,c=v.useContext(s);if(c)return c;if(r!==void 0)return r;throw Error(`\`${n}\` must be used within \`${t}\``)}return[o,s]}let i=()=>{let t=n.map(e=>v.createContext(e));return function(n){let r=n?.[e]||t;return v.useMemo(()=>({[`__scope${e}`]:{...n,[e]:r}}),[n,r])}};return i.scopeName=e,[r,hn(i,...t)]}function hn(...e){let t=e[0];if(e.length===1)return t;let n=()=>{let n=e.map(e=>({useScope:e(),scopeName:e.scopeName}));return function(e){let r=n.reduce((t,{useScope:n,scopeName:r})=>{let i=n(e)[`__scope${r}`];return{...t,...i}},{});return v.useMemo(()=>({[`__scope${t.scopeName}`]:r}),[r])}};return n.scopeName=t.scopeName,n}var gn=globalThis?.document?v.useLayoutEffect:()=>{},_n=v.useId||(()=>void 0),vn=0;function yn(e){let[t,n]=v.useState(_n());return gn(()=>{e||n(e=>e??String(vn++))},[e]),e||(t?`radix-${t}`:``)}var bn=v.useEffectEvent,xn=v.useInsertionEffect;function Sn(e){if(typeof bn==`function`)return bn(e);let t=v.useRef(()=>{throw Error(`Cannot call an event handler while rendering.`)});return typeof xn==`function`?xn(()=>{t.current=e}):gn(()=>{t.current=e}),v.useMemo(()=>((...e)=>t.current?.(...e)),[])}var Cn=v.useInsertionEffect||gn;function wn({prop:e,defaultProp:t,onChange:n=()=>{},caller:r}){let[i,a,o]=Tn({defaultProp:t,onChange:n}),s=e!==void 0,c=s?e:i;{let t=v.useRef(e!==void 0);v.useEffect(()=>{let e=t.current;e!==s&&console.warn(`${r} is changing from ${e?`controlled`:`uncontrolled`} to ${s?`controlled`:`uncontrolled`}. Components should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled value for the lifetime of the component.`),t.current=s},[s,r])}return[c,v.useCallback(t=>{if(s){let n=En(t)?t(e):t;n!==e&&o.current?.(n)}else a(t)},[s,e,a,o])]}function Tn({defaultProp:e,onChange:t}){let[n,r]=v.useState(e),i=v.useRef(n),a=v.useRef(t);return Cn(()=>{a.current=t},[t]),v.useEffect(()=>{i.current!==n&&(a.current?.(n),i.current=n)},[n,i]),[n,r,a]}function En(e){return typeof e==`function`}var Dn=l(h(),1),On=[`a`,`button`,`div`,`form`,`h2`,`h3`,`img`,`input`,`label`,`li`,`nav`,`ol`,`p`,`select`,`span`,`svg`,`ul`].reduce((e,t)=>{let n=ve(`Primitive.${t}`),r=v.forwardRef((e,r)=>{let{asChild:i,...a}=e,o=i?n:t;return typeof window<`u`&&(window[Symbol.for(`radix-ui`)]=!0),(0,L.jsx)(o,{...a,ref:r})});return r.displayName=`Primitive.${t}`,{...e,[t]:r}},{});function kn(e,t){e&&Dn.flushSync(()=>e.dispatchEvent(t))}function An(e){let t=v.useRef(e);return v.useEffect(()=>{t.current=e}),v.useMemo(()=>((...e)=>t.current?.(...e)),[])}var jn=`DismissableLayer`,Mn=`dismissableLayer.update`,Nn=`dismissableLayer.pointerDownOutside`,Pn=`dismissableLayer.focusOutside`,Fn,In=v.createContext({layers:new Set,layersWithOutsidePointerEventsDisabled:new Set,branches:new Set,dismissableSurfaces:new Set}),Ln=v.forwardRef((e,t)=>{let{disableOutsidePointerEvents:n=!1,deferPointerDownOutside:r=!1,onEscapeKeyDown:i,onPointerDownOutside:a,onFocusOutside:o,onInteractOutside:s,onDismiss:c,...l}=e,u=v.useContext(In),[d,f]=v.useState(null),p=d?.ownerDocument??globalThis?.document,[,m]=v.useState({}),h=_e(t,f),g=Array.from(u.layers),[_]=[...u.layersWithOutsidePointerEventsDisabled].slice(-1),y=g.indexOf(_),b=d?g.indexOf(d):-1,x=u.layersWithOutsidePointerEventsDisabled.size>0,S=b>=y,C=v.useRef(!1),w=Vn(e=>{let t=e.target;if(!(t instanceof Node))return;let n=[...u.branches].some(e=>e.contains(t));!S||n||(a?.(e),s?.(e),e.defaultPrevented||c?.())},{ownerDocument:p,deferPointerDownOutside:r,isDeferredPointerDownOutsideRef:C,dismissableSurfaces:u.dismissableSurfaces}),T=Hn(e=>{if(r&&C.current)return;let t=e.target;[...u.branches].some(e=>e.contains(t))||(o?.(e),s?.(e),e.defaultPrevented||c?.())},p),ee=d?b===g.length-1:!1,te=Sn(e=>{e.key===`Escape`&&(i?.(e),!e.defaultPrevented&&c&&(e.preventDefault(),c()))});return v.useEffect(()=>{if(ee)return p.addEventListener(`keydown`,te,{capture:!0}),()=>p.removeEventListener(`keydown`,te,{capture:!0})},[p,ee]),v.useEffect(()=>{if(d)return n&&(u.layersWithOutsidePointerEventsDisabled.size===0&&(Fn=p.body.style.pointerEvents,p.body.style.pointerEvents=`none`),u.layersWithOutsidePointerEventsDisabled.add(d)),u.layers.add(d),Un(),()=>{n&&(u.layersWithOutsidePointerEventsDisabled.delete(d),u.layersWithOutsidePointerEventsDisabled.size===0&&(p.body.style.pointerEvents=Fn))}},[d,p,n,u]),v.useEffect(()=>()=>{d&&(u.layers.delete(d),u.layersWithOutsidePointerEventsDisabled.delete(d),Un())},[d,u]),v.useEffect(()=>{let e=()=>m({});return document.addEventListener(Mn,e),()=>document.removeEventListener(Mn,e)},[]),(0,L.jsx)(On.div,{...l,ref:h,style:{pointerEvents:x?S?`auto`:`none`:void 0,...e.style},onFocusCapture:pn(e.onFocusCapture,T.onFocusCapture),onBlurCapture:pn(e.onBlurCapture,T.onBlurCapture),onPointerDownCapture:pn(e.onPointerDownCapture,w.onPointerDownCapture)})});Ln.displayName=jn;var Rn=`DismissableLayerBranch`,zn=v.forwardRef((e,t)=>{let n=v.useContext(In),r=v.useRef(null),i=_e(t,r);return v.useEffect(()=>{let e=r.current;if(e)return n.branches.add(e),()=>{n.branches.delete(e)}},[n.branches]),(0,L.jsx)(On.div,{...e,ref:i})});zn.displayName=Rn;function Bn(){let e=v.useContext(In),[t,n]=v.useState(null);return v.useEffect(()=>{if(t)return e.dismissableSurfaces.add(t),()=>{e.dismissableSurfaces.delete(t)}},[t,e.dismissableSurfaces]),n}function Vn(e,t){let{ownerDocument:n=globalThis?.document,deferPointerDownOutside:r=!1,isDeferredPointerDownOutsideRef:i,dismissableSurfaces:a}=t,o=An(e),s=v.useRef(!1),c=v.useRef(!1),l=v.useRef(new Map),u=v.useRef(()=>{});return v.useEffect(()=>{function e(){c.current=!1,i.current=!1,l.current.clear()}function t(){return Array.from(l.current.values()).some(Boolean)}function d(e){if(!c.current)return;let t=e.target;t instanceof Node&&[...a].some(e=>e.contains(t))||l.current.set(e.type,!0),e.type===`click`&&window.setTimeout(()=>{c.current&&u.current()},0)}function f(e){c.current&&l.current.set(e.type,!1)}let p=a=>{if(a.target&&!s.current){let s=function(){n.removeEventListener(`click`,u.current);let r=t();e(),r||Wn(Nn,o,d,{discrete:!0})},d={originalEvent:a};c.current=!0,i.current=r&&a.button===0,l.current.clear(),!r||a.button!==0?s():(n.removeEventListener(`click`,u.current),u.current=s,n.addEventListener(`click`,u.current,{once:!0}))}else n.removeEventListener(`click`,u.current),e();s.current=!1},m=[`pointerup`,`mousedown`,`mouseup`,`touchstart`,`touchend`,`click`];for(let e of m)n.addEventListener(e,d,!0),n.addEventListener(e,f);let h=window.setTimeout(()=>{n.addEventListener(`pointerdown`,p)},0);return()=>{window.clearTimeout(h),n.removeEventListener(`pointerdown`,p),n.removeEventListener(`click`,u.current);for(let e of m)n.removeEventListener(e,d,!0),n.removeEventListener(e,f)}},[n,o,r,i,a]),{onPointerDownCapture:()=>s.current=!0}}function Hn(e,t=globalThis?.document){let n=An(e),r=v.useRef(!1);return v.useEffect(()=>{let e=e=>{e.target&&!r.current&&Wn(Pn,n,{originalEvent:e},{discrete:!1})};return t.addEventListener(`focusin`,e),()=>t.removeEventListener(`focusin`,e)},[t,n]),{onFocusCapture:()=>r.current=!0,onBlurCapture:()=>r.current=!1}}function Un(){let e=new CustomEvent(Mn);document.dispatchEvent(e)}function Wn(e,t,n,{discrete:r}){let i=n.originalEvent.target,a=new CustomEvent(e,{bubbles:!1,cancelable:!0,detail:n});t&&i.addEventListener(e,t,{once:!0}),r?kn(i,a):i.dispatchEvent(a)}var Gn=`focusScope.autoFocusOnMount`,Kn=`focusScope.autoFocusOnUnmount`,qn={bubbles:!1,cancelable:!0},Jn=`FocusScope`,Yn=v.forwardRef((e,t)=>{let{loop:n=!1,trapped:r=!1,onMountAutoFocus:i,onUnmountAutoFocus:a,...o}=e,[s,c]=v.useState(null),l=An(i),u=An(a),d=v.useRef(null),f=_e(t,c),p=v.useRef({paused:!1,pause(){this.paused=!0},resume(){this.paused=!1}}).current;v.useEffect(()=>{if(r){let e=function(e){if(p.paused||!s)return;let t=e.target;s.contains(t)?d.current=t:nr(d.current,{select:!0})},t=function(e){if(p.paused||!s)return;let t=e.relatedTarget;t!==null&&(s.contains(t)||nr(d.current,{select:!0}))},n=function(e){if(document.activeElement===document.body)for(let t of e)t.removedNodes.length>0&&nr(s)};document.addEventListener(`focusin`,e),document.addEventListener(`focusout`,t);let r=new MutationObserver(n);return s&&r.observe(s,{childList:!0,subtree:!0}),()=>{document.removeEventListener(`focusin`,e),document.removeEventListener(`focusout`,t),r.disconnect()}}},[r,s,p.paused]),v.useEffect(()=>{if(s){rr.add(p);let e=document.activeElement;if(!s.contains(e)){let t=new CustomEvent(Gn,qn);s.addEventListener(Gn,l),s.dispatchEvent(t),t.defaultPrevented||(Xn(or(Qn(s)),{select:!0}),document.activeElement===e&&nr(s))}return()=>{s.removeEventListener(Gn,l),setTimeout(()=>{let t=new CustomEvent(Kn,qn);s.addEventListener(Kn,u),s.dispatchEvent(t),t.defaultPrevented||nr(e??document.body,{select:!0}),s.removeEventListener(Kn,u),rr.remove(p)},0)}}},[s,l,u,p]);let m=v.useCallback(e=>{if(!n&&!r||p.paused)return;let t=e.key===`Tab`&&!e.altKey&&!e.ctrlKey&&!e.metaKey,i=document.activeElement;if(t&&i){let t=e.currentTarget,[r,a]=Zn(t);r&&a?!e.shiftKey&&i===a?(e.preventDefault(),n&&nr(r,{select:!0})):e.shiftKey&&i===r&&(e.preventDefault(),n&&nr(a,{select:!0})):i===t&&e.preventDefault()}},[n,r,p.paused]);return(0,L.jsx)(On.div,{tabIndex:-1,...o,ref:f,onKeyDown:m})});Yn.displayName=Jn;function Xn(e,{select:t=!1}={}){let n=document.activeElement;for(let r of e)if(nr(r,{select:t}),document.activeElement!==n)return}function Zn(e){let t=Qn(e);return[$n(t,e),$n(t.reverse(),e)]}function Qn(e){let t=[],n=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT,{acceptNode:e=>{let t=e.tagName===`INPUT`&&e.type===`hidden`;return e.disabled||e.hidden||t?NodeFilter.FILTER_SKIP:e.tabIndex>=0?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP}});for(;n.nextNode();)t.push(n.currentNode);return t}function $n(e,t){for(let n of e)if(!er(n,{upTo:t}))return n}function er(e,{upTo:t}){if(getComputedStyle(e).visibility===`hidden`)return!0;for(;e;){if(t!==void 0&&e===t)return!1;if(getComputedStyle(e).display===`none`)return!0;e=e.parentElement}return!1}function tr(e){return e instanceof HTMLInputElement&&`select`in e}function nr(e,{select:t=!1}={}){if(e&&e.focus){let n=document.activeElement;e.focus({preventScroll:!0}),e!==n&&tr(e)&&t&&e.select()}}var rr=ir();function ir(){let e=[];return{add(t){let n=e[0];t!==n&&n?.pause(),e=ar(e,t),e.unshift(t)},remove(t){e=ar(e,t),e[0]?.resume()}}}function ar(e,t){let n=[...e],r=n.indexOf(t);return r!==-1&&n.splice(r,1),n}function or(e){return e.filter(e=>e.tagName!==`A`)}var sr=`Portal`,cr=v.forwardRef((e,t)=>{let{container:n,...r}=e,[i,a]=v.useState(!1);gn(()=>a(!0),[]);let o=n||i&&globalThis?.document?.body;return o?Dn.createPortal((0,L.jsx)(On.div,{...r,ref:t}),o):null});cr.displayName=sr;function lr(e,t){return v.useReducer((e,n)=>t[e][n]??e,e)}var ur=e=>{let{present:t,children:n}=e,r=dr(t),i=typeof n==`function`?n({present:r.isPresent}):v.Children.only(n),a=pr(r.ref,hr(i));return typeof n==`function`||r.isPresent?v.cloneElement(i,{ref:a}):null};ur.displayName=`Presence`;function dr(e){let[t,n]=v.useState(),r=v.useRef(null),i=v.useRef(e),a=v.useRef(`none`),[o,s]=lr(e?`mounted`:`unmounted`,{mounted:{UNMOUNT:`unmounted`,ANIMATION_OUT:`unmountSuspended`},unmountSuspended:{MOUNT:`mounted`,ANIMATION_END:`unmounted`},unmounted:{MOUNT:`mounted`}});return v.useEffect(()=>{let e=mr(r.current);a.current=o===`mounted`?e:`none`},[o]),gn(()=>{let t=r.current,n=i.current;if(n!==e){let r=a.current,o=mr(t);e?s(`MOUNT`):o===`none`||t?.display===`none`?s(`UNMOUNT`):s(n&&r!==o?`ANIMATION_OUT`:`UNMOUNT`),i.current=e}},[e,s]),gn(()=>{if(t){let e,n=t.ownerDocument.defaultView??window,o=a=>{let o=mr(r.current).includes(CSS.escape(a.animationName));if(a.target===t&&o&&(s(`ANIMATION_END`),!i.current)){let r=t.style.animationFillMode;t.style.animationFillMode=`forwards`,e=n.setTimeout(()=>{t.style.animationFillMode===`forwards`&&(t.style.animationFillMode=r)})}},c=e=>{e.target===t&&(a.current=mr(r.current))};return t.addEventListener(`animationstart`,c),t.addEventListener(`animationcancel`,o),t.addEventListener(`animationend`,o),()=>{n.clearTimeout(e),t.removeEventListener(`animationstart`,c),t.removeEventListener(`animationcancel`,o),t.removeEventListener(`animationend`,o)}}else s(`ANIMATION_END`)},[t,s]),{isPresent:[`mounted`,`unmountSuspended`].includes(o),ref:v.useCallback(e=>{r.current=e?getComputedStyle(e):null,n(e)},[])}}function fr(e,t){if(typeof e==`function`)return e(t);e!=null&&(e.current=t)}function pr(...e){let t=v.useRef(e);return t.current=e,v.useCallback(e=>{let n=t.current,r=!1,i=n.map(t=>{let n=fr(t,e);return!r&&typeof n==`function`&&(r=!0),n});if(r)return()=>{for(let e=0;e{_r||={start:yr(),end:yr()};let{start:e,end:t}=_r;return document.body.firstElementChild!==e&&document.body.insertAdjacentElement(`afterbegin`,e),document.body.lastElementChild!==t&&document.body.insertAdjacentElement(`beforeend`,t),gr++,()=>{gr===1&&(_r?.start.remove(),_r?.end.remove(),_r=null),gr=Math.max(0,gr-1)}},[])}function yr(){let e=document.createElement(`span`);return e.setAttribute(`data-radix-focus-guard`,``),e.tabIndex=0,e.style.outline=`none`,e.style.opacity=`0`,e.style.position=`fixed`,e.style.pointerEvents=`none`,e}var br=function(){return br=Object.assign||function(e){for(var t,n=1,r=arguments.length;n`u`)return Jr;var t=Xr(e),n=document.documentElement.clientWidth,r=window.innerWidth;return{left:t[0],top:t[1],right:t[2],gap:Math.max(0,r-n+t[2]-t[0])}},Qr=qr(),$r=`data-scroll-locked`,ei=function(e,t,n,r){var i=e.left,a=e.top,o=e.right,s=e.gap;return n===void 0&&(n=`margin`),` - .${Tr} { - overflow: hidden ${r}; - padding-right: ${s}px ${r}; - } - body[${$r}] { - overflow: hidden ${r}; - overscroll-behavior: contain; - ${[t&&`position: relative ${r};`,n===`margin`&&` - padding-left: ${i}px; - padding-top: ${a}px; - padding-right: ${o}px; - margin-left:0; - margin-top:0; - margin-right: ${s}px ${r}; - `,n===`padding`&&`padding-right: ${s}px ${r};`].filter(Boolean).join(``)} - } - - .${Cr} { - right: ${s}px ${r}; - } - - .${wr} { - margin-right: ${s}px ${r}; - } - - .${Cr} .${Cr} { - right: 0 ${r}; - } - - .${wr} .${wr} { - margin-right: 0 ${r}; - } - - body[${$r}] { - ${Er}: ${s}px; - } -`},ti=function(){var e=parseInt(document.body.getAttribute(`data-scroll-locked`)||`0`,10);return isFinite(e)?e:0},ni=function(){v.useEffect(function(){return document.body.setAttribute($r,(ti()+1).toString()),function(){var e=ti()-1;e<=0?document.body.removeAttribute($r):document.body.setAttribute($r,e.toString())}},[])},ri=function(e){var t=e.noRelative,n=e.noImportant,r=e.gapMode,i=r===void 0?`margin`:r;ni();var a=v.useMemo(function(){return Zr(i)},[i]);return v.createElement(Qr,{styles:ei(a,!t,i,n?``:`!important`)})},ii=!1;if(typeof window<`u`)try{var ai=Object.defineProperty({},"passive",{get:function(){return ii=!0,!0}});window.addEventListener(`test`,ai,ai),window.removeEventListener(`test`,ai,ai)}catch{ii=!1}var oi=ii?{passive:!1}:!1,si=function(e){return e.tagName===`TEXTAREA`},ci=function(e,t){if(!(e instanceof Element))return!1;var n=window.getComputedStyle(e);return n[t]!==`hidden`&&!(n.overflowY===n.overflowX&&!si(e)&&n[t]===`visible`)},li=function(e){return ci(e,`overflowY`)},ui=function(e){return ci(e,`overflowX`)},di=function(e,t){var n=t.ownerDocument,r=t;do{if(typeof ShadowRoot<`u`&&r instanceof ShadowRoot&&(r=r.host),mi(e,r)){var i=hi(e,r);if(i[1]>i[2])return!0}r=r.parentNode}while(r&&r!==n.body);return!1},fi=function(e){return[e.scrollTop,e.scrollHeight,e.clientHeight]},pi=function(e){return[e.scrollLeft,e.scrollWidth,e.clientWidth]},mi=function(e,t){return e===`v`?li(t):ui(t)},hi=function(e,t){return e===`v`?fi(t):pi(t)},gi=function(e,t){return e===`h`&&t===`rtl`?-1:1},_i=function(e,t,n,r,i){var a=gi(e,window.getComputedStyle(t).direction),o=a*r,s=n.target,c=t.contains(s),l=!1,u=o>0,d=0,f=0;do{if(!s)break;var p=hi(e,s),m=p[0],h=p[1]-p[2]-a*m;(m||h)&&mi(e,s)&&(d+=h,f+=m);var g=s.parentNode;s=g&&g.nodeType===Node.DOCUMENT_FRAGMENT_NODE?g.host:g}while(!c&&s!==document.body||c&&(t.contains(s)||t===s));return(u&&(i&&Math.abs(d)<1||!i&&o>d)||!u&&(i&&Math.abs(f)<1||!i&&-o>f))&&(l=!0),l},vi=function(e){return`changedTouches`in e?[e.changedTouches[0].clientX,e.changedTouches[0].clientY]:[0,0]},yi=function(e){return[e.deltaX,e.deltaY]},bi=function(e){return e&&`current`in e?e.current:e},xi=function(e,t){return e[0]===t[0]&&e[1]===t[1]},Si=function(e){return` - .block-interactivity-${e} {pointer-events: none;} - .allow-interactivity-${e} {pointer-events: all;} -`},Ci=0,wi=[];function Ti(e){var t=v.useRef([]),n=v.useRef([0,0]),r=v.useRef(),i=v.useState(Ci++)[0],a=v.useState(qr)[0],o=v.useRef(e);v.useEffect(function(){o.current=e},[e]),v.useEffect(function(){if(e.inert){document.body.classList.add(`block-interactivity-${i}`);var t=Sr([e.lockRef.current],(e.shards||[]).map(bi),!0).filter(Boolean);return t.forEach(function(e){return e.classList.add(`allow-interactivity-${i}`)}),function(){document.body.classList.remove(`block-interactivity-${i}`),t.forEach(function(e){return e.classList.remove(`allow-interactivity-${i}`)})}}},[e.inert,e.lockRef.current,e.shards]);var s=v.useCallback(function(e,t){if(`touches`in e&&e.touches.length===2||e.type===`wheel`&&e.ctrlKey)return!o.current.allowPinchZoom;var i=vi(e),a=n.current,s=`deltaX`in e?e.deltaX:a[0]-i[0],c=`deltaY`in e?e.deltaY:a[1]-i[1],l,u=e.target,d=Math.abs(s)>Math.abs(c)?`h`:`v`;if(`touches`in e&&d===`h`&&u.type===`range`)return!1;var f=window.getSelection(),p=f&&f.anchorNode;if(p&&(p===u||p.contains(u)))return!1;var m=di(d,u);if(!m)return!0;if(m?l=d:(l=d===`v`?`h`:`v`,m=di(d,u)),!m)return!1;if(!r.current&&`changedTouches`in e&&(s||c)&&(r.current=l),!l)return!0;var h=r.current||l;return _i(h,t,e,h===`h`?s:c,!0)},[]),c=v.useCallback(function(e){var n=e;if(!(!wi.length||wi[wi.length-1]!==a)){var r=`deltaY`in n?yi(n):vi(n),i=t.current.filter(function(e){return e.name===n.type&&(e.target===n.target||n.target===e.shadowParent)&&xi(e.delta,r)})[0];if(i&&i.should){n.cancelable&&n.preventDefault();return}if(!i){var c=(o.current.shards||[]).map(bi).filter(Boolean).filter(function(e){return e.contains(n.target)});(c.length>0?s(n,c[0]):!o.current.noIsolation)&&n.cancelable&&n.preventDefault()}}},[]),l=v.useCallback(function(e,n,r,i){var a={name:e,delta:n,target:r,should:i,shadowParent:Ei(r)};t.current.push(a),setTimeout(function(){t.current=t.current.filter(function(e){return e!==a})},1)},[]),u=v.useCallback(function(e){n.current=vi(e),r.current=void 0},[]),d=v.useCallback(function(t){l(t.type,yi(t),t.target,s(t,e.lockRef.current))},[]),f=v.useCallback(function(t){l(t.type,vi(t),t.target,s(t,e.lockRef.current))},[]);v.useEffect(function(){return wi.push(a),e.setCallbacks({onScrollCapture:d,onWheelCapture:d,onTouchMoveCapture:f}),document.addEventListener(`wheel`,c,oi),document.addEventListener(`touchmove`,c,oi),document.addEventListener(`touchstart`,u,oi),function(){wi=wi.filter(function(e){return e!==a}),document.removeEventListener(`wheel`,c,oi),document.removeEventListener(`touchmove`,c,oi),document.removeEventListener(`touchstart`,u,oi)}},[]);var p=e.removeScrollBar,m=e.inert;return v.createElement(v.Fragment,null,m?v.createElement(a,{styles:Si(i)}):null,p?v.createElement(ri,{noRelative:e.noRelative,gapMode:e.gapMode}):null)}function Ei(e){for(var t=null;e!==null;)e instanceof ShadowRoot&&(t=e.host,e=e.host),e=e.parentNode;return t}var Di=Ir(Lr,Ti),Oi=v.forwardRef(function(e,t){return v.createElement(zr,br({},e,{ref:t,sideCar:Di}))});Oi.classNames=zr.classNames;var ki=function(e){return typeof document>`u`?null:(Array.isArray(e)?e[0]:e).ownerDocument.body},Ai=new WeakMap,ji=new WeakMap,Mi={},Ni=0,Pi=function(e){return e&&(e.host||Pi(e.parentNode))},R=function(e,t){return t.map(function(t){if(e.contains(t))return t;var n=Pi(t);return n&&e.contains(n)?n:(console.error(`aria-hidden`,t,`in not contained inside`,e,`. Doing nothing`),null)}).filter(function(e){return!!e})},z=function(e,t,n,r){var i=R(t,Array.isArray(e)?e:[e]);Mi[n]||(Mi[n]=new WeakMap);var a=Mi[n],o=[],s=new Set,c=new Set(i),l=function(e){!e||s.has(e)||(s.add(e),l(e.parentNode))};i.forEach(l);var u=function(e){!e||c.has(e)||Array.prototype.forEach.call(e.children,function(e){if(s.has(e))u(e);else try{var t=e.getAttribute(r),i=t!==null&&t!==`false`,c=(Ai.get(e)||0)+1,l=(a.get(e)||0)+1;Ai.set(e,c),a.set(e,l),o.push(e),c===1&&i&&ji.set(e,!0),l===1&&e.setAttribute(n,`true`),i||e.setAttribute(r,`true`)}catch(t){console.error(`aria-hidden: cannot operate on `,e,t)}})};return u(t),s.clear(),Ni++,function(){o.forEach(function(e){var t=Ai.get(e)-1,i=a.get(e)-1;Ai.set(e,t),a.set(e,i),t||(ji.has(e)||e.removeAttribute(r),ji.delete(e)),i||e.removeAttribute(n)}),Ni--,Ni||(Ai=new WeakMap,Ai=new WeakMap,ji=new WeakMap,Mi={})}},Fi=function(e,t,n){n===void 0&&(n=`data-aria-hidden`);var r=Array.from(Array.isArray(e)?e:[e]),i=t||ki(e);return i?(r.push.apply(r,Array.from(i.querySelectorAll(`[aria-live], script`))),z(r,i,n,`aria-hidden`)):function(){return null}},Ii=`Dialog`,[Li,Ri]=mn(Ii),[zi,Bi]=Li(Ii),Vi=e=>{let{__scopeDialog:t,children:n,open:r,defaultOpen:i,onOpenChange:a,modal:o=!0}=e,s=v.useRef(null),c=v.useRef(null),[l,u]=wn({prop:r,defaultProp:i??!1,onChange:a,caller:Ii});return(0,L.jsx)(zi,{scope:t,triggerRef:s,contentRef:c,contentId:yn(),titleId:yn(),descriptionId:yn(),open:l,onOpenChange:u,onOpenToggle:v.useCallback(()=>u(e=>!e),[u]),modal:o,children:n})};Vi.displayName=Ii;var Hi=`DialogTrigger`,Ui=v.forwardRef((e,t)=>{let{__scopeDialog:n,...r}=e,i=Bi(Hi,n),a=_e(t,i.triggerRef);return(0,L.jsx)(On.button,{type:`button`,"aria-haspopup":`dialog`,"aria-expanded":i.open,"aria-controls":i.open?i.contentId:void 0,"data-state":la(i.open),...r,ref:a,onClick:pn(e.onClick,i.onOpenToggle)})});Ui.displayName=Hi;var Wi=`DialogPortal`,[Gi,Ki]=Li(Wi,{forceMount:void 0}),qi=e=>{let{__scopeDialog:t,forceMount:n,children:r,container:i}=e,a=Bi(Wi,t);return(0,L.jsx)(Gi,{scope:t,forceMount:n,children:v.Children.map(r,e=>(0,L.jsx)(ur,{present:n||a.open,children:(0,L.jsx)(cr,{asChild:!0,container:i,children:e})}))})};qi.displayName=Wi;var Ji=`DialogOverlay`,Yi=v.forwardRef((e,t)=>{let n=Ki(Ji,e.__scopeDialog),{forceMount:r=n.forceMount,...i}=e,a=Bi(Ji,e.__scopeDialog);return a.modal?(0,L.jsx)(ur,{present:r||a.open,children:(0,L.jsx)(Zi,{...i,ref:t})}):null});Yi.displayName=Ji;var Xi=ve(`DialogOverlay.RemoveScroll`),Zi=v.forwardRef((e,t)=>{let{__scopeDialog:n,...r}=e,i=Bi(Ji,n),a=_e(t,Bn());return(0,L.jsx)(Oi,{as:Xi,allowPinchZoom:!0,shards:[i.contentRef],children:(0,L.jsx)(On.div,{"data-state":la(i.open),...r,ref:a,style:{pointerEvents:`auto`,...r.style}})})}),Qi=`DialogContent`,$i=v.forwardRef((e,t)=>{let n=Ki(Qi,e.__scopeDialog),{forceMount:r=n.forceMount,...i}=e,a=Bi(Qi,e.__scopeDialog);return(0,L.jsx)(ur,{present:r||a.open,children:a.modal?(0,L.jsx)(ea,{...i,ref:t}):(0,L.jsx)(ta,{...i,ref:t})})});$i.displayName=Qi;var ea=v.forwardRef((e,t)=>{let n=Bi(Qi,e.__scopeDialog),r=v.useRef(null),i=_e(t,n.contentRef,r);return v.useEffect(()=>{let e=r.current;if(e)return Fi(e)},[]),(0,L.jsx)(na,{...e,ref:i,trapFocus:n.open,disableOutsidePointerEvents:n.open,onCloseAutoFocus:pn(e.onCloseAutoFocus,e=>{e.preventDefault(),n.triggerRef.current?.focus()}),onPointerDownOutside:pn(e.onPointerDownOutside,e=>{let t=e.detail.originalEvent,n=t.button===0&&t.ctrlKey===!0;(t.button===2||n)&&e.preventDefault()}),onFocusOutside:pn(e.onFocusOutside,e=>e.preventDefault())})}),ta=v.forwardRef((e,t)=>{let n=Bi(Qi,e.__scopeDialog),r=v.useRef(!1),i=v.useRef(!1);return(0,L.jsx)(na,{...e,ref:t,trapFocus:!1,disableOutsidePointerEvents:!1,onCloseAutoFocus:t=>{e.onCloseAutoFocus?.(t),t.defaultPrevented||(r.current||n.triggerRef.current?.focus(),t.preventDefault()),r.current=!1,i.current=!1},onInteractOutside:t=>{e.onInteractOutside?.(t),t.defaultPrevented||(r.current=!0,t.detail.originalEvent.type===`pointerdown`&&(i.current=!0));let a=t.target;n.triggerRef.current?.contains(a)&&t.preventDefault(),t.detail.originalEvent.type===`focusin`&&i.current&&t.preventDefault()}})}),na=v.forwardRef((e,t)=>{let{__scopeDialog:n,trapFocus:r,onOpenAutoFocus:i,onCloseAutoFocus:a,...o}=e,s=Bi(Qi,n);return vr(),(0,L.jsx)(L.Fragment,{children:(0,L.jsx)(Yn,{asChild:!0,loop:!0,trapped:r,onMountAutoFocus:i,onUnmountAutoFocus:a,children:(0,L.jsx)(Ln,{role:`dialog`,id:s.contentId,"aria-describedby":s.descriptionId,"aria-labelledby":s.titleId,"data-state":la(s.open),...o,ref:t,deferPointerDownOutside:!0,onDismiss:()=>s.onOpenChange(!1)})})})}),ra=`DialogTitle`,ia=v.forwardRef((e,t)=>{let{__scopeDialog:n,...r}=e,i=Bi(ra,n);return(0,L.jsx)(On.h2,{id:i.titleId,...r,ref:t})});ia.displayName=ra;var aa=`DialogDescription`,oa=v.forwardRef((e,t)=>{let{__scopeDialog:n,...r}=e,i=Bi(aa,n);return(0,L.jsx)(On.p,{id:i.descriptionId,...r,ref:t})});oa.displayName=aa;var sa=`DialogClose`,ca=v.forwardRef((e,t)=>{let{__scopeDialog:n,...r}=e,i=Bi(sa,n);return(0,L.jsx)(On.button,{type:`button`,...r,ref:t,onClick:pn(e.onClick,()=>i.onOpenChange(!1))})});ca.displayName=sa;function la(e){return e?`open`:`closed`}var ua=Vi,da=v.forwardRef(({className:e,children:t,...n},r)=>(0,L.jsxs)(qi,{children:[(0,L.jsx)(Yi,{className:`fixed inset-0 z-50 bg-black/40 data-[state=open]:animate-in data-[state=closed]:animate-out`}),(0,L.jsxs)($i,{ref:r,className:cn(`fixed left-1/2 top-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4 border bg-card p-6 shadow-lg rounded-xl`,e),...n,children:[t,(0,L.jsxs)(ca,{className:`absolute right-4 top-4 opacity-70 hover:opacity-100`,children:[(0,L.jsx)(me,{className:`h-4 w-4`}),(0,L.jsx)(`span`,{className:`sr-only`,children:`关闭`})]})]})]}));da.displayName=`DialogContent`;function fa({className:e,...t}){return(0,L.jsx)(`div`,{className:cn(`flex flex-col space-y-1.5`,e),...t})}function pa({className:e,...t}){return(0,L.jsx)(ia,{className:cn(`text-lg font-semibold`,e),...t})}function ma(e,t){return function(){return e.apply(t,arguments)}}var{toString:ha}=Object.prototype,{getPrototypeOf:ga}=Object,{iterator:_a,toStringTag:va}=Symbol,ya=(({hasOwnProperty:e})=>(t,n)=>e.call(t,n))(Object.prototype),ba=(e,t)=>{let n=e,r=[];for(;n!=null&&n!==Object.prototype;){if(r.indexOf(n)!==-1)return!1;if(r.push(n),ya(n,t))return!0;n=ga(n)}return!1},xa=(e,t)=>e!=null&&ba(e,t)?e[t]:void 0,Sa=(e=>t=>{let n=ha.call(t);return e[n]||(e[n]=n.slice(8,-1).toLowerCase())})(Object.create(null)),Ca=e=>(e=e.toLowerCase(),t=>Sa(t)===e),wa=e=>t=>typeof t===e,{isArray:Ta}=Array,Ea=wa(`undefined`);function Da(e){return e!==null&&!Ea(e)&&e.constructor!==null&&!Ea(e.constructor)&&ja(e.constructor.isBuffer)&&e.constructor.isBuffer(e)}var Oa=Ca(`ArrayBuffer`);function ka(e){let t;return t=typeof ArrayBuffer<`u`&&ArrayBuffer.isView?ArrayBuffer.isView(e):e&&e.buffer&&Oa(e.buffer),t}var Aa=wa(`string`),ja=wa(`function`),Ma=wa(`number`),Na=e=>typeof e==`object`&&!!e,Pa=e=>e===!0||e===!1,Fa=e=>{if(!Na(e))return!1;let t=ga(e);return(t===null||t===Object.prototype||ga(t)===null)&&!ba(e,va)&&!ba(e,_a)},Ia=e=>{if(!Na(e)||Da(e))return!1;try{return Object.keys(e).length===0&&Object.getPrototypeOf(e)===Object.prototype}catch{return!1}},La=Ca(`Date`),Ra=Ca(`File`),za=e=>!!(e&&e.uri!==void 0),Ba=e=>e&&e.getParts!==void 0,Va=Ca(`Blob`),Ha=Ca(`FileList`),Ua=e=>Na(e)&&ja(e.pipe);function Wa(){return typeof globalThis<`u`?globalThis:typeof self<`u`?self:typeof window<`u`?window:typeof global<`u`?global:{}}var Ga=Wa(),Ka=Ga.FormData===void 0?void 0:Ga.FormData,qa=e=>{if(!e)return!1;if(Ka&&e instanceof Ka)return!0;let t=ga(e);if(!t||t===Object.prototype||!ja(e.append))return!1;let n=Sa(e);return n===`formdata`||n===`object`&&ja(e.toString)&&e.toString()===`[object FormData]`},Ja=Ca(`URLSearchParams`),[Ya,Xa,Za,Qa]=[`ReadableStream`,`Request`,`Response`,`Headers`].map(Ca),$a=e=>e.trim?e.trim():e.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,``);function eo(e,t,{allOwnKeys:n=!1}={}){if(e==null)return;let r,i;if(typeof e!=`object`&&(e=[e]),Ta(e))for(r=0,i=e.length;r0;)if(i=n[r],t===i.toLowerCase())return i;return null}var no=typeof globalThis<`u`?globalThis:typeof self<`u`?self:typeof window<`u`?window:global,ro=e=>!Ea(e)&&e!==no;function io(...e){let{caseless:t,skipUndefined:n}=ro(this)&&this||{},r={},i=(e,i)=>{if(i===`__proto__`||i===`constructor`||i===`prototype`)return;let a=t&&typeof i==`string`&&to(r,i)||i,o=ya(r,a)?r[a]:void 0;Fa(o)&&Fa(e)?r[a]=io(o,e):Fa(e)?r[a]=io({},e):Ta(e)?r[a]=e.slice():(!n||!Ea(e))&&(r[a]=e)};for(let t=0,n=e.length;t(eo(t,(t,r)=>{n&&ja(t)?Object.defineProperty(e,r,{__proto__:null,value:ma(t,n),writable:!0,enumerable:!0,configurable:!0}):Object.defineProperty(e,r,{__proto__:null,value:t,writable:!0,enumerable:!0,configurable:!0})},{allOwnKeys:r}),e),oo=e=>(e.charCodeAt(0)===65279&&(e=e.slice(1)),e),so=(e,t,n,r)=>{e.prototype=Object.create(t.prototype,r),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)},co=(e,t,n,r)=>{let i,a,o,s={};if(t||={},e==null)return t;do{for(i=Object.getOwnPropertyNames(e),a=i.length;a-->0;)o=i[a],(!r||r(o,e,t))&&!s[o]&&(t[o]=e[o],s[o]=!0);e=n!==!1&&ga(e)}while(e&&(!n||n(e,t))&&e!==Object.prototype);return t},lo=(e,t,n)=>{e=String(e),(n===void 0||n>e.length)&&(n=e.length),n-=t.length;let r=e.indexOf(t,n);return r!==-1&&r===n},uo=e=>{if(!e)return null;if(Ta(e))return e;let t=e.length;if(!Ma(t))return null;let n=Array(t);for(;t-->0;)n[t]=e[t];return n},fo=(e=>t=>e&&t instanceof e)(typeof Uint8Array<`u`&&ga(Uint8Array)),po=(e,t)=>{let n=(e&&e[_a]).call(e),r;for(;(r=n.next())&&!r.done;){let n=r.value;t.call(e,n[0],n[1])}},B=(e,t)=>{let n,r=[];for(;(n=e.exec(t))!==null;)r.push(n);return r},V=Ca(`HTMLFormElement`),mo=e=>e.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,function(e,t,n){return t.toUpperCase()+n}),{propertyIsEnumerable:ho}=Object.prototype,go=Ca(`RegExp`),_o=(e,t)=>{let n=Object.getOwnPropertyDescriptors(e),r={};eo(n,(n,i)=>{let a;(a=t(n,i,e))!==!1&&(r[i]=a||n)}),Object.defineProperties(e,r)},vo=e=>{_o(e,(t,n)=>{if(ja(e)&&[`arguments`,`caller`,`callee`].includes(n))return!1;let r=e[n];if(ja(r)){if(t.enumerable=!1,`writable`in t){t.writable=!1;return}t.set||=()=>{throw Error(`Can not rewrite read-only method '`+n+`'`)}}})},yo=(e,t)=>{let n={},r=e=>{e.forEach(e=>{n[e]=!0})};return Ta(e)?r(e):r(String(e).split(t)),n},bo=()=>{},xo=(e,t)=>e!=null&&Number.isFinite(e=+e)?e:t;function So(e){return!!(e&&ja(e.append)&&e[va]===`FormData`&&e[_a])}var Co=e=>{let t=new WeakSet,n=e=>{if(Na(e)){if(t.has(e))return;if(Da(e))return e;if(!(`toJSON`in e)){t.add(e);let r=Ta(e)?[]:{};return eo(e,(e,t)=>{let i=n(e);!Ea(i)&&(r[t]=i)}),t.delete(e),r}}return e};return n(e)},wo=Ca(`AsyncFunction`),To=e=>e&&(Na(e)||ja(e))&&ja(e.then)&&ja(e.catch),Eo=((e,t)=>e?setImmediate:t?((e,t)=>(no.addEventListener(`message`,({source:n,data:r})=>{n===no&&r===e&&t.length&&t.shift()()},!1),n=>{t.push(n),no.postMessage(e,`*`)}))(`axios@${Math.random()}`,[]):e=>setTimeout(e))(typeof setImmediate==`function`,ja(no.postMessage)),Do=typeof queueMicrotask<`u`?queueMicrotask.bind(no):typeof process<`u`&&process.nextTick||Eo,Oo=e=>e!=null&&ja(e[_a]),H={isArray:Ta,isArrayBuffer:Oa,isBuffer:Da,isFormData:qa,isArrayBufferView:ka,isString:Aa,isNumber:Ma,isBoolean:Pa,isObject:Na,isPlainObject:Fa,isEmptyObject:Ia,isReadableStream:Ya,isRequest:Xa,isResponse:Za,isHeaders:Qa,isUndefined:Ea,isDate:La,isFile:Ra,isReactNativeBlob:za,isReactNative:Ba,isBlob:Va,isRegExp:go,isFunction:ja,isStream:Ua,isURLSearchParams:Ja,isTypedArray:fo,isFileList:Ha,forEach:eo,merge:io,extend:ao,trim:$a,stripBOM:oo,inherits:so,toFlatObject:co,kindOf:Sa,kindOfTest:Ca,endsWith:lo,toArray:uo,forEachEntry:po,matchAll:B,isHTMLForm:V,hasOwnProperty:ya,hasOwnProp:ya,hasOwnInPrototypeChain:ba,getSafeProp:xa,reduceDescriptors:_o,freezeMethods:vo,toObjectSet:yo,toCamelCase:mo,noop:bo,toFiniteNumber:xo,findKey:to,global:no,isContextDefined:ro,isSpecCompliantForm:So,toJSONObject:Co,isAsyncFn:wo,isThenable:To,setImmediate:Eo,asap:Do,isIterable:Oo,isSafeIterable:e=>e!=null&&ba(e,_a)&&Oo(e)},ko=H.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`]),Ao=e=>{let t={},n,r,i;return e&&e.split(` -`).forEach(function(e){i=e.indexOf(`:`),n=e.substring(0,i).trim().toLowerCase(),r=e.substring(i+1).trim(),!(!n||t[n]&&ko[n])&&(n===`set-cookie`?t[n]?t[n].push(r):t[n]=[r]:t[n]=t[n]?t[n]+`, `+r:r)}),t};function jo(e){let t=0,n=e.length;for(;tt;){let t=e.charCodeAt(n-1);if(t!==9&&t!==32)break;--n}return t===0&&n===e.length?e:e.slice(t,n)}var Mo=RegExp(`[\\u0000-\\u0008\\u000a-\\u001f\\u007f]+`,`g`),No=RegExp(`[^\\u0009\\u0020-\\u007e\\u0080-\\u00ff]+`,`g`);function Po(e,t){return H.isArray(e)?e.map(e=>Po(e,t)):jo(String(e).replace(t,``))}var Fo=e=>Po(e,Mo),Io=e=>Po(e,No);function Lo(e){let t=Object.create(null);return H.forEach(e.toJSON(),(e,n)=>{t[n]=Io(e)}),t}var Ro=Symbol(`internals`);function zo(e){return e&&String(e).trim().toLowerCase()}function Bo(e){return e===!1||e==null?e:H.isArray(e)?e.map(Bo):Fo(String(e))}function Vo(e){let t=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g,r;for(;r=n.exec(e);)t[r[1]]=r[2];return t}var Ho=e=>/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(e.trim());function Uo(e,t,n,r,i){if(H.isFunction(r))return r.call(this,t,n);if(i&&(t=n),H.isString(t)){if(H.isString(r))return t.indexOf(r)!==-1;if(H.isRegExp(r))return r.test(t)}}function Wo(e){return e.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,(e,t,n)=>t.toUpperCase()+n)}function Go(e,t){let n=H.toCamelCase(` `+t);[`get`,`set`,`has`].forEach(r=>{Object.defineProperty(e,r+n,{__proto__:null,value:function(e,n,i){return this[r].call(this,t,e,n,i)},configurable:!0})})}var Ko=class{constructor(e){e&&this.set(e)}set(e,t,n){let r=this;function i(e,t,n){let i=zo(t);if(!i)return;let a=H.findKey(r,i);(!a||r[a]===void 0||n===!0||n===void 0&&r[a]!==!1)&&(r[a||t]=Bo(e))}let a=(e,t)=>H.forEach(e,(e,n)=>i(e,n,t));if(H.isPlainObject(e)||e instanceof this.constructor)a(e,t);else if(H.isString(e)&&(e=e.trim())&&!Ho(e))a(Ao(e),t);else if(H.isObject(e)&&H.isSafeIterable(e)){let n=Object.create(null),r,i;for(let t of e){if(!H.isArray(t))throw TypeError(`Object iterator must return a key-value pair`);i=t[0],H.hasOwnProp(n,i)?(r=n[i],n[i]=H.isArray(r)?[...r,t[1]]:[r,t[1]]):n[i]=t[1]}a(n,t)}else e!=null&&i(t,e,n);return this}get(e,t){if(e=zo(e),e){let n=H.findKey(this,e);if(n){let e=this[n];if(!t)return e;if(t===!0)return Vo(e);if(H.isFunction(t))return t.call(this,e,n);if(H.isRegExp(t))return t.exec(e);throw TypeError(`parser must be boolean|regexp|function`)}}}has(e,t){if(e=zo(e),e){let n=H.findKey(this,e);return!!(n&&this[n]!==void 0&&(!t||Uo(this,this[n],n,t)))}return!1}delete(e,t){let n=this,r=!1;function i(e){if(e=zo(e),e){let i=H.findKey(n,e);i&&(!t||Uo(n,n[i],i,t))&&(delete n[i],r=!0)}}return H.isArray(e)?e.forEach(i):i(e),r}clear(e){let t=Object.keys(this),n=t.length,r=!1;for(;n--;){let i=t[n];(!e||Uo(this,this[i],i,e,!0))&&(delete this[i],r=!0)}return r}normalize(e){let t=this,n={};return H.forEach(this,(r,i)=>{let a=H.findKey(n,i);if(a){t[a]=Bo(r),delete t[i];return}let o=e?Wo(i):String(i).trim();o!==i&&delete t[i],t[o]=Bo(r),n[o]=!0}),this}concat(...e){return this.constructor.concat(this,...e)}toJSON(e){let t=Object.create(null);return H.forEach(this,(n,r)=>{n!=null&&n!==!1&&(t[r]=e&&H.isArray(n)?n.join(`, `):n)}),t}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map(([e,t])=>e+`: `+t).join(` -`)}getSetCookie(){return this.get(`set-cookie`)||[]}get[Symbol.toStringTag](){return`AxiosHeaders`}static from(e){return e instanceof this?e:new this(e)}static concat(e,...t){let n=new this(e);return t.forEach(e=>n.set(e)),n}static accessor(e){let t=(this[Ro]=this[Ro]={accessors:{}}).accessors,n=this.prototype;function r(e){let r=zo(e);t[r]||(Go(n,e),t[r]=!0)}return H.isArray(e)?e.forEach(r):r(e),this}};Ko.accessor([`Content-Type`,`Content-Length`,`Accept`,`Accept-Encoding`,`User-Agent`,`Authorization`]),H.reduceDescriptors(Ko.prototype,({value:e},t)=>{let n=t[0].toUpperCase()+t.slice(1);return{get:()=>e,set(e){this[n]=e}}}),H.freezeMethods(Ko);var qo=`[REDACTED ****]`;function Jo(e){if(H.hasOwnProp(e,`toJSON`))return!0;let t=Object.getPrototypeOf(e);for(;t&&t!==Object.prototype;){if(H.hasOwnProp(t,`toJSON`))return!0;t=Object.getPrototypeOf(t)}return!1}function Yo(e,t){let n=new Set(t.map(e=>String(e).toLowerCase())),r=[],i=e=>{if(typeof e!=`object`||!e||H.isBuffer(e))return e;if(r.indexOf(e)!==-1)return;e instanceof Ko&&(e=e.toJSON()),r.push(e);let t;if(H.isArray(e))t=[],e.forEach((e,n)=>{let r=i(e);H.isUndefined(r)||(t[n]=r)});else{if(!H.isPlainObject(e)&&Jo(e))return r.pop(),e;t=Object.create(null);for(let[r,a]of Object.entries(e)){let e=n.has(r.toLowerCase())?qo:i(a);H.isUndefined(e)||(t[r]=e)}}return r.pop(),t};return i(e)}var U=class e extends Error{static from(t,n,r,i,a,o){let s=new e(t.message,n||t.code,r,i,a);return Object.defineProperty(s,"cause",{__proto__:null,value:t,writable:!0,enumerable:!1,configurable:!0}),s.name=t.name,t.status!=null&&s.status==null&&(s.status=t.status),o&&Object.assign(s,o),s}constructor(e,t,n,r,i){super(e),Object.defineProperty(this,"message",{__proto__:null,value:e,enumerable:!0,writable:!0,configurable:!0}),this.name=`AxiosError`,this.isAxiosError=!0,t&&(this.code=t),n&&(this.config=n),r&&(this.request=r),i&&(this.response=i,this.status=i.status)}toJSON(){let e=this.config,t=e&&H.hasOwnProp(e,`redact`)?e.redact:void 0,n=H.isArray(t)&&t.length>0?Yo(e,t):H.toJSONObject(e);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:n,code:this.code,status:this.status}}};U.ERR_BAD_OPTION_VALUE=`ERR_BAD_OPTION_VALUE`,U.ERR_BAD_OPTION=`ERR_BAD_OPTION`,U.ECONNABORTED=`ECONNABORTED`,U.ETIMEDOUT=`ETIMEDOUT`,U.ECONNREFUSED=`ECONNREFUSED`,U.ERR_NETWORK=`ERR_NETWORK`,U.ERR_FR_TOO_MANY_REDIRECTS=`ERR_FR_TOO_MANY_REDIRECTS`,U.ERR_DEPRECATED=`ERR_DEPRECATED`,U.ERR_BAD_RESPONSE=`ERR_BAD_RESPONSE`,U.ERR_BAD_REQUEST=`ERR_BAD_REQUEST`,U.ERR_CANCELED=`ERR_CANCELED`,U.ERR_NOT_SUPPORT=`ERR_NOT_SUPPORT`,U.ERR_INVALID_URL=`ERR_INVALID_URL`,U.ERR_FORM_DATA_DEPTH_EXCEEDED=`ERR_FORM_DATA_DEPTH_EXCEEDED`;function Xo(e){return H.isPlainObject(e)||H.isArray(e)}function Zo(e){return H.endsWith(e,`[]`)?e.slice(0,-2):e}function Qo(e,t,n){return e?e.concat(t).map(function(e,t){return e=Zo(e),!n&&t?`[`+e+`]`:e}).join(n?`.`:``):t}function $o(e){return H.isArray(e)&&!e.some(Xo)}var es=H.toFlatObject(H,{},null,function(e){return/^is[A-Z]/.test(e)});function ts(e,t,n){if(!H.isObject(e))throw TypeError(`target must be an object`);t||=new FormData,n=H.toFlatObject(n,{metaTokens:!0,dots:!1,indexes:!1},!1,function(e,t){return!H.isUndefined(t[e])});let r=n.metaTokens,i=n.visitor||m,a=n.dots,o=n.indexes,s=n.Blob||typeof Blob<`u`&&Blob,c=n.maxDepth===void 0?100:n.maxDepth,l=s&&H.isSpecCompliantForm(t),u=[];if(!H.isFunction(i))throw TypeError(`visitor must be a function`);function d(e){if(e===null)return``;if(H.isDate(e))return e.toISOString();if(H.isBoolean(e))return e.toString();if(!l&&H.isBlob(e))throw new U(`Blob is not supported. Use a Buffer instead.`);if(H.isArrayBuffer(e)||H.isTypedArray(e)){if(l&&typeof s==`function`)return new s([e]);if(typeof Buffer<`u`)return Buffer.from(e);throw new U(`Blob is not supported. Use a Buffer instead.`,U.ERR_NOT_SUPPORT)}return e}function f(e){if(e>c)throw new U(`Object is too deeply nested (`+e+` levels). Max depth: `+c,U.ERR_FORM_DATA_DEPTH_EXCEEDED)}function p(e,t){if(c===1/0)return JSON.stringify(e);let n=[];return JSON.stringify(e,function(e,r){if(!H.isObject(r))return r;for(;n.length&&n[n.length-1]!==this;)n.pop();return n.push(r),f(t+n.length-1),r})}function m(e,n,i){let s=e;if(H.isReactNative(t)&&H.isReactNativeBlob(e))return t.append(Qo(i,n,a),d(e)),!1;if(e&&!i&&typeof e==`object`){if(H.endsWith(n,`{}`))n=r?n:n.slice(0,-2),e=p(e,1);else if(H.isArray(e)&&$o(e)||(H.isFileList(e)||H.endsWith(n,`[]`))&&(s=H.toArray(e)))return n=Zo(n),s.forEach(function(e,r){!(H.isUndefined(e)||e===null)&&t.append(o===!0?Qo([n],r,a):o===null?n:n+`[]`,d(e))}),!1}return Xo(e)?!0:(t.append(Qo(i,n,a),d(e)),!1)}let h=Object.assign(es,{defaultVisitor:m,convertValue:d,isVisitable:Xo});function g(e,n,r=0){if(!H.isUndefined(e)){if(f(r),u.indexOf(e)!==-1)throw Error(`Circular reference detected in `+n.join(`.`));u.push(e),H.forEach(e,function(e,a){(!(H.isUndefined(e)||e===null)&&i.call(t,e,H.isString(a)?a.trim():a,n,h))===!0&&g(e,n?n.concat(a):[a],r+1)}),u.pop()}}if(!H.isObject(e))throw TypeError(`data must be an object`);return g(e),t}function ns(e){let t={"!":`%21`,"'":`%27`,"(":`%28`,")":`%29`,"~":`%7E`,"%20":`+`};return encodeURIComponent(e).replace(/[!'()~]|%20/g,function(e){return t[e]})}function rs(e,t){this._pairs=[],e&&ts(e,this,t)}var is=rs.prototype;is.append=function(e,t){this._pairs.push([e,t])},is.toString=function(e){let t=e?t=>e.call(this,t,ns):ns;return this._pairs.map(function(e){return t(e[0])+`=`+t(e[1])},``).join(`&`)};function as(e){return encodeURIComponent(e).replace(/%3A/gi,`:`).replace(/%24/g,`$`).replace(/%2C/gi,`,`).replace(/%20/g,`+`)}function os(e,t,n){if(!t)return e;e||=``;let r=H.isFunction(n)?{serialize:n}:n,i=H.getSafeProp(r,`encode`)||as,a=H.getSafeProp(r,`serialize`),o;if(o=a?a(t,r):H.isURLSearchParams(t)?t.toString():new rs(t,r).toString(i),o){let t=e.indexOf(`#`);t!==-1&&(e=e.slice(0,t)),e+=(e.indexOf(`?`)===-1?`?`:`&`)+o}return e}var ss=class{constructor(){this.handlers=[]}use(e,t,n){return this.handlers.push({fulfilled:e,rejected:t,synchronous:n?n.synchronous:!1,runWhen:n?n.runWhen:null}),this.handlers.length-1}eject(e){this.handlers[e]&&(this.handlers[e]=null)}clear(){this.handlers&&=[]}forEach(e){H.forEach(this.handlers,function(t){t!==null&&e(t)})}},cs={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1,legacyInterceptorReqResOrdering:!0,advertiseZstdAcceptEncoding:!1,validateStatusUndefinedResolves:!0},ls={isBrowser:!0,classes:{URLSearchParams:typeof URLSearchParams<`u`?URLSearchParams:rs,FormData:typeof FormData<`u`?FormData:null,Blob:typeof Blob<`u`?Blob:null},protocols:[`http`,`https`,`file`,`blob`,`url`,`data`]},us=s({hasBrowserEnv:()=>ds,hasStandardBrowserEnv:()=>ps,hasStandardBrowserWebWorkerEnv:()=>ms,navigator:()=>fs,origin:()=>hs}),ds=typeof window<`u`&&typeof document<`u`,fs=typeof navigator==`object`&&navigator||void 0,ps=ds&&(!fs||[`ReactNative`,`NativeScript`,`NS`].indexOf(fs.product)<0),ms=typeof WorkerGlobalScope<`u`&&self instanceof WorkerGlobalScope&&typeof self.importScripts==`function`,hs=ds&&window.location.href||`http://localhost`,gs={...us,...ls};function _s(e,t){return ts(e,new gs.classes.URLSearchParams,{visitor:function(e,t,n,r){return gs.isNode&&H.isBuffer(e)?(this.append(t,e.toString(`base64`)),!1):r.defaultVisitor.apply(this,arguments)},...t})}var vs=100;function ys(e){if(e>vs)throw new U(`FormData field is too deeply nested (`+e+` levels). Max depth: `+vs,U.ERR_FORM_DATA_DEPTH_EXCEEDED)}function bs(e){let t=[],n=/\w+|\[(\w*)]/g,r;for(;(r=n.exec(e))!==null;)ys(t.length),t.push(r[0]===`[]`?``:r[1]||r[0]);return t}function xs(e){let t={},n=Object.keys(e),r,i=n.length,a;for(r=0;r=e.length;return a=!a&&H.isArray(r)?r.length:a,s?(H.hasOwnProp(r,a)?r[a]=H.isArray(r[a])?r[a].concat(n):[r[a],n]:r[a]=n,!o):((!H.hasOwnProp(r,a)||!H.isObject(r[a]))&&(r[a]=[]),t(e,n,r[a],i)&&H.isArray(r[a])&&(r[a]=xs(r[a])),!o)}if(H.isFormData(e)&&H.isFunction(e.entries)){let n={};return H.forEachEntry(e,(e,r)=>{t(bs(e),r,n,0)}),n}return null}var Cs=(e,t)=>e!=null&&H.hasOwnProp(e,t)?e[t]:void 0;function ws(e,t,n){if(H.isString(e))try{return(t||JSON.parse)(e),H.trim(e)}catch(e){if(e.name!==`SyntaxError`)throw e}return(n||JSON.stringify)(e)}var Ts={transitional:cs,adapter:[`xhr`,`http`,`fetch`],transformRequest:[function(e,t){let n=t.getContentType()||``,r=n.indexOf(`application/json`)>-1,i=H.isObject(e);if(i&&H.isHTMLForm(e)&&(e=new FormData(e)),H.isFormData(e))return r?JSON.stringify(Ss(e)):e;if(H.isArrayBuffer(e)||H.isBuffer(e)||H.isStream(e)||H.isFile(e)||H.isBlob(e)||H.isReadableStream(e))return e;if(H.isArrayBufferView(e))return e.buffer;if(H.isURLSearchParams(e))return t.setContentType(`application/x-www-form-urlencoded;charset=utf-8`,!1),e.toString();let a;if(i){let t=Cs(this,`formSerializer`);if(n.indexOf(`application/x-www-form-urlencoded`)>-1)return _s(e,t).toString();if((a=H.isFileList(e))||n.indexOf(`multipart/form-data`)>-1){let n=Cs(this,`env`),r=n&&n.FormData;return ts(a?{"files[]":e}:e,r&&new r,t)}}return i||r?(t.setContentType(`application/json`,!1),ws(e)):e}],transformResponse:[function(e){let t=Cs(this,`transitional`)||Ts.transitional,n=t&&t.forcedJSONParsing,r=Cs(this,`responseType`),i=r===`json`;if(H.isResponse(e)||H.isReadableStream(e))return e;if(e&&H.isString(e)&&(n&&!r||i)){let n=!(t&&t.silentJSONParsing)&&i;try{return JSON.parse(e,Cs(this,`parseReviver`))}catch(e){if(n)throw e.name===`SyntaxError`?U.from(e,U.ERR_BAD_RESPONSE,this,null,Cs(this,`response`)):e}}return e}],timeout:0,xsrfCookieName:`XSRF-TOKEN`,xsrfHeaderName:`X-XSRF-TOKEN`,maxContentLength:-1,maxBodyLength:-1,env:{FormData:gs.classes.FormData,Blob:gs.classes.Blob},validateStatus:function(e){return e>=200&&e<300},headers:{common:{Accept:`application/json, text/plain, */*`,"Content-Type":void 0}}};H.forEach([`delete`,`get`,`head`,`post`,`put`,`patch`,`query`],e=>{Ts.headers[e]={}});function Es(e,t){let n=this||Ts,r=t||n,i=Ko.from(r.headers),a=r.data;return H.forEach(e,function(e){a=e.call(n,a,i.normalize(),t?t.status:void 0)}),i.normalize(),a}function Ds(e){return!!(e&&e.__CANCEL__)}var Os=class extends U{constructor(e,t,n){super(e??`canceled`,U.ERR_CANCELED,t,n),this.name=`CanceledError`,this.__CANCEL__=!0}};function ks(e,t,n){let r=n.config.validateStatus;!n.status||!r||r(n.status)?e(n):t(new U(`Request failed with status code `+n.status,n.status>=400&&n.status<500?U.ERR_BAD_REQUEST:U.ERR_BAD_RESPONSE,n.config,n.request,n))}function As(e){let t=/^([-+\w]{1,25}):(?:\/\/)?/.exec(e);return t&&t[1]||``}function js(e,t){e||=10;let n=Array(e),r=Array(e),i=0,a=0,o;return t=t===void 0?1e3:t,function(s){let c=Date.now(),l=r[a];o||=c,n[i]=s,r[i]=c;let u=a,d=0;for(;u!==i;)d+=n[u++],u%=e;if(i=(i+1)%e,i===a&&(a=(a+1)%e),c-o{n=r,i=null,a&&=(clearTimeout(a),null),e(...t)};return[(...e)=>{let t=Date.now(),s=t-n;s>=r?o(e,t):(i=e,a||=setTimeout(()=>{a=null,o(i)},r-s))},()=>i&&o(i)]}var Ns=(e,t,n=3)=>{let r=0,i=js(50,250);return Ms(n=>{if(!n||typeof n.loaded!=`number`)return;let a=n.loaded,o=n.lengthComputable?n.total:void 0,s=o==null?a:Math.min(a,o),c=Math.max(0,s-r),l=i(c);r=Math.max(r,s),e({loaded:s,total:o,progress:o?s/o:void 0,bytes:c,rate:l||void 0,estimated:l&&o?(o-s)/l:void 0,event:n,lengthComputable:o!=null,[t?`download`:`upload`]:!0})},n)},Ps=(e,t)=>{let n=e!=null;return[r=>t[0]({lengthComputable:n,total:e,loaded:r}),t[1]]},Fs=e=>(...t)=>H.asap(()=>e(...t)),Is=gs.hasStandardBrowserEnv?((e,t)=>n=>(n=new URL(n,gs.origin),e.protocol===n.protocol&&e.host===n.host&&(t||e.port===n.port)))(new URL(gs.origin),gs.navigator&&/(msie|trident)/i.test(gs.navigator.userAgent)):()=>!0,Ls=gs.hasStandardBrowserEnv?{write(e,t,n,r,i,a,o){if(typeof document>`u`)return;let s=[`${e}=${encodeURIComponent(t)}`];H.isNumber(n)&&s.push(`expires=${new Date(n).toUTCString()}`),H.isString(r)&&s.push(`path=${r}`),H.isString(i)&&s.push(`domain=${i}`),a===!0&&s.push(`secure`),H.isString(o)&&s.push(`SameSite=${o}`),document.cookie=s.join(`; `)},read(e){if(typeof document>`u`)return null;let t=document.cookie.split(`;`);for(let n=0;ne instanceof Ko?{...e}:e;function qs(e,t){e||={},t||={};let n=Object.create(null);Object.defineProperty(n,"hasOwnProperty",{__proto__:null,value:Object.prototype.hasOwnProperty,enumerable:!1,writable:!0,configurable:!0});function r(e,t,n,r){return H.isPlainObject(e)&&H.isPlainObject(t)?H.merge.call({caseless:r},e,t):H.isPlainObject(t)?H.merge({},t):H.isArray(t)?t.slice():t}function i(e,t,n,i){if(!H.isUndefined(t))return r(e,t,n,i);if(!H.isUndefined(e))return r(void 0,e,n,i)}function a(e,t){if(!H.isUndefined(t))return r(void 0,t)}function o(e,t){if(!H.isUndefined(t))return r(void 0,t);if(!H.isUndefined(e))return r(void 0,e)}function s(n){let r=H.hasOwnProp(t,`transitional`)?t.transitional:void 0;if(!H.isUndefined(r))if(H.isPlainObject(r)){if(H.hasOwnProp(r,n))return r[n]}else return;let i=H.hasOwnProp(e,`transitional`)?e.transitional:void 0;if(H.isPlainObject(i)&&H.hasOwnProp(i,n))return i[n]}function c(n,i,a){if(H.hasOwnProp(t,a))return r(n,i);if(H.hasOwnProp(e,a))return r(void 0,n)}let l={url:a,method:a,data:a,baseURL:o,transformRequest:o,transformResponse:o,paramsSerializer:o,timeout:o,timeoutMessage:o,withCredentials:o,withXSRFToken:o,adapter:o,responseType:o,xsrfCookieName:o,xsrfHeaderName:o,onUploadProgress:o,onDownloadProgress:o,decompress:o,maxContentLength:o,maxBodyLength:o,beforeRedirect:o,transport:o,httpAgent:o,httpsAgent:o,cancelToken:o,socketPath:o,allowedSocketPaths:o,responseEncoding:o,validateStatus:c,headers:(e,t,n)=>i(Ks(e),Ks(t),n,!0)};return H.forEach(Object.keys({...e,...t}),function(r){if(r===`__proto__`||r===`constructor`||r===`prototype`)return;let a=H.hasOwnProp(l,r)?l[r]:i,o=a(H.hasOwnProp(e,r)?e[r]:void 0,H.hasOwnProp(t,r)?t[r]:void 0,r);H.isUndefined(o)&&a!==c||(n[r]=o)}),H.hasOwnProp(t,`validateStatus`)&&H.isUndefined(t.validateStatus)&&s(`validateStatusUndefinedResolves`)===!1&&(H.hasOwnProp(e,`validateStatus`)?n.validateStatus=r(void 0,e.validateStatus):delete n.validateStatus),n}var Js=[`content-type`,`content-length`];function Ys(e,t,n){if(n!==`content-only`){e.set(t);return}Object.entries(t||{}).forEach(([t,n])=>{Js.includes(t.toLowerCase())&&e.set(t,n)})}var Xs=e=>encodeURIComponent(e).replace(/%([0-9A-F]{2})/gi,(e,t)=>String.fromCharCode(parseInt(t,16)));function Zs(e){let t=qs({},e),n=e=>H.hasOwnProp(t,e)?t[e]:void 0,r=n(`data`),i=n(`withXSRFToken`),a=n(`xsrfHeaderName`),o=n(`xsrfCookieName`),s=n(`headers`),c=n(`auth`),l=n(`baseURL`),u=n(`allowAbsoluteUrls`),d=n(`url`);if(t.headers=s=Ko.from(s),t.url=os(Gs(l,d,u,t),n(`params`),n(`paramsSerializer`)),c){let t=H.getSafeProp(c,`username`)||``,n=H.getSafeProp(c,`password`)||``;try{s.set(`Authorization`,`Basic `+btoa(t+`:`+(n?Xs(n):``)))}catch(t){throw U.from(t,U.ERR_BAD_OPTION_VALUE,e)}}if(H.isFormData(r)&&(gs.hasStandardBrowserEnv||gs.hasStandardBrowserWebWorkerEnv||H.isReactNative(r)?s.setContentType(void 0):H.isFunction(r.getHeaders)&&Ys(s,r.getHeaders(),n(`formDataHeaderPolicy`))),gs.hasStandardBrowserEnv&&(H.isFunction(i)&&(i=i(t)),i===!0||i==null&&Is(t.url))){let e=a&&o&&Ls.read(o);e&&s.set(a,e)}return t}var Qs=typeof XMLHttpRequest<`u`&&function(e){return new Promise(function(t,n){let r=Zs(e),i=r.data,a=Ko.from(r.headers).normalize(),{responseType:o,onUploadProgress:s,onDownloadProgress:c}=r,l,u,d,f,p;function m(){f&&f(),p&&p(),r.cancelToken&&r.cancelToken.unsubscribe(l),r.signal&&r.signal.removeEventListener(`abort`,l)}let h=new XMLHttpRequest;h.open(r.method.toUpperCase(),r.url,!0),h.timeout=r.timeout;function g(){if(!h)return;let r=Ko.from(`getAllResponseHeaders`in h&&h.getAllResponseHeaders());ks(function(e){t(e),m()},function(e){n(e),m()},{data:!o||o===`text`||o===`json`?h.responseText:h.response,status:h.status,statusText:h.statusText,headers:r,config:e,request:h}),h=null}`onloadend`in h?h.onloadend=g:h.onreadystatechange=function(){!h||h.readyState!==4||h.status===0&&!(h.responseURL&&h.responseURL.startsWith(`file:`))||setTimeout(g)},h.onabort=function(){h&&=(n(new U(`Request aborted`,U.ECONNABORTED,e,h)),m(),null)},h.onerror=function(t){let r=new U(t&&t.message?t.message:`Network Error`,U.ERR_NETWORK,e,h);r.event=t||null,n(r),m(),h=null},h.ontimeout=function(){let t=r.timeout?`timeout of `+r.timeout+`ms exceeded`:`timeout exceeded`,i=r.transitional||cs;r.timeoutErrorMessage&&(t=r.timeoutErrorMessage),n(new U(t,i.clarifyTimeoutError?U.ETIMEDOUT:U.ECONNABORTED,e,h)),m(),h=null},i===void 0&&a.setContentType(null),`setRequestHeader`in h&&H.forEach(Lo(a),function(e,t){h.setRequestHeader(t,e)}),H.isUndefined(r.withCredentials)||(h.withCredentials=!!r.withCredentials),o&&o!==`json`&&(h.responseType=r.responseType),c&&([d,p]=Ns(c,!0),h.addEventListener(`progress`,d)),s&&h.upload&&([u,f]=Ns(s),h.upload.addEventListener(`progress`,u),h.upload.addEventListener(`loadend`,f)),(r.cancelToken||r.signal)&&(l=t=>{h&&=(n(!t||t.type?new Os(null,e,h):t),h.abort(),m(),null)},r.cancelToken&&r.cancelToken.subscribe(l),r.signal&&(r.signal.aborted?l():r.signal.addEventListener(`abort`,l)));let _=As(r.url);if(_&&!gs.protocols.includes(_)){n(new U(`Unsupported protocol `+_+`:`,U.ERR_BAD_REQUEST,e)),m();return}h.send(i||null)})},$s=(e,t)=>{if(e=e?e.filter(Boolean):[],!t&&!e.length)return;let n=new AbortController,r=!1,i=function(e){if(!r){r=!0,o();let t=e instanceof Error?e:this.reason;n.abort(t instanceof U?t:new Os(t instanceof Error?t.message:t))}},a=t&&setTimeout(()=>{a=null,i(new U(`timeout of ${t}ms exceeded`,U.ETIMEDOUT))},t),o=()=>{e&&=(a&&clearTimeout(a),a=null,e.forEach(e=>{e.unsubscribe?e.unsubscribe(i):e.removeEventListener(`abort`,i)}),null)};e.forEach(e=>e.addEventListener(`abort`,i,{once:!0}));let{signal:s}=n;return s.unsubscribe=()=>H.asap(o),s},ec=function*(e,t){let n=e.byteLength;if(!t||n{let i=tc(e,t),a=0,o,s=e=>{o||(o=!0,r&&r(e))};return new ReadableStream({async pull(e){try{let{done:t,value:r}=await i.next();if(t){s(),e.close();return}let o=r.byteLength;n&&n(a+=o),e.enqueue(new Uint8Array(r))}catch(e){throw s(e),e}},cancel(e){return s(e),i.return()}},{highWaterMark:2})},ic=e=>e>=48&&e<=57||e>=65&&e<=70||e>=97&&e<=102,ac=(e,t,n)=>t+2e>=2&&r.charCodeAt(e-2)===37&&r.charCodeAt(e-1)===51&&(r.charCodeAt(e)===68||r.charCodeAt(e)===100);i>=0&&(r.charCodeAt(i)===61?(n++,i--):a(i)&&(n++,i-=3)),n===1&&i>=0&&(r.charCodeAt(i)===61||a(i))&&n++;let o=Math.floor(e/4)*3-(n||0);return o>0?o:0}let i=0;for(let e=0,t=r.length;e=55296&&n<=56319&&e+1=56320&&t<=57343?(i+=4,e++):i+=3}else i+=3}return i}var sc=`1.18.1`,cc=64*1024,{isFunction:lc}=H,uc=e=>encodeURIComponent(e).replace(/%([0-9A-F]{2})/gi,(e,t)=>String.fromCharCode(parseInt(t,16))),dc=e=>{if(!H.isString(e))return e;try{return decodeURIComponent(e)}catch{return e}},fc=(e,...t)=>{try{return!!e(...t)}catch{return!1}},pc=e=>{let t=e.indexOf(`://`),n=e;return t!==-1&&(n=n.slice(t+3)),n.includes(`@`)||n.includes(`:`)},mc=e=>{let t=H.global!==void 0&&H.global!==null?H.global:globalThis,{ReadableStream:n,TextEncoder:r}=t;e=H.merge.call({skipUndefined:!0},{Request:t.Request,Response:t.Response},e);let{fetch:i,Request:a,Response:o}=e,s=i?lc(i):typeof fetch==`function`,c=lc(a),l=lc(o);if(!s)return!1;let u=s&&lc(n),d=s&&(typeof r==`function`?(e=>t=>e.encode(t))(new r):async e=>new Uint8Array(await new a(e).arrayBuffer())),f=c&&u&&fc(()=>{let e=!1,t=new a(gs.origin,{body:new n,method:`POST`,get duplex(){return e=!0,`half`}}),r=t.headers.has(`Content-Type`);return t.body!=null&&t.body.cancel(),e&&!r}),p=l&&u&&fc(()=>H.isReadableStream(new o(``).body)),m={stream:p&&(e=>e.body)};s&&[`text`,`arrayBuffer`,`blob`,`formData`,`stream`].forEach(e=>{!m[e]&&(m[e]=(t,n)=>{let r=t&&t[e];if(r)return r.call(t);throw new U(`Response type '${e}' is not supported`,U.ERR_NOT_SUPPORT,n)})});let h=async e=>{if(e==null)return 0;if(H.isBlob(e))return e.size;if(H.isSpecCompliantForm(e))return(await new a(gs.origin,{method:`POST`,body:e}).arrayBuffer()).byteLength;if(H.isArrayBufferView(e)||H.isArrayBuffer(e))return e.byteLength;if(H.isURLSearchParams(e)&&(e+=``),H.isString(e))return(await d(e)).byteLength},g=async(e,t)=>H.toFiniteNumber(e.getContentLength())??h(t);return async e=>{let{url:t,method:n,data:s,signal:l,cancelToken:d,timeout:_,onDownloadProgress:v,onUploadProgress:y,responseType:b,headers:x,withCredentials:S=`same-origin`,fetchOptions:C,maxContentLength:w,maxBodyLength:T}=Zs(e),ee=H.isNumber(w)&&w>-1,te=H.isNumber(T)&&T>-1,ne=t=>H.hasOwnProp(e,t)?e[t]:void 0,E=i||fetch;b=b?(b+``).toLowerCase():`text`;let re=$s([l,d&&d.toAbortSignal()],_),D=null,O=re&&re.unsubscribe&&(()=>{re.unsubscribe()}),ie,ae=null,oe=()=>new U(`Request body larger than maxBodyLength limit`,U.ERR_BAD_REQUEST,e,D);try{let i,l=ne(`auth`);if(l&&(i={username:H.getSafeProp(l,`username`)||``,password:H.getSafeProp(l,`password`)||``}),pc(t)){let e=new URL(t,gs.origin);!i&&(e.username||e.password)&&(i={username:dc(e.username),password:dc(e.password)}),(e.username||e.password)&&(e.username=``,e.password=``,t=e.href)}if(i&&(x.delete(`authorization`),x.set(`Authorization`,`Basic `+btoa(uc((i.username||``)+`:`+(i.password||``))))),ee&&typeof t==`string`&&t.startsWith(`data:`)&&oc(t)>w)throw new U(`maxContentLength size of `+w+` exceeded`,U.ERR_BAD_RESPONSE,e,D);if(te&&n!==`get`&&n!==`head`){let e=await h(s);if(typeof e==`number`&&isFinite(e)&&(ie=e,e>T))throw oe()}let d=te&&(H.isReadableStream(s)||H.isStream(s)),_=(e,t,n)=>rc(e,cc,e=>{if(te&&e>T)throw ae=oe();t&&t(e)},n);if(f&&n!==`get`&&n!==`head`&&(y||d)){if(ie??=await g(x,s),ie!==0||d){let e=new a(t,{method:`POST`,body:s,duplex:`half`}),n;if(H.isFormData(s)&&(n=e.headers.get(`content-type`))&&x.setContentType(n),e.body){let[t,n]=y&&Ps(ie,Ns(Fs(y)))||[];s=_(e.body,t,n)}}}else if(d&&!c&&u&&n!==`get`&&n!==`head`)s=_(s);else if(d&&c&&!f&&n!==`get`&&n!==`head`)throw new U(`Stream request bodies are not supported by the current fetch implementation`,U.ERR_NOT_SUPPORT,e,D);H.isString(S)||(S=S?`include`:`omit`);let k=c&&`credentials`in a.prototype;if(H.isFormData(s)){let e=x.getContentType();e&&/^multipart\/form-data/i.test(e)&&!/boundary=/i.test(e)&&x.delete(`content-type`)}x.set(`User-Agent`,`axios/`+sc,!1);let A={...C,signal:re,method:n.toUpperCase(),headers:Lo(x.normalize()),body:s,duplex:`half`,credentials:k?S:void 0};D=c&&new a(t,A);let se=await(c?E(D,C):E(t,A)),ce=Ko.from(se.headers);if(ee){let t=H.toFiniteNumber(ce.getContentLength());if(t!=null&&t>w)throw new U(`maxContentLength size of `+w+` exceeded`,U.ERR_BAD_RESPONSE,e,D)}let le=p&&(b===`stream`||b===`response`);if(p&&se.body&&(v||ee||le&&O)){let t={};[`status`,`statusText`,`headers`].forEach(e=>{t[e]=se[e]});let n=H.toFiniteNumber(ce.getContentLength()),[r,i]=v&&Ps(n,Ns(Fs(v),!0))||[],a=0;se=new o(rc(se.body,cc,t=>{if(ee&&(a=t,a>w))throw new U(`maxContentLength size of `+w+` exceeded`,U.ERR_BAD_RESPONSE,e,D);r&&r(t)},()=>{i&&i(),O&&O()}),t)}b||=`text`;let j=await m[H.findKey(m,b)||`text`](se,e);if(ee&&!p&&!le){let t;if(j!=null&&(typeof j.byteLength==`number`?t=j.byteLength:typeof j.size==`number`?t=j.size:typeof j==`string`&&(t=typeof r==`function`?new r().encode(j).byteLength:j.length)),typeof t==`number`&&t>w)throw new U(`maxContentLength size of `+w+` exceeded`,U.ERR_BAD_RESPONSE,e,D)}return!le&&O&&O(),await new Promise((t,n)=>{ks(t,n,{data:j,headers:Ko.from(se.headers),status:se.status,statusText:se.statusText,config:e,request:D})})}catch(t){if(O&&O(),re&&re.aborted&&re.reason instanceof U){let n=re.reason;throw n.config=e,D&&(n.request=D),t!==n&&Object.defineProperty(n,"cause",{__proto__:null,value:t,writable:!0,enumerable:!1,configurable:!0}),n}if(ae)throw D&&!ae.request&&(ae.request=D),ae;if(t instanceof U)throw D&&!t.request&&(t.request=D),t;if(t&&t.name===`TypeError`&&/Load failed|fetch/i.test(t.message)){let n=new U(`Network Error`,U.ERR_NETWORK,e,D,t&&t.response);throw Object.defineProperty(n,"cause",{__proto__:null,value:t.cause||t,writable:!0,enumerable:!1,configurable:!0}),n}throw U.from(t,t&&t.code,e,D,t&&t.response)}}},hc=new Map,gc=e=>{let t=e&&e.env||{},{fetch:n,Request:r,Response:i}=t,a=[r,i,n],o=a.length,s,c,l=hc;for(;o--;)s=a[o],c=l.get(s),c===void 0&&l.set(s,c=o?new Map:mc(t)),l=c;return c};gc();var _c={http:null,xhr:Qs,fetch:{get:gc}};H.forEach(_c,(e,t)=>{if(e){try{Object.defineProperty(e,"name",{__proto__:null,value:t})}catch{}Object.defineProperty(e,"adapterName",{__proto__:null,value:t})}});var vc=e=>`- ${e}`,yc=e=>H.isFunction(e)||e===null||e===!1;function bc(e,t){e=H.isArray(e)?e:[e];let{length:n}=e,r,i,a={};for(let o=0;o`adapter ${e} `+(t===!1?`is not supported by the environment`:`is not available in the build`));throw new U(`There is no suitable adapter to dispatch the request `+(n?e.length>1?`since : -`+e.map(vc).join(` -`):` `+vc(e[0]):`as no adapter specified`),U.ERR_NOT_SUPPORT)}return i}var xc={getAdapter:bc,adapters:_c};function Sc(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw new Os(null,e)}function Cc(e){return Sc(e),e.headers=Ko.from(e.headers),e.data=Es.call(e,e.transformRequest),[`post`,`put`,`patch`].indexOf(e.method)!==-1&&e.headers.setContentType(`application/x-www-form-urlencoded`,!1),xc.getAdapter(e.adapter||Ts.adapter,e)(e).then(function(t){Sc(e),e.response=t;try{t.data=Es.call(e,e.transformResponse,t)}finally{delete e.response}return t.headers=Ko.from(t.headers),t},function(t){if(!Ds(t)&&(Sc(e),t&&t.response)){e.response=t.response;try{t.response.data=Es.call(e,e.transformResponse,t.response)}finally{delete e.response}t.response.headers=Ko.from(t.response.headers)}return Promise.reject(t)})}var wc={};[`object`,`boolean`,`number`,`function`,`string`,`symbol`].forEach((e,t)=>{wc[e]=function(n){return typeof n===e||`a`+(t<1?`n `:` `)+e}});var Tc={};wc.transitional=function(e,t,n){function r(e,t){return`[Axios v`+sc+`] Transitional option '`+e+`'`+t+(n?`. `+n:``)}return(n,i,a)=>{if(e===!1)throw new U(r(i,` has been removed`+(t?` in `+t:``)),U.ERR_DEPRECATED);return t&&!Tc[i]&&(Tc[i]=!0,console.warn(r(i,` has been deprecated since v`+t+` and will be removed in the near future`))),e?e(n,i,a):!0}},wc.spelling=function(e){return(t,n)=>(console.warn(`${n} is likely a misspelling of ${e}`),!0)};function Ec(e,t,n){if(typeof e!=`object`||!e)throw new U(`options must be an object`,U.ERR_BAD_OPTION_VALUE);let r=Object.keys(e),i=r.length;for(;i-->0;){let a=r[i],o=Object.prototype.hasOwnProperty.call(t,a)?t[a]:void 0;if(o){let t=e[a],n=t===void 0||o(t,a,e);if(n!==!0)throw new U(`option `+a+` must be `+n,U.ERR_BAD_OPTION_VALUE);continue}if(n!==!0)throw new U(`Unknown option `+a,U.ERR_BAD_OPTION)}}var Dc={assertOptions:Ec,validators:wc},Oc=Dc.validators,kc=class{constructor(e){this.defaults=e||{},this.interceptors={request:new ss,response:new ss}}async request(e,t){try{return await this._request(e,t)}catch(e){if(e instanceof Error){let t={};Error.captureStackTrace?Error.captureStackTrace(t):t=Error();let n=(()=>{if(!t.stack)return``;let e=t.stack.indexOf(` -`);return e===-1?``:t.stack.slice(e+1)})();try{if(!e.stack)e.stack=n;else if(n){let t=n.indexOf(` -`),r=t===-1?-1:n.indexOf(` -`,t+1),i=r===-1?``:n.slice(r+1);String(e.stack).endsWith(i)||(e.stack+=` -`+n)}}catch{}}throw e}}_request(e,t){typeof e==`string`?(t||={},t.url=e):t=e||{},t=qs(this.defaults,t);let{transitional:n,paramsSerializer:r,headers:i}=t;n!==void 0&&Dc.assertOptions(n,{silentJSONParsing:Oc.transitional(Oc.boolean),forcedJSONParsing:Oc.transitional(Oc.boolean),clarifyTimeoutError:Oc.transitional(Oc.boolean),legacyInterceptorReqResOrdering:Oc.transitional(Oc.boolean),advertiseZstdAcceptEncoding:Oc.transitional(Oc.boolean),validateStatusUndefinedResolves:Oc.transitional(Oc.boolean)},!1),r!=null&&(H.isFunction(r)?t.paramsSerializer={serialize:r}:Dc.assertOptions(r,{encode:Oc.function,serialize:Oc.function},!0)),t.allowAbsoluteUrls!==void 0||(this.defaults.allowAbsoluteUrls===void 0?t.allowAbsoluteUrls=!0:t.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls),Dc.assertOptions(t,{baseUrl:Oc.spelling(`baseURL`),withXsrfToken:Oc.spelling(`withXSRFToken`)},!0),t.method=(t.method||this.defaults.method||`get`).toLowerCase();let a=i&&H.merge(i.common,i[t.method]);i&&H.forEach([`delete`,`get`,`head`,`post`,`put`,`patch`,`query`,`common`],e=>{delete i[e]}),t.headers=Ko.concat(a,i);let o=[],s=!0;this.interceptors.request.forEach(function(e){if(typeof e.runWhen==`function`&&e.runWhen(t)===!1)return;s&&=e.synchronous;let n=t.transitional||cs;n&&n.legacyInterceptorReqResOrdering?o.unshift(e.fulfilled,e.rejected):o.push(e.fulfilled,e.rejected)});let c=[];this.interceptors.response.forEach(function(e){c.push(e.fulfilled,e.rejected)});let l,u=0,d;if(!s){let e=[Cc.bind(this),void 0];for(e.unshift(...o),e.push(...c),d=e.length,l=Promise.resolve(t);u{if(!n._listeners)return;let t=n._listeners.length;for(;t-->0;)n._listeners[t](e);n._listeners=null}),this.promise.then=e=>{let t,r=new Promise(e=>{n.subscribe(e),t=e}).then(e);return r.cancel=function(){n.unsubscribe(t)},r},e(function(e,r,i){n.reason||(n.reason=new Os(e,r,i),t(n.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(e){if(this.reason){e(this.reason);return}this._listeners?this._listeners.push(e):this._listeners=[e]}unsubscribe(e){if(!this._listeners)return;let t=this._listeners.indexOf(e);t!==-1&&this._listeners.splice(t,1)}toAbortSignal(){let e=new AbortController,t=t=>{e.abort(t)};return this.subscribe(t),e.signal.unsubscribe=()=>this.unsubscribe(t),e.signal}static source(){let t;return{token:new e(function(e){t=e}),cancel:t}}};function jc(e){return function(t){return e.apply(null,t)}}function Mc(e){return H.isObject(e)&&e.isAxiosError===!0}var Nc={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(Nc).forEach(([e,t])=>{Nc[t]=e});function Pc(e){let t=new kc(e),n=ma(kc.prototype.request,t);return H.extend(n,kc.prototype,t,{allOwnKeys:!0}),H.extend(n,t,null,{allOwnKeys:!0}),n.create=function(t){return Pc(qs(e,t))},n}var Fc=Pc(Ts);Fc.Axios=kc,Fc.CanceledError=Os,Fc.CancelToken=Ac,Fc.isCancel=Ds,Fc.VERSION=sc,Fc.toFormData=ts,Fc.AxiosError=U,Fc.Cancel=Fc.CanceledError,Fc.all=function(e){return Promise.all(e)},Fc.spread=jc,Fc.isAxiosError=Mc,Fc.mergeConfig=qs,Fc.AxiosHeaders=Ko,Fc.formToJSON=e=>Ss(H.isHTMLForm(e)?new FormData(e):e),Fc.getAdapter=xc.getAdapter,Fc.HttpStatusCode=Nc,Fc.default=Fc;var Ic=`pets_admin_token`,Lc=()=>localStorage.getItem(Ic)||``,W=e=>localStorage.setItem(Ic,e),Rc=()=>localStorage.removeItem(Ic),zc=Fc.create({baseURL:`/api`,timeout:2e4});zc.interceptors.request.use(e=>{let t=Lc();return t&&(e.headers.Authorization=`Bearer ${t}`),e}),zc.interceptors.response.use(e=>{let t=e.data;if(t?.code===0)return t.data;throw Error(t?.message||`请求失败`)},e=>Fc.isCancel(e)?Promise.reject(e):(e.response?.status===401&&(Rc(),window.dispatchEvent(new Event(`admin-auth-expired`))),Promise.reject(Error(e.response?.data?.message||(e.code===`ECONNABORTED`?`请求超时,请重试`:`无法连接服务器,请稍后重试`)))));var Bc={login:(e,t)=>zc.post(`/admin/login`,{username:e,password:t}),stats:e=>zc.get(`/admin/stats`,{signal:e}),list:(e,t,n)=>zc.get(`/admin/${e}`,{params:t,signal:n}),userPets:(e,t)=>zc.get(`/admin/users/${e}/pets`,{signal:t}),walk:(e,t)=>zc.get(`/admin/walks/${e}`,{signal:t}),setUserDisabled:(e,t)=>zc.put(`/admin/users/${e}/disabled`,{disabled:t}),cancelMeetup:e=>zc.put(`/admin/meetups/${e}/status`,{status:`cancelled`})},Vc={overview:`工作台`,users:`用户管理`,pets:`宠物档案`,walks:`遛狗记录`,meetups:`约遛活动`,tasks:`日常任务`,files:`文件管理`},Hc=e=>e&&!Number.isNaN(Date.parse(e))?new Date(e).toLocaleString(`zh-CN`,{hour12:!1}):`—`,Uc=(e=0)=>e>=1048576?`${(e/1048576).toFixed(1)} MB`:`${(e/1024).toFixed(1)} KB`,Wc=(e=0)=>`${Math.floor(e/3600)}小时 ${Math.floor(e%3600/60)}分钟`,Gc={food:`喂食`,water:`饮水`,walk:`运动`,medicine:`用药`,grooming:`清洁`,other:`其他`},Kc={users:[[`enabled`,`正常`],[`disabled`,`已停用`]],pets:[[`active`,`在用`],[`archived`,`已归档`]],walks:[[`active`,`遛狗中`],[`paused`,`已暂停`],[`finished`,`已结束`]],meetups:[[`open`,`开放`],[`cancelled`,`已取消`]],tasks:Object.entries(Gc)},qc={users:`搜索用户昵称或 ID`,pets:`搜索宠物名字、品种或主人 ID`,walks:`搜索记录 ID 或用户 ID`,meetups:`搜索活动名称、地点或 ID`,tasks:`搜索任务名称、用户或宠物 ID`,files:`搜索文件名、MD5 或 ID`},Jc=[{key:`users`,icon:pe,sub:`每一位养宠伙伴`},{key:`pets`,icon:M,sub:`记录它们的成长`},{key:`walks`,icon:ue,sub:`一起走过的路`},{key:`meetups`,icon:D,sub:`相约下一次出发`},{key:`tasks`,icon:O,sub:`照顾好每一个日常`},{key:`files`,icon:A,sub:`留住温暖的瞬间`}];function Yc({stats:e,navigate:t}){let n=Math.max(1,...(e?.daily_walks||[]).map(e=>e.count));return(0,L.jsxs)(L.Fragment,{children:[(0,L.jsxs)(`section`,{className:`welcome`,children:[(0,L.jsxs)(`div`,{children:[(0,L.jsx)(`p`,{className:`eyebrow`,children:`A LITTLE CARE, EVERY DAY`}),(0,L.jsx)(`h2`,{children:`把小日常,照顾成好日子。`}),(0,L.jsx)(`p`,{children:`从一张宠物档案,到每一次快乐出门。`})]}),(0,L.jsx)(`img`,{src:`/brand-logo.png`,alt:`肉垫计划`})]}),(0,L.jsx)(`div`,{className:`stat-grid`,children:Jc.map(({key:n,icon:r,sub:i})=>(0,L.jsxs)(`button`,{className:`stat-card tint-${n}`,onClick:()=>t(n),children:[(0,L.jsxs)(`div`,{className:`stat-top`,children:[(0,L.jsx)(`span`,{className:`stat-icon`,children:(0,L.jsx)(r,{size:20})}),(0,L.jsx)(re,{size:16})]}),(0,L.jsx)(`span`,{children:Vc[n]}),(0,L.jsx)(`strong`,{children:e?.[n]??`—`}),(0,L.jsx)(`small`,{children:i})]},n))}),(0,L.jsxs)(`div`,{className:`overview-grid`,children:[(0,L.jsxs)(`section`,{className:`panel`,children:[(0,L.jsxs)(`header`,{className:`panel-heading`,children:[(0,L.jsxs)(`div`,{children:[(0,L.jsx)(`h2`,{children:`这周,一起走了多少次`}),(0,L.jsx)(`p`,{children:`最近 7 天的遛狗记录`})]}),(0,L.jsx)(ue,{size:20})]}),(0,L.jsxs)(`div`,{className:`bar-chart`,role:`img`,"aria-label":`最近七天遛狗次数`,children:[(e?.daily_walks||[]).map(e=>(0,L.jsxs)(`div`,{className:`chart-column`,children:[(0,L.jsx)(`span`,{children:e.count}),(0,L.jsx)(`div`,{className:`bar-space`,children:(0,L.jsx)(`div`,{className:`chart-bar`,style:{height:`${e.count/n*100}%`,minHeight:e.count?6:2},title:`${e.date}:${e.count}次`})}),(0,L.jsx)(`small`,{children:e.date.slice(5).replace(`-`,`/`)})]},e.date)),!e&&(0,L.jsx)(`div`,{className:`empty`,children:`正在加载趋势`})]})]}),(0,L.jsxs)(`section`,{className:`panel today`,children:[(0,L.jsxs)(`header`,{className:`panel-heading`,children:[(0,L.jsxs)(`div`,{children:[(0,L.jsx)(`h2`,{children:`今天的陪伴`}),(0,L.jsx)(`p`,{children:`活动与日常一目了然`})]}),(0,L.jsx)(D,{size:20})]}),(0,L.jsxs)(`dl`,{children:[(0,L.jsxs)(`div`,{children:[(0,L.jsx)(`dt`,{children:`今日出门`}),(0,L.jsxs)(`dd`,{children:[e?.today_walks??`—`,(0,L.jsx)(`small`,{children:`次`})]})]}),(0,L.jsxs)(`div`,{children:[(0,L.jsx)(`dt`,{children:`正在遛狗 / 暂停中`}),(0,L.jsxs)(`dd`,{children:[e?.active_walks??`—`,(0,L.jsx)(`small`,{children:`次`})]})]}),(0,L.jsxs)(`div`,{children:[(0,L.jsx)(`dt`,{children:`待开始的约遛`}),(0,L.jsxs)(`dd`,{children:[e?.upcoming_meetups??`—`,(0,L.jsx)(`small`,{children:`场`})]})]}),(0,L.jsxs)(`div`,{children:[(0,L.jsx)(`dt`,{children:`今日任务已完成`}),(0,L.jsxs)(`dd`,{children:[e?.today_completions??`—`,(0,L.jsx)(`small`,{children:`项`})]})]})]})]})]}),(0,L.jsxs)(`section`,{className:`summary-strip`,children:[(0,L.jsxs)(`div`,{children:[(0,L.jsx)(ue,{size:18}),(0,L.jsx)(`span`,{children:`累计遛狗距离`}),(0,L.jsxs)(`strong`,{children:[e?(e.distance_meters/1e3).toFixed(2):`—`,` km`]})]}),(0,L.jsxs)(`div`,{children:[(0,L.jsx)(A,{size:18}),(0,L.jsx)(`span`,{children:`文件存储用量`}),(0,L.jsx)(`strong`,{children:e?Uc(e.storage_bytes):`—`})]})]})]})}var Xc=v.forwardRef(({className:e,...t},n)=>(0,L.jsx)(`div`,{className:`relative w-full overflow-auto`,children:(0,L.jsx)(`table`,{ref:n,className:cn(`w-full caption-bottom text-sm`,e),...t})}));Xc.displayName=`Table`;var Zc=v.forwardRef(({className:e,...t},n)=>(0,L.jsx)(`thead`,{ref:n,className:cn(`[&_tr]:border-b`,e),...t}));Zc.displayName=`TableHeader`;var Qc=v.forwardRef(({className:e,...t},n)=>(0,L.jsx)(`tbody`,{ref:n,className:cn(`[&_tr:last-child]:border-0`,e),...t}));Qc.displayName=`TableBody`;var $c=v.forwardRef(({className:e,...t},n)=>(0,L.jsx)(`tr`,{ref:n,className:cn(`border-b transition-colors hover:bg-muted/50`,e),...t}));$c.displayName=`TableRow`;var el=v.forwardRef(({className:e,...t},n)=>(0,L.jsx)(`th`,{ref:n,className:cn(`h-10 px-3 text-left align-middle font-medium text-muted-foreground`,e),...t}));el.displayName=`TableHead`;var G=v.forwardRef(({className:e,...t},n)=>(0,L.jsx)(`td`,{ref:n,className:cn(`p-3 align-middle`,e),...t}));G.displayName=`TableCell`;var tl=Fe(`inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold`,{variants:{variant:{default:`border-transparent bg-primary/15 text-primary`,secondary:`border-transparent bg-secondary text-secondary-foreground`,destructive:`border-transparent bg-destructive/15 text-destructive`,outline:`text-foreground`,success:`border-transparent bg-emerald-100 text-emerald-700`,warning:`border-transparent bg-amber-100 text-amber-700`,muted:`border-transparent bg-muted text-muted-foreground`}},defaultVariants:{variant:`default`}});function nl({className:e,variant:t,...n}){return(0,L.jsx)(`div`,{className:cn(tl({variant:t}),e),...n})}function rl({url:e,person:t=!1}){let[n,r]=(0,v.useState)(``);return(0,L.jsx)(`span`,{className:`avatar`,children:e&&n!==e?(0,L.jsx)(`img`,{src:e,alt:``,onError:()=>r(e)}):t?(0,L.jsx)(fe,{size:20}):(0,L.jsx)(M,{size:20})})}function il({row:e,section:t}){let n=t===`users`?e.disabled?`已停用`:`正常`:t===`pets`?e.archived?`已归档`:`在用`:t===`tasks`?e.completed?`今日已完成`:`今日待完成`:{active:`遛狗中`,paused:`已暂停`,finished:`已结束`,open:`开放`,cancelled:`已取消`}[e.status||``]||`—`;return(0,L.jsx)(nl,{variant:e.disabled||e.archived||e.status===`cancelled`?`muted`:e.status===`paused`?`warning`:`default`,children:n})}function al({name:e,id:t,url:n,person:r=!1}){return(0,L.jsxs)(`div`,{className:`identity`,children:[n!==void 0&&(0,L.jsx)(rl,{url:n,person:r}),(0,L.jsxs)(`div`,{children:[(0,L.jsx)(`strong`,{children:e||(r?`未设置昵称`:`未命名`)}),(0,L.jsx)(`small`,{className:`mono`,title:t,children:t||`—`})]})]})}function ol({row:e,action:t,detail:n,disabled:r}){let[i,a]=(0,v.useState)(!1),[o,s]=(0,v.useState)(null),[c,l]=(0,v.useState)(``),[u,d]=(0,v.useState)(!1),[f,p]=(0,v.useState)(0);return(0,v.useEffect)(()=>{if(!i||o)return;let t=new AbortController;return d(!0),l(``),Bc.userPets(e.id,t.signal).then(e=>{t.signal.aborted||(s(e),d(!1))}).catch(e=>{t.signal.aborted||l(e.message)}).finally(()=>{t.signal.aborted||d(!1)}),()=>t.abort()},[i,e.id,o,f]),(0,L.jsxs)(v.Fragment,{children:[(0,L.jsxs)($c,{children:[(0,L.jsx)(G,{children:(0,L.jsx)(`button`,{className:`tree-toggle`,"aria-expanded":i,"aria-label":`${i?`收起`:`展开`}${e.nickname||`用户`}的宠物`,onClick:()=>a(!i),children:i?(0,L.jsx)(ie,{size:16}):(0,L.jsx)(oe,{size:16})})}),(0,L.jsx)(G,{children:(0,L.jsx)(al,{name:e.nickname,id:e.id,url:e.avatar_url||``,person:!0})}),(0,L.jsx)(G,{children:(0,L.jsxs)(`button`,{className:`text-action`,onClick:()=>a(!i),children:[e.pet_count||0,` 只宠物`]})}),(0,L.jsx)(G,{children:Hc(e.created_at)}),(0,L.jsx)(G,{children:(0,L.jsx)(il,{row:e,section:`users`})}),(0,L.jsx)(G,{children:(0,L.jsx)(dn,{variant:`outline`,size:`sm`,disabled:r,onClick:()=>t(e),children:e.disabled?`启用用户`:`停用用户`})})]}),i&&(0,L.jsx)($c,{className:`tree-row`,children:(0,L.jsx)(G,{colSpan:6,children:(0,L.jsxs)(`div`,{className:`pet-tree`,children:[(0,L.jsxs)(`div`,{className:`tree-heading`,children:[(0,L.jsx)(M,{size:16}),(0,L.jsxs)(`strong`,{children:[e.nickname||`用户`,`的宠物`]}),(0,L.jsx)(`span`,{children:`包括已归档档案`})]}),u?(0,L.jsxs)(`div`,{className:`tree-message`,children:[(0,L.jsx)(le,{size:16,className:`animate-spin`}),`加载宠物中`]}):c?(0,L.jsxs)(`div`,{className:`tree-message error-text`,children:[c,(0,L.jsx)(dn,{size:`sm`,variant:`outline`,onClick:()=>p(f+1),children:`重试`})]}):o?.length?(0,L.jsx)(`div`,{className:`pet-tree-grid`,children:o.map(e=>(0,L.jsxs)(`button`,{className:`pet-tree-card`,onClick:()=>n(`pets`,e),children:[(0,L.jsx)(al,{name:e.name,id:e.breed||`未填写品种`,url:e.avatar_url||``}),(0,L.jsx)(il,{row:e,section:`pets`}),(0,L.jsx)(oe,{size:16})]},e.id))}):(0,L.jsx)(`div`,{className:`tree-message`,children:`该用户还没有添加宠物`})]})})})]})}var sl={users:[``,`用户`,`宠物`,`注册时间`,`状态`,`操作`],pets:[`宠物`,`品种 / 性别`,`主人`,`体重`,`状态`,`操作`],walks:[`遛狗人`,`同行宠物`,`开始时间`,`距离 / 时长`,`状态`,`操作`],meetups:[`活动`,`发起人`,`地点 / 时间`,`人数`,`状态`,`操作`],tasks:[`任务`,`用户 / 宠物`,`类别`,`计划时间`,`今日状态`,`操作`],files:[`文件`,`类型`,`大小`,`上传时间`,`操作`]};function cl({section:e,revision:t,action:n,detail:r,actionBusy:i}){let[a,o]=(0,v.useState)(1),[s,c]=(0,v.useState)(``),[l,u]=(0,v.useState)(``),[d,f]=(0,v.useState)(``),[p,m]=(0,v.useState)(null),[h,g]=(0,v.useState)(!0),[_,y]=(0,v.useState)(``),[b,x]=(0,v.useState)(0);(0,v.useEffect)(()=>{let t=new AbortController;return g(!0),y(``),m(null),Bc.list(e,{page:a,page_size:10,q:s,status:d},t.signal).then(e=>{if(!t.signal.aborted){if(a>Math.max(1,Math.ceil(e.total/10))){o(Math.max(1,Math.ceil(e.total/10)));return}m(e)}}).catch(e=>{t.signal.aborted||y(e.message)}).finally(()=>{t.signal.aborted||g(!1)}),()=>t.abort()},[e,a,s,d,t,b]);let S=Math.max(1,Math.ceil((p?.total||0)/10));return(0,L.jsxs)(`section`,{className:`panel records`,children:[(0,L.jsxs)(`div`,{className:`records-heading`,children:[(0,L.jsxs)(`div`,{children:[(0,L.jsx)(`h2`,{children:Vc[e]}),(0,L.jsxs)(`p`,{children:[p?`共 ${p.total} 条记录`:`读取记录中`,e===`users`&&` · 展开用户查看宠物`]})]}),(0,L.jsx)(`span`,{className:`per-page`,children:`每页 10 条`})]}),(0,L.jsxs)(`div`,{className:`toolbar`,children:[(0,L.jsxs)(`form`,{onSubmit:e=>{e.preventDefault(),o(1),c(l.trim()),x(b+1)},className:`search-form`,children:[(0,L.jsx)(de,{size:17}),(0,L.jsx)(fn,{value:l,maxLength:128,onChange:e=>u(e.target.value),placeholder:qc[e],"aria-label":qc[e]}),(0,L.jsx)(dn,{variant:`outline`,type:`submit`,disabled:h,children:`搜索`})]}),Kc[e]&&(0,L.jsxs)(`select`,{value:d,onChange:e=>{f(e.target.value),o(1)},"aria-label":`筛选状态`,children:[(0,L.jsx)(`option`,{value:``,children:e===`tasks`?`全部类别`:`全部状态`}),Kc[e].map(([e,t])=>(0,L.jsx)(`option`,{value:e,children:t},e))]}),(s||d)&&(0,L.jsx)(dn,{variant:`ghost`,onClick:()=>{u(``),c(``),f(``),o(1)},children:`重置`})]}),_?(0,L.jsxs)(`div`,{className:`empty error-text`,role:`alert`,children:[(0,L.jsx)(se,{size:30}),(0,L.jsx)(`p`,{children:_}),(0,L.jsx)(dn,{variant:`outline`,onClick:()=>x(b+1),children:`重新加载`})]}):h?(0,L.jsxs)(`div`,{className:`empty`,role:`status`,children:[(0,L.jsx)(le,{size:28,className:`animate-spin`}),(0,L.jsxs)(`p`,{children:[`正在加载`,Vc[e]]})]}):p?.items.length?(0,L.jsxs)(Xc,{children:[(0,L.jsx)(Zc,{children:(0,L.jsx)($c,{children:sl[e].map((e,t)=>(0,L.jsx)(el,{children:e},t))})}),(0,L.jsx)(Qc,{children:p.items.map(a=>e===`users`?(0,L.jsx)(ol,{row:a,action:e=>n(`users`,e),detail:r,disabled:i},`${t}-${a.id}`):(0,L.jsxs)($c,{children:[e===`pets`?(0,L.jsxs)(L.Fragment,{children:[(0,L.jsx)(G,{children:(0,L.jsx)(al,{name:a.name,id:a.id,url:a.avatar_url||``})}),(0,L.jsxs)(G,{children:[a.breed||`未填写品种`,(0,L.jsx)(`small`,{children:a.gender===`male`?`男孩`:a.gender===`female`?`女孩`:`未填写`})]}),(0,L.jsx)(G,{children:(0,L.jsx)(al,{name:a.user_name,id:a.user_id,person:!0})}),(0,L.jsx)(G,{children:a.weight_kg?`${a.weight_kg} kg`:`—`}),(0,L.jsx)(G,{children:(0,L.jsx)(il,{row:a,section:e})})]}):e===`walks`?(0,L.jsxs)(L.Fragment,{children:[(0,L.jsx)(G,{children:(0,L.jsx)(al,{name:a.user_name,id:a.user_id,person:!0})}),(0,L.jsxs)(G,{children:[(0,L.jsx)(`div`,{className:`pet-tags`,children:a.pet_names?.length?a.pet_names.map((e,t)=>(0,L.jsxs)(`span`,{children:[(0,L.jsx)(M,{size:12}),e]},t)):`—`}),(0,L.jsxs)(`small`,{className:`mono`,title:a.id,children:[`记录 `,a.id.slice(0,8)]})]}),(0,L.jsx)(G,{children:Hc(a.started_at)}),(0,L.jsxs)(G,{children:[((a.distance_meters||0)/1e3).toFixed(2),` km`,(0,L.jsx)(`small`,{children:Wc(a.duration_seconds)})]}),(0,L.jsx)(G,{children:(0,L.jsx)(il,{row:a,section:e})})]}):e===`meetups`?(0,L.jsxs)(L.Fragment,{children:[(0,L.jsxs)(G,{children:[(0,L.jsx)(`strong`,{children:a.title}),(0,L.jsx)(`small`,{className:`mono`,children:a.id.slice(0,8)})]}),(0,L.jsx)(G,{children:a.user_name||`未设置昵称`}),(0,L.jsxs)(G,{children:[a.place_name,(0,L.jsx)(`small`,{children:Hc(a.starts_at)})]}),(0,L.jsxs)(G,{children:[a.participants,` / `,a.max_people]}),(0,L.jsx)(G,{children:(0,L.jsx)(il,{row:a,section:e})})]}):e===`tasks`?(0,L.jsxs)(L.Fragment,{children:[(0,L.jsxs)(G,{children:[(0,L.jsx)(`strong`,{children:a.title}),(0,L.jsx)(`small`,{children:a.repeat_rule===`daily`?`每天`:`单次`})]}),(0,L.jsxs)(G,{children:[a.user_name||`未设置昵称`,(0,L.jsx)(`small`,{children:a.pet_name||`—`})]}),(0,L.jsx)(G,{children:Gc[a.category||``]||a.category||`—`}),(0,L.jsx)(G,{children:a.time_of_day}),(0,L.jsx)(G,{children:(0,L.jsx)(il,{row:a,section:e})})]}):(0,L.jsxs)(L.Fragment,{children:[(0,L.jsxs)(G,{children:[(0,L.jsx)(`strong`,{className:`file-name`,title:a.name,children:a.name}),(0,L.jsx)(`small`,{className:`mono`,children:a.id.slice(0,8)})]}),(0,L.jsx)(G,{children:a.content_type}),(0,L.jsx)(G,{children:Uc(a.size)}),(0,L.jsx)(G,{children:Hc(a.created_at)})]}),(0,L.jsx)(G,{children:(0,L.jsxs)(`div`,{className:`row-actions`,children:[(0,L.jsx)(dn,{variant:`ghost`,size:`sm`,onClick:()=>r(e,a),children:`查看详情`}),e===`meetups`&&a.status===`open`&&(0,L.jsx)(dn,{variant:`outline`,size:`sm`,disabled:i,onClick:()=>n(e,a),children:`取消活动`})]})})]},a.id))})]}):(0,L.jsxs)(`div`,{className:`empty`,children:[(0,L.jsx)(se,{size:32}),(0,L.jsx)(`h3`,{children:s||d?`没有符合条件的记录`:`这里还没有记录`}),(0,L.jsx)(`p`,{children:s||d?`试试其他关键词或清除筛选条件。`:`用户在小程序中的日常,会慢慢汇集到这里。`})]}),(0,L.jsxs)(`footer`,{className:`pagination`,children:[(0,L.jsx)(`span`,{children:p?.total?`第 ${(a-1)*10+1}–${Math.min(a*10,p.total)} 条,共 ${p.total} 条`:`共 0 条`}),(0,L.jsxs)(`div`,{children:[(0,L.jsx)(dn,{variant:`outline`,size:`icon`,"aria-label":`上一页`,disabled:h||a<=1,onClick:()=>o(a-1),children:(0,L.jsx)(ae,{size:16})}),(0,L.jsxs)(`span`,{children:[`第 `,a,` / `,S,` 页`]}),(0,L.jsx)(dn,{variant:`outline`,size:`icon`,"aria-label":`下一页`,disabled:h||a>=S,onClick:()=>o(a+1),children:(0,L.jsx)(oe,{size:16})})]})]})]})}function ll({points:e}){let t=e.filter(e=>Number.isFinite(e.latitude)&&Number.isFinite(e.longitude));if(!t.length)return(0,L.jsxs)(`div`,{className:`empty compact`,children:[(0,L.jsx)(ue,{size:28}),`这条记录尚未采集足迹`]});let n=t[0],r=t.map(e=>[(e.longitude-n.longitude)*Math.cos(n.latitude*Math.PI/180),e.latitude-n.latitude]),i=r.map(e=>e[0]),a=r.map(e=>e[1]),o=Math.min(...i),s=Math.max(...i),c=Math.min(...a),l=Math.max(...a),u=Math.min(440/(s-o||1e-6),200/(l-c||1e-6)),d=r.map(([e,t])=>[250+(e-(o+s)/2)*u,120-(t-(c+l)/2)*u]),[f,p]=[d[0],d[d.length-1]];return(0,L.jsxs)(`div`,{className:`track`,children:[(0,L.jsxs)(`svg`,{viewBox:`0 0 500 240`,role:`img`,"aria-label":`遛狗足迹路线示意`,children:[(0,L.jsx)(`defs`,{children:(0,L.jsx)(`pattern`,{id:`grid`,width:`25`,height:`25`,patternUnits:`userSpaceOnUse`,children:(0,L.jsx)(`path`,{d:`M 25 0 L 0 0 0 25`,fill:`none`,stroke:`#eaded3`,strokeWidth:`1`})})}),(0,L.jsx)(`rect`,{width:`500`,height:`240`,fill:`url(#grid)`}),(0,L.jsx)(`polyline`,{points:d.map(e=>e.join(`,`)).join(` `),fill:`none`,stroke:`#b95738`,strokeWidth:`4`,strokeLinecap:`round`,strokeLinejoin:`round`}),(0,L.jsx)(`circle`,{cx:f[0],cy:f[1],r:`7`,fill:`#8aa2bd`,stroke:`white`,strokeWidth:`3`}),(0,L.jsx)(`circle`,{cx:p[0],cy:p[1],r:`7`,fill:`#b95738`,stroke:`white`,strokeWidth:`3`})]}),(0,L.jsxs)(`p`,{children:[`足迹路线示意 · 蓝色起点 / 橙色终点 · `,t.length,` 个位置点`]})]})}function ul({value:e,close:t}){let[n,r]=(0,v.useState)([]),[i,a]=(0,v.useState)(!1),[o,s]=(0,v.useState)(``);(0,v.useEffect)(()=>{if(r([]),s(``),a(!1),!e||e.section!==`walks`)return;let t=new AbortController;return a(!0),Bc.walk(e.row.id,t.signal).then(e=>{t.signal.aborted||r(e.points)}).catch(e=>{t.signal.aborted||s(e.message)}).finally(()=>{t.signal.aborted||a(!1)}),()=>t.abort()},[e]);let c=e?.row,l=e?.section,u=c?l===`pets`?[[`主人`,c.user_name],[`主人 ID`,c.user_id],[`品种`,c.breed||c.species],[`性别`,c.gender===`male`?`男孩`:c.gender===`female`?`女孩`:`未填写`],[`生日`,c.birth_date],[`体重`,c.weight_kg?`${c.weight_kg} kg`:`未填写`],[`毛色`,c.coat],[`过敏提醒`,c.allergies],[`照顾备注`,c.care_notes],[`创建时间`,Hc(c.created_at)]]:l===`walks`?[[`遛狗人`,c.user_name],[`用户 ID`,c.user_id],[`同行宠物`,c.pet_names?.join(`、`)||`—`],[`开始时间`,Hc(c.started_at)],[`结束时间`,Hc(c.ended_at)],[`距离`,`${((c.distance_meters||0)/1e3).toFixed(2)} km`],[`已记录时长`,Wc(c.duration_seconds)],[`位置分享`,c.share_enabled?`已开启`:`未开启`]]:l===`meetups`?[[`发起人`,c.user_name],[`集合地点`,c.place_name],[`活动时间`,Hc(c.starts_at)],[`参与人数`,`${c.participants}/${c.max_people}`],[`活动说明`,c.description],[`坐标`,`${c.longitude}, ${c.latitude}`]]:l===`tasks`?[[`用户`,c.user_name],[`宠物`,c.pet_name],[`类别`,Gc[c.category||``]||c.category],[`计划时间`,c.time_of_day],[`重复规则`,c.repeat_rule===`daily`?`每天`:`单次`],[`创建时间`,Hc(c.created_at)]]:[[`文件类型`,c.content_type],[`大小`,Uc(c.size)],[`MD5`,c.md5],[`存储桶`,c.bucket],[`对象路径`,c.object_key],[`文件 ID`,c.id],[`上传时间`,Hc(c.created_at)]]:[];return(0,L.jsx)(ua,{open:!!e,onOpenChange:e=>{e||t()},children:(0,L.jsxs)(da,{className:`detail-dialog`,"aria-describedby":void 0,children:[(0,L.jsx)(fa,{children:(0,L.jsx)(pa,{children:c?.name||c?.title||(l===`walks`?`遛狗详情`:`记录详情`)})}),c&&(0,L.jsxs)(L.Fragment,{children:[(0,L.jsxs)(`div`,{className:`detail-summary`,children:[(0,L.jsx)(al,{name:c.name||c.title||c.user_name,id:c.id,url:c.avatar_url}),(0,L.jsx)(il,{row:c,section:l})]}),l===`files`&&c.url&&(0,L.jsxs)(L.Fragment,{children:[(0,L.jsx)(`img`,{className:`file-preview`,src:c.url,alt:c.name||`文件预览`}),(0,L.jsxs)(`a`,{href:c.url,target:`_blank`,rel:`noreferrer`,className:`file-link`,children:[`查看原图`,(0,L.jsx)(k,{size:14})]})]}),(0,L.jsx)(`dl`,{className:`detail-grid`,children:u.map(([e,t])=>(0,L.jsxs)(`div`,{children:[(0,L.jsx)(`dt`,{children:e}),(0,L.jsx)(`dd`,{children:t||`—`})]},e))}),l===`walks`&&(i?(0,L.jsxs)(`div`,{className:`empty compact`,children:[(0,L.jsx)(le,{className:`animate-spin`}),`加载足迹中`]}):o?(0,L.jsx)(`p`,{className:`error-banner`,role:`alert`,children:o}):(0,L.jsx)(ll,{points:n})),(0,L.jsx)(`div`,{className:`dialog-actions`,children:(0,L.jsx)(dn,{variant:`outline`,onClick:t,children:`关闭`})})]})]})})}var dl={overview:ce,users:pe,pets:M,walks:ue,meetups:D,tasks:O,files:A};function fl(){let[e,t]=(0,v.useState)(Lc()),[n,r]=(0,v.useState)(`sundynix`),[i,a]=(0,v.useState)(``),[o,s]=(0,v.useState)(`overview`),[c,l]=(0,v.useState)(0),[u,d]=(0,v.useState)(null),[f,p]=(0,v.useState)(``),[m,h]=(0,v.useState)(!1),[g,_]=(0,v.useState)(!1),[y,b]=(0,v.useState)(``),[x,S]=(0,v.useState)(null),[C,w]=(0,v.useState)(null);(0,v.useEffect)(()=>{let e=()=>{t(``),S(null),w(null),p(`登录已过期,请重新登录`)};return window.addEventListener(`admin-auth-expired`,e),()=>window.removeEventListener(`admin-auth-expired`,e)},[]),(0,v.useEffect)(()=>{if(!e||o!==`overview`)return;let t=new AbortController;return h(!0),p(``),Bc.stats(t.signal).then(e=>{t.signal.aborted||d(e)}).catch(e=>{t.signal.aborted||p(e.message)}).finally(()=>{t.signal.aborted||h(!1)}),()=>t.abort()},[o,e,c]);async function T(e){if(e.preventDefault(),!m){h(!0),p(``);try{let e=await Bc.login(n.trim(),i);W(e.token),t(e.token),a(``)}catch(e){p(e.message)}finally{h(!1)}}}function ee(){Rc(),t(``),a(``),d(null),S(null),w(null),p(``),b(``)}function te(e){h(!1),s(e),p(``),b(``)}async function ne(){if(!(!C||g)){_(!0),p(``);try{C.section===`users`?await Bc.setUserDisabled(C.row.id,!C.row.disabled):await Bc.cancelMeetup(C.row.id),b(C.section===`users`?C.row.disabled?`用户已启用`:`用户已停用,位置分享已关闭`:`活动已取消`),w(null),l(e=>e+1)}catch(e){p(e.message)}finally{_(!1)}}}let E=C?.section===`users`?C.row.disabled?`启用用户`:`停用用户`:`取消约遛活动`;return e?(0,L.jsxs)(`div`,{className:`app-shell`,children:[(0,L.jsxs)(`aside`,{className:`sidebar`,children:[(0,L.jsxs)(`div`,{className:`brand`,children:[(0,L.jsx)(`img`,{src:`/brand-logo.png`,alt:``}),(0,L.jsxs)(`div`,{children:[(0,L.jsx)(`strong`,{children:`肉垫计划`}),(0,L.jsx)(`small`,{children:`PAWPRINT PLAN`})]})]}),(0,L.jsx)(`p`,{className:`side-caption`,children:`陪伴工作台`}),(0,L.jsx)(`nav`,{"aria-label":`管理导航`,children:Object.keys(Vc).map(e=>{let t=dl[e];return(0,L.jsxs)(`button`,{className:`nav-item ${o===e?`active`:``}`,"aria-current":o===e?`page`:void 0,title:Vc[e],onClick:()=>te(e),children:[(0,L.jsx)(t,{size:19}),(0,L.jsx)(`span`,{children:Vc[e]}),o===e&&(0,L.jsx)(`span`,{className:`nav-dot`})]},e)})}),(0,L.jsxs)(`div`,{className:`side-note`,children:[(0,L.jsx)(M,{size:22}),(0,L.jsxs)(`p`,{children:[`陪伴它们的每一天,`,(0,L.jsx)(`br`,{}),`都值得记录。`]})]}),(0,L.jsxs)(`div`,{className:`side-bottom`,children:[(0,L.jsx)(`span`,{className:`admin-indicator`,children:`管理员`}),(0,L.jsxs)(dn,{variant:`ghost`,onClick:ee,title:`退出登录`,children:[(0,L.jsx)(j,{size:16}),(0,L.jsx)(`span`,{children:`退出登录`})]})]})]}),(0,L.jsxs)(`main`,{className:`content`,children:[(0,L.jsxs)(`header`,{className:`topbar`,children:[(0,L.jsxs)(`div`,{children:[(0,L.jsxs)(`p`,{className:`eyebrow`,children:[`肉垫计划 / `,o===`overview`?`今天的日常`:`数据管理`]}),(0,L.jsx)(`h1`,{children:Vc[o]})]}),(0,L.jsxs)(`div`,{className:`topbar-actions`,children:[(0,L.jsx)(`span`,{className:`today-date`,children:new Date().toLocaleDateString(`zh-CN`,{month:`long`,day:`numeric`,weekday:`long`})}),(0,L.jsxs)(dn,{variant:`outline`,disabled:m||g,onClick:()=>l(e=>e+1),children:[(0,L.jsx)(N,{size:16,className:m?`animate-spin`:``}),`刷新`]}),(0,L.jsx)(dn,{variant:`ghost`,className:`mobile-logout`,size:`icon`,onClick:ee,"aria-label":`退出登录`,children:(0,L.jsx)(j,{size:18})})]})]}),f&&!C&&(0,L.jsxs)(`div`,{className:`error-banner`,role:`alert`,children:[f,(0,L.jsx)(dn,{variant:`ghost`,size:`sm`,onClick:()=>p(``),children:`关闭`})]}),y&&(0,L.jsxs)(`div`,{className:`notice`,role:`status`,children:[(0,L.jsx)(O,{size:16}),y,(0,L.jsx)(`button`,{"aria-label":`关闭提示`,onClick:()=>b(``),children:(0,L.jsx)(me,{size:16})})]}),o===`overview`?(0,L.jsx)(Yc,{stats:u,navigate:te}):(0,L.jsx)(cl,{section:o,revision:c,action:(e,t)=>{p(``),w({section:e,row:t})},detail:(e,t)=>S({section:e,row:t}),actionBusy:g},o),(0,L.jsx)(`footer`,{className:`page-footer`,children:`肉垫计划 · 把每一份陪伴,认真记下来`})]}),(0,L.jsx)(ul,{value:x,close:()=>S(null)}),(0,L.jsx)(ua,{open:!!C,onOpenChange:e=>{!e&&!g&&(w(null),p(``))},children:(0,L.jsxs)(da,{"aria-describedby":`action-description`,children:[(0,L.jsx)(fa,{children:(0,L.jsx)(pa,{children:E})}),(0,L.jsx)(`p`,{id:`action-description`,className:`confirm-copy`,children:C?.section===`users`?C.row.disabled?`确认恢复「${C.row.nickname||`该用户`}」的访问权限?`:`停用「${C.row.nickname||`该用户`}」后,将无法使用小程序接口,现有位置分享也会关闭。`:`确认取消「${C?.row.title}」?取消后活动将停止接受报名。`}),f&&(0,L.jsx)(`p`,{className:`error-banner`,role:`alert`,children:f}),(0,L.jsxs)(`div`,{className:`dialog-actions`,children:[(0,L.jsx)(dn,{variant:`outline`,disabled:g,onClick:()=>{w(null),p(``)},children:`暂不操作`}),(0,L.jsxs)(dn,{disabled:g,onClick:()=>void ne(),children:[g&&(0,L.jsx)(le,{size:16,className:`animate-spin`}),`确认`,E]})]})]})})]}):(0,L.jsxs)(`main`,{className:`login-page`,children:[(0,L.jsxs)(`section`,{className:`login-story`,children:[(0,L.jsx)(`img`,{src:`/brand-logo.png`,alt:`肉垫计划`}),(0,L.jsx)(`p`,{className:`eyebrow`,children:`PAWPRINT PLAN`}),(0,L.jsxs)(`h1`,{children:[`每一段陪伴,`,(0,L.jsx)(`br`,{}),`都有迹可循。`]}),(0,L.jsxs)(`p`,{children:[`让宠物的日常更有温度,`,(0,L.jsx)(`br`,{}),`让每一次出门都值得记录。`]}),(0,L.jsxs)(`div`,{className:`story-tags`,children:[(0,L.jsxs)(`span`,{children:[(0,L.jsx)(M,{size:16}),`宠物档案`]}),(0,L.jsxs)(`span`,{children:[(0,L.jsx)(ue,{size:16}),`快乐出门`]}),(0,L.jsxs)(`span`,{children:[(0,L.jsx)(O,{size:16}),`日常照顾`]})]})]}),(0,L.jsxs)(`form`,{className:`login-card`,onSubmit:T,children:[(0,L.jsx)(`span`,{className:`login-mark`,children:(0,L.jsx)(M,{size:26})}),(0,L.jsx)(`p`,{className:`eyebrow`,children:`肉垫计划 · 管理后台`}),(0,L.jsx)(`h2`,{children:`欢迎回来`}),(0,L.jsx)(`p`,{className:`muted`,children:`今天也一起,照顾好每一个小日常。`}),(0,L.jsx)(`label`,{htmlFor:`username`,children:`管理员账号`}),(0,L.jsx)(fn,{id:`username`,autoComplete:`username`,value:n,onChange:e=>r(e.target.value),required:!0,maxLength:64}),(0,L.jsx)(`label`,{htmlFor:`password`,children:`密码`}),(0,L.jsx)(fn,{id:`password`,type:`password`,autoComplete:`current-password`,value:i,onChange:e=>a(e.target.value),required:!0}),f&&(0,L.jsx)(`p`,{className:`error-banner`,role:`alert`,children:f}),(0,L.jsxs)(dn,{disabled:m,className:`w-full login-submit`,children:[m&&(0,L.jsx)(le,{size:16,className:`animate-spin`}),m?`正在登录`:`进入管理后台`]}),(0,L.jsx)(`small`,{className:`login-footnote`,children:`肉垫计划 · 给陪伴一个温暖的地方`})]})]})}(0,y.createRoot)(document.getElementById(`root`)).render((0,L.jsx)(v.StrictMode,{children:(0,L.jsx)(fl,{})})); \ No newline at end of file diff --git a/pets-be/internal/admin/dist/assets/index-7B3h3Yq6.css b/pets-be/internal/admin/dist/assets/index-CkSlqiFn.css similarity index 88% rename from pets-be/internal/admin/dist/assets/index-7B3h3Yq6.css rename to pets-be/internal/admin/dist/assets/index-CkSlqiFn.css index ff26b52..50b2034 100644 --- a/pets-be/internal/admin/dist/assets/index-7B3h3Yq6.css +++ b/pets-be/internal/admin/dist/assets/index-CkSlqiFn.css @@ -1 +1 @@ -*,:before,:after,::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:#3b82f680;--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:0 solid #e5e7eb}:before,:after{--tw-content:""}html,:host{-webkit-text-size-adjust:100%;tab-size:4;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}body{line-height:inherit;margin:0}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;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-feature-settings:normal;font-variation-settings:normal;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-feature-settings:inherit;font-variation-settings:inherit;font-family: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:#0000;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button{height:auto}::-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{margin:0;padding:0;list-style:none}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder{opacity:1;color:#9ca3af}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{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.sr-only{clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{inset:0}.left-1\/2{left:50%}.right-4{right:1rem}.top-1\/2{top:50%}.top-4{top:1rem}.z-50{z-index:50}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.h-10{height:2.5rem}.h-4{height:1rem}.h-8{height:2rem}.h-9{height:2.25rem}.w-4{width:1rem}.w-9{width:2.25rem}.w-full{width:100%}.max-w-lg{max-width:32rem}.caption-bottom{caption-side:bottom}.-translate-x-1\/2{--tw-translate-x:-50%;transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-1\/2{--tw-translate-y:-50%;transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:1s linear infinite spin}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-center{justify-content:center}.gap-2{gap:.5rem}.gap-4{gap:1rem}.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))}.overflow-auto{overflow:auto}.whitespace-nowrap{white-space:nowrap}.rounded-full{border-radius:9999px}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-input{border-color:hsl(var(--input))}.border-transparent{border-color:#0000}.bg-amber-100{--tw-bg-opacity:1;background-color:rgb(254 243 199/var(--tw-bg-opacity,1))}.bg-black\/40{background-color:#0006}.bg-card{background-color:hsl(var(--card))}.bg-destructive{background-color:hsl(var(--destructive))}.bg-destructive\/15{background-color:hsl(var(--destructive) / .15)}.bg-emerald-100{--tw-bg-opacity:1;background-color:rgb(209 250 229/var(--tw-bg-opacity,1))}.bg-muted{background-color:hsl(var(--muted))}.bg-primary{background-color:hsl(var(--primary))}.bg-primary\/15{background-color:hsl(var(--primary) / .15)}.bg-secondary{background-color:hsl(var(--secondary))}.p-3{padding:.75rem}.p-6{padding:1.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-8{padding-left:2rem;padding-right:2rem}.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}.pt-0{padding-top:0}.text-left{text-align:left}.align-middle{vertical-align:middle}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-medium{font-weight:500}.font-semibold{font-weight:600}.leading-none{line-height:1}.tracking-tight{letter-spacing:-.025em}.text-amber-700{--tw-text-opacity:1;color:rgb(180 83 9/var(--tw-text-opacity,1))}.text-card-foreground{color:hsl(var(--card-foreground))}.text-destructive{color:hsl(var(--destructive))}.text-destructive-foreground{color:hsl(var(--destructive-foreground))}.text-emerald-700{--tw-text-opacity:1;color:rgb(4 120 87/var(--tw-text-opacity,1))}.text-foreground{color:hsl(var(--foreground))}.text-muted-foreground{color:hsl(var(--muted-foreground))}.text-primary{color:hsl(var(--primary))}.text-primary-foreground{color:hsl(var(--primary-foreground))}.text-secondary-foreground{color:hsl(var(--secondary-foreground))}.underline-offset-4{text-underline-offset:4px}.opacity-70{opacity:.7}.shadow{--tw-shadow:0 1px 3px 0 #0000001a, 0 1px 2px -1px #0000001a;--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px 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-lg{--tw-shadow:0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a;--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 #0000000d;--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)}.outline{outline-style:solid}.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-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}:root{--background:30 100% 98%;--foreground:20 20% 30%;--card:0 0% 100%;--card-foreground:20 20% 30%;--primary:15 54% 47%;--primary-foreground:0 0% 100%;--secondary:30 100% 94%;--secondary-foreground:20 20% 30%;--muted:30 38% 96%;--muted-foreground:23 16% 46%;--accent:30 100% 94%;--accent-foreground:20 20% 30%;--destructive:0 60% 48%;--destructive-foreground:0 0% 100%;--border:27 36% 88%;--input:27 36% 85%;--ring:15 54% 47%;--radius:.85rem}*{box-sizing:border-box;border-color:hsl(var(--border))}body{color:#604a40;background:#fff9f3;margin:0;font-family:ui-rounded,Hiragino Maru Gothic ProN,PingFang SC,system-ui,sans-serif;font-size:14px}button,input,select{font:inherit}button:focus-visible,a:focus-visible,select:focus-visible{outline-offset:3px;outline:2px solid #b95738}h1,h2,h3,p{margin:0}button{cursor:pointer}button:disabled{cursor:default}strong{font-weight:600}.app-shell{min-height:100vh}.sidebar{z-index:20;background:#fffefd;border-right:1px solid #ece2d8;flex-direction:column;width:238px;padding:28px 16px;display:flex;position:fixed;inset:0 auto 0 0}.brand{align-items:center;gap:12px;padding:0 12px 32px;display:flex}.brand img{border:3px solid #fffaf4;border-radius:50%;width:48px;height:48px;box-shadow:0 0 0 1px #ead8ca}.brand strong{letter-spacing:1px;font-size:20px;display:block}.brand small{color:#9d8779;letter-spacing:2px;margin-top:4px;font-size:9px;display:block}.side-caption{color:#9d8779;letter-spacing:1px;margin-bottom:14px;padding:0 15px;font-size:11px}.sidebar nav{gap:7px;display:grid}.nav-item{color:#886c5f;text-align:left;background:0 0;border:none;border-radius:13px;align-items:center;gap:12px;min-height:46px;padding:13px 15px;display:flex}.nav-item:hover{background:#fff5eb}.nav-item.active{color:#b95738;background:#ffeadc;font-weight:600}.nav-dot{background:#b95738;border-radius:50%;width:5px;height:5px;margin-left:auto}.side-note{color:#9b7057;background:#fff6ed;border-radius:18px;margin-top:auto;margin-bottom:24px;padding:22px 18px;font-size:12px;line-height:1.9}.side-note svg{color:#d9956e;margin-bottom:8px}.side-bottom{border-top:1px solid #f0e8e0;justify-content:space-between;align-items:center;padding-top:20px;display:flex}.admin-indicator{color:#886c5f;padding-left:9px;font-size:12px}.content{max-width:1780px;margin-left:238px;padding:32px 38px 24px}.topbar{justify-content:space-between;align-items:center;gap:16px;margin-bottom:26px;display:flex}.eyebrow{color:#9d7965;letter-spacing:1.8px;margin-bottom:9px;font-size:10px;font-weight:600}.topbar h1{letter-spacing:1px;font-size:27px;font-weight:600}.topbar-actions{align-items:center;gap:14px;display:flex}.today-date{color:#9d8779;font-size:12px}.mobile-logout{display:none}.welcome{background:linear-gradient(110deg,#fff0dd,#ffdec7);border:1px solid #ffeadb;border-radius:24px;justify-content:space-between;align-items:center;min-height:180px;padding:32px 36px;display:flex;overflow:hidden}.welcome h2{color:#694c3f;margin:10px 0 13px;font-size:25px;font-weight:600}.welcome p:not(.eyebrow){color:#98745d;font-size:13px}.welcome img{border:5px solid #fffaf4;border-radius:50%;width:116px;height:116px;transform:rotate(-8deg);box-shadow:0 8px 30px #a5623615}.stat-grid{grid-template-columns:repeat(6,minmax(0,1fr));gap:14px;margin:22px 0;display:grid}.stat-card,.panel{background:#fff;border:1px solid #ece2d8;border-radius:19px;box-shadow:0 6px 28px #604a4004}.stat-card{text-align:left;padding:18px;transition:transform .2s,border-color .2s}.stat-card:hover{border-color:#ddb699;transform:translateY(-3px)}.stat-top{color:#bca89c;justify-content:space-between;align-items:center;margin-bottom:15px;display:flex}.stat-icon{color:#b95738;background:#fff0e2;border-radius:12px;place-items:center;width:38px;height:38px;display:grid}.tint-pets .stat-icon,.tint-tasks .stat-icon{color:#977eae;background:#f1eaf8}.tint-walks .stat-icon,.tint-files .stat-icon{color:#7d96b6;background:#edf2fb}.stat-card>span{color:#886c5f;font-size:12px}.stat-card strong{margin:6px 0;font-size:30px;display:block}.stat-card small{color:#a48d7e;white-space:nowrap;font-size:10px}.overview-grid{grid-template-columns:1.6fr 1fr;gap:20px;display:grid}.panel-heading{justify-content:space-between;align-items:center;padding:24px 25px 0;display:flex}.panel-heading h2,.records-heading h2{font-size:17px;font-weight:600}.panel-heading p,.records-heading p{color:#a18a7c;margin-top:7px;font-size:12px}.panel-heading>svg{color:#c6a28c}.bar-chart{align-items:flex-end;gap:18px;height:232px;padding:28px 26px;display:flex}.chart-column{flex-direction:column;flex:1;align-items:center;gap:8px;min-width:0;height:100%;display:flex}.chart-column>span{color:#9d7965;font-size:12px}.bar-space{flex:1;align-items:flex-end;width:100%;max-width:42px;display:flex}.chart-bar{background:linear-gradient(#f2bc94,#d88760);border-radius:7px 7px 2px 2px;width:100%;transition:height .3s}.chart-column small{color:#a48d7e;font-size:11px}.today dl{margin:0;padding:12px 25px 20px}.today dl>div{border-bottom:1px solid #f2eae4;justify-content:space-between;align-items:center;padding:14px 0;display:flex}.today dl>div:last-child{border:0}.today dt{color:#886c5f;font-size:12px}.today dd{margin:0;font-size:21px}.today dd small{color:#a48d7e;margin-left:5px;font-size:11px}.summary-strip{background:#fff5eb;border:1px dashed #e6d2c2;border-radius:15px;gap:28px;margin-top:20px;padding:18px 22px;display:flex}.summary-strip>div{color:#9d7965;align-items:center;gap:9px;font-size:12px;display:flex}.summary-strip strong{color:#604a40;margin-left:8px}.records{overflow:hidden}.records-heading{justify-content:space-between;align-items:center;padding:24px 26px 16px;display:flex}.per-page{color:#9d7965;background:#fff6ed;border:1px solid #f4e6d8;border-radius:8px;padding:5px 10px;font-size:11px}.toolbar{flex-wrap:wrap;align-items:center;gap:12px;padding:0 26px 22px;display:flex}.search-form{flex:1;align-items:center;gap:8px;max-width:490px;display:flex;position:relative}.search-form>svg{pointer-events:none;color:#a48d7e;position:absolute;left:12px}.search-form input{border-radius:10px;min-width:140px;padding-left:36px}.toolbar select{color:#886c5f;background:#fff;border:1px solid #e6d9cf;border-radius:10px;height:36px;padding:8px 30px 8px 12px;font-size:12px}table{min-width:760px}thead{background:#fffaf6}th{white-space:nowrap;padding:13px 18px!important;font-size:12px!important}td{max-width:360px;font-size:12px;padding:15px 18px!important}td small{color:#a48d7e;margin-top:5px;font-size:10px;display:block}td strong{display:block}.identity{align-items:center;gap:10px;min-width:0;display:flex}.identity strong{color:#604a40;font-size:13px}.identity small{text-overflow:ellipsis;white-space:nowrap;color:#a48d7e;max-width:185px;margin-top:5px;font-size:10px;display:block;overflow:hidden}.avatar{color:#c58d6a;background:#fff1e4;border-radius:12px;flex:none;place-items:center;width:38px;height:38px;display:grid;overflow:hidden}.avatar img{-o-object-fit:cover;object-fit:cover;width:100%;height:100%}.mono{font-family:ui-monospace,SFMono-Regular,monospace}.pet-tags{flex-wrap:wrap;gap:5px;max-width:250px;display:flex}.pet-tags>span{color:#9d6a4e;background:#fff3e8;border-radius:7px;align-items:center;gap:4px;padding:4px 7px;font-size:11px;display:flex}.row-actions{white-space:nowrap;align-items:center;gap:5px;display:flex}.tree-toggle{color:#ad826b;background:#fffaf6;border:1px solid #f0e4da;border-radius:8px;place-items:center;width:28px;height:28px;display:grid}.text-action{color:#b95738;background:0 0;border:none;padding:0}.tree-row td{background:#fffcf9;padding:0 20px 16px 56px!important}.pet-tree{border-left:2px solid #ecd8c8;padding:14px 18px 5px}.tree-heading{color:#9d7965;align-items:center;gap:7px;margin-bottom:14px;font-size:12px;display:flex}.tree-heading strong{display:inline}.tree-heading>span{color:#b29a89;margin-left:auto;font-size:10px}.pet-tree-grid{grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:10px;display:grid}.pet-tree-card{text-align:left;background:#fff;border:1px solid #f0e2d6;border-radius:12px;justify-content:space-between;align-items:center;gap:12px;padding:13px 14px;display:flex}.pet-tree-card:hover{background:#fffaf6;border-color:#deb697}.pet-tree-card .identity{flex:1}.pet-tree-card>svg{color:#bfa390}.pet-tree-card .identity small{font-family:inherit}.tree-message{color:#a48d7e;align-items:center;gap:10px;padding:12px 0;font-size:12px;display:flex}.pagination{color:#9d8779;border-top:1px solid #f0e7df;justify-content:space-between;align-items:center;gap:16px;padding:18px 25px;font-size:12px;display:flex}.pagination>div{align-items:center;gap:15px;display:flex}.pagination button{border-radius:9px}.empty{color:#a48d7e;text-align:center;flex-direction:column;justify-content:center;align-items:center;gap:12px;min-height:230px;padding:35px 20px;display:flex}.empty svg{color:#c9ae9a}.empty h3{color:#8e7160;font-size:15px;font-weight:500}.empty p{font-size:12px;line-height:1.8}.empty.compact{min-height:150px}.error-banner,.notice{color:#a04b31;background:#fff0e7;border:1px solid #f0d7c9;border-radius:12px;justify-content:space-between;align-items:center;gap:12px;margin-bottom:18px;padding:12px 15px;font-size:12px;display:flex}.notice{color:#806499;background:#f5f0fb;border-color:#e6dcef;justify-content:flex-start}.notice button{color:inherit;background:0 0;border:none;margin-left:auto}.error-text{color:#a04b31}.page-footer{text-align:center;color:#b49c8b;letter-spacing:1px;padding:24px 0 5px;font-size:10px}.detail-dialog{width:calc(100% - 32px);max-width:700px;max-height:85vh;overflow:auto;border-radius:22px!important;padding:26px!important}.detail-summary{border-bottom:1px solid #f0e7df;justify-content:space-between;align-items:center;gap:10px;padding:14px 0;display:flex}.detail-summary .identity small{max-width:330px}.detail-grid{grid-template-columns:1fr 1fr;gap:20px;margin:7px 0;display:grid}.detail-grid>div{min-width:0}.detail-grid dt{color:#a48d7e;margin-bottom:7px;font-size:11px}.detail-grid dd{overflow-wrap:anywhere;white-space:pre-wrap;margin:0;font-size:13px;line-height:1.8}.dialog-actions{justify-content:flex-end;gap:10px;margin-top:10px;display:flex}.confirm-copy{color:#886c5f;font-size:13px;line-height:1.9}.track{background:#fffaf5;border:1px solid #eee0d4;border-radius:16px;padding:14px}.track svg{border-radius:10px;width:100%;display:block}.track p{color:#a48d7e;text-align:center;padding-top:10px;font-size:10px}.file-preview{-o-object-fit:contain;object-fit:contain;background:#fff8f0;border-radius:12px;width:100%;max-height:260px}.file-link{color:#b95738;align-items:center;gap:5px;font-size:12px;display:flex}.file-name{text-overflow:ellipsis;white-space:nowrap;max-width:220px;overflow:hidden}.login-page{background:radial-gradient(at 15% 20%,#ffead4,#0000 50%),radial-gradient(at 95% 90%,#f1eaf8,#0000 45%),#fff9f3;justify-content:center;align-items:center;gap:100px;min-height:100vh;padding:40px;display:flex}.login-story{max-width:480px}.login-story>img{border:4px solid #fffaf4;border-radius:50%;width:94px;height:94px;margin-bottom:30px;transform:rotate(-6deg);box-shadow:0 12px 40px #aa683219}.login-story h1{letter-spacing:2px;font-size:42px;font-weight:600;line-height:1.55}.login-story>p:not(.eyebrow){color:#a0816a;margin-top:20px;font-size:14px;line-height:1.9}.story-tags{gap:20px;margin-top:40px;display:flex}.story-tags>span{color:#b28d72;align-items:center;gap:7px;font-size:12px;display:flex}.login-card{background:#fff;border:1px solid #eee1d6;border-radius:27px;width:400px;padding:35px;box-shadow:0 20px 80px #98694b0b}.login-mark{color:#c07851;background:#fff0e2;border-radius:16px;place-items:center;width:48px;height:48px;margin-bottom:24px;display:grid}.login-card h2{font-size:26px;font-weight:600}.muted{color:#a18a7c;margin:10px 0 28px;font-size:12px;line-height:1.8}.login-card label{color:#8e7160;margin:17px 0 8px;font-size:12px;display:block}.login-card input{border-radius:11px;height:42px}.login-submit{border-radius:11px;height:42px;margin-top:25px}.login-footnote{text-align:center;color:#baa392;margin-top:25px;font-size:10px;display:block}.login-card .error-banner{margin-top:16px;margin-bottom:0;line-height:1.7}@media (width>=1550px){.content{padding-left:52px;padding-right:52px}}@media (width<=1240px){.stat-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.sidebar{width:210px}.content{margin-left:210px;padding:26px}.today-date{display:none}.overview-grid{grid-template-columns:1.4fr 1fr}.login-page{gap:55px}.login-story h1{font-size:35px}}@media (width<=880px){.sidebar{width:76px;padding:22px 9px}.content{margin-left:76px;padding:24px 20px}.brand{padding:0 3px 28px}.brand img{width:45px;height:45px}.brand>div,.side-caption,.nav-item>span,.side-note,.side-bottom{display:none}.nav-item{justify-content:center;padding:13px 0}.mobile-logout{display:inline-flex}.overview-grid{grid-template-columns:1fr}.summary-strip{flex-wrap:wrap;gap:15px}.welcome{min-height:170px;padding:26px}.welcome h2{font-size:22px}.welcome img{width:85px;height:85px}.login-page{gap:35px}.login-story h1{font-size:28px}.story-tags{flex-wrap:wrap;gap:12px}.login-card{width:360px;padding:28px}}@media (width<=620px){.sidebar{width:60px;padding:20px 6px}.brand{padding:0 0 22px}.brand img{width:40px;height:40px}.content{margin-left:60px;padding:20px 12px}.topbar h1{font-size:22px}.topbar-actions{gap:5px}.topbar-actions>button{padding:8px;font-size:11px}.eyebrow{letter-spacing:1px;font-size:9px}.welcome{padding:22px}.welcome img{display:none}.welcome h2{font-size:20px}.stat-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}.stat-card{padding:15px}.toolbar{padding:0 14px 18px}.records-heading{padding:22px 15px 18px}.records-heading p{max-width:170px;line-height:1.8}.search-form{flex-basis:100%;max-width:none}.pagination{flex-direction:column;align-items:flex-start;gap:13px;padding:16px 12px}.pagination>div{justify-content:space-between;width:100%}.detail-grid{grid-template-columns:1fr}.detail-summary .identity small{max-width:190px}.login-page{flex-direction:column;gap:22px;padding:25px}.login-story{width:min(400px,100%)}.login-story>img{border-radius:50%;width:54px;height:54px;margin:0 0 10px}.login-story h1{font-size:25px;line-height:1.7}.login-story h1 br,.login-story>p:not(.eyebrow),.story-tags{display:none}.login-card{width:min(400px,100%);padding:28px}.bar-chart{gap:10px;padding-left:20px;padding-right:20px}}.placeholder\:text-muted-foreground::placeholder{color:hsl(var(--muted-foreground))}.hover\:bg-accent:hover{background-color:hsl(var(--accent))}.hover\:bg-destructive\/90:hover{background-color:hsl(var(--destructive) / .9)}.hover\:bg-muted\/50:hover{background-color:hsl(var(--muted) / .5)}.hover\:bg-primary\/90:hover{background-color:hsl(var(--primary) / .9)}.hover\:bg-secondary\/80:hover{background-color:hsl(var(--secondary) / .8)}.hover\:text-accent-foreground:hover{color:hsl(var(--accent-foreground))}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}.focus-visible\:outline-none:focus-visible{outline-offset:2px;outline:2px solid #0000}.focus-visible\:ring-2:focus-visible{--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-visible\:ring-ring:focus-visible{--tw-ring-color:hsl(var(--ring))}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.\[\&_tr\:last-child\]\:border-0 tr:last-child{border-width:0}.\[\&_tr\]\:border-b tr{border-bottom-width:1px} +*,:before,:after,::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:#3b82f680;--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:0 solid #e5e7eb}:before,:after{--tw-content:""}html,:host{-webkit-text-size-adjust:100%;tab-size:4;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}body{line-height:inherit;margin:0}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;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-feature-settings:normal;font-variation-settings:normal;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-feature-settings:inherit;font-variation-settings:inherit;font-family: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:#0000;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button{height:auto}::-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{margin:0;padding:0;list-style:none}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder{opacity:1;color:#9ca3af}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{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.sr-only{clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{inset:0}.left-1\/2{left:50%}.right-4{right:1rem}.top-1\/2{top:50%}.top-4{top:1rem}.z-50{z-index:50}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.h-10{height:2.5rem}.h-4{height:1rem}.h-8{height:2rem}.h-9{height:2.25rem}.w-4{width:1rem}.w-9{width:2.25rem}.w-full{width:100%}.max-w-lg{max-width:32rem}.caption-bottom{caption-side:bottom}.-translate-x-1\/2{--tw-translate-x:-50%;transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-1\/2{--tw-translate-y:-50%;transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:1s linear infinite spin}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-center{justify-content:center}.gap-2{gap:.5rem}.gap-4{gap:1rem}.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))}.overflow-auto{overflow:auto}.whitespace-nowrap{white-space:nowrap}.rounded-full{border-radius:9999px}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-input{border-color:hsl(var(--input))}.border-transparent{border-color:#0000}.bg-amber-100{--tw-bg-opacity:1;background-color:rgb(254 243 199/var(--tw-bg-opacity,1))}.bg-black\/40{background-color:#0006}.bg-card{background-color:hsl(var(--card))}.bg-destructive{background-color:hsl(var(--destructive))}.bg-destructive\/15{background-color:hsl(var(--destructive) / .15)}.bg-emerald-100{--tw-bg-opacity:1;background-color:rgb(209 250 229/var(--tw-bg-opacity,1))}.bg-muted{background-color:hsl(var(--muted))}.bg-primary{background-color:hsl(var(--primary))}.bg-primary\/15{background-color:hsl(var(--primary) / .15)}.bg-secondary{background-color:hsl(var(--secondary))}.p-3{padding:.75rem}.p-6{padding:1.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-8{padding-left:2rem;padding-right:2rem}.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}.pt-0{padding-top:0}.text-left{text-align:left}.align-middle{vertical-align:middle}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-medium{font-weight:500}.font-semibold{font-weight:600}.leading-none{line-height:1}.tracking-tight{letter-spacing:-.025em}.text-amber-700{--tw-text-opacity:1;color:rgb(180 83 9/var(--tw-text-opacity,1))}.text-card-foreground{color:hsl(var(--card-foreground))}.text-destructive{color:hsl(var(--destructive))}.text-destructive-foreground{color:hsl(var(--destructive-foreground))}.text-emerald-700{--tw-text-opacity:1;color:rgb(4 120 87/var(--tw-text-opacity,1))}.text-foreground{color:hsl(var(--foreground))}.text-muted-foreground{color:hsl(var(--muted-foreground))}.text-primary{color:hsl(var(--primary))}.text-primary-foreground{color:hsl(var(--primary-foreground))}.text-secondary-foreground{color:hsl(var(--secondary-foreground))}.underline-offset-4{text-underline-offset:4px}.opacity-70{opacity:.7}.shadow{--tw-shadow:0 1px 3px 0 #0000001a, 0 1px 2px -1px #0000001a;--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px 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-lg{--tw-shadow:0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a;--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 #0000000d;--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)}.outline{outline-style:solid}.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-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}:root{--background:30 100% 98%;--foreground:20 20% 30%;--card:0 0% 100%;--card-foreground:20 20% 30%;--primary:15 54% 47%;--primary-foreground:0 0% 100%;--secondary:30 100% 94%;--secondary-foreground:20 20% 30%;--muted:30 38% 96%;--muted-foreground:23 16% 46%;--accent:30 100% 94%;--accent-foreground:20 20% 30%;--destructive:0 60% 48%;--destructive-foreground:0 0% 100%;--border:27 36% 88%;--input:27 36% 85%;--ring:15 54% 47%;--radius:.85rem}*{box-sizing:border-box;border-color:hsl(var(--border))}body{color:#604a40;background:#fff9f3;margin:0;font-family:ui-rounded,Hiragino Maru Gothic ProN,PingFang SC,system-ui,sans-serif;font-size:14px}button,input,select{font:inherit}button:focus-visible,a:focus-visible,select:focus-visible{outline-offset:3px;outline:2px solid #b95738}h1,h2,h3,p{margin:0}button{cursor:pointer}button:disabled{cursor:default}strong{font-weight:600}.app-shell{min-height:100vh}.sidebar{z-index:20;background:#fffefd;border-right:1px solid #ece2d8;flex-direction:column;width:238px;padding:28px 16px;display:flex;position:fixed;inset:0 auto 0 0}.brand{align-items:center;gap:12px;padding:0 12px 32px;display:flex}.brand img{border:3px solid #fffaf4;border-radius:50%;width:48px;height:48px;box-shadow:0 0 0 1px #ead8ca}.brand strong{letter-spacing:1px;font-size:20px;display:block}.brand small{color:#9d8779;letter-spacing:2px;margin-top:4px;font-size:9px;display:block}.side-caption{color:#9d8779;letter-spacing:1px;margin-bottom:14px;padding:0 15px;font-size:11px}.sidebar nav{gap:7px;display:grid}.nav-item{color:#886c5f;text-align:left;background:0 0;border:none;border-radius:13px;align-items:center;gap:12px;min-height:46px;padding:13px 15px;display:flex}.nav-item:hover{background:#fff5eb}.nav-item.active{color:#b95738;background:#ffeadc;font-weight:600}.nav-dot{background:#b95738;border-radius:50%;width:5px;height:5px;margin-left:auto}.side-note{color:#9b7057;background:#fff6ed;border-radius:18px;margin-top:auto;margin-bottom:24px;padding:22px 18px;font-size:12px;line-height:1.9}.side-note svg{color:#d9956e;margin-bottom:8px}.side-bottom{border-top:1px solid #f0e8e0;justify-content:space-between;align-items:center;padding-top:20px;display:flex}.admin-indicator{color:#886c5f;padding-left:9px;font-size:12px}.content{max-width:1780px;margin-left:238px;padding:32px 38px 24px}.topbar{justify-content:space-between;align-items:center;gap:16px;margin-bottom:26px;display:flex}.eyebrow{color:#9d7965;letter-spacing:1.8px;margin-bottom:9px;font-size:10px;font-weight:600}.topbar h1{letter-spacing:1px;font-size:27px;font-weight:600}.topbar-actions{align-items:center;gap:14px;display:flex}.today-date{color:#9d8779;font-size:12px}.mobile-logout{display:none}.welcome{background:linear-gradient(110deg,#fff0dd,#ffdec7);border:1px solid #ffeadb;border-radius:24px;justify-content:space-between;align-items:center;min-height:180px;padding:32px 36px;display:flex;overflow:hidden}.welcome h2{color:#694c3f;margin:10px 0 13px;font-size:25px;font-weight:600}.welcome p:not(.eyebrow){color:#98745d;font-size:13px}.welcome img{border:5px solid #fffaf4;border-radius:50%;width:116px;height:116px;transform:rotate(-8deg);box-shadow:0 8px 30px #a5623615}.stat-grid{grid-template-columns:repeat(6,minmax(0,1fr));gap:14px;margin:22px 0;display:grid}.stat-card,.panel{background:#fff;border:1px solid #ece2d8;border-radius:19px;box-shadow:0 6px 28px #604a4004}.stat-card{text-align:left;padding:18px;transition:transform .2s,border-color .2s}.stat-card:hover{border-color:#ddb699;transform:translateY(-3px)}.stat-top{color:#bca89c;justify-content:space-between;align-items:center;margin-bottom:15px;display:flex}.stat-icon{color:#b95738;background:#fff0e2;border-radius:12px;place-items:center;width:38px;height:38px;display:grid}.tint-pets .stat-icon,.tint-tasks .stat-icon{color:#977eae;background:#f1eaf8}.tint-walks .stat-icon,.tint-files .stat-icon{color:#7d96b6;background:#edf2fb}.stat-card>span{color:#886c5f;font-size:12px}.stat-card strong{margin:6px 0;font-size:30px;display:block}.stat-card small{color:#a48d7e;white-space:nowrap;font-size:10px}.overview-grid{grid-template-columns:1.6fr 1fr;gap:20px;display:grid}.panel-heading{justify-content:space-between;align-items:center;padding:24px 25px 0;display:flex}.panel-heading h2,.records-heading h2{font-size:17px;font-weight:600}.panel-heading p,.records-heading p{color:#a18a7c;margin-top:7px;font-size:12px}.panel-heading>svg{color:#c6a28c}.bar-chart{align-items:flex-end;gap:18px;height:232px;padding:28px 26px;display:flex}.chart-column{flex-direction:column;flex:1;align-items:center;gap:8px;min-width:0;height:100%;display:flex}.chart-column>span{color:#9d7965;font-size:12px}.bar-space{flex:1;align-items:flex-end;width:100%;max-width:42px;display:flex}.chart-bar{background:linear-gradient(#f2bc94,#d88760);border-radius:7px 7px 2px 2px;width:100%;transition:height .3s}.chart-column small{color:#a48d7e;font-size:11px}.today dl{margin:0;padding:12px 25px 20px}.today dl>div{border-bottom:1px solid #f2eae4;justify-content:space-between;align-items:center;padding:14px 0;display:flex}.today dl>div:last-child{border:0}.today dt{color:#886c5f;font-size:12px}.today dd{margin:0;font-size:21px}.today dd small{color:#a48d7e;margin-left:5px;font-size:11px}.summary-strip{background:#fff5eb;border:1px dashed #e6d2c2;border-radius:15px;gap:28px;margin-top:20px;padding:18px 22px;display:flex}.summary-strip>div{color:#9d7965;align-items:center;gap:9px;font-size:12px;display:flex}.summary-strip strong{color:#604a40;margin-left:8px}.records{overflow:hidden}.records-heading{justify-content:space-between;align-items:center;padding:24px 26px 16px;display:flex}.per-page{color:#9d7965;background:#fff6ed;border:1px solid #f4e6d8;border-radius:8px;padding:5px 10px;font-size:11px}.toolbar{flex-wrap:wrap;align-items:center;gap:12px;padding:0 26px 22px;display:flex}.search-form{flex:1;align-items:center;gap:8px;max-width:490px;display:flex;position:relative}.search-form>svg{pointer-events:none;color:#a48d7e;position:absolute;left:12px}.search-form input{border-radius:10px;min-width:140px;padding-left:36px}.toolbar select{color:#886c5f;background:#fff;border:1px solid #e6d9cf;border-radius:10px;height:36px;padding:8px 30px 8px 12px;font-size:12px}table{min-width:760px}thead{background:#fffaf6}th{white-space:nowrap;padding:13px 18px!important;font-size:12px!important}td{max-width:360px;font-size:12px;padding:15px 18px!important}td small{color:#a48d7e;margin-top:5px;font-size:10px;display:block}td strong{display:block}.identity{align-items:center;gap:10px;min-width:0;display:flex}.identity strong{color:#604a40;font-size:13px}.identity small{text-overflow:ellipsis;white-space:nowrap;color:#a48d7e;max-width:185px;margin-top:5px;font-size:10px;display:block;overflow:hidden}.avatar{color:#c58d6a;background:#fff1e4;border-radius:12px;flex:none;place-items:center;width:38px;height:38px;display:grid;overflow:hidden}.avatar img{-o-object-fit:cover;object-fit:cover;width:100%;height:100%}.mono{font-family:ui-monospace,SFMono-Regular,monospace}.pet-tags{flex-wrap:wrap;gap:5px;max-width:250px;display:flex}.pet-tags>span{color:#9d6a4e;background:#fff3e8;border-radius:7px;align-items:center;gap:4px;padding:4px 7px;font-size:11px;display:flex}.row-actions{white-space:nowrap;align-items:center;gap:5px;display:flex}.tree-toggle{color:#ad826b;background:#fffaf6;border:1px solid #f0e4da;border-radius:8px;place-items:center;width:28px;height:28px;display:grid}.text-action{color:#b95738;background:0 0;border:none;padding:0}.tree-row td{background:#fffcf9;padding:0 20px 16px 56px!important}.pet-tree{border-left:2px solid #ecd8c8;padding:14px 18px 5px}.tree-heading{color:#9d7965;align-items:center;gap:7px;margin-bottom:14px;font-size:12px;display:flex}.tree-heading strong{display:inline}.tree-heading>span{color:#b29a89;margin-left:auto;font-size:10px}.pet-tree-grid{grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:10px;display:grid}.pet-tree-card{text-align:left;background:#fff;border:1px solid #f0e2d6;border-radius:12px;justify-content:space-between;align-items:center;gap:12px;padding:13px 14px;display:flex}.pet-tree-card:hover{background:#fffaf6;border-color:#deb697}.pet-tree-card .identity{flex:1}.pet-tree-card>svg{color:#bfa390}.pet-tree-card .identity small{font-family:inherit}.tree-message{color:#a48d7e;align-items:center;gap:10px;padding:12px 0;font-size:12px;display:flex}.pagination{color:#9d8779;border-top:1px solid #f0e7df;justify-content:space-between;align-items:center;gap:16px;padding:18px 25px;font-size:12px;display:flex}.pagination>div{align-items:center;gap:15px;display:flex}.pagination button{border-radius:9px}.empty{color:#a48d7e;text-align:center;flex-direction:column;justify-content:center;align-items:center;gap:12px;min-height:230px;padding:35px 20px;display:flex}.empty svg{color:#c9ae9a}.empty h3{color:#8e7160;font-size:15px;font-weight:500}.empty p{font-size:12px;line-height:1.8}.empty.compact{min-height:150px}.error-banner,.notice{color:#a04b31;background:#fff0e7;border:1px solid #f0d7c9;border-radius:12px;justify-content:space-between;align-items:center;gap:12px;margin-bottom:18px;padding:12px 15px;font-size:12px;display:flex}.notice{color:#806499;background:#f5f0fb;border-color:#e6dcef;justify-content:flex-start}.notice button{color:inherit;background:0 0;border:none;margin-left:auto}.error-text{color:#a04b31}.page-footer{text-align:center;color:#b49c8b;letter-spacing:1px;padding:24px 0 5px;font-size:10px}.detail-dialog{width:calc(100% - 32px);max-width:700px;max-height:85vh;overflow:auto;border-radius:22px!important;padding:26px!important}.detail-summary{border-bottom:1px solid #f0e7df;justify-content:space-between;align-items:center;gap:10px;padding:14px 0;display:flex}.detail-summary .identity small{max-width:330px}.detail-grid{grid-template-columns:1fr 1fr;gap:20px;margin:7px 0;display:grid}.detail-grid>div{min-width:0}.detail-grid dt{color:#a48d7e;margin-bottom:7px;font-size:11px}.detail-grid dd{overflow-wrap:anywhere;white-space:pre-wrap;margin:0;font-size:13px;line-height:1.8}.dialog-actions{justify-content:flex-end;gap:10px;margin-top:10px;display:flex}.confirm-copy{color:#886c5f;font-size:13px;line-height:1.9}.track{background:#fffaf5;border:1px solid #eee0d4;border-radius:16px;padding:14px}.track svg{border-radius:10px;width:100%;display:block}.track p{color:#a48d7e;text-align:center;padding-top:10px;font-size:10px}.file-preview{-o-object-fit:contain;object-fit:contain;background:#fff8f0;border-radius:12px;width:100%;max-height:260px}.file-link{color:#b95738;align-items:center;gap:5px;font-size:12px;display:flex}.file-name{text-overflow:ellipsis;white-space:nowrap;max-width:220px;overflow:hidden}.login-page{background:radial-gradient(at 15% 20%,#ffead4,#0000 50%),radial-gradient(at 95% 90%,#f1eaf8,#0000 45%),#fff9f3;justify-content:center;align-items:center;gap:100px;min-height:100vh;padding:40px;display:flex}.login-story{max-width:480px}.login-story>img{border:4px solid #fffaf4;border-radius:50%;width:94px;height:94px;margin-bottom:30px;transform:rotate(-6deg);box-shadow:0 12px 40px #aa683219}.login-story h1{letter-spacing:2px;font-size:42px;font-weight:600;line-height:1.55}.login-story>p:not(.eyebrow){color:#a0816a;margin-top:20px;font-size:14px;line-height:1.9}.story-tags{gap:20px;margin-top:40px;display:flex}.story-tags>span{color:#b28d72;align-items:center;gap:7px;font-size:12px;display:flex}.login-card{background:#fff;border:1px solid #eee1d6;border-radius:27px;width:400px;padding:35px;box-shadow:0 20px 80px #98694b0b}.login-mark{color:#c07851;background:#fff0e2;border-radius:16px;place-items:center;width:48px;height:48px;margin-bottom:24px;display:grid}.login-card h2{font-size:26px;font-weight:600}.muted{color:#a18a7c;margin:10px 0 28px;font-size:12px;line-height:1.8}.login-card label{color:#8e7160;margin:17px 0 8px;font-size:12px;display:block}.login-card input{border-radius:11px;height:42px}.login-submit{border-radius:11px;height:42px;margin-top:25px}.login-footnote{text-align:center;color:#baa392;margin-top:25px;font-size:10px;display:block}.login-card .error-banner{margin-top:16px;margin-bottom:0;line-height:1.7}@media (width>=1550px){.content{padding-left:52px;padding-right:52px}}@media (width<=1240px){.stat-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.sidebar{width:210px}.content{margin-left:210px;padding:26px}.today-date{display:none}.overview-grid{grid-template-columns:1.4fr 1fr}.login-page{gap:55px}.login-story h1{font-size:35px}}@media (width<=880px){.sidebar{width:76px;padding:22px 9px}.content{margin-left:76px;padding:24px 20px}.brand{padding:0 3px 28px}.brand img{width:45px;height:45px}.brand>div,.side-caption,.nav-item>span,.side-note,.side-bottom{display:none}.nav-item{justify-content:center;padding:13px 0}.mobile-logout{display:inline-flex}.overview-grid{grid-template-columns:1fr}.summary-strip{flex-wrap:wrap;gap:15px}.welcome{min-height:170px;padding:26px}.welcome h2{font-size:22px}.welcome img{width:85px;height:85px}.login-page{gap:35px}.login-story h1{font-size:28px}.story-tags{flex-wrap:wrap;gap:12px}.login-card{width:360px;padding:28px}}@media (width<=620px){.sidebar{width:60px;padding:20px 6px}.brand{padding:0 0 22px}.brand img{width:40px;height:40px}.content{margin-left:60px;padding:20px 12px}.topbar h1{font-size:22px}.topbar-actions{gap:5px}.topbar-actions>button{padding:8px;font-size:11px}.eyebrow{letter-spacing:1px;font-size:9px}.welcome{padding:22px}.welcome img{display:none}.welcome h2{font-size:20px}.stat-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}.stat-card{padding:15px}.toolbar{padding:0 14px 18px}.records-heading{padding:22px 15px 18px}.records-heading p{max-width:170px;line-height:1.8}.search-form{flex-basis:100%;max-width:none}.pagination{flex-direction:column;align-items:flex-start;gap:13px;padding:16px 12px}.pagination>div{justify-content:space-between;width:100%}.detail-grid{grid-template-columns:1fr}.detail-summary .identity small{max-width:190px}.login-page{flex-direction:column;gap:22px;padding:25px}.login-story{width:min(400px,100%)}.login-story>img{border-radius:50%;width:54px;height:54px;margin:0 0 10px}.login-story h1{font-size:25px;line-height:1.7}.login-story h1 br,.login-story>p:not(.eyebrow),.story-tags{display:none}.login-card{width:min(400px,100%);padding:28px}.bar-chart{gap:10px;padding-left:20px;padding-right:20px}}.nav-item{text-decoration:none}.breed-alphabet{flex-wrap:wrap;gap:6px;padding:0 24px 24px;display:flex}.breed-alphabet button{color:#927766;border:1px solid #eeded1;border-radius:9px;min-width:30px;height:30px;padding:0 8px}.breed-alphabet button.active{color:#b85837;background:#ffeadc;border-color:#dfa080}.breed-aliases{white-space:normal;max-width:240px}.breed-form{gap:18px;display:grid}.breed-form label{gap:8px;display:grid}.breed-form .breed-enabled{align-items:center;gap:10px;display:flex}.breed-dialog{max-height:85vh;overflow-y:auto}.breed-fact-fields{grid-template-columns:1fr 1fr;gap:16px;display:grid}.breed-form textarea{resize:vertical;border:1px solid #eadacb;border-radius:12px;width:100%;padding:12px}.breed-source-badges{flex-wrap:wrap;gap:6px;max-width:280px;display:flex}.breed-source-badges a{text-decoration:none}.breed-editor-tabs{gap:10px;margin-bottom:8px;display:flex}.breed-source-list{gap:16px;display:grid}.breed-source-card{background:#fffbf7;border:1px solid #ead9cc;border-radius:16px;padding:18px}.breed-source-card header{justify-content:space-between;align-items:center;gap:12px;display:flex}.breed-source-card small{color:#a28a78;margin-top:8px;display:block}.breed-source-card dl{gap:12px;margin-top:18px;display:grid}.breed-source-card dl>div{grid-template-columns:90px 1fr;gap:12px;display:grid}.breed-source-card dt{color:#a28a78;font-size:13px}.breed-source-card dd{overflow-wrap:anywhere;margin:0;font-size:14px}.breed-form select{background:#fff;border:1px solid #ead9cc;border-radius:10px;width:100%;min-height:40px;padding:8px}.placeholder\:text-muted-foreground::placeholder{color:hsl(var(--muted-foreground))}.hover\:bg-accent:hover{background-color:hsl(var(--accent))}.hover\:bg-destructive\/90:hover{background-color:hsl(var(--destructive) / .9)}.hover\:bg-muted\/50:hover{background-color:hsl(var(--muted) / .5)}.hover\:bg-primary\/90:hover{background-color:hsl(var(--primary) / .9)}.hover\:bg-secondary\/80:hover{background-color:hsl(var(--secondary) / .8)}.hover\:text-accent-foreground:hover{color:hsl(var(--accent-foreground))}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}.focus-visible\:outline-none:focus-visible{outline-offset:2px;outline:2px solid #0000}.focus-visible\:ring-2:focus-visible{--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-visible\:ring-ring:focus-visible{--tw-ring-color:hsl(var(--ring))}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.\[\&_tr\:last-child\]\:border-0 tr:last-child{border-width:0}.\[\&_tr\]\:border-b tr{border-bottom-width:1px} diff --git a/pets-be/internal/admin/dist/assets/index-N2FSM0pD.js b/pets-be/internal/admin/dist/assets/index-N2FSM0pD.js new file mode 100644 index 0000000..f22c4a8 --- /dev/null +++ b/pets-be/internal/admin/dist/assets/index-N2FSM0pD.js @@ -0,0 +1,59 @@ +var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),s=(e,n)=>{let r={};for(var i in e)t(r,i,{get:e[i],enumerable:!0});return n||t(r,Symbol.toStringTag,{value:`Module`}),r},c=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;li[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},l=(n,r,a)=>(a=n==null?{}:e(i(n)),c(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),e.crossOrigin===`use-credentials`?t.credentials=`include`:e.crossOrigin===`anonymous`?t.credentials=`omit`:t.credentials=`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var u=o((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.portal`),r=Symbol.for(`react.fragment`),i=Symbol.for(`react.strict_mode`),a=Symbol.for(`react.profiler`),o=Symbol.for(`react.consumer`),s=Symbol.for(`react.context`),c=Symbol.for(`react.forward_ref`),l=Symbol.for(`react.suspense`),u=Symbol.for(`react.memo`),d=Symbol.for(`react.lazy`),f=Symbol.for(`react.activity`),p=Symbol.iterator;function m(e){return typeof e!=`object`||!e?null:(e=p&&e[p]||e[`@@iterator`],typeof e==`function`?e:null)}var h={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},g=Object.assign,_={};function v(e,t,n){this.props=e,this.context=t,this.refs=_,this.updater=n||h}v.prototype.isReactComponent={},v.prototype.setState=function(e,t){if(typeof e!=`object`&&typeof e!=`function`&&e!=null)throw Error(`takes an object of state variables to update or a function which returns an object of state variables.`);this.updater.enqueueSetState(this,e,t,`setState`)},v.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,`forceUpdate`)};function y(){}y.prototype=v.prototype;function b(e,t,n){this.props=e,this.context=t,this.refs=_,this.updater=n||h}var x=b.prototype=new y;x.constructor=b,g(x,v.prototype),x.isPureReactComponent=!0;var S=Array.isArray;function C(){}var w={H:null,A:null,T:null,S:null},T=Object.prototype.hasOwnProperty;function E(e,n,r){var i=r.ref;return{$$typeof:t,type:e,key:n,ref:i===void 0?null:i,props:r}}function ee(e,t){return E(e.type,t,e.props)}function D(e){return typeof e==`object`&&!!e&&e.$$typeof===t}function te(e){var t={"=":`=0`,":":`=2`};return`$`+e.replace(/[=:]/g,function(e){return t[e]})}var O=/\/+/g;function k(e,t){return typeof e==`object`&&e&&e.key!=null?te(``+e.key):t.toString(36)}function ne(e){switch(e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason;default:switch(typeof e.status==`string`?e.then(C,C):(e.status=`pending`,e.then(function(t){e.status===`pending`&&(e.status=`fulfilled`,e.value=t)},function(t){e.status===`pending`&&(e.status=`rejected`,e.reason=t)})),e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason}}throw e}function re(e,r,i,a,o){var s=typeof e;(s===`undefined`||s===`boolean`)&&(e=null);var c=!1;if(e===null)c=!0;else switch(s){case`bigint`:case`string`:case`number`:c=!0;break;case`object`:switch(e.$$typeof){case t:case n:c=!0;break;case d:return c=e._init,re(c(e._payload),r,i,a,o)}}if(c)return o=o(e),c=a===``?`.`+k(e,0):a,S(o)?(i=``,c!=null&&(i=c.replace(O,`$&/`)+`/`),re(o,r,i,``,function(e){return e})):o!=null&&(D(o)&&(o=ee(o,i+(o.key==null||e&&e.key===o.key?``:(``+o.key).replace(O,`$&/`)+`/`)+c)),r.push(o)),1;c=0;var l=a===``?`.`:a+`:`;if(S(e))for(var u=0;u{t.exports=u()})),f=o((e=>{function t(e,t){var n=e.length;e.push(t);a:for(;0>>1,a=e[r];if(0>>1;ri(c,n))li(u,c)?(e[r]=u,e[l]=n,r=l):(e[r]=c,e[s]=n,r=s);else if(li(u,n))e[r]=u,e[l]=n,r=l;else break a}}return t}function i(e,t){var n=e.sortIndex-t.sortIndex;return n===0?e.id-t.id:n}if(e.unstable_now=void 0,typeof performance==`object`&&typeof performance.now==`function`){var a=performance;e.unstable_now=function(){return a.now()}}else{var o=Date,s=o.now();e.unstable_now=function(){return o.now()-s}}var c=[],l=[],u=1,d=null,f=3,p=!1,m=!1,h=!1,g=!1,_=typeof setTimeout==`function`?setTimeout:null,v=typeof clearTimeout==`function`?clearTimeout:null,y=typeof setImmediate<`u`?setImmediate:null;function b(e){for(var i=n(l);i!==null;){if(i.callback===null)r(l);else if(i.startTime<=e)r(l),i.sortIndex=i.expirationTime,t(c,i);else break;i=n(l)}}function x(e){if(h=!1,b(e),!m)if(n(c)!==null)m=!0,S||(S=!0,D());else{var t=n(l);t!==null&&k(x,t.startTime-e)}}var S=!1,C=-1,w=5,T=-1;function E(){return g?!0:!(e.unstable_now()-Tt&&E());){var o=d.callback;if(typeof o==`function`){d.callback=null,f=d.priorityLevel;var s=o(d.expirationTime<=t);if(t=e.unstable_now(),typeof s==`function`){d.callback=s,b(t),i=!0;break b}d===n(c)&&r(c),b(t)}else r(c);d=n(c)}if(d!==null)i=!0;else{var u=n(l);u!==null&&k(x,u.startTime-t),i=!1}}break a}finally{d=null,f=a,p=!1}i=void 0}}finally{i?D():S=!1}}}var D;if(typeof y==`function`)D=function(){y(ee)};else if(typeof MessageChannel<`u`){var te=new MessageChannel,O=te.port2;te.port1.onmessage=ee,D=function(){O.postMessage(null)}}else D=function(){_(ee,0)};function k(t,n){C=_(function(){t(e.unstable_now())},n)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(e){e.callback=null},e.unstable_forceFrameRate=function(e){0>e||125o?(r.sortIndex=a,t(l,r),n(c)===null&&r===n(l)&&(h?(v(C),C=-1):h=!0,k(x,a-o))):(r.sortIndex=s,t(c,r),m||p||(m=!0,S||(S=!0,D()))),r},e.unstable_shouldYield=E,e.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}})),p=o(((e,t)=>{t.exports=f()})),m=o((e=>{var t=d();function n(e){var t=`https://react.dev/errors/`+e;if(1{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=m()})),g=o((e=>{var t=p(),n=d(),r=h();function i(e){var t=`https://react.dev/errors/`+e;if(1ce||(e.current=se[ce],se[ce]=null,ce--)}function P(e,t){ce++,se[ce]=e.current,e.current=t}var le=M(null),ue=M(null),de=M(null),fe=M(null);function pe(e,t){switch(P(de,t),P(ue,e),P(le,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?Vd(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)t=Vd(t),e=Hd(t,e);else switch(e){case`svg`:e=1;break;case`math`:e=2;break;default:e=0}}N(le),P(le,e)}function me(){N(le),N(ue),N(de)}function he(e){e.memoizedState!==null&&P(fe,e);var t=le.current,n=Hd(t,e.type);t!==n&&(P(ue,e),P(le,n))}function ge(e){ue.current===e&&(N(le),N(ue)),fe.current===e&&(N(fe),Qf._currentValue=oe)}var _e,ve;function ye(e){if(_e===void 0)try{throw Error()}catch(e){var t=e.stack.trim().match(/\n( *(at )?)/);_e=t&&t[1]||``,ve=-1)`:-1i||c[r]!==l[i]){var u=` +`+c[r].replace(` at new `,` at `);return e.displayName&&u.includes(``)&&(u=u.replace(``,e.displayName)),u}while(1<=r&&0<=i);break}}}finally{be=!1,Error.prepareStackTrace=n}return(n=e?e.displayName||e.name:``)?ye(n):``}function Se(e,t){switch(e.tag){case 26:case 27:case 5:return ye(e.type);case 16:return ye(`Lazy`);case 13:return e.child!==t&&t!==null?ye(`Suspense Fallback`):ye(`Suspense`);case 19:return ye(`SuspenseList`);case 0:case 15:return xe(e.type,!1);case 11:return xe(e.type.render,!1);case 1:return xe(e.type,!0);case 31:return ye(`Activity`);default:return``}}function Ce(e){try{var t=``,n=null;do t+=Se(e,n),n=e,e=e.return;while(e);return t}catch(e){return` +Error generating stack: `+e.message+` +`+e.stack}}var we=Object.prototype.hasOwnProperty,Te=t.unstable_scheduleCallback,Ee=t.unstable_cancelCallback,De=t.unstable_shouldYield,Oe=t.unstable_requestPaint,ke=t.unstable_now,Ae=t.unstable_getCurrentPriorityLevel,je=t.unstable_ImmediatePriority,Me=t.unstable_UserBlockingPriority,Ne=t.unstable_NormalPriority,Pe=t.unstable_LowPriority,Fe=t.unstable_IdlePriority,Ie=t.log,Le=t.unstable_setDisableYieldValue,Re=null,ze=null;function Be(e){if(typeof Ie==`function`&&Le(e),ze&&typeof ze.setStrictMode==`function`)try{ze.setStrictMode(Re,e)}catch{}}var Ve=Math.clz32?Math.clz32:We,He=Math.log,Ue=Math.LN2;function We(e){return e>>>=0,e===0?32:31-(He(e)/Ue|0)|0}var Ge=256,Ke=262144,qe=4194304;function Je(e){var t=e&42;if(t!==0)return t;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return e&261888;case 262144:case 524288:case 1048576:case 2097152:return e&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return e&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function Ye(e,t,n){var r=e.pendingLanes;if(r===0)return 0;var i=0,a=e.suspendedLanes,o=e.pingedLanes;e=e.warmLanes;var s=r&134217727;return s===0?(s=r&~a,s===0?o===0?n||(n=r&~e,n!==0&&(i=Je(n))):i=Je(o):i=Je(s)):(r=s&~a,r===0?(o&=s,o===0?n||(n=s&~e,n!==0&&(i=Je(n))):i=Je(o)):i=Je(r)),i===0?0:t!==0&&t!==i&&(t&a)===0&&(a=i&-i,n=t&-t,a>=n||a===32&&n&4194048)?t:i}function Xe(e,t){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)===0}function Ze(e,t){switch(e){case 1:case 2:case 4:case 8:case 64:return t+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function Qe(){var e=qe;return qe<<=1,!(qe&62914560)&&(qe=4194304),e}function $e(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function et(e,t){e.pendingLanes|=t,t!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function tt(e,t,n,r,i,a){var o=e.pendingLanes;e.pendingLanes=n,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=n,e.entangledLanes&=n,e.errorRecoveryDisabledLanes&=n,e.shellSuspendCounter=0;var s=e.entanglements,c=e.expirationTimes,l=e.hiddenUpdates;for(n=o&~n;0`u`||window.document===void 0||window.document.createElement===void 0),mn=!1;if(pn)try{var hn={};Object.defineProperty(hn,"passive",{get:function(){mn=!0}}),window.addEventListener(`test`,hn,hn),window.removeEventListener(`test`,hn,hn)}catch{mn=!1}var gn=null,_n=null,vn=null;function yn(){if(vn)return vn;var e,t=_n,n=t.length,r,i=`value`in gn?gn.value:gn.textContent,a=i.length;for(e=0;e=Zn),er=` `,tr=!1;function nr(e,t){switch(e){case`keyup`:return Yn.indexOf(t.keyCode)!==-1;case`keydown`:return t.keyCode!==229;case`keypress`:case`mousedown`:case`focusout`:return!0;default:return!1}}function rr(e){return e=e.detail,typeof e==`object`&&`data`in e?e.data:null}var ir=!1;function ar(e,t){switch(e){case`compositionend`:return rr(t);case`keypress`:return t.which===32?(tr=!0,er):null;case`textInput`:return e=t.data,e===er&&tr?null:e;default:return null}}function or(e,t){if(ir)return e===`compositionend`||!Xn&&nr(e,t)?(e=yn(),vn=_n=gn=null,ir=!1,e):null;switch(e){case`paste`:return null;case`keypress`:if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:n,offset:t-e};e=r}a:{for(;n;){if(n.nextSibling){n=n.nextSibling;break a}n=n.parentNode}n=void 0}n=Or(n)}}function Ar(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?Ar(e,t.parentNode):`contains`in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function jr(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var t=Bt(e.document);t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href==`string`}catch{n=!1}if(n)e=t.contentWindow;else break;t=Bt(e.document)}return t}function Mr(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t===`input`&&(e.type===`text`||e.type===`search`||e.type===`tel`||e.type===`url`||e.type===`password`)||t===`textarea`||e.contentEditable===`true`)}var Nr=pn&&`documentMode`in document&&11>=document.documentMode,Pr=null,Fr=null,Ir=null,Lr=!1;function Rr(e,t,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;Lr||Pr==null||Pr!==Bt(r)||(r=Pr,`selectionStart`in r&&Mr(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),Ir&&Dr(Ir,r)||(Ir=r,r=Ed(Fr,`onSelect`),0>=o,i-=o,Ai=1<<32-Ve(t)+i|n<h?(g=d,d=null):g=d.sibling;var _=p(i,d,s[h],c);if(_===null){d===null&&(d=g);break}e&&d&&_.alternate===null&&t(i,d),a=o(_,a,h),u===null?l=_:u.sibling=_,u=_,d=g}if(h===s.length)return n(i,d),F&&Mi(i,h),l;if(d===null){for(;hg?(_=h,h=null):_=h.sibling;var y=p(a,h,v.value,l);if(y===null){h===null&&(h=_);break}e&&h&&y.alternate===null&&t(a,h),s=o(y,s,g),d===null?u=y:d.sibling=y,d=y,h=_}if(v.done)return n(a,h),F&&Mi(a,g),u;if(h===null){for(;!v.done;g++,v=c.next())v=f(a,v.value,l),v!==null&&(s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return F&&Mi(a,g),u}for(h=r(h);!v.done;g++,v=c.next())v=m(h,a,g,v.value,l),v!==null&&(e&&v.alternate!==null&&h.delete(v.key===null?g:v.key),s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return e&&h.forEach(function(e){return t(a,e)}),F&&Mi(a,g),u}function b(e,r,o,c){if(typeof o==`object`&&o&&o.type===y&&o.key===null&&(o=o.props.children),typeof o==`object`&&o){switch(o.$$typeof){case _:a:{for(var l=o.key;r!==null;){if(r.key===l){if(l=o.type,l===y){if(r.tag===7){n(e,r.sibling),c=a(r,o.props.children),c.return=e,e=c;break a}}else if(r.elementType===l||typeof l==`object`&&l&&l.$$typeof===D&&Da(l)===r.type){n(e,r.sibling),c=a(r,o.props),Pa(c,o),c.return=e,e=c;break a}n(e,r);break}else t(e,r);r=r.sibling}o.type===y?(c=_i(o.props.children,e.mode,c,o.key),c.return=e,e=c):(c=gi(o.type,o.key,o.props,null,e.mode,c),Pa(c,o),c.return=e,e=c)}return s(e);case v:a:{for(l=o.key;r!==null;){if(r.key===l)if(r.tag===4&&r.stateNode.containerInfo===o.containerInfo&&r.stateNode.implementation===o.implementation){n(e,r.sibling),c=a(r,o.children||[]),c.return=e,e=c;break a}else{n(e,r);break}else t(e,r);r=r.sibling}c=bi(o,e.mode,c),c.return=e,e=c}return s(e);case D:return o=Da(o),b(e,r,o,c)}if(ae(o))return h(e,r,o,c);if(ne(o)){if(l=ne(o),typeof l!=`function`)throw Error(i(150));return o=l.call(o),g(e,r,o,c)}if(typeof o.then==`function`)return b(e,r,Na(o),c);if(o.$$typeof===C)return b(e,r,ia(e,o),c);Fa(e,o)}return typeof o==`string`&&o!==``||typeof o==`number`||typeof o==`bigint`?(o=``+o,r!==null&&r.tag===6?(n(e,r.sibling),c=a(r,o),c.return=e,e=c):(n(e,r),c=vi(o,e.mode,c),c.return=e,e=c),s(e)):n(e,r)}return function(e,t,n,r){try{Ma=0;var i=b(e,t,n,r);return ja=null,i}catch(t){if(t===Ca||t===Ta)throw t;var a=fi(29,t,null,e.mode);return a.lanes=r,a.return=e,a}}}var La=Ia(!0),Ra=Ia(!1),za=!1;function Ba(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function Va(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,callbacks:null})}function Ha(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function Ua(e,t,n){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,G&2){var i=r.pending;return i===null?t.next=t:(t.next=i.next,i.next=t),r.pending=t,t=li(e),ci(e,null,n),t}return ai(e,r,t,n),li(e)}function Wa(e,t,n){if(t=t.updateQueue,t!==null&&(t=t.shared,n&4194048)){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,rt(e,n)}}function Ga(e,t){var n=e.updateQueue,r=e.alternate;if(r!==null&&(r=r.updateQueue,n===r)){var i=null,a=null;if(n=n.firstBaseUpdate,n!==null){do{var o={lane:n.lane,tag:n.tag,payload:n.payload,callback:null,next:null};a===null?i=a=o:a=a.next=o,n=n.next}while(n!==null);a===null?i=a=t:a=a.next=t}else i=a=t;n={baseState:r.baseState,firstBaseUpdate:i,lastBaseUpdate:a,shared:r.shared,callbacks:r.callbacks},e.updateQueue=n;return}e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}var Ka=!1;function qa(){if(Ka){var e=ma;if(e!==null)throw e}}function Ja(e,t,n,r){Ka=!1;var i=e.updateQueue;za=!1;var a=i.firstBaseUpdate,o=i.lastBaseUpdate,s=i.shared.pending;if(s!==null){i.shared.pending=null;var c=s,l=c.next;c.next=null,o===null?a=l:o.next=l,o=c;var u=e.alternate;u!==null&&(u=u.updateQueue,s=u.lastBaseUpdate,s!==o&&(s===null?u.firstBaseUpdate=l:s.next=l,u.lastBaseUpdate=c))}if(a!==null){var d=i.baseState;o=0,u=l=c=null,s=a;do{var f=s.lane&-536870913,p=f!==s.lane;if(p?(q&f)===f:(r&f)===f){f!==0&&f===pa&&(Ka=!0),u!==null&&(u=u.next={lane:0,tag:s.tag,payload:s.payload,callback:null,next:null});a:{var h=e,g=s;f=t;var _=n;switch(g.tag){case 1:if(h=g.payload,typeof h==`function`){d=h.call(_,d,f);break a}d=h;break a;case 3:h.flags=h.flags&-65537|128;case 0:if(h=g.payload,f=typeof h==`function`?h.call(_,d,f):h,f==null)break a;d=m({},d,f);break a;case 2:za=!0}}f=s.callback,f!==null&&(e.flags|=64,p&&(e.flags|=8192),p=i.callbacks,p===null?i.callbacks=[f]:p.push(f))}else p={lane:f,tag:s.tag,payload:s.payload,callback:s.callback,next:null},u===null?(l=u=p,c=d):u=u.next=p,o|=f;if(s=s.next,s===null){if(s=i.shared.pending,s===null)break;p=s,s=p.next,p.next=null,i.lastBaseUpdate=p,i.shared.pending=null}}while(1);u===null&&(c=d),i.baseState=c,i.firstBaseUpdate=l,i.lastBaseUpdate=u,a===null&&(i.shared.lanes=0),Kl|=o,e.lanes=o,e.memoizedState=d}}function Ya(e,t){if(typeof e!=`function`)throw Error(i(191,e));e.call(t)}function Xa(e,t){var n=e.callbacks;if(n!==null)for(e.callbacks=null,e=0;ea?a:8;var o=A.T,s={};A.T=s,Fs(e,!1,t,n);try{var c=i(),l=A.S;l!==null&&l(s,c),typeof c==`object`&&c&&typeof c.then==`function`?Ps(e,t,_a(c,r),pu(e)):Ps(e,t,r,pu(e))}catch(n){Ps(e,t,{then:function(){},status:`rejected`,reason:n},pu())}finally{j.p=a,o!==null&&s.types!==null&&(o.types=s.types),A.T=o}}function ws(){}function Ts(e,t,n,r){if(e.tag!==5)throw Error(i(476));var a=Es(e).queue;Cs(e,a,t,oe,n===null?ws:function(){return Ds(e),n(r)})}function Es(e){var t=e.memoizedState;if(t!==null)return t;t={memoizedState:oe,baseState:oe,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Io,lastRenderedState:oe},next:null};var n={};return t.next={memoizedState:n,baseState:n,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Io,lastRenderedState:n},next:null},e.memoizedState=t,e=e.alternate,e!==null&&(e.memoizedState=t),t}function Ds(e){var t=Es(e);t.next===null&&(t=e.alternate.memoizedState),Ps(e,t.next.queue,{},pu())}function Os(){return ra(Qf)}function ks(){return jo().memoizedState}function As(){return jo().memoizedState}function js(e){for(var t=e.return;t!==null;){switch(t.tag){case 24:case 3:var n=pu();e=Ha(n);var r=Ua(t,e,n);r!==null&&(hu(r,t,n),Wa(r,t,n)),t={cache:la()},e.payload=t;return}t=t.return}}function Ms(e,t,n){var r=pu();n={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null},Is(e)?Ls(t,n):(n=oi(e,t,n,r),n!==null&&(hu(n,e,r),Rs(n,t,r)))}function Ns(e,t,n){Ps(e,t,n,pu())}function Ps(e,t,n,r){var i={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null};if(Is(e))Ls(t,i);else{var a=e.alternate;if(e.lanes===0&&(a===null||a.lanes===0)&&(a=t.lastRenderedReducer,a!==null))try{var o=t.lastRenderedState,s=a(o,n);if(i.hasEagerState=!0,i.eagerState=s,Er(s,o))return ai(e,t,i,0),Bl===null&&ii(),!1}catch{}if(n=oi(e,t,i,r),n!==null)return hu(n,e,r),Rs(n,t,r),!0}return!1}function Fs(e,t,n,r){if(r={lane:2,revertLane:dd(),gesture:null,action:r,hasEagerState:!1,eagerState:null,next:null},Is(e)){if(t)throw Error(i(479))}else t=oi(e,n,r,2),t!==null&&hu(t,e,2)}function Is(e){var t=e.alternate;return e===V||t!==null&&t===V}function Ls(e,t){ho=mo=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function Rs(e,t,n){if(n&4194048){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,rt(e,n)}}var zs={readContext:ra,use:Po,useCallback:xo,useContext:xo,useEffect:xo,useImperativeHandle:xo,useLayoutEffect:xo,useInsertionEffect:xo,useMemo:xo,useReducer:xo,useRef:xo,useState:xo,useDebugValue:xo,useDeferredValue:xo,useTransition:xo,useSyncExternalStore:xo,useId:xo,useHostTransitionStatus:xo,useFormState:xo,useActionState:xo,useOptimistic:xo,useMemoCache:xo,useCacheRefresh:xo};zs.useEffectEvent=xo;var Bs={readContext:ra,use:Po,useCallback:function(e,t){return Ao().memoizedState=[e,t===void 0?null:t],e},useContext:ra,useEffect:us,useImperativeHandle:function(e,t,n){n=n==null?null:n.concat([e]),cs(4194308,4,gs.bind(null,t,e),n)},useLayoutEffect:function(e,t){return cs(4194308,4,e,t)},useInsertionEffect:function(e,t){cs(4,2,e,t)},useMemo:function(e,t){var n=Ao();t=t===void 0?null:t;var r=e();if(go){Be(!0);try{e()}finally{Be(!1)}}return n.memoizedState=[r,t],r},useReducer:function(e,t,n){var r=Ao();if(n!==void 0){var i=n(t);if(go){Be(!0);try{n(t)}finally{Be(!1)}}}else i=t;return r.memoizedState=r.baseState=i,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:i},r.queue=e,e=e.dispatch=Ms.bind(null,V,e),[r.memoizedState,e]},useRef:function(e){var t=Ao();return e={current:e},t.memoizedState=e},useState:function(e){e=Ko(e);var t=e.queue,n=Ns.bind(null,V,t);return t.dispatch=n,[e.memoizedState,n]},useDebugValue:vs,useDeferredValue:function(e,t){return xs(Ao(),e,t)},useTransition:function(){var e=Ko(!1);return e=Cs.bind(null,V,e.queue,!0,!1),Ao().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,t,n){var r=V,a=Ao();if(F){if(n===void 0)throw Error(i(407));n=n()}else{if(n=t(),Bl===null)throw Error(i(349));q&127||Vo(r,t,n)}a.memoizedState=n;var o={value:n,getSnapshot:t};return a.queue=o,us(Uo.bind(null,r,o,e),[e]),r.flags|=2048,os(9,{destroy:void 0},Ho.bind(null,r,o,n,t),null),n},useId:function(){var e=Ao(),t=Bl.identifierPrefix;if(F){var n=ji,r=Ai;n=(r&~(1<<32-Ve(r)-1)).toString(32)+n,t=`_`+t+`R_`+n,n=_o++,0<\/script>`,o=o.removeChild(o.firstChild);break;case`select`:o=typeof r.is==`string`?s.createElement(`select`,{is:r.is}):s.createElement(`select`),r.multiple?o.multiple=!0:r.size&&(o.size=r.size);break;default:o=typeof r.is==`string`?s.createElement(a,{is:r.is}):s.createElement(a)}}o[ut]=t,o[dt]=r;a:for(s=t.child;s!==null;){if(s.tag===5||s.tag===6)o.appendChild(s.stateNode);else if(s.tag!==4&&s.tag!==27&&s.child!==null){s.child.return=s,s=s.child;continue}if(s===t)break a;for(;s.sibling===null;){if(s.return===null||s.return===t)break a;s=s.return}s.sibling.return=s.return,s=s.sibling}t.stateNode=o;a:switch(Pd(o,a,r),a){case`button`:case`input`:case`select`:case`textarea`:r=!!r.autoFocus;break a;case`img`:r=!0;break a;default:r=!1}r&&Pc(t)}}return W(t),U(t,t.type,e===null?null:e.memoizedProps,t.pendingProps,n),null;case 6:if(e&&t.stateNode!=null)e.memoizedProps!==r&&Pc(t);else{if(typeof r!=`string`&&t.stateNode===null)throw Error(i(166));if(e=de.current,Wi(t)){if(e=t.stateNode,n=t.memoizedProps,r=null,a=Li,a!==null)switch(a.tag){case 27:case 5:r=a.memoizedProps}e[ut]=t,e=!!(e.nodeValue===n||r!==null&&!0===r.suppressHydrationWarning||Md(e.nodeValue,n)),e||I(t,!0)}else e=Bd(e).createTextNode(r),e[ut]=t,t.stateNode=e}return W(t),null;case 31:if(n=t.memoizedState,e===null||e.memoizedState!==null){if(r=Wi(t),n!==null){if(e===null){if(!r)throw Error(i(318));if(e=t.memoizedState,e=e===null?null:e.dehydrated,!e)throw Error(i(557));e[ut]=t}else Gi(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;W(t),e=!1}else n=Ki(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=n),e=!0;if(!e)return t.flags&256?(co(t),t):(co(t),null);if(t.flags&128)throw Error(i(558))}return W(t),null;case 13:if(r=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(a=Wi(t),r!==null&&r.dehydrated!==null){if(e===null){if(!a)throw Error(i(318));if(a=t.memoizedState,a=a===null?null:a.dehydrated,!a)throw Error(i(317));a[ut]=t}else Gi(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;W(t),a=!1}else a=Ki(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=a),a=!0;if(!a)return t.flags&256?(co(t),t):(co(t),null)}return co(t),t.flags&128?(t.lanes=n,t):(n=r!==null,e=e!==null&&e.memoizedState!==null,n&&(r=t.child,a=null,r.alternate!==null&&r.alternate.memoizedState!==null&&r.alternate.memoizedState.cachePool!==null&&(a=r.alternate.memoizedState.cachePool.pool),o=null,r.memoizedState!==null&&r.memoizedState.cachePool!==null&&(o=r.memoizedState.cachePool.pool),o!==a&&(r.flags|=2048)),n!==e&&n&&(t.child.flags|=8192),Ic(t,t.updateQueue),W(t),null);case 4:return me(),e===null&&Sd(t.stateNode.containerInfo),W(t),null;case 10:return Qi(t.type),W(t),null;case 19:if(N(lo),r=t.memoizedState,r===null)return W(t),null;if(a=(t.flags&128)!=0,o=r.rendering,o===null)if(a)Lc(r,!1);else{if(Y!==0||e!==null&&e.flags&128)for(e=t.child;e!==null;){if(o=uo(e),o!==null){for(t.flags|=128,Lc(r,!1),e=o.updateQueue,t.updateQueue=e,Ic(t,e),t.subtreeFlags=0,e=n,n=t.child;n!==null;)hi(n,e),n=n.sibling;return P(lo,lo.current&1|2),F&&Mi(t,r.treeForkCount),t.child}e=e.sibling}r.tail!==null&&ke()>nu&&(t.flags|=128,a=!0,Lc(r,!1),t.lanes=4194304)}else{if(!a)if(e=uo(o),e!==null){if(t.flags|=128,a=!0,e=e.updateQueue,t.updateQueue=e,Ic(t,e),Lc(r,!0),r.tail===null&&r.tailMode===`hidden`&&!o.alternate&&!F)return W(t),null}else 2*ke()-r.renderingStartTime>nu&&n!==536870912&&(t.flags|=128,a=!0,Lc(r,!1),t.lanes=4194304);r.isBackwards?(o.sibling=t.child,t.child=o):(e=r.last,e===null?t.child=o:e.sibling=o,r.last=o)}return r.tail===null?(W(t),null):(e=r.tail,r.rendering=e,r.tail=e.sibling,r.renderingStartTime=ke(),e.sibling=null,n=lo.current,P(lo,a?n&1|2:n&1),F&&Mi(t,r.treeForkCount),e);case 22:case 23:return co(t),to(),r=t.memoizedState!==null,e===null?r&&(t.flags|=8192):e.memoizedState!==null!==r&&(t.flags|=8192),r?n&536870912&&!(t.flags&128)&&(W(t),t.subtreeFlags&6&&(t.flags|=8192)):W(t),n=t.updateQueue,n!==null&&Ic(t,n.retryQueue),n=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(n=e.memoizedState.cachePool.pool),r=null,t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(r=t.memoizedState.cachePool.pool),r!==n&&(t.flags|=2048),e!==null&&N(ya),null;case 24:return n=null,e!==null&&(n=e.memoizedState.cache),t.memoizedState.cache!==n&&(t.flags|=2048),Qi(ca),W(t),null;case 25:return null;case 30:return null}throw Error(i(156,t.tag))}function zc(e,t){switch(Fi(t),t.tag){case 1:return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return Qi(ca),me(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 26:case 27:case 5:return ge(t),null;case 31:if(t.memoizedState!==null){if(co(t),t.alternate===null)throw Error(i(340));Gi()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 13:if(co(t),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(i(340));Gi()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return N(lo),null;case 4:return me(),null;case 10:return Qi(t.type),null;case 22:case 23:return co(t),to(),e!==null&&N(ya),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 24:return Qi(ca),null;case 25:return null;default:return null}}function Bc(e,t){switch(Fi(t),t.tag){case 3:Qi(ca),me();break;case 26:case 27:case 5:ge(t);break;case 4:me();break;case 31:t.memoizedState!==null&&co(t);break;case 13:co(t);break;case 19:N(lo);break;case 10:Qi(t.type);break;case 22:case 23:co(t),to(),e!==null&&N(ya);break;case 24:Qi(ca)}}function Vc(e,t){try{var n=t.updateQueue,r=n===null?null:n.lastEffect;if(r!==null){var i=r.next;n=i;do{if((n.tag&e)===e){r=void 0;var a=n.create,o=n.inst;r=a(),o.destroy=r}n=n.next}while(n!==i)}}catch(e){Z(t,t.return,e)}}function Hc(e,t,n){try{var r=t.updateQueue,i=r===null?null:r.lastEffect;if(i!==null){var a=i.next;r=a;do{if((r.tag&e)===e){var o=r.inst,s=o.destroy;if(s!==void 0){o.destroy=void 0,i=t;var c=n,l=s;try{l()}catch(e){Z(i,c,e)}}}r=r.next}while(r!==a)}}catch(e){Z(t,t.return,e)}}function Uc(e){var t=e.updateQueue;if(t!==null){var n=e.stateNode;try{Xa(t,n)}catch(t){Z(e,e.return,t)}}}function Wc(e,t,n){n.props=qs(e.type,e.memoizedProps),n.state=e.memoizedState;try{n.componentWillUnmount()}catch(n){Z(e,t,n)}}function Gc(e,t){try{var n=e.ref;if(n!==null){switch(e.tag){case 26:case 27:case 5:var r=e.stateNode;break;case 30:r=e.stateNode;break;default:r=e.stateNode}typeof n==`function`?e.refCleanup=n(r):n.current=r}}catch(n){Z(e,t,n)}}function Kc(e,t){var n=e.ref,r=e.refCleanup;if(n!==null)if(typeof r==`function`)try{r()}catch(n){Z(e,t,n)}finally{e.refCleanup=null,e=e.alternate,e!=null&&(e.refCleanup=null)}else if(typeof n==`function`)try{n(null)}catch(n){Z(e,t,n)}else n.current=null}function qc(e){var t=e.type,n=e.memoizedProps,r=e.stateNode;try{a:switch(t){case`button`:case`input`:case`select`:case`textarea`:n.autoFocus&&r.focus();break a;case`img`:n.src?r.src=n.src:n.srcSet&&(r.srcset=n.srcSet)}}catch(t){Z(e,e.return,t)}}function Jc(e,t,n){try{var r=e.stateNode;Fd(r,e.type,n,t),r[dt]=t}catch(t){Z(e,e.return,t)}}function Yc(e){return e.tag===5||e.tag===3||e.tag===26||e.tag===27&&Zd(e.type)||e.tag===4}function Xc(e){a:for(;;){for(;e.sibling===null;){if(e.return===null||Yc(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.tag===27&&Zd(e.type)||e.flags&2||e.child===null||e.tag===4)continue a;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function Zc(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?(n.nodeType===9?n.body:n.nodeName===`HTML`?n.ownerDocument.body:n).insertBefore(e,t):(t=n.nodeType===9?n.body:n.nodeName===`HTML`?n.ownerDocument.body:n,t.appendChild(e),n=n._reactRootContainer,n!=null||t.onclick!==null||(t.onclick=rn));else if(r!==4&&(r===27&&Zd(e.type)&&(n=e.stateNode,t=null),e=e.child,e!==null))for(Zc(e,t,n),e=e.sibling;e!==null;)Zc(e,t,n),e=e.sibling}function Qc(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(r!==4&&(r===27&&Zd(e.type)&&(n=e.stateNode),e=e.child,e!==null))for(Qc(e,t,n),e=e.sibling;e!==null;)Qc(e,t,n),e=e.sibling}function $c(e){var t=e.stateNode,n=e.memoizedProps;try{for(var r=e.type,i=t.attributes;i.length;)t.removeAttributeNode(i[0]);Pd(t,r,n),t[ut]=e,t[dt]=n}catch(t){Z(e,e.return,t)}}var el=!1,tl=!1,nl=!1,rl=typeof WeakSet==`function`?WeakSet:Set,il=null;function al(e,t){if(e=e.containerInfo,Rd=sp,e=jr(e),Mr(e)){if(`selectionStart`in e)var n={start:e.selectionStart,end:e.selectionEnd};else a:{n=(n=e.ownerDocument)&&n.defaultView||window;var r=n.getSelection&&n.getSelection();if(r&&r.rangeCount!==0){n=r.anchorNode;var a=r.anchorOffset,o=r.focusNode;r=r.focusOffset;try{n.nodeType,o.nodeType}catch{n=null;break a}var s=0,c=-1,l=-1,u=0,d=0,f=e,p=null;b:for(;;){for(var m;f!==n||a!==0&&f.nodeType!==3||(c=s+a),f!==o||r!==0&&f.nodeType!==3||(l=s+r),f.nodeType===3&&(s+=f.nodeValue.length),(m=f.firstChild)!==null;)p=f,f=m;for(;;){if(f===e)break b;if(p===n&&++u===a&&(c=s),p===o&&++d===r&&(l=s),(m=f.nextSibling)!==null)break;f=p,p=f.parentNode}f=m}n=c===-1||l===-1?null:{start:c,end:l}}else n=null}n||={start:0,end:0}}else n=null;for(zd={focusedElem:e,selectionRange:n},sp=!1,il=t;il!==null;)if(t=il,e=t.child,t.subtreeFlags&1028&&e!==null)e.return=t,il=e;else for(;il!==null;){switch(t=il,o=t.alternate,e=t.flags,t.tag){case 0:if(e&4&&(e=t.updateQueue,e=e===null?null:e.events,e!==null))for(n=0;n title`))),Pd(o,r,n),o[ut]=e,Ct(o),r=o;break a;case`link`:var s=Vf(`link`,`href`,a).get(r+(n.href||``));if(s){for(var c=0;cg&&(o=g,g=h,h=o);var _=kr(s,h),v=kr(s,g);if(_&&v&&(p.rangeCount!==1||p.anchorNode!==_.node||p.anchorOffset!==_.offset||p.focusNode!==v.node||p.focusOffset!==v.offset)){var y=d.createRange();y.setStart(_.node,_.offset),p.removeAllRanges(),h>g?(p.addRange(y),p.extend(v.node,v.offset)):(y.setEnd(v.node,v.offset),p.addRange(y))}}}}for(d=[],p=s;p=p.parentNode;)p.nodeType===1&&d.push({element:p,left:p.scrollLeft,top:p.scrollTop});for(typeof s.focus==`function`&&s.focus(),s=0;sn?32:n,A.T=null,n=uu,uu=null;var o=ou,s=cu;if(au=0,su=ou=null,cu=0,G&6)throw Error(i(331));var c=G;if(G|=4,Fl(o.current),Dl(o,o.current,s,n),G=c,id(0,!1),ze&&typeof ze.onPostCommitFiberRoot==`function`)try{ze.onPostCommitFiberRoot(Re,o)}catch{}return!0}finally{j.p=a,A.T=r,Vu(e,t)}}function Wu(e,t,n){t=Si(n,t),t=$s(e.stateNode,t,2),e=Ua(e,t,2),e!==null&&(et(e,2),rd(e))}function Z(e,t,n){if(e.tag===3)Wu(e,e,n);else for(;t!==null;){if(t.tag===3){Wu(t,e,n);break}else if(t.tag===1){var r=t.stateNode;if(typeof t.type.getDerivedStateFromError==`function`||typeof r.componentDidCatch==`function`&&(iu===null||!iu.has(r))){e=Si(n,e),n=ec(2),r=Ua(t,n,2),r!==null&&(tc(n,r,t,e),et(r,2),rd(r));break}}t=t.return}}function Gu(e,t,n){var r=e.pingCache;if(r===null){r=e.pingCache=new zl;var i=new Set;r.set(t,i)}else i=r.get(t),i===void 0&&(i=new Set,r.set(t,i));i.has(n)||(Wl=!0,i.add(n),e=Ku.bind(null,e,t,n),t.then(e,e))}function Ku(e,t,n){var r=e.pingCache;r!==null&&r.delete(t),e.pingedLanes|=e.suspendedLanes&n,e.warmLanes&=~n,Bl===e&&(q&n)===n&&(Y===4||Y===3&&(q&62914560)===q&&300>ke()-eu?!(G&2)&&Su(e,0):Jl|=n,Xl===q&&(Xl=0)),rd(e)}function qu(e,t){t===0&&(t=Qe()),e=si(e,t),e!==null&&(et(e,t),rd(e))}function Ju(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),qu(e,n)}function Yu(e,t){var n=0;switch(e.tag){case 31:case 13:var r=e.stateNode,a=e.memoizedState;a!==null&&(n=a.retryLane);break;case 19:r=e.stateNode;break;case 22:r=e.stateNode._retryCache;break;default:throw Error(i(314))}r!==null&&r.delete(t),qu(e,n)}function Xu(e,t){return Te(e,t)}var Zu=null,Qu=null,$u=!1,ed=!1,td=!1,nd=0;function rd(e){e!==Qu&&e.next===null&&(Qu===null?Zu=Qu=e:Qu=Qu.next=e),ed=!0,$u||($u=!0,ud())}function id(e,t){if(!td&&ed){td=!0;do for(var n=!1,r=Zu;r!==null;){if(!t)if(e!==0){var i=r.pendingLanes;if(i===0)var a=0;else{var o=r.suspendedLanes,s=r.pingedLanes;a=(1<<31-Ve(42|e)+1)-1,a&=i&~(o&~s),a=a&201326741?a&201326741|1:a?a|2:0}a!==0&&(n=!0,ld(r,a))}else a=q,a=Ye(r,r===Bl?a:0,r.cancelPendingCommit!==null||r.timeoutHandle!==-1),!(a&3)||Xe(r,a)||(n=!0,ld(r,a));r=r.next}while(n);td=!1}}function ad(){od()}function od(){ed=$u=!1;var e=0;nd!==0&&Gd()&&(e=nd);for(var t=ke(),n=null,r=Zu;r!==null;){var i=r.next,a=sd(r,t);a===0?(r.next=null,n===null?Zu=i:n.next=i,i===null&&(Qu=n)):(n=r,(e!==0||a&3)&&(ed=!0)),r=i}au!==0&&au!==5||id(e,!1),nd!==0&&(nd=0)}function sd(e,t){for(var n=e.suspendedLanes,r=e.pingedLanes,i=e.expirationTimes,a=e.pendingLanes&-62914561;0s)break;var u=c.transferSize,d=c.initiatorType;u&&Id(d)&&(c=c.responseEnd,o+=u*(c`u`?null:document;function xf(e,t,n){var r=bf;if(r&&typeof t==`string`&&t){var i=Ht(t);i=`link[rel="`+e+`"][href="`+i+`"]`,typeof n==`string`&&(i+=`[crossorigin="`+n+`"]`),hf.has(i)||(hf.add(i),e={rel:e,crossOrigin:n,href:t},r.querySelector(i)===null&&(t=r.createElement(`link`),Pd(t,`link`,e),Ct(t),r.head.appendChild(t)))}}function Sf(e){_f.D(e),xf(`dns-prefetch`,e,null)}function Cf(e,t){_f.C(e,t),xf(`preconnect`,e,t)}function wf(e,t,n){_f.L(e,t,n);var r=bf;if(r&&e&&t){var i=`link[rel="preload"][as="`+Ht(t)+`"]`;t===`image`&&n&&n.imageSrcSet?(i+=`[imagesrcset="`+Ht(n.imageSrcSet)+`"]`,typeof n.imageSizes==`string`&&(i+=`[imagesizes="`+Ht(n.imageSizes)+`"]`)):i+=`[href="`+Ht(e)+`"]`;var a=i;switch(t){case`style`:a=Af(e);break;case`script`:a=Pf(e)}mf.has(a)||(e=m({rel:`preload`,href:t===`image`&&n&&n.imageSrcSet?void 0:e,as:t},n),mf.set(a,e),r.querySelector(i)!==null||t===`style`&&r.querySelector(jf(a))||t===`script`&&r.querySelector(Ff(a))||(t=r.createElement(`link`),Pd(t,`link`,e),Ct(t),r.head.appendChild(t)))}}function Tf(e,t){_f.m(e,t);var n=bf;if(n&&e){var r=t&&typeof t.as==`string`?t.as:`script`,i=`link[rel="modulepreload"][as="`+Ht(r)+`"][href="`+Ht(e)+`"]`,a=i;switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:a=Pf(e)}if(!mf.has(a)&&(e=m({rel:`modulepreload`,href:e},t),mf.set(a,e),n.querySelector(i)===null)){switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:if(n.querySelector(Ff(a)))return}r=n.createElement(`link`),Pd(r,`link`,e),Ct(r),n.head.appendChild(r)}}}function Ef(e,t,n){_f.S(e,t,n);var r=bf;if(r&&e){var i=St(r).hoistableStyles,a=Af(e);t||=`default`;var o=i.get(a);if(!o){var s={loading:0,preload:null};if(o=r.querySelector(jf(a)))s.loading=5;else{e=m({rel:`stylesheet`,href:e,"data-precedence":t},n),(n=mf.get(a))&&Rf(e,n);var c=o=r.createElement(`link`);Ct(c),Pd(c,`link`,e),c._p=new Promise(function(e,t){c.onload=e,c.onerror=t}),c.addEventListener(`load`,function(){s.loading|=1}),c.addEventListener(`error`,function(){s.loading|=2}),s.loading|=4,Lf(o,t,r)}o={type:`stylesheet`,instance:o,count:1,state:s},i.set(a,o)}}}function Df(e,t){_f.X(e,t);var n=bf;if(n&&e){var r=St(n).hoistableScripts,i=Pf(e),a=r.get(i);a||(a=n.querySelector(Ff(i)),a||(e=m({src:e,async:!0},t),(t=mf.get(i))&&zf(e,t),a=n.createElement(`script`),Ct(a),Pd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function Of(e,t){_f.M(e,t);var n=bf;if(n&&e){var r=St(n).hoistableScripts,i=Pf(e),a=r.get(i);a||(a=n.querySelector(Ff(i)),a||(e=m({src:e,async:!0,type:`module`},t),(t=mf.get(i))&&zf(e,t),a=n.createElement(`script`),Ct(a),Pd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function kf(e,t,n,r){var a=(a=de.current)?gf(a):null;if(!a)throw Error(i(446));switch(e){case`meta`:case`title`:return null;case`style`:return typeof n.precedence==`string`&&typeof n.href==`string`?(t=Af(n.href),n=St(a).hoistableStyles,r=n.get(t),r||(r={type:`style`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};case`link`:if(n.rel===`stylesheet`&&typeof n.href==`string`&&typeof n.precedence==`string`){e=Af(n.href);var o=St(a).hoistableStyles,s=o.get(e);if(s||(a=a.ownerDocument||a,s={type:`stylesheet`,instance:null,count:0,state:{loading:0,preload:null}},o.set(e,s),(o=a.querySelector(jf(e)))&&!o._p&&(s.instance=o,s.state.loading=5),mf.has(e)||(n={rel:`preload`,as:`style`,href:n.href,crossOrigin:n.crossOrigin,integrity:n.integrity,media:n.media,hrefLang:n.hrefLang,referrerPolicy:n.referrerPolicy},mf.set(e,n),o||Nf(a,e,n,s.state))),t&&r===null)throw Error(i(528,``));return s}if(t&&r!==null)throw Error(i(529,``));return null;case`script`:return t=n.async,n=n.src,typeof n==`string`&&t&&typeof t!=`function`&&typeof t!=`symbol`?(t=Pf(n),n=St(a).hoistableScripts,r=n.get(t),r||(r={type:`script`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};default:throw Error(i(444,e))}}function Af(e){return`href="`+Ht(e)+`"`}function jf(e){return`link[rel="stylesheet"][`+e+`]`}function Mf(e){return m({},e,{"data-precedence":e.precedence,precedence:null})}function Nf(e,t,n,r){e.querySelector(`link[rel="preload"][as="style"][`+t+`]`)?r.loading=1:(t=e.createElement(`link`),r.preload=t,t.addEventListener(`load`,function(){return r.loading|=1}),t.addEventListener(`error`,function(){return r.loading|=2}),Pd(t,`link`,n),Ct(t),e.head.appendChild(t))}function Pf(e){return`[src="`+Ht(e)+`"]`}function Ff(e){return`script[async]`+e}function If(e,t,n){if(t.count++,t.instance===null)switch(t.type){case`style`:var r=e.querySelector(`style[data-href~="`+Ht(n.href)+`"]`);if(r)return t.instance=r,Ct(r),r;var a=m({},n,{"data-href":n.href,"data-precedence":n.precedence,href:null,precedence:null});return r=(e.ownerDocument||e).createElement(`style`),Ct(r),Pd(r,`style`,a),Lf(r,n.precedence,e),t.instance=r;case`stylesheet`:a=Af(n.href);var o=e.querySelector(jf(a));if(o)return t.state.loading|=4,t.instance=o,Ct(o),o;r=Mf(n),(a=mf.get(a))&&Rf(r,a),o=(e.ownerDocument||e).createElement(`link`),Ct(o);var s=o;return s._p=new Promise(function(e,t){s.onload=e,s.onerror=t}),Pd(o,`link`,r),t.state.loading|=4,Lf(o,n.precedence,e),t.instance=o;case`script`:return o=Pf(n.src),(a=e.querySelector(Ff(o)))?(t.instance=a,Ct(a),a):(r=n,(a=mf.get(o))&&(r=m({},n),zf(r,a)),e=e.ownerDocument||e,a=e.createElement(`script`),Ct(a),Pd(a,`link`,r),e.head.appendChild(a),t.instance=a);case`void`:return null;default:throw Error(i(443,t.type))}else t.type===`stylesheet`&&!(t.state.loading&4)&&(r=t.instance,t.state.loading|=4,Lf(r,n.precedence,e));return t.instance}function Lf(e,t,n){for(var r=n.querySelectorAll(`link[rel="stylesheet"][data-precedence],style[data-precedence]`),i=r.length?r[r.length-1]:null,a=i,o=0;o title`):null)}function Uf(e,t,n){if(n===1||t.itemProp!=null)return!1;switch(e){case`meta`:case`title`:return!0;case`style`:if(typeof t.precedence!=`string`||typeof t.href!=`string`||t.href===``)break;return!0;case`link`:if(typeof t.rel!=`string`||typeof t.href!=`string`||t.href===``||t.onLoad||t.onError)break;switch(t.rel){case`stylesheet`:return e=t.disabled,typeof t.precedence==`string`&&e==null;default:return!0}case`script`:if(t.async&&typeof t.async!=`function`&&typeof t.async!=`symbol`&&!t.onLoad&&!t.onError&&t.src&&typeof t.src==`string`)return!0}return!1}function Wf(e){return!(e.type===`stylesheet`&&!(e.state.loading&3))}function Gf(e,t,n,r){if(n.type===`stylesheet`&&(typeof r.media!=`string`||!1!==matchMedia(r.media).matches)&&!(n.state.loading&4)){if(n.instance===null){var i=Af(r.href),a=t.querySelector(jf(i));if(a){t=a._p,typeof t==`object`&&t&&typeof t.then==`function`&&(e.count++,e=Jf.bind(e),t.then(e,e)),n.state.loading|=4,n.instance=a,Ct(a);return}a=t.ownerDocument||t,r=Mf(r),(i=mf.get(i))&&Rf(r,i),a=a.createElement(`link`),Ct(a);var o=a;o._p=new Promise(function(e,t){o.onload=e,o.onerror=t}),Pd(a,`link`,r),n.instance=a}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(n,t),(t=n.state.preload)&&!(n.state.loading&3)&&(e.count++,n=Jf.bind(e),t.addEventListener(`load`,n),t.addEventListener(`error`,n))}}var Kf=0;function qf(e,t){return e.stylesheets&&e.count===0&&Xf(e,e.stylesheets),0Kf?50:800)+t);return e.unsuspend=n,function(){e.unsuspend=null,clearTimeout(r),clearTimeout(i)}}:null}function Jf(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)Xf(this,this.stylesheets);else if(this.unsuspend){var e=this.unsuspend;this.unsuspend=null,e()}}}var Yf=null;function Xf(e,t){e.stylesheets=null,e.unsuspend!==null&&(e.count++,Yf=new Map,t.forEach(Zf,e),Yf=null,Jf.call(e))}function Zf(e,t){if(!(t.state.loading&4)){var n=Yf.get(e);if(n)var r=n.get(null);else{n=new Map,Yf.set(e,n);for(var i=e.querySelectorAll(`link[data-precedence],style[data-precedence]`),a=0;a{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=g()})),v=l(d(),1),y=_(),b=`modulepreload`,x=function(e){return`/`+e},S={},C=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}function s(e){return import.meta.resolve?import.meta.resolve(e):new URL(e,new URL(`../../../src/node/plugins/importAnalysisBuild.ts`,import.meta.url)).href}r=o(t.map(t=>{if(t=x(t,n),t=s(t),t in S)return;S[t]=!0;let r=t.endsWith(`.css`);for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}let i=document.createElement(`link`);if(i.rel=r?`stylesheet`:b,r||(i.as=`script`),i.crossOrigin=``,i.href=t,a&&i.setAttribute(`nonce`,a),document.head.appendChild(i),r)return new Promise((e,n)=>{i.addEventListener(`load`,e),i.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})},w=/^(?:[a-z][a-z0-9+.-]*:|[\\/]{2})/i,T=/^[\\/]{2}/;function E(e,t){return t+e.replace(/\\/g,`/`)}var ee=`popstate`;function D(e){return typeof e==`object`&&!!e&&`pathname`in e&&`search`in e&&`hash`in e&&`state`in e&&`key`in e}function te(e={}){function t(e,t){let n=t.state?.masked,{pathname:r,search:i,hash:a}=n||e.location;return ie(``,{pathname:r,search:i,hash:a},t.state&&t.state.usr||null,t.state&&t.state.key||`default`,n?{pathname:e.location.pathname,search:e.location.search,hash:e.location.hash}:void 0)}function n(e,t){return typeof t==`string`?t:ae(t)}return j(t,n,null,e)}function O(e,t){if(e===!1||e==null)throw Error(t)}function k(e,t){if(!e){typeof console<`u`&&console.warn(t);try{throw Error(t)}catch{}}}function ne(){return Math.random().toString(36).substring(2,10)}function re(e,t){return{usr:e.state,key:e.key,idx:t,masked:e.mask?{pathname:e.pathname,search:e.search,hash:e.hash}:void 0}}function ie(e,t,n=null,r,i){return{pathname:typeof e==`string`?e:e.pathname,search:``,hash:``,...typeof t==`string`?A(t):t,state:n,key:t&&t.key||r||ne(),mask:i}}function ae({pathname:e=`/`,search:t=``,hash:n=``}){return t&&t!==`?`&&(e+=t.charAt(0)===`?`?t:`?`+t),n&&n!==`#`&&(e+=n.charAt(0)===`#`?n:`#`+n),e}function A(e){let t={};if(e){let n=e.indexOf(`#`);n>=0&&(t.hash=e.substring(n),e=e.substring(0,n));let r=e.indexOf(`?`);r>=0&&(t.search=e.substring(r),e=e.substring(0,r)),e&&(t.pathname=e)}return t}function j(e,t,n,r={}){let{window:i=document.defaultView,v5Compat:a=!1}=r,o=i.history,s=`POP`,c=null,l=u();l??(l=0,o.replaceState({...o.state,idx:l},``));function u(){return(o.state||{idx:null}).idx}function d(){s=`POP`;let e=u(),t=e==null?null:e-l;l=e,c&&c({action:s,location:h.location,delta:t})}function f(e,t){s=`PUSH`;let r=D(e)?e:ie(h.location,e,t);n&&n(r,e),l=u()+1;let d=re(r,l),f=h.createHref(r.mask||r);try{o.pushState(d,``,f)}catch(e){if(e instanceof DOMException&&e.name===`DataCloneError`)throw e;i.location.assign(f)}a&&c&&c({action:s,location:h.location,delta:1})}function p(e,t){s=`REPLACE`;let r=D(e)?e:ie(h.location,e,t);n&&n(r,e),l=u();let i=re(r,l),d=h.createHref(r.mask||r);o.replaceState(i,``,d),a&&c&&c({action:s,location:h.location,delta:0})}function m(e){return oe(i,e)}let h={get action(){return s},get location(){return e(i,o)},listen(e){if(c)throw Error(`A history only accepts one active listener`);return i.addEventListener(ee,d),c=e,()=>{i.removeEventListener(ee,d),c=null}},createHref(e){return t(i,e)},createURL:m,encodeLocation(e){let t=m(e);return{pathname:t.pathname,search:t.search,hash:t.hash}},push:f,replace:p,go(e){return o.go(e)}};return h}function oe(e,t,n=!1){let r=`http://localhost`;e&&(r=e.location.origin===`null`?e.location.href:e.location.origin),O(r,`No window.location.(origin|href) available to create URL`);let i=typeof t==`string`?t:ae(t);return i=i.replace(/ $/,`%20`),!n&&T.test(i)&&(i=r+i),new URL(i,r)}function se(e,t,n=`/`){return ce(e,t,n,!1)}function ce(e,t,n,r,i){let a=Te((typeof t==`string`?A(t):t).pathname||`/`,n);if(a==null)return null;let o=i??N(e),s=null,c=we(a);for(let e=0;s==null&&e{let c={relativePath:s===void 0?e.path||``:s,caseSensitive:e.caseSensitive===!0,childrenIndex:a,route:e};if(c.relativePath.startsWith(`/`)){if(!c.relativePath.startsWith(r)&&o)return;O(c.relativePath.startsWith(r),`Absolute route path "${c.relativePath}" nested under path "${r}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`),c.relativePath=c.relativePath.slice(r.length)}let l=Ne([r,c.relativePath]),u=n.concat(c);e.children&&e.children.length>0&&(O(e.index!==!0,`Index routes must not have child routes. Please remove all child routes from route path "${l}".`),P(e.children,t,u,l,o)),!(e.path==null&&!e.index)&&t.push({path:l,score:ve(l,e.index),routesMeta:u.map((e,t)=>{let[n,r]=Ce(e.relativePath,e.caseSensitive,t===u.length-1);return{...e,matcher:n,compiledParams:r}})})};return e.forEach((e,t)=>{if(e.path===``||!e.path?.includes(`?`))a(e,t);else for(let n of le(e.path))a(e,t,!0,n)}),t}function le(e){let t=e.split(`/`);if(t.length===0)return[];let[n,...r]=t,i=n.endsWith(`?`),a=n.replace(/\?$/,``);if(r.length===0)return i?[a,``]:[a];let o=le(r.join(`/`)),s=[];return s.push(...o.map(e=>e===``?a:[a,e].join(`/`))),i&&s.push(...o),s.map(t=>e.startsWith(`/`)&&t===``?`/`:t)}function ue(e){e.sort((e,t)=>e.score===t.score?ye(e.routesMeta.map(e=>e.childrenIndex),t.routesMeta.map(e=>e.childrenIndex)):t.score-e.score)}var de=/^:[\w-]+$/,fe=3,pe=2,me=1,he=10,ge=-2,_e=e=>e===`*`;function ve(e,t){let n=e.split(`/`),r=n.length;return n.some(_e)&&(r+=ge),t&&(r+=pe),n.filter(e=>!_e(e)).reduce((e,t)=>e+(de.test(t)?fe:t===``?me:he),r)}function ye(e,t){return e.length===t.length&&e.slice(0,-1).every((e,n)=>e===t[n])?e[e.length-1]-t[t.length-1]:0}function be(e,t,n=!1){let{routesMeta:r}=e,i={},a=`/`,o=[];for(let e=0;e{if(t===`*`){let e=s[r]||``;o=Pe(a.slice(0,a.length-e.length),1)}let i=s[r];return n&&!i?e[t]=void 0:e[t]=(i||``).replace(/%2F/g,`/`),e},{}),pathname:a,pathnameBase:o,pattern:e}}function Ce(e,t=!1,n=!0){k(e===`*`||!e.endsWith(`*`)||e.endsWith(`/*`),`Route path "${e}" will be treated as if it were "${e.replace(/\*$/,`/*`)}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${e.replace(/\*$/,`/*`)}".`);let r=[],i=`^`+e.replace(/\/*\*?$/,``).replace(/^\/*/,`/`).replace(/[\\.*+^${}|()[\]]/g,`\\$&`).replace(/\/:([\w-]+)(\?)?/g,(e,t,n,i,a)=>{if(r.push({paramName:t,isOptional:n!=null}),n){let t=a.charAt(i+e.length);return t&&t!==`/`?`/([^\\/]*)`:`(?:/([^\\/]*))?`}return`/([^\\/]+)`}).replace(/\/([\w-]+)\?(\/|$)/g,`(/$1)?$2`);return e.endsWith(`*`)?(r.push({paramName:`*`}),i+=e===`*`||e===`/*`?`(.*)$`:`(?:\\/(.+)|\\/*)$`):n?i+=`\\/*$`:e!==``&&e!==`/`&&(i+=`(?:(?=\\/|$))`),[new RegExp(i,t?void 0:`i`),r]}function we(e){try{return e.split(`/`).map(e=>decodeURIComponent(e).replace(/\//g,`%2F`)).join(`/`)}catch(t){return k(!1,`The URL path "${e}" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${t}).`),e}}function Te(e,t){if(t===`/`)return e;if(!e.toLowerCase().startsWith(t.toLowerCase()))return null;let n=t.endsWith(`/`)?t.length-1:t.length,r=e.charAt(n);return r&&r!==`/`?null:e.slice(n)||`/`}function Ee(e,t=`/`){let{pathname:n,search:r=``,hash:i=``}=typeof e==`string`?A(e):e,a;return n?(n=Me(n),a=n.startsWith(`/`)||n.startsWith(`\\`)?De(n.substring(1),`/`):De(n,t)):a=t,{pathname:a,search:Ie(r),hash:Le(i)}}function De(e,t){let n=Pe(t).split(`/`);return e.split(`/`).forEach(e=>{e===`..`?n.length>1&&n.pop():e!==`.`&&n.push(e)}),n.length>1?n.join(`/`):`/`}function Oe(e,t,n,r){return`Cannot include a '${e}' character in a manually specified \`to.${t}\` field [${JSON.stringify(r)}]. Please separate it out to the \`to.${n}\` field. Alternatively you may provide the full path as a string in and the router will parse it for you.`}function ke(e){return e.filter((e,t)=>t===0||e.route.path&&e.route.path.length>0)}function Ae(e){let t=ke(e);return t.map((e,n)=>n===t.length-1?e.pathname:e.pathnameBase)}function je(e,t,n,r=!1){let i;typeof e==`string`?i=A(e):(i={...e},O(!i.pathname||!i.pathname.includes(`?`),Oe(`?`,`pathname`,`search`,i)),O(!i.pathname||!i.pathname.includes(`#`),Oe(`#`,`pathname`,`hash`,i)),O(!i.search||!i.search.includes(`#`),Oe(`#`,`search`,`hash`,i)));let a=e===``||i.pathname===``,o=a?`/`:i.pathname,s;if(o==null)s=n;else{let e=t.length-1;if(!r&&o.startsWith(`..`)){let t=o.split(`/`);for(;t[0]===`..`;)t.shift(),--e;i.pathname=t.join(`/`)}s=e>=0?t[e]:`/`}let c=Ee(i,s),l=o&&o!==`/`&&o.endsWith(`/`),u=(a||o===`.`)&&n.endsWith(`/`);return!c.pathname.endsWith(`/`)&&(l||u)&&(c.pathname+=`/`),c}var Me=e=>e.replace(/[\\/]{2,}/g,`/`),Ne=e=>Me(e.join(`/`));function Pe(e,t=0){let n=e.length;for(;n>t&&e.charCodeAt(n-1)===47;)n--;return n===e.length?e:e.slice(0,n)}var Fe=e=>Pe(e).replace(/^\/*/,`/`),Ie=e=>!e||e===`?`?``:e.startsWith(`?`)?e:`?`+e,Le=e=>!e||e===`#`?``:e.startsWith(`#`)?e:`#`+e,Re=class{constructor(e,t,n,r=!1){this.status=e,this.statusText=t||``,this.internal=r,n instanceof Error?(this.data=n.toString(),this.error=n):this.data=n}};function ze(e){return e!=null&&typeof e.status==`number`&&typeof e.statusText==`string`&&typeof e.internal==`boolean`&&`data`in e}function Be(e){return Ne(e.map(e=>e.route.path).filter(Boolean))||`/`}var Ve=typeof window<`u`&&window.document!==void 0&&window.document.createElement!==void 0;function He(e,t){let n=e;if(typeof n!=`string`||!w.test(n))return{absoluteURL:void 0,isExternal:!1,to:n};let r=n,i=!1;if(Ve)try{let e=new URL(window.location.href),r=T.test(n)?new URL(E(n,e.protocol)):new URL(n),a=Te(r.pathname,t);r.origin===e.origin&&a!=null?n=a+r.search+r.hash:i=!0}catch{k(!1,` contains an invalid URL which will probably break when clicked - please update to a valid URL path.`)}return{absoluteURL:r,isExternal:i,to:n}}Object.getOwnPropertyNames(Object.prototype).sort().join(`\0`);var Ue=new URL(`http://localhost`);function We(e){if(e.createURL)return e.createURL(`/`);try{return new URL(e.createHref(`/`),Ue)}catch{return Ue}}function Ge(e,t){return e.origin===t.origin&&(e.origin!==`null`||e.protocol===t.protocol&&e.host===t.host)}function Ke(e,t){if(e.startsWith(`//`))return!0;let n=t.protocol.toLowerCase();return e.toLowerCase().startsWith(n)?t.host===``||e.slice(n.length).startsWith(`//`):!1}function qe(e,t,n,r){let i=null;try{i=e==null?null:new URL(e,n)}catch{}let a=new URL(t,n),o=i!=null&&!Ge(i,n),s=!Ge(a,n);if(r===`reject`){if(o||s)throw Error(`External navigation is not allowed`)}else if(s&&(i==null||!Ke(e,i)||!Ge(i,a)))throw Error(`External navigation is not allowed`)}var Je=[`POST`,`PUT`,`PATCH`,`DELETE`];new Set(Je);var Ye=[`GET`,...Je];new Set(Ye);var Xe=[`about:`,`blob:`,`chrome:`,`chrome-untrusted:`,`content:`,`data:`,`devtools:`,`file:`,`filesystem:`,`javascript:`];function Ze(e){try{return Xe.includes(new URL(e).protocol)}catch{return!1}}var Qe=v.createContext(null);Qe.displayName=`DataRouter`;var $e=v.createContext(null);$e.displayName=`DataRouterState`;var et=v.createContext(!1);function tt(){return v.useContext(et)}var nt=v.createContext({isTransitioning:!1});nt.displayName=`ViewTransition`;var rt=v.createContext(new Map);rt.displayName=`Fetchers`;var it=v.createContext(null);it.displayName=`Await`;var at=v.createContext(null);at.displayName=`Navigation`;var ot=v.createContext(null);ot.displayName=`Location`;var st=v.createContext({outlet:null,matches:[],isDataRoute:!1});st.displayName=`Route`;var ct=v.createContext(null);ct.displayName=`RouteError`;var lt=`REACT_ROUTER_ERROR`,ut=`REDIRECT`,dt=`ROUTE_ERROR_RESPONSE`;function ft(e){if(e.startsWith(`${lt}:${ut}:{`))try{let t=JSON.parse(e.slice(28));if(typeof t==`object`&&t&&typeof t.status==`number`&&typeof t.statusText==`string`&&typeof t.location==`string`&&typeof t.reloadDocument==`boolean`&&typeof t.replace==`boolean`)return t}catch{}}function pt(e){if(e.startsWith(`${lt}:${dt}:{`))try{let t=JSON.parse(e.slice(40));if(typeof t==`object`&&t&&typeof t.status==`number`&&typeof t.statusText==`string`)return new Re(t.status,t.statusText,t.data)}catch{}}function mt(e,{relative:t}={}){O(ht(),`useHref() may be used only in the context of a component.`);let{basename:n,navigator:r}=v.useContext(at),{hash:i,pathname:a,search:o}=St(e,{relative:t}),s=a;return n!==`/`&&(s=a===`/`?n:Ne([n,a])),r.createHref({pathname:s,search:o,hash:i})}function ht(){return v.useContext(ot)!=null}function gt(){return O(ht(),`useLocation() may be used only in the context of a component.`),v.useContext(ot).location}var _t=`You should call navigate() in a React.useEffect(), not when your component is first rendered.`;function vt(e){v.useContext(at).static||v.useLayoutEffect(e)}function yt(){let{isDataRoute:e}=v.useContext(st);return e?Vt():bt()}function bt(){O(ht(),`useNavigate() may be used only in the context of a component.`);let e=v.useContext(Qe),{basename:t,navigator:n}=v.useContext(at),{matches:r}=v.useContext(st),{pathname:i}=gt(),a=JSON.stringify(Ae(r)),o=v.useRef(!1);return vt(()=>{o.current=!0}),v.useCallback((r,s={})=>{if(k(o.current,_t),!o.current)return;if(typeof r==`number`){n.go(r);return}let c=je(r,JSON.parse(a),i,s.relative===`path`);e==null&&t!==`/`&&(c.pathname=c.pathname===`/`?t:Ne([t,c.pathname])),qe(typeof r==`string`?r:ae(r),n.createHref(c),We(n),`reject`),(s.replace?n.replace:n.push)(c,s.state,s)},[t,n,a,i,e])}v.createContext(null);function xt(){let{matches:e}=v.useContext(st);return e[e.length-1]?.params??{}}function St(e,{relative:t}={}){let{matches:n}=v.useContext(st),{pathname:r}=gt(),i=JSON.stringify(Ae(n));return v.useMemo(()=>je(e,JSON.parse(i),r,t===`path`),[e,i,r,t])}function Ct(e,t){return wt(e,t)}function wt(e,t,n){O(ht(),`useRoutes() may be used only in the context of a component.`);let{navigator:r}=v.useContext(at),{matches:i}=v.useContext(st),a=i[i.length-1],o=a?a.params:{},s=a?a.pathname:`/`,c=a?a.pathnameBase:`/`,l=a&&a.route;{let e=l&&l.path||``;Ut(s,!l||e.endsWith(`*`)||e.endsWith(`*?`),`You rendered descendant (or called \`useRoutes()\`) at "${s}" (under ) but the parent route path has no trailing "*". This means if you navigate deeper, the parent won't match anymore and therefore the child routes will never render. + +Please change the parent to .`)}let u=gt(),d;if(t){let e=typeof t==`string`?A(t):t;O(c===`/`||e.pathname?.startsWith(c),`When overriding the location using \`\` or \`useRoutes(routes, location)\`, the location pathname must begin with the portion of the URL pathname that was matched by all parent routes. The current pathname base is "${c}" but pathname "${e.pathname}" was given in the \`location\` prop.`),d=e}else d=u;let f=d.pathname||`/`,p=f;if(c!==`/`){let e=c.replace(/^\//,``).split(`/`);p=`/`+f.replace(/^\//,``).split(`/`).slice(e.length).join(`/`)}let m=n&&n.state.matches.length?n.state.matches.map(e=>Object.assign(e,{route:n.manifest[e.route.id]||e.route})):se(e,{pathname:p});k(l||m!=null,`No routes matched location "${d.pathname}${d.search}${d.hash}" `),k(m==null||m[m.length-1].route.element!==void 0||m[m.length-1].route.Component!==void 0||m[m.length-1].route.lazy!==void 0,`Matched leaf route at location "${d.pathname}${d.search}${d.hash}" does not have an element or Component. This means it will render an with a null value by default resulting in an "empty" page.`);let h=jt(m&&m.map(e=>Object.assign({},e,{params:Object.assign({},o,e.params),pathname:Ne([c,r.encodeLocation?r.encodeLocation(e.pathname.replace(/%/g,`%25`).replace(/\?/g,`%3F`).replace(/#/g,`%23`)).pathname:e.pathname]),pathnameBase:e.pathnameBase===`/`?c:Ne([c,r.encodeLocation?r.encodeLocation(e.pathnameBase.replace(/%/g,`%25`).replace(/\?/g,`%3F`).replace(/#/g,`%23`)).pathname:e.pathnameBase])})),i,n);return t&&h?v.createElement(ot.Provider,{value:{location:{pathname:`/`,search:``,hash:``,state:null,key:`default`,mask:void 0,...d},navigationType:`POP`}},h):h}function Tt(){let e=Bt(),t=ze(e)?`${e.status} ${e.statusText}`:e instanceof Error?e.message:JSON.stringify(e),n=e instanceof Error?e.stack:null,r=`rgba(200,200,200, 0.5)`,i={padding:`0.5rem`,backgroundColor:r},a={padding:`2px 4px`,backgroundColor:r},o=null;return console.error(`Error handled by React Router default ErrorBoundary:`,e),o=v.createElement(v.Fragment,null,v.createElement(`p`,null,`💿 Hey developer 👋`),v.createElement(`p`,null,`You can provide a way better UX than this when your app throws errors by providing your own `,v.createElement(`code`,{style:a},`ErrorBoundary`),` or`,` `,v.createElement(`code`,{style:a},`errorElement`),` prop on your route.`)),v.createElement(v.Fragment,null,v.createElement(`h2`,null,`Unexpected Application Error!`),v.createElement(`h3`,{style:{fontStyle:`italic`}},t),n?v.createElement(`pre`,{style:i},n):null,o)}var Et=v.createElement(Tt,null),Dt=class extends v.Component{constructor(e){super(e),this.state={location:e.location,revalidation:e.revalidation,error:e.error}}static getDerivedStateFromError(e){return{error:e}}static getDerivedStateFromProps(e,t){return t.location!==e.location||t.revalidation!==`idle`&&e.revalidation===`idle`?{error:e.error,location:e.location,revalidation:e.revalidation}:{error:e.error===void 0?t.error:e.error,location:t.location,revalidation:e.revalidation||t.revalidation}}componentDidCatch(e,t){this.props.onError?this.props.onError(e,t):console.error(`React Router caught the following error during render`,e)}render(){let e=this.state.error;if(this.context&&typeof e==`object`&&e&&`digest`in e&&typeof e.digest==`string`){let t=pt(e.digest);t&&(e=t)}let t=e===void 0?this.props.children:v.createElement(st.Provider,{value:this.props.routeContext},v.createElement(ct.Provider,{value:e,children:this.props.component}));return this.context?v.createElement(kt,{error:e},t):t}};Dt.contextType=et;var Ot=new WeakMap;function kt({children:e,error:t}){let{basename:n,navigator:r}=v.useContext(at);if(typeof t==`object`&&t&&`digest`in t&&typeof t.digest==`string`){let e=ft(t.digest);if(e){let i=Ot.get(t);if(i)throw i;let a=He(e.location,n),o=a.absoluteURL||a.to;if(qe(e.location,o,We(r),`allow-explicit`),Ze(o))throw Error(`Invalid redirect location`);if(Ve&&!Ot.get(t))if(a.isExternal||e.reloadDocument)window.location.href=o;else{let n=Promise.resolve().then(()=>window.__reactRouterDataRouter.navigate(a.to,{replace:e.replace}));throw Ot.set(t,n),n}return v.createElement(`meta`,{httpEquiv:`refresh`,content:`0;url=${o}`})}}return e}function At({routeContext:e,match:t,children:n}){let r=v.useContext(Qe);return r&&r.static&&r.staticContext&&(t.route.errorElement||t.route.ErrorBoundary)&&(r.staticContext._deepestRenderedBoundaryId=t.route.id),v.createElement(st.Provider,{value:e},n)}function jt(e,t=[],n){let r=n?.state;if(e==null){if(!r)return null;if(r.errors)e=r.matches;else if(t.length===0&&!r.initialized&&r.matches.length>0)e=r.matches;else return null}let i=e,a=r?.errors;if(a!=null){let e=i.findIndex(e=>e.route.id&&a?.[e.route.id]!==void 0);O(e>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(a).join(`,`)}`),i=i.slice(0,Math.min(i.length,e+1))}let o=!1,s=-1;if(n&&r){o=r.renderFallback;for(let e=0;e=0?i.slice(0,s+1):[i[0]];break}}}}let c=n?.onError,l=r&&c?(e,t)=>{c(e,{location:r.location,params:r.matches?.[0]?.params??{},pattern:Be(r.matches),errorInfo:t})}:void 0;return i.reduceRight((e,n,c)=>{let u,d=!1,f=null,p=null;r&&(u=a&&n.route.id?a[n.route.id]:void 0,f=n.route.errorElement||Et,o&&(s<0&&c===0?(Ut(`route-fallback`,!1,"No `HydrateFallback` element provided to render during initial hydration"),d=!0,p=null):s===c&&(d=!0,p=n.route.hydrateFallbackElement||null)));let m=t.concat(i.slice(0,c+1)),h=()=>{let t;return t=u?f:d?p:n.route.Component?v.createElement(n.route.Component,null):n.route.element?n.route.element:e,v.createElement(At,{match:n,routeContext:{outlet:e,matches:m,isDataRoute:r!=null},children:t})};return r&&(n.route.ErrorBoundary||n.route.errorElement||c===0)?v.createElement(Dt,{location:r.location,revalidation:r.revalidation,component:f,error:u,children:h(),routeContext:{outlet:null,matches:m,isDataRoute:!0},onError:l}):h()},null)}function Mt(e){return`${e} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function Nt(e){let t=v.useContext(Qe);return O(t,Mt(e)),t}function Pt(e){let t=v.useContext($e);return O(t,Mt(e)),t}function Ft(e){let t=v.useContext(st);return O(t,Mt(e)),t}function It(e){let t=Ft(e),n=t.matches[t.matches.length-1];return O(n.route.id,`${e} can only be used on routes that contain a unique "id"`),n.route.id}function Lt(){return It(`useRouteId`)}function Rt(){let e=Pt(`useNavigation`);return v.useMemo(()=>{let{matches:t,historyAction:n,...r}=e.navigation;return r},[e.navigation])}function zt(){let{matches:e,loaderData:t}=Pt(`useMatches`);return v.useMemo(()=>e.map(e=>M(e,t)),[e,t])}function Bt(){let e=v.useContext(ct),t=Pt(`useRouteError`),n=It(`useRouteError`);return e===void 0?t.errors?.[n]:e}function Vt(){let{router:e}=Nt(`useNavigate`),t=It(`useNavigate`),n=v.useRef(!1);return vt(()=>{n.current=!0}),v.useCallback(async(r,i={})=>{k(n.current,_t),n.current&&(typeof r==`number`?await e.navigate(r):await e.navigate(r,{fromRouteId:t,...i}))},[e,t])}var Ht={};function Ut(e,t,n){!t&&!Ht[e]&&(Ht[e]=!0,k(!1,n))}v.memo(Wt);function Wt({routes:e,manifest:t,future:n,state:r,isStatic:i,onError:a}){return wt(e,void 0,{manifest:t,state:r,isStatic:i,onError:a,future:n})}function Gt({to:e,replace:t,state:n,relative:r}){O(ht(),` may be used only in the context of a component.`);let{static:i,navigator:a}=v.useContext(at);k(!i,` must not be used on the initial render in a . This is a no-op, but you should modify your code so the is only ever rendered in response to some user interaction or state change.`);let{matches:o}=v.useContext(st),{pathname:s}=gt(),c=yt(),l=je(e,Ae(o),s,r===`path`);qe(typeof e==`string`?e:ae(e),a.createHref(l),We(a),`reject`);let u=JSON.stringify(l);return v.useEffect(()=>{c(JSON.parse(u),{replace:t,state:n,relative:r})},[c,u,r,t,n]),null}function Kt(e){O(!1,`A is only ever to be used as the child of element, never rendered directly. Please wrap your in a .`)}function qt({basename:e=`/`,children:t=null,location:n,navigationType:r=`POP`,navigator:i,static:a=!1,useTransitions:o}){O(!ht(),`You cannot render a inside another . You should never have more than one in your app.`);let s=e.replace(/^\/*/,`/`),c=v.useMemo(()=>({basename:s,navigator:i,static:a,useTransitions:o,future:{}}),[s,i,a,o]);typeof n==`string`&&(n=A(n));let{pathname:l=`/`,search:u=``,hash:d=``,state:f=null,key:p=`default`,mask:m}=n,h=v.useMemo(()=>{let e=Te(l,s);return e==null?null:{location:{pathname:e,search:u,hash:d,state:f,key:p,mask:m},navigationType:r}},[s,l,u,d,f,p,r,m]);return k(h!=null,` is not able to match the URL "${l}${u}${d}" because it does not start with the basename, so the won't render anything.`),h==null?null:v.createElement(at.Provider,{value:c},v.createElement(ot.Provider,{children:t,value:h}))}function Jt({children:e,location:t}){return Ct(Yt(e),t)}v.Component;function Yt(e,t=[]){let n=[];return v.Children.forEach(e,(e,r)=>{if(!v.isValidElement(e))return;let i=[...t,r];if(e.type===v.Fragment){n.push.apply(n,Yt(e.props.children,i));return}O(e.type===Kt,`[${typeof e.type==`string`?e.type:e.type.name}] is not a component. All component children of must be a or `),O(!e.props.index||!e.props.children,`An index route cannot have child routes.`);let a={id:e.props.id||i.join(`-`),caseSensitive:e.props.caseSensitive,element:e.props.element,Component:e.props.Component,index:e.props.index,path:e.props.path,middleware:e.props.middleware,loader:e.props.loader,action:e.props.action,hydrateFallbackElement:e.props.hydrateFallbackElement,HydrateFallback:e.props.HydrateFallback,errorElement:e.props.errorElement,ErrorBoundary:e.props.ErrorBoundary,hasErrorBoundary:e.props.hasErrorBoundary===!0||e.props.ErrorBoundary!=null||e.props.errorElement!=null,shouldRevalidate:e.props.shouldRevalidate,handle:e.props.handle,lazy:e.props.lazy};e.props.children&&(a.children=Yt(e.props.children,i)),n.push(a)}),n}var Xt=`get`,Zt=`application/x-www-form-urlencoded`;function Qt(e){return typeof HTMLElement<`u`&&e instanceof HTMLElement}function $t(e){return Qt(e)&&e.tagName.toLowerCase()===`button`}function en(e){return Qt(e)&&e.tagName.toLowerCase()===`form`}function tn(e){return Qt(e)&&e.tagName.toLowerCase()===`input`}function nn(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}function rn(e,t){return e.button===0&&(!t||t===`_self`)&&!nn(e)}var an=null;function on(){if(an===null)try{new FormData(document.createElement(`form`),0),an=!1}catch{an=!0}return an}var sn=new Set([`application/x-www-form-urlencoded`,`multipart/form-data`,`text/plain`]);function cn(e){return e!=null&&!sn.has(e)?(k(!1,`"${e}" is not a valid \`encType\` for \`
\`/\`\` and will default to "${Zt}"`),null):e}function ln(e,t){let n,r,i,a,o;if(en(e)){let o=e.getAttribute(`action`);r=o?Te(o,t):null,n=e.getAttribute(`method`)||Xt,i=cn(e.getAttribute(`enctype`))||Zt,a=new FormData(e)}else if($t(e)||tn(e)&&(e.type===`submit`||e.type===`image`)){let o=e.form;if(o==null)throw Error(`Cannot submit a + ); })} @@ -318,6 +334,8 @@ export default function App() { )} {tab === "overview" ? ( + ) : tab === "breeds" ? ( + ) : ( = { + cku: "CKU", + fci: "FCI", + akc: "AKC", + rkc: "英国皇家犬业俱乐部", + editorial: "编辑整理", +}; +const factLabels: Record = { + name: "中文名", + english_name: "英文名", + aliases: "别名", + origin: "起源地", + breed_group: "分组", + fci_number: "FCI 编号", + height: "肩高", + weight: "体重", + life_span: "寿命参考", + exercise: "运动参考", + grooming: "梳理参考", + temperament: "性格倾向", + traits: "指数", + size: "体型", + coat_length: "毛长", + sheds: "掉毛情况", + scope: "标准范围", +}; +function parseTraits(value: string): Record { + try { + return JSON.parse(value) || {}; + } catch { + return {}; + } +} +export default function Breeds({ revision }: { revision: number }) { + const [page, setPage] = useState(1), + [query, setQuery] = useState(""), + [draft, setDraft] = useState(""), + [initial, setInitial] = useState(""), + [status, setStatus] = useState(""); + const [data, setData] = useState(null), + [busy, setBusy] = useState(true), + [retry, setRetry] = useState(0), + [error, setError] = useState(""), + [notice, setNotice] = useState(""); + const [sourceView, setSourceView] = useState(false); + const [editing, setEditing] = useState(null), + [form, setForm] = useState(empty), + [confirm, setConfirm] = useState(null), + [saving, setSaving] = useState(false), + [writeError, setWriteError] = useState(""); + useEffect(() => { + const controller = new AbortController(); + setBusy(true); + setError(""); + api + .breeds( + { page, page_size: 10, q: query, status, initial }, + controller.signal, + ) + .then((result) => { + if (controller.signal.aborted) return; + const last = Math.max(1, Math.ceil(result.total / 10)); + if (page > last) { + setPage(last); + return; + } + setData(result); + }) + .catch((e) => { + if (!controller.signal.aborted) setError(e.message); + }) + .finally(() => { + if (!controller.signal.aborted) setBusy(false); + }); + return () => controller.abort(); + }, [page, query, initial, status, revision, retry]); + function edit(row: Breed | "new") { + setEditing(row); + setSourceView(false); + setForm( + row === "new" + ? { ...empty } + : { + name: row.name, + english_name: row.english_name, + aliases: row.aliases, + enabled: row.enabled, + origin: row.origin || "", + breed_group: row.breed_group || "", + height: row.height || "", + weight: row.weight || "", + summary: row.summary || "", + temperament: row.temperament || "", + care_notes: row.care_notes || "", + fci_number: row.fci_number || "", + life_span: row.life_span || "", + exercise: row.exercise || "", + grooming: row.grooming || "", + traits: parseTraits(row.traits), + }, + ); + setWriteError(""); + } + async function save(e: FormEvent) { + e.preventDefault(); + if (saving || !editing) return; + setSaving(true); + setWriteError(""); + try { + await api.saveBreed(editing === "new" ? "" : editing.id, { + ...form, + name: form.name.trim(), + }); + setEditing(null); + setNotice("品种资料已保存"); + setRetry((v) => v + 1); + } catch (e) { + setWriteError((e as Error).message); + } finally { + setSaving(false); + } + } + async function toggle() { + if (!confirm || saving) return; + setSaving(true); + setWriteError(""); + try { + await api.setBreedEnabled(confirm.id, !confirm.enabled); + setNotice( + confirm.enabled ? "品种已停用,已有宠物档案保持原资料" : "品种已启用", + ); + setConfirm(null); + setRetry((v) => v + 1); + } catch (e) { + setWriteError((e as Error).message); + } finally { + setSaving(false); + } + } + const pages = Math.max(1, Math.ceil((data?.total || 0) / 10)); + return ( +
+
+
+

狗狗品种

+

+ {data ? `共 ${data.total} 个品种` : "读取品种中"} · 按中文名称拼音 + A–Z 排序 +

+
+ +
+ {notice && ( +
+ {notice} + +
+ )} +
+ { + e.preventDefault(); + setPage(1); + setQuery(draft.trim()); + setRetry((v) => v + 1); + }} + > + + setDraft(e.target.value)} + maxLength={128} + placeholder="搜索品种、别名或拼音" + aria-label="搜索品种、别名或拼音" + /> + + + +
+
+ {["", ..."ABCDEFGHIJKLMNOPQRSTUVWXYZ", "#"].map((letter) => ( + + ))} +
+ {error ? ( +
+

{error}

+ +
+ ) : busy ? ( +
+ +

正在加载品种

+
+ ) : !data?.items.length ? ( +
+

没有符合条件的品种,可以新增补充。

+
+ ) : ( + + + + {["字母", "品种", "别名", "来源", "状态", "操作"].map((label) => ( + {label} + ))} + + + + {data.items.map((row) => ( + + + {row.initial} + + + {row.name} + {row.english_name || row.pinyin} + {row.summary ? "已整理百科" : "百科待补充"} + + + {row.aliases || "—"} + + + {row.references?.length ? ( +
+ {row.references.map((ref) => ( + + {providerNames[ref.provider] || ref.provider} + + ))} +
+ ) : row.source_url ? ( + + {row.source} + + ) : ( + row.source + )} +
+ + + {row.enabled ? "已启用" : "已停用"} + + + +
+ + +
+
+
+ ))} +
+
+ )} +
+ + {data?.total + ? `第 ${(page - 1) * 10 + 1}–${Math.min(page * 10, data.total)} 条,共 ${data.total} 条` + : "共 0 条"}{" "} + · 每页 10 条 + +
+ + + 第 {page} / {pages} 页 + + +
+
+ { + if (!open && !saving) setEditing(null); + }} + > + + + + {editing === "new" ? "新增品种" : "编辑品种"} + + +

+ 拼音和 A–Z 分组自动生成。别名用于搜索,例如“边牧”。 +

+
+ + +
+ {sourceView && editing && editing !== "new" ? ( +
+

+ 各机构的分类、标准与指数单独保留。展示资料由编辑整理,保存后后续导入会保留人工修改。 +

+ {editing.references?.length ? ( + editing.references.map((ref) => ( +
+
+ + {providerNames[ref.provider] || ref.provider} + + + 查看原始资料 + +
+ + 采集于 {ref.retrieved_at} · {ref.external_id} + +
+ {Object.entries(ref.facts).map(([key, value]) => ( +
+
{factLabels[key] || key}
+
+ {key === "traits" + ? Object.entries(parseTraits(value)) + .map( + ([label, score]) => `${label} ${score}/5`, + ) + .join(" · ") + : value} +
+
+ ))} +
+
+ )) + ) : ( +

这是手动录入的犬种,暂未关联官方资料。

+ )} +
+ ) : ( +
+ + + +
+ {( + [ + ["origin", "起源地"], + ["breed_group", "FCI 分组"], + ["fci_number", "FCI 编号"], + ["life_span", "寿命参考"], + ["height", "参考肩高(含单位)"], + ["weight", "参考体重(含单位)"], + ["exercise", "运动参考"], + ["grooming", "毛发护理"], + ] as const + ).map(([key, label]) => ( + + ))} +
+