@wuxh/daily-avatar 0.0.1-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +115 -0
- package/dist/configManager.d.mts +86 -0
- package/dist/configManager.mjs +1 -0
- package/dist/configManager.umd.js +1 -0
- package/dist/index.js +6 -0
- package/package.json +51 -0
- package/userscripts/v2ex-daily-avatar.user.js +301 -0
package/README.md
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Daily Avatar UI
|
|
2
|
+
|
|
3
|
+
这是一个自动更换头像脚本设计的 UI 界面库。它提供了一套现代化的、样式隔离的配置面板和状态监控组件。
|
|
4
|
+
|
|
5
|
+
> **⚠️ 注意**:本项目仅包含 UI 界面、配置管理和状态流转逻辑。实际的头像获取(Fetch)与上传(Upload)功能需要在宿主脚本(如 Tampermonkey 脚本)中实现并注册到此 UI 中。
|
|
6
|
+
|
|
7
|
+
## ✨ 特性
|
|
8
|
+
|
|
9
|
+
- **🛡️ 样式隔离**:采用 Shadow DOM 技术封装,确保 UI 样式(Tailwind CSS)完全独立,既不污染宿主网页,也不受宿主网页样式干扰。
|
|
10
|
+
- **🎨 现代化界面**:基于 Preact + Tailwind CSS v4 构建,提供简洁、美观的配置面板和状态悬浮窗。
|
|
11
|
+
- **⚙️ 完整配置**:内置设置面板,支持调节更新频率、切换头像来源(Unsplash/自定义API/随机)、管理通知偏好。
|
|
12
|
+
- **📊 状态监控**:实时展示更新成功率、历史记录、下次更新倒计时等统计信息。
|
|
13
|
+
|
|
14
|
+
## 🚀 集成指南
|
|
15
|
+
|
|
16
|
+
如果你是 UserScript 开发者,可以通过以下步骤将此 UI 集成到你的脚本中。
|
|
17
|
+
|
|
18
|
+
### 1. 引入资源
|
|
19
|
+
|
|
20
|
+
在你的 UserScript Metadata 中引入构建好的 IIFE 资源文件:
|
|
21
|
+
|
|
22
|
+
```javascript
|
|
23
|
+
// @require TODO: 替换为实际的 UI 库 URL
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### 2. 初始化与注册
|
|
27
|
+
|
|
28
|
+
UI 库加载后会在全局暴露 `window.daily_avatar_UI` 对象。你需要初始化它,并注册实际的更新逻辑。
|
|
29
|
+
|
|
30
|
+
```javascript
|
|
31
|
+
(function() {
|
|
32
|
+
'use strict';
|
|
33
|
+
|
|
34
|
+
// 1. 等待 UI 库加载
|
|
35
|
+
const waitForUI = () => new Promise(resolve => {
|
|
36
|
+
if (window.daily_avatar_UI) return resolve();
|
|
37
|
+
const timer = setInterval(() => {
|
|
38
|
+
if (window.daily_avatar_UI) {
|
|
39
|
+
clearInterval(timer);
|
|
40
|
+
resolve();
|
|
41
|
+
}
|
|
42
|
+
}, 50);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
async function main() {
|
|
46
|
+
await waitForUI();
|
|
47
|
+
|
|
48
|
+
// 2. 准备配置管理器
|
|
49
|
+
const configManager = new TampermonkeyConfigManager();
|
|
50
|
+
|
|
51
|
+
const { init, store } = window.daily_avatar_UI;
|
|
52
|
+
|
|
53
|
+
// 3. 初始化 UI
|
|
54
|
+
// configManager 用于持久化存储配置和状态
|
|
55
|
+
init(configManager);
|
|
56
|
+
|
|
57
|
+
// 4. 注册核心更新逻辑 (Handler)
|
|
58
|
+
// 当用户点击"立即更新"或自动触发时,UI 会调用此 Handler
|
|
59
|
+
store.getState().registerUpdateHandler(async () => {
|
|
60
|
+
console.log('UI 请求更新头像...');
|
|
61
|
+
|
|
62
|
+
// --- 在这里实现你的业务逻辑 ---
|
|
63
|
+
// 1. 获取头像数据
|
|
64
|
+
// const imageBlob = await fetchAvatarImage();
|
|
65
|
+
|
|
66
|
+
// 2. 上传到目标网站
|
|
67
|
+
// await uploadAvatar(imageBlob);
|
|
68
|
+
|
|
69
|
+
// 3. 记录结果
|
|
70
|
+
// 成功时:configManager.recordSuccess()
|
|
71
|
+
// 失败时:抛出 Error,UI 会自动捕获并显示错误通知
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
main();
|
|
76
|
+
})();
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## 🛠️ 本地开发
|
|
80
|
+
|
|
81
|
+
### 安装依赖
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
pnpm install
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### 启动开发服务器
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
pnpm dev
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
这将启动 Vite 服务器,你可以在浏览器中预览 UI 组件。
|
|
94
|
+
|
|
95
|
+
### 构建
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
pnpm build
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
构建产物将输出到 `dist/` 目录:
|
|
102
|
+
* `index.iife.js`: 包含完整 UI 和样式的 IIFE 包,适合 UserScript 引用。
|
|
103
|
+
* `index.js`: ESM 格式包。
|
|
104
|
+
|
|
105
|
+
## 🏗️ 技术栈
|
|
106
|
+
|
|
107
|
+
* **UI 框架**: [Preact](https://preactjs.com/) (轻量级 React 替代方案)
|
|
108
|
+
* **状态管理**: [Zustand](https://github.com/pmndrs/zustand) (Vanilla store + Custom hooks)
|
|
109
|
+
* **样式引擎**: [Tailwind CSS v4](https://tailwindcss.com/)
|
|
110
|
+
* **构建工具**: [Vite](https://vitejs.dev/) & [tsdown](https://github.com/sxzz/tsdown)
|
|
111
|
+
* **隔离方案**: Native Shadow DOM
|
|
112
|
+
|
|
113
|
+
## 📄 License
|
|
114
|
+
|
|
115
|
+
MIT
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
//#region src/constants/defaultConf.d.ts
|
|
2
|
+
declare const DEFAULT_CONFIG: {
|
|
3
|
+
enabled: boolean;
|
|
4
|
+
autoStart: boolean;
|
|
5
|
+
updateInterval: number;
|
|
6
|
+
updateTime: string;
|
|
7
|
+
checkOnLoad: boolean;
|
|
8
|
+
enableNotifications: boolean;
|
|
9
|
+
notifyOnSuccess: boolean;
|
|
10
|
+
notifyOnFailure: boolean;
|
|
11
|
+
notifyOnStart: boolean;
|
|
12
|
+
retryOnFail: boolean;
|
|
13
|
+
maxRetries: number;
|
|
14
|
+
retryInterval: number;
|
|
15
|
+
debugMode: boolean;
|
|
16
|
+
logToConsole: boolean;
|
|
17
|
+
avatarSource: string;
|
|
18
|
+
apiUrl: string;
|
|
19
|
+
unsplashKey: string;
|
|
20
|
+
};
|
|
21
|
+
//#endregion
|
|
22
|
+
//#region src/types/config.d.ts
|
|
23
|
+
type Config = typeof DEFAULT_CONFIG;
|
|
24
|
+
//#endregion
|
|
25
|
+
//#region src/constants/defaultState.d.ts
|
|
26
|
+
declare const defaultState: {
|
|
27
|
+
lastUpdate: number;
|
|
28
|
+
lastSuccess: number;
|
|
29
|
+
lastError: null;
|
|
30
|
+
errorCount: number;
|
|
31
|
+
successCount: number;
|
|
32
|
+
totalUpdates: number;
|
|
33
|
+
lastImageUrl: string;
|
|
34
|
+
isUpdating: boolean;
|
|
35
|
+
nextScheduledUpdate: number;
|
|
36
|
+
updateHistory: never[];
|
|
37
|
+
};
|
|
38
|
+
//#endregion
|
|
39
|
+
//#region src/types/state.d.ts
|
|
40
|
+
type State = typeof defaultState;
|
|
41
|
+
//#endregion
|
|
42
|
+
//#region src/lib/configManager/Base.d.ts
|
|
43
|
+
interface BaseConfigManager<TConfig = any, TState = any> {
|
|
44
|
+
config: TConfig;
|
|
45
|
+
state: TState;
|
|
46
|
+
loadConfig(): TConfig | Promise<TConfig>;
|
|
47
|
+
saveConfig(newConfig: Partial<TConfig>): boolean | Promise<boolean>;
|
|
48
|
+
resetConfig(): boolean | Promise<boolean>;
|
|
49
|
+
getConfig(): TConfig;
|
|
50
|
+
loadState(): TState | Promise<TState>;
|
|
51
|
+
saveState(newState: Partial<TState>): boolean | Promise<boolean>;
|
|
52
|
+
getStats(): any;
|
|
53
|
+
cleanupOldData(daysToKeep?: number): boolean | Promise<boolean>;
|
|
54
|
+
exportData(): any;
|
|
55
|
+
importData(data: any): boolean | Promise<boolean>;
|
|
56
|
+
listStorage(): string[] | Promise<string[]>;
|
|
57
|
+
clearAllData(): boolean | Promise<boolean>;
|
|
58
|
+
recordSuccess(imageUrl?: string): TState | Promise<TState>;
|
|
59
|
+
recordError(error: any): TState | Promise<TState>;
|
|
60
|
+
hasUpdatedToday(): boolean;
|
|
61
|
+
}
|
|
62
|
+
//#endregion
|
|
63
|
+
//#region src/lib/configManager/Browser.d.ts
|
|
64
|
+
declare class BrowserConfigManager implements BaseConfigManager<Config, State> {
|
|
65
|
+
config: Config;
|
|
66
|
+
state: State;
|
|
67
|
+
constructor();
|
|
68
|
+
loadConfig(): Promise<Config>;
|
|
69
|
+
saveConfig(newConfig: Partial<Config>): Promise<boolean>;
|
|
70
|
+
resetConfig(): Promise<boolean>;
|
|
71
|
+
getConfig(): Config;
|
|
72
|
+
private getDefaultState;
|
|
73
|
+
loadState(): Promise<State>;
|
|
74
|
+
saveState(newState: any): Promise<boolean>;
|
|
75
|
+
recordSuccess(imageUrl?: string): Promise<State>;
|
|
76
|
+
recordError(error: any): Promise<State>;
|
|
77
|
+
hasUpdatedToday(): boolean;
|
|
78
|
+
getStats(): any;
|
|
79
|
+
cleanupOldData(daysToKeep?: number): boolean;
|
|
80
|
+
exportData(): any;
|
|
81
|
+
importData(data: any): boolean;
|
|
82
|
+
listStorage(): Promise<string[]>;
|
|
83
|
+
clearAllData(): Promise<boolean>;
|
|
84
|
+
}
|
|
85
|
+
//#endregion
|
|
86
|
+
export { BrowserConfigManager };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{openDB as e}from"idb";const t={enabled:!0,autoStart:!0,updateInterval:1440*60*1e3,updateTime:`09:00`,checkOnLoad:!0,enableNotifications:!0,notifyOnSuccess:!0,notifyOnFailure:!0,notifyOnStart:!1,retryOnFail:!0,maxRetries:3,retryInterval:300*1e3,debugMode:!1,logToConsole:!0,avatarSource:`api`,apiUrl:``,unsplashKey:``},n=e(`daily-avatar`,1,{upgrade(e){e.objectStoreNames.contains(`config-store`)||e.createObjectStore(`config-store`),e.objectStoreNames.contains(`state-store`)||e.createObjectStore(`state-store`)}});var r=class{config;state;constructor(){this.config={...t},this.state=this.getDefaultState(),this.loadConfig(),this.loadState()}async loadConfig(){let e=await n,r=await e.get(`config-store`,`avatarConfig`);if(!r){await e.put(`config-store`,t,`avatarConfig`);let n={...t};return this.config=n,n}let i={...t,...r};return this.config=i,i}async saveConfig(e){return this.config={...this.config,...e},await(await n).put(`config-store`,this.config,`avatarConfig`),!0}async resetConfig(){return await(await n).put(`config-store`,t,`avatarConfig`),this.config={...t},!0}getConfig(){return{...this.config}}getDefaultState(){return{lastUpdate:0,lastSuccess:0,lastError:null,errorCount:0,successCount:0,totalUpdates:0,lastImageUrl:``,isUpdating:!1,nextScheduledUpdate:0,updateHistory:[]}}async loadState(){let e=this.getDefaultState(),t=await(await n).get(`state-store`,`avatarState`),r=t?{...e,...t}:e;return this.state=r,r}async saveState(e){return this.state={...this.state,...e},this.state.updateHistory&&this.state.updateHistory.length>100&&(this.state.updateHistory=this.state.updateHistory.slice(-100)),await(await n).put(`state-store`,this.state,`avatarState`),!0}async recordSuccess(e=``){let t=Date.now(),n={lastUpdate:t,lastSuccess:t,lastError:null,successCount:this.state.successCount+1,totalUpdates:this.state.totalUpdates+1,lastImageUrl:e,isUpdating:!1,nextScheduledUpdate:t+this.config.updateInterval,updateHistory:[...this.state.updateHistory||[],{timestamp:t,status:`success`,imageUrl:e}]};return await this.saveState(n),this.state}async recordError(e){let t=Date.now(),n={lastUpdate:t,lastError:{message:e.message,timestamp:t,code:e.code||`UNKNOWN`},errorCount:this.state.errorCount+1,totalUpdates:this.state.totalUpdates+1,isUpdating:!1,updateHistory:[...this.state.updateHistory||[],{timestamp:t,status:`error`,error:e.message}]};return await this.saveState(n),this.state}hasUpdatedToday(){if(!this.state.lastSuccess)return!1;let e=new Date(this.state.lastSuccess),t=new Date;return e.getDate()===t.getDate()&&e.getMonth()===t.getMonth()&&e.getFullYear()===t.getFullYear()}getStats(){let e=Date.now(),t=this.state.lastSuccess,n=t?e-t:null,r=this.state.totalUpdates,i=this.state.successCount,a=r>0?Math.round(i/r*100):0,o=this.state.nextScheduledUpdate||(t?t+this.config.updateInterval:e+this.config.updateInterval),s=Math.max(0,o-e);return{totalUpdates:r,successCount:i,errorCount:this.state.errorCount,successRate:a,lastUpdateTime:t,timeSinceLastUpdate:n,timeUntilNextUpdate:s,nextUpdateTime:o,hasUpdatedToday:this.hasUpdatedToday(),lastError:this.state.lastError}}cleanupOldData(e=30){let t=Date.now()-e*24*60*60*1e3;if(this.state.updateHistory){let e=this.state.updateHistory.filter(e=>e.timestamp>=t);this.saveState({updateHistory:e})}return!0}exportData(){return{config:this.config,state:this.state,version:`1.0`,exportDate:new Date().toISOString()}}importData(e){return e.config&&this.saveConfig(e.config),e.state&&this.saveState(e.state),!0}async listStorage(){let e=await n,t=await e.getAllKeys(`config-store`),r=await e.getAllKeys(`state-store`);return[...t.map(e=>`config:${e}`),...r.map(e=>`state:${e}`)]}async clearAllData(){let e=await n;return await e.clear(`config-store`),await e.clear(`state-store`),this.config={...t},this.state=this.getDefaultState(),!0}};export{r as BrowserConfigManager};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require(`idb`)):typeof define==`function`&&define.amd?define([`exports`,`idb`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.DailyAvatarBrowserConfigManager={},e.idb))})(this,function(e,t){let n={enabled:!0,autoStart:!0,updateInterval:1440*60*1e3,updateTime:`09:00`,checkOnLoad:!0,enableNotifications:!0,notifyOnSuccess:!0,notifyOnFailure:!0,notifyOnStart:!1,retryOnFail:!0,maxRetries:3,retryInterval:300*1e3,debugMode:!1,logToConsole:!0,avatarSource:`api`,apiUrl:``,unsplashKey:``},r=(0,t.openDB)(`daily-avatar`,1,{upgrade(e){e.objectStoreNames.contains(`config-store`)||e.createObjectStore(`config-store`),e.objectStoreNames.contains(`state-store`)||e.createObjectStore(`state-store`)}});e.BrowserConfigManager=class{config;state;constructor(){this.config={...n},this.state=this.getDefaultState(),this.loadConfig(),this.loadState()}async loadConfig(){let e=await r,t=await e.get(`config-store`,`avatarConfig`);if(!t){await e.put(`config-store`,n,`avatarConfig`);let t={...n};return this.config=t,t}let i={...n,...t};return this.config=i,i}async saveConfig(e){return this.config={...this.config,...e},await(await r).put(`config-store`,this.config,`avatarConfig`),!0}async resetConfig(){return await(await r).put(`config-store`,n,`avatarConfig`),this.config={...n},!0}getConfig(){return{...this.config}}getDefaultState(){return{lastUpdate:0,lastSuccess:0,lastError:null,errorCount:0,successCount:0,totalUpdates:0,lastImageUrl:``,isUpdating:!1,nextScheduledUpdate:0,updateHistory:[]}}async loadState(){let e=this.getDefaultState(),t=await(await r).get(`state-store`,`avatarState`),n=t?{...e,...t}:e;return this.state=n,n}async saveState(e){return this.state={...this.state,...e},this.state.updateHistory&&this.state.updateHistory.length>100&&(this.state.updateHistory=this.state.updateHistory.slice(-100)),await(await r).put(`state-store`,this.state,`avatarState`),!0}async recordSuccess(e=``){let t=Date.now(),n={lastUpdate:t,lastSuccess:t,lastError:null,successCount:this.state.successCount+1,totalUpdates:this.state.totalUpdates+1,lastImageUrl:e,isUpdating:!1,nextScheduledUpdate:t+this.config.updateInterval,updateHistory:[...this.state.updateHistory||[],{timestamp:t,status:`success`,imageUrl:e}]};return await this.saveState(n),this.state}async recordError(e){let t=Date.now(),n={lastUpdate:t,lastError:{message:e.message,timestamp:t,code:e.code||`UNKNOWN`},errorCount:this.state.errorCount+1,totalUpdates:this.state.totalUpdates+1,isUpdating:!1,updateHistory:[...this.state.updateHistory||[],{timestamp:t,status:`error`,error:e.message}]};return await this.saveState(n),this.state}hasUpdatedToday(){if(!this.state.lastSuccess)return!1;let e=new Date(this.state.lastSuccess),t=new Date;return e.getDate()===t.getDate()&&e.getMonth()===t.getMonth()&&e.getFullYear()===t.getFullYear()}getStats(){let e=Date.now(),t=this.state.lastSuccess,n=t?e-t:null,r=this.state.totalUpdates,i=this.state.successCount,a=r>0?Math.round(i/r*100):0,o=this.state.nextScheduledUpdate||(t?t+this.config.updateInterval:e+this.config.updateInterval),s=Math.max(0,o-e);return{totalUpdates:r,successCount:i,errorCount:this.state.errorCount,successRate:a,lastUpdateTime:t,timeSinceLastUpdate:n,timeUntilNextUpdate:s,nextUpdateTime:o,hasUpdatedToday:this.hasUpdatedToday(),lastError:this.state.lastError}}cleanupOldData(e=30){let t=Date.now()-e*24*60*60*1e3;if(this.state.updateHistory){let e=this.state.updateHistory.filter(e=>e.timestamp>=t);this.saveState({updateHistory:e})}return!0}exportData(){return{config:this.config,state:this.state,version:`1.0`,exportDate:new Date().toISOString()}}importData(e){return e.config&&this.saveConfig(e.config),e.state&&this.saveState(e.state),!0}async listStorage(){let e=await r,t=await e.getAllKeys(`config-store`),n=await e.getAllKeys(`state-store`);return[...t.map(e=>`config:${e}`),...n.map(e=>`state:${e}`)]}async clearAllData(){let e=await r;return await e.clear(`config-store`),await e.clear(`state-store`),this.config={...n},this.state=this.getDefaultState(),!0}}});
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
(function(U,T){typeof exports=="object"&&typeof module<"u"?T(exports):typeof define=="function"&&define.amd?define(["exports"],T):(U=typeof globalThis<"u"?globalThis:U||self,T(U.daily_avatar_UI=U.daily_avatar_UI||{}))})(this,(function(U){"use strict";var T,y,le,M,se,ce,de,ue,G,X,Q,A={},pe=[],Re=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,D=Array.isArray;function j(e,t){for(var r in t)e[r]=t[r];return e}function Y(e){e&&e.parentNode&&e.parentNode.removeChild(e)}function he(e,t,r){var o,i,a,c={};for(a in t)a=="key"?o=t[a]:a=="ref"?i=t[a]:c[a]=t[a];if(arguments.length>2&&(c.children=arguments.length>3?T.call(arguments,2):r),typeof e=="function"&&e.defaultProps!=null)for(a in e.defaultProps)c[a]===void 0&&(c[a]=e.defaultProps[a]);return R(e,c,o,i,null)}function R(e,t,r,o,i){var a={type:e,props:t,key:r,ref:o,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:i??++le,__i:-1,__u:0};return i==null&&y.vnode!=null&&y.vnode(a),a}function I(e){return e.children}function L(e,t){this.props=e,this.context=t}function N(e,t){if(t==null)return e.__?N(e.__,e.__i+1):null;for(var r;t<e.__k.length;t++)if((r=e.__k[t])!=null&&r.__e!=null)return r.__e;return typeof e.type=="function"?N(e):null}function ge(e){var t,r;if((e=e.__)!=null&&e.__c!=null){for(e.__e=e.__c.base=null,t=0;t<e.__k.length;t++)if((r=e.__k[t])!=null&&r.__e!=null){e.__e=e.__c.base=r.__e;break}return ge(e)}}function fe(e){(!e.__d&&(e.__d=!0)&&M.push(e)&&!F.__r++||se!=y.debounceRendering)&&((se=y.debounceRendering)||ce)(F)}function F(){for(var e,t,r,o,i,a,c,s=1;M.length;)M.length>s&&M.sort(de),e=M.shift(),s=M.length,e.__d&&(r=void 0,o=void 0,i=(o=(t=e).__v).__e,a=[],c=[],t.__P&&((r=j({},o)).__v=o.__v+1,y.vnode&&y.vnode(r),Z(t.__P,r,o,t.__n,t.__P.namespaceURI,32&o.__u?[i]:null,a,i??N(o),!!(32&o.__u),c),r.__v=o.__v,r.__.__k[r.__i]=r,we(a,r,c),o.__e=o.__=null,r.__e!=i&&ge(r)));F.__r=0}function be(e,t,r,o,i,a,c,s,p,d,u){var l,f,h,w,v,_,g,b=o&&o.__k||pe,S=t.length;for(p=Le(r,t,b,p,S),l=0;l<S;l++)(h=r.__k[l])!=null&&(f=h.__i==-1?A:b[h.__i]||A,h.__i=l,_=Z(e,h,f,i,a,c,s,p,d,u),w=h.__e,h.ref&&f.ref!=h.ref&&(f.ref&&te(f.ref,null,h),u.push(h.ref,h.__c||w,h)),v==null&&w!=null&&(v=w),(g=!!(4&h.__u))||f.__k===h.__k?p=ve(h,p,e,g):typeof h.type=="function"&&_!==void 0?p=_:w&&(p=w.nextSibling),h.__u&=-7);return r.__e=v,p}function Le(e,t,r,o,i){var a,c,s,p,d,u=r.length,l=u,f=0;for(e.__k=new Array(i),a=0;a<i;a++)(c=t[a])!=null&&typeof c!="boolean"&&typeof c!="function"?(typeof c=="string"||typeof c=="number"||typeof c=="bigint"||c.constructor==String?c=e.__k[a]=R(null,c,null,null,null):D(c)?c=e.__k[a]=R(I,{children:c},null,null,null):c.constructor==null&&c.__b>0?c=e.__k[a]=R(c.type,c.props,c.key,c.ref?c.ref:null,c.__v):e.__k[a]=c,p=a+f,c.__=e,c.__b=e.__b+1,s=null,(d=c.__i=Fe(c,r,p,l))!=-1&&(l--,(s=r[d])&&(s.__u|=2)),s==null||s.__v==null?(d==-1&&(i>u?f--:i<u&&f++),typeof c.type!="function"&&(c.__u|=4)):d!=p&&(d==p-1?f--:d==p+1?f++:(d>p?f--:f++,c.__u|=4))):e.__k[a]=null;if(l)for(a=0;a<u;a++)(s=r[a])!=null&&(2&s.__u)==0&&(s.__e==o&&(o=N(s)),xe(s,s));return o}function ve(e,t,r,o){var i,a;if(typeof e.type=="function"){for(i=e.__k,a=0;i&&a<i.length;a++)i[a]&&(i[a].__=e,t=ve(i[a],t,r,o));return t}e.__e!=t&&(o&&(t&&e.type&&!t.parentNode&&(t=N(e)),r.insertBefore(e.__e,t||null)),t=e.__e);do t=t&&t.nextSibling;while(t!=null&&t.nodeType==8);return t}function Fe(e,t,r,o){var i,a,c,s=e.key,p=e.type,d=t[r],u=d!=null&&(2&d.__u)==0;if(d===null&&s==null||u&&s==d.key&&p==d.type)return r;if(o>(u?1:0)){for(i=r-1,a=r+1;i>=0||a<t.length;)if((d=t[c=i>=0?i--:a++])!=null&&(2&d.__u)==0&&s==d.key&&p==d.type)return c}return-1}function _e(e,t,r){t[0]=="-"?e.setProperty(t,r??""):e[t]=r==null?"":typeof r!="number"||Re.test(t)?r:r+"px"}function B(e,t,r,o,i){var a,c;e:if(t=="style")if(typeof r=="string")e.style.cssText=r;else{if(typeof o=="string"&&(e.style.cssText=o=""),o)for(t in o)r&&t in r||_e(e.style,t,"");if(r)for(t in r)o&&r[t]==o[t]||_e(e.style,t,r[t])}else if(t[0]=="o"&&t[1]=="n")a=t!=(t=t.replace(ue,"$1")),c=t.toLowerCase(),t=c in e||t=="onFocusOut"||t=="onFocusIn"?c.slice(2):t.slice(2),e.l||(e.l={}),e.l[t+a]=r,r?o?r.u=o.u:(r.u=G,e.addEventListener(t,a?Q:X,a)):e.removeEventListener(t,a?Q:X,a);else{if(i=="http://www.w3.org/2000/svg")t=t.replace(/xlink(H|:h)/,"h").replace(/sName$/,"s");else if(t!="width"&&t!="height"&&t!="href"&&t!="list"&&t!="form"&&t!="tabIndex"&&t!="download"&&t!="rowSpan"&&t!="colSpan"&&t!="role"&&t!="popover"&&t in e)try{e[t]=r??"";break e}catch{}typeof r=="function"||(r==null||r===!1&&t[4]!="-"?e.removeAttribute(t):e.setAttribute(t,t=="popover"&&r==1?"":r))}}function ye(e){return function(t){if(this.l){var r=this.l[t.type+e];if(t.t==null)t.t=G++;else if(t.t<r.u)return;return r(y.event?y.event(t):t)}}}function Z(e,t,r,o,i,a,c,s,p,d){var u,l,f,h,w,v,_,g,b,S,E,K,H,De,V,O,ae,C=t.type;if(t.constructor!=null)return null;128&r.__u&&(p=!!(32&r.__u),a=[s=t.__e=r.__e]),(u=y.__b)&&u(t);e:if(typeof C=="function")try{if(g=t.props,b="prototype"in C&&C.prototype.render,S=(u=C.contextType)&&o[u.__c],E=u?S?S.props.value:u.__:o,r.__c?_=(l=t.__c=r.__c).__=l.__E:(b?t.__c=l=new C(g,E):(t.__c=l=new L(g,E),l.constructor=C,l.render=We),S&&S.sub(l),l.state||(l.state={}),l.__n=o,f=l.__d=!0,l.__h=[],l._sb=[]),b&&l.__s==null&&(l.__s=l.state),b&&C.getDerivedStateFromProps!=null&&(l.__s==l.state&&(l.__s=j({},l.__s)),j(l.__s,C.getDerivedStateFromProps(g,l.__s))),h=l.props,w=l.state,l.__v=t,f)b&&C.getDerivedStateFromProps==null&&l.componentWillMount!=null&&l.componentWillMount(),b&&l.componentDidMount!=null&&l.__h.push(l.componentDidMount);else{if(b&&C.getDerivedStateFromProps==null&&g!==h&&l.componentWillReceiveProps!=null&&l.componentWillReceiveProps(g,E),t.__v==r.__v||!l.__e&&l.shouldComponentUpdate!=null&&l.shouldComponentUpdate(g,l.__s,E)===!1){for(t.__v!=r.__v&&(l.props=g,l.state=l.__s,l.__d=!1),t.__e=r.__e,t.__k=r.__k,t.__k.some(function($){$&&($.__=t)}),K=0;K<l._sb.length;K++)l.__h.push(l._sb[K]);l._sb=[],l.__h.length&&c.push(l);break e}l.componentWillUpdate!=null&&l.componentWillUpdate(g,l.__s,E),b&&l.componentDidUpdate!=null&&l.__h.push(function(){l.componentDidUpdate(h,w,v)})}if(l.context=E,l.props=g,l.__P=e,l.__e=!1,H=y.__r,De=0,b){for(l.state=l.__s,l.__d=!1,H&&H(t),u=l.render(l.props,l.state,l.context),V=0;V<l._sb.length;V++)l.__h.push(l._sb[V]);l._sb=[]}else do l.__d=!1,H&&H(t),u=l.render(l.props,l.state,l.context),l.state=l.__s;while(l.__d&&++De<25);l.state=l.__s,l.getChildContext!=null&&(o=j(j({},o),l.getChildContext())),b&&!f&&l.getSnapshotBeforeUpdate!=null&&(v=l.getSnapshotBeforeUpdate(h,w)),O=u,u!=null&&u.type===I&&u.key==null&&(O=me(u.props.children)),s=be(e,D(O)?O:[O],t,r,o,i,a,c,s,p,d),l.base=t.__e,t.__u&=-161,l.__h.length&&c.push(l),_&&(l.__E=l.__=null)}catch($){if(t.__v=null,p||a!=null)if($.then){for(t.__u|=p?160:128;s&&s.nodeType==8&&s.nextSibling;)s=s.nextSibling;a[a.indexOf(s)]=null,t.__e=s}else{for(ae=a.length;ae--;)Y(a[ae]);ee(t)}else t.__e=r.__e,t.__k=r.__k,$.then||ee(t);y.__e($,t,r)}else a==null&&t.__v==r.__v?(t.__k=r.__k,t.__e=r.__e):s=t.__e=Be(r.__e,t,r,o,i,a,c,p,d);return(u=y.diffed)&&u(t),128&t.__u?void 0:s}function ee(e){e&&e.__c&&(e.__c.__e=!0),e&&e.__k&&e.__k.forEach(ee)}function we(e,t,r){for(var o=0;o<r.length;o++)te(r[o],r[++o],r[++o]);y.__c&&y.__c(t,e),e.some(function(i){try{e=i.__h,i.__h=[],e.some(function(a){a.call(i)})}catch(a){y.__e(a,i.__v)}})}function me(e){return typeof e!="object"||e==null||e.__b&&e.__b>0?e:D(e)?e.map(me):j({},e)}function Be(e,t,r,o,i,a,c,s,p){var d,u,l,f,h,w,v,_=r.props||A,g=t.props,b=t.type;if(b=="svg"?i="http://www.w3.org/2000/svg":b=="math"?i="http://www.w3.org/1998/Math/MathML":i||(i="http://www.w3.org/1999/xhtml"),a!=null){for(d=0;d<a.length;d++)if((h=a[d])&&"setAttribute"in h==!!b&&(b?h.localName==b:h.nodeType==3)){e=h,a[d]=null;break}}if(e==null){if(b==null)return document.createTextNode(g);e=document.createElementNS(i,b,g.is&&g),s&&(y.__m&&y.__m(t,a),s=!1),a=null}if(b==null)_===g||s&&e.data==g||(e.data=g);else{if(a=a&&T.call(e.childNodes),!s&&a!=null)for(_={},d=0;d<e.attributes.length;d++)_[(h=e.attributes[d]).name]=h.value;for(d in _)if(h=_[d],d!="children"){if(d=="dangerouslySetInnerHTML")l=h;else if(!(d in g)){if(d=="value"&&"defaultValue"in g||d=="checked"&&"defaultChecked"in g)continue;B(e,d,null,h,i)}}for(d in g)h=g[d],d=="children"?f=h:d=="dangerouslySetInnerHTML"?u=h:d=="value"?w=h:d=="checked"?v=h:s&&typeof h!="function"||_[d]===h||B(e,d,h,_[d],i);if(u)s||l&&(u.__html==l.__html||u.__html==e.innerHTML)||(e.innerHTML=u.__html),t.__k=[];else if(l&&(e.innerHTML=""),be(t.type=="template"?e.content:e,D(f)?f:[f],t,r,o,b=="foreignObject"?"http://www.w3.org/1999/xhtml":i,a,c,a?a[0]:r.__k&&N(r,0),s,p),a!=null)for(d=a.length;d--;)Y(a[d]);s||(d="value",b=="progress"&&w==null?e.removeAttribute("value"):w!=null&&(w!==e[d]||b=="progress"&&!w||b=="option"&&w!=_[d])&&B(e,d,w,_[d],i),d="checked",v!=null&&v!=e[d]&&B(e,d,v,_[d],i))}return e}function te(e,t,r){try{if(typeof e=="function"){var o=typeof e.__u=="function";o&&e.__u(),o&&t==null||(e.__u=e(t))}else e.current=t}catch(i){y.__e(i,r)}}function xe(e,t,r){var o,i;if(y.unmount&&y.unmount(e),(o=e.ref)&&(o.current&&o.current!=e.__e||te(o,null,t)),(o=e.__c)!=null){if(o.componentWillUnmount)try{o.componentWillUnmount()}catch(a){y.__e(a,t)}o.base=o.__P=null}if(o=e.__k)for(i=0;i<o.length;i++)o[i]&&xe(o[i],t,r||typeof e.type!="function");r||Y(e.__e),e.__c=e.__=e.__e=void 0}function We(e,t,r){return this.constructor(e,r)}function ke(e,t,r){var o,i,a,c;t==document&&(t=document.documentElement),y.__&&y.__(e,t),i=(o=!1)?null:t.__k,a=[],c=[],Z(t,e=t.__k=he(I,null,[e]),i||A,A,t.namespaceURI,i?null:t.firstChild?T.call(t.childNodes):null,a,i?i.__e:t.firstChild,o,c),we(a,e,c)}T=pe.slice,y={__e:function(e,t,r,o){for(var i,a,c;t=t.__;)if((i=t.__c)&&!i.__)try{if((a=i.constructor)&&a.getDerivedStateFromError!=null&&(i.setState(a.getDerivedStateFromError(e)),c=i.__d),i.componentDidCatch!=null&&(i.componentDidCatch(e,o||{}),c=i.__d),c)return i.__E=i}catch(s){e=s}throw e}},le=0,L.prototype.setState=function(e,t){var r;r=this.__s!=null&&this.__s!=this.state?this.__s:this.__s=j({},this.state),typeof e=="function"&&(e=e(j({},r),this.props)),e&&j(r,e),e!=null&&this.__v&&(t&&this._sb.push(t),fe(this))},L.prototype.forceUpdate=function(e){this.__v&&(this.__e=!0,e&&this.__h.push(e),fe(this))},L.prototype.render=I,M=[],ce=typeof Promise=="function"?Promise.prototype.then.bind(Promise.resolve()):setTimeout,de=function(e,t){return e.__v.__b-t.__v.__b},F.__r=0,ue=/(PointerCapture)$|Capture$/i,G=0,X=ye(!1),Q=ye(!0);const qe='@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-space-y-reverse:0;--tw-space-x-reverse:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-100:oklch(93.6% .032 17.717);--color-red-200:oklch(88.5% .062 18.334);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-red-700:oklch(50.5% .213 27.518);--color-yellow-500:oklch(79.5% .184 86.047);--color-yellow-600:oklch(68.1% .162 75.834);--color-green-100:oklch(96.2% .044 156.743);--color-green-200:oklch(92.5% .084 155.995);--color-green-500:oklch(72.3% .219 149.579);--color-green-600:oklch(62.7% .194 149.214);--color-blue-50:oklch(97% .014 254.604);--color-blue-100:oklch(93.2% .032 255.585);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-blue-700:oklch(48.8% .243 264.376);--color-blue-800:oklch(42.4% .199 265.638);--color-gray-50:oklch(98.5% .002 247.839);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-500:oklch(55.1% .027 264.364);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-700:oklch(37.3% .034 259.733);--color-gray-800:oklch(27.8% .033 256.848);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-md:28rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--tracking-wide:.025em;--tracking-wider:.05em;--radius-lg:.5rem;--radius-xl:.75rem;--ease-out:cubic-bezier(0,0,.2,1);--animate-spin:spin 1s linear infinite;--blur-sm:8px;--blur-md:12px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}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-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);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}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.inset-0{inset:calc(var(--spacing)*0)}.top-1{top:calc(var(--spacing)*1)}.top-4{top:calc(var(--spacing)*4)}.right-4{right:calc(var(--spacing)*4)}.bottom-4{bottom:calc(var(--spacing)*4)}.left-1{left:calc(var(--spacing)*1)}.left-\\[22px\\]{left:22px}.z-50{z-index:50}.z-\\[100\\]{z-index:100}.container{width:100%}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.mr-2{margin-right:calc(var(--spacing)*2)}.mr-2\\.5{margin-right:calc(var(--spacing)*2.5)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.-ml-1{margin-left:calc(var(--spacing)*-1)}.ml-2{margin-left:calc(var(--spacing)*2)}.block{display:block}.flex{display:flex}.inline-flex{display:inline-flex}.h-1\\.5{height:calc(var(--spacing)*1.5)}.h-2{height:calc(var(--spacing)*2)}.h-2\\.5{height:calc(var(--spacing)*2.5)}.h-4{height:calc(var(--spacing)*4)}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-full{height:100%}.max-h-\\[90vh\\]{max-height:90vh}.w-2\\.5{width:calc(var(--spacing)*2.5)}.w-4{width:calc(var(--spacing)*4)}.w-5{width:calc(var(--spacing)*5)}.w-6{width:calc(var(--spacing)*6)}.w-11{width:calc(var(--spacing)*11)}.w-16{width:calc(var(--spacing)*16)}.w-64{width:calc(var(--spacing)*64)}.w-full{width:100%}.max-w-md{max-width:var(--container-md)}.flex-1{flex:1}.flex-shrink-0{flex-shrink:0}.animate-spin{animation:var(--animate-spin)}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.appearance-none{appearance:none}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-2{gap:calc(var(--spacing)*2)}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2\\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2.5)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2.5)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*3)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*3)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*4)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*4)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-8>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*8)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*8)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-x-1>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing)*1)*var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing)*1)*calc(1 - var(--tw-space-x-reverse)))}:where(.space-x-2>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing)*2)*var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-x-reverse)))}:where(.space-x-3>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing)*3)*var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing)*3)*calc(1 - var(--tw-space-x-reverse)))}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-blue-100{border-color:var(--color-blue-100)}.border-blue-400{border-color:var(--color-blue-400)}.border-blue-600{border-color:var(--color-blue-600)}.border-gray-100{border-color:var(--color-gray-100)}.border-gray-200{border-color:var(--color-gray-200)}.border-gray-300{border-color:var(--color-gray-300)}.border-green-200{border-color:var(--color-green-200)}.border-green-600{border-color:var(--color-green-600)}.border-red-200{border-color:var(--color-red-200)}.border-red-600{border-color:var(--color-red-600)}.border-transparent{border-color:#0000}.border-white{border-color:var(--color-white)}.border-yellow-600{border-color:var(--color-yellow-600)}.bg-black\\/20{background-color:#0003}@supports (color:color-mix(in lab,red,red)){.bg-black\\/20{background-color:color-mix(in oklab,var(--color-black)20%,transparent)}}.bg-blue-50{background-color:var(--color-blue-50)}.bg-blue-400{background-color:var(--color-blue-400)}.bg-blue-500{background-color:var(--color-blue-500)}.bg-blue-600{background-color:var(--color-blue-600)}.bg-gray-50{background-color:var(--color-gray-50)}.bg-gray-50\\/30{background-color:#f9fafb4d}@supports (color:color-mix(in lab,red,red)){.bg-gray-50\\/30{background-color:color-mix(in oklab,var(--color-gray-50)30%,transparent)}}.bg-gray-50\\/50{background-color:#f9fafb80}@supports (color:color-mix(in lab,red,red)){.bg-gray-50\\/50{background-color:color-mix(in oklab,var(--color-gray-50)50%,transparent)}}.bg-gray-50\\/80{background-color:#f9fafbcc}@supports (color:color-mix(in lab,red,red)){.bg-gray-50\\/80{background-color:color-mix(in oklab,var(--color-gray-50)80%,transparent)}}.bg-gray-100{background-color:var(--color-gray-100)}.bg-gray-200{background-color:var(--color-gray-200)}.bg-gray-200\\/50{background-color:#e5e7eb80}@supports (color:color-mix(in lab,red,red)){.bg-gray-200\\/50{background-color:color-mix(in oklab,var(--color-gray-200)50%,transparent)}}.bg-green-100{background-color:var(--color-green-100)}.bg-green-500{background-color:var(--color-green-500)}.bg-red-100{background-color:var(--color-red-100)}.bg-red-500{background-color:var(--color-red-500)}.bg-white{background-color:var(--color-white)}.bg-white\\/95{background-color:#fffffff2}@supports (color:color-mix(in lab,red,red)){.bg-white\\/95{background-color:color-mix(in oklab,var(--color-white)95%,transparent)}}.bg-yellow-500{background-color:var(--color-yellow-500)}.bg-gradient-to-r{--tw-gradient-position:to right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-blue-400{--tw-gradient-from:var(--color-blue-400);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-blue-500{--tw-gradient-to:var(--color-blue-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.p-1\\.5{padding:calc(var(--spacing)*1.5)}.p-2{padding:calc(var(--spacing)*2)}.p-3{padding:calc(var(--spacing)*3)}.p-4{padding:calc(var(--spacing)*4)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-5{padding-inline:calc(var(--spacing)*5)}.px-6{padding-inline:calc(var(--spacing)*6)}.py-0\\.5{padding-block:calc(var(--spacing)*.5)}.py-2{padding-block:calc(var(--spacing)*2)}.py-2\\.5{padding-block:calc(var(--spacing)*2.5)}.py-3{padding-block:calc(var(--spacing)*3)}.py-4{padding-block:calc(var(--spacing)*4)}.py-6{padding-block:calc(var(--spacing)*6)}.pt-1{padding-top:calc(var(--spacing)*1)}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\\[10px\\]{font-size:10px}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.text-blue-400{color:var(--color-blue-400)}.text-blue-500{color:var(--color-blue-500)}.text-blue-600{color:var(--color-blue-600)}.text-gray-400{color:var(--color-gray-400)}.text-gray-500{color:var(--color-gray-500)}.text-gray-600{color:var(--color-gray-600)}.text-gray-700{color:var(--color-gray-700)}.text-gray-800{color:var(--color-gray-800)}.text-green-600{color:var(--color-green-600)}.text-red-600{color:var(--color-red-600)}.text-white{color:var(--color-white)}.uppercase{text-transform:uppercase}.accent-blue-600{accent-color:var(--color-blue-600)}.opacity-25{opacity:.25}.opacity-70{opacity:.7}.opacity-75{opacity:.75}.shadow-\\[0_0_8px_rgba\\(59\\,130\\,246\\,0\\.3\\)\\]{--tw-shadow:0 0 8px var(--tw-shadow-color,#3b82f64d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.backdrop-blur-md{--tw-backdrop-blur:blur(var(--blur-md));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.duration-500{--tw-duration:.5s;transition-duration:.5s}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.outline-none{--tw-outline-style:none;outline-style:none}@media(hover:hover){.hover\\:border-gray-200:hover{border-color:var(--color-gray-200)}.hover\\:bg-blue-600:hover{background-color:var(--color-blue-600)}.hover\\:bg-blue-700:hover{background-color:var(--color-blue-700)}.hover\\:bg-gray-50:hover{background-color:var(--color-gray-50)}.hover\\:bg-gray-100:hover{background-color:var(--color-gray-100)}.hover\\:bg-gray-200:hover{background-color:var(--color-gray-200)}.hover\\:bg-red-50:hover{background-color:var(--color-red-50)}.hover\\:bg-white:hover{background-color:var(--color-white)}.hover\\:text-gray-600:hover{color:var(--color-gray-600)}.hover\\:text-gray-800:hover{color:var(--color-gray-800)}.hover\\:text-red-700:hover{color:var(--color-red-700)}.hover\\:underline:hover{text-decoration-line:underline}.hover\\:opacity-100:hover{opacity:1}}.focus\\:border-blue-500:focus{border-color:var(--color-blue-500)}.focus\\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\\:ring-blue-500:focus{--tw-ring-color:var(--color-blue-500)}.active\\:bg-blue-800:active{background-color:var(--color-blue-800)}}:host{--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity));-webkit-text-size-adjust:100%;tab-size:4;border-style:solid;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}*,:before,:after{box-sizing:border-box;border:0 solid #e5e7eb}.panel-style{border:1px solid #9ca3af!important;box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -1px #0000000f!important}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-space-x-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"<length-percentage>";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"<length-percentage>";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"<length-percentage>";inherits:false;initial-value:100%}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@keyframes spin{to{transform:rotate(360deg)}}';var Je=0;function n(e,t,r,o,i,a){t||(t={});var c,s,p=t;if("ref"in p)for(s in p={},t)s=="ref"?c=t[s]:p[s]=t[s];var d={type:e,props:p,key:r,ref:c,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:--Je,__i:-1,__u:0,__source:i,__self:a};if(typeof e=="function"&&(c=e.defaultProps))for(s in c)p[s]===void 0&&(p[s]=c[s]);return y.vnode&&y.vnode(d),d}const Ke=e=>{let t;const r=new Set,o=(d,u)=>{const l=typeof d=="function"?d(t):d;if(!Object.is(l,t)){const f=t;t=u??(typeof l!="object"||l===null)?l:Object.assign({},t,l),r.forEach(h=>h(t,f))}},i=()=>t,s={setState:o,getState:i,getInitialState:()=>p,subscribe:d=>(r.add(d),()=>r.delete(d))},p=t=e(o,i,s);return s},Ve=(e=>Ke),Se={BASE_URL:"/",DEV:!1,MODE:"production",PROD:!0,SSR:!1},P=new Map,W=e=>{const t=P.get(e);return t?Object.fromEntries(Object.entries(t.stores).map(([r,o])=>[r,o.getState()])):{}},Ge=(e,t,r)=>{if(e===void 0)return{type:"untracked",connection:t.connect(r)};const o=P.get(r.name);if(o)return{type:"tracked",store:e,...o};const i={connection:t.connect(r),stores:{}};return P.set(r.name,i),{type:"tracked",store:e,...i}},Xe=(e,t)=>{if(t===void 0)return;const r=P.get(e);r&&(delete r.stores[t],Object.keys(r.stores).length===0&&P.delete(e))},Qe=e=>{var t,r;if(!e)return;const o=e.split(`
|
|
2
|
+
`),i=o.findIndex(c=>c.includes("api.setState"));if(i<0)return;const a=((t=o[i+1])==null?void 0:t.trim())||"";return(r=/.+ (.+) .+/.exec(a))==null?void 0:r[1]},Ye=(e,t={})=>(r,o,i)=>{const{enabled:a,anonymousActionType:c,store:s,...p}=t;let d;try{d=(a??(Se?"production":void 0)!=="production")&&window.__REDUX_DEVTOOLS_EXTENSION__}catch{}if(!d)return e(r,o,i);const{connection:u,...l}=Ge(s,d,p);let f=!0;i.setState=((v,_,g)=>{const b=r(v,_);if(!f)return b;const S=g===void 0?{type:c||Qe(new Error().stack)||"anonymous"}:typeof g=="string"?{type:g}:g;return s===void 0?(u?.send(S,o()),b):(u?.send({...S,type:`${s}/${S.type}`},{...W(p.name),[s]:i.getState()}),b)}),i.devtools={cleanup:()=>{u&&typeof u.unsubscribe=="function"&&u.unsubscribe(),Xe(p.name,s)}};const h=(...v)=>{const _=f;f=!1,r(...v),f=_},w=e(i.setState,o,i);if(l.type==="untracked"?u?.init(w):(l.stores[l.store]=i,u?.init(Object.fromEntries(Object.entries(l.stores).map(([v,_])=>[v,v===l.store?w:_.getState()])))),i.dispatchFromDevtools&&typeof i.dispatch=="function"){let v=!1;const _=i.dispatch;i.dispatch=(...g)=>{(Se?"production":void 0)!=="production"&&g[0].type==="__setState"&&!v&&(console.warn('[zustand devtools middleware] "__setState" action type is reserved to set state from the devtools. Avoid using it.'),v=!0),_(...g)}}return u.subscribe(v=>{var _;switch(v.type){case"ACTION":if(typeof v.payload!="string"){console.error("[zustand devtools middleware] Unsupported action format");return}return re(v.payload,g=>{if(g.type==="__setState"){if(s===void 0){h(g.state);return}Object.keys(g.state).length!==1&&console.error(`
|
|
3
|
+
[zustand devtools middleware] Unsupported __setState action format.
|
|
4
|
+
When using 'store' option in devtools(), the 'state' should have only one key, which is a value of 'store' that was passed in devtools(),
|
|
5
|
+
and value of this only key should be a state object. Example: { "type": "__setState", "state": { "abc123Store": { "foo": "bar" } } }
|
|
6
|
+
`);const b=g.state[s];if(b==null)return;JSON.stringify(i.getState())!==JSON.stringify(b)&&h(b);return}i.dispatchFromDevtools&&typeof i.dispatch=="function"&&i.dispatch(g)});case"DISPATCH":switch(v.payload.type){case"RESET":return h(w),s===void 0?u?.init(i.getState()):u?.init(W(p.name));case"COMMIT":if(s===void 0){u?.init(i.getState());return}return u?.init(W(p.name));case"ROLLBACK":return re(v.state,g=>{if(s===void 0){h(g),u?.init(i.getState());return}h(g[s]),u?.init(W(p.name))});case"JUMP_TO_STATE":case"JUMP_TO_ACTION":return re(v.state,g=>{if(s===void 0){h(g);return}JSON.stringify(i.getState())!==JSON.stringify(g[s])&&h(g[s])});case"IMPORT_STATE":{const{nextLiftedState:g}=v.payload,b=(_=g.computedStates.slice(-1)[0])==null?void 0:_.state;if(!b)return;h(s===void 0?b:b[s]),u?.send(null,g);return}case"PAUSE_RECORDING":return f=!f}return}}),w},re=(e,t)=>{let r;try{r=JSON.parse(e)}catch(o){console.error("[zustand devtools middleware] Could not parse the received json",o)}r!==void 0&&t(r)},Ze=e=>(t,r,o)=>{const i=o.subscribe;return o.subscribe=((c,s,p)=>{let d=c;if(s){const u=p?.equalityFn||Object.is;let l=c(o.getState());d=f=>{const h=c(f);if(!u(l,h)){const w=l;s(l=h,w)}},p?.fireImmediately&&s(l,l)}return i(d)}),e(t,r,o)};var q,m,oe,Ce,ne=0,je=[],x=y,Te=x.__b,Ue=x.__r,Me=x.diffed,Ie=x.__c,Ee=x.unmount,Ne=x.__;function ze(e,t){x.__h&&x.__h(m,e,ne||t),ne=0;var r=m.__H||(m.__H={__:[],__h:[]});return e>=r.__.length&&r.__.push({}),r.__[e]}function $e(e){return ne=1,et(He,e)}function et(e,t,r){var o=ze(q++,2);if(o.t=e,!o.__c&&(o.__=[He(void 0,t),function(s){var p=o.__N?o.__N[0]:o.__[0],d=o.t(p,s);p!==d&&(o.__N=[d,o.__[1]],o.__c.setState({}))}],o.__c=m,!m.__f)){var i=function(s,p,d){if(!o.__c.__H)return!0;var u=o.__c.__H.__.filter(function(f){return!!f.__c});if(u.every(function(f){return!f.__N}))return!a||a.call(this,s,p,d);var l=o.__c.props!==s;return u.forEach(function(f){if(f.__N){var h=f.__[0];f.__=f.__N,f.__N=void 0,h!==f.__[0]&&(l=!0)}}),a&&a.call(this,s,p,d)||l};m.__f=!0;var a=m.shouldComponentUpdate,c=m.componentWillUpdate;m.componentWillUpdate=function(s,p,d){if(this.__e){var u=a;a=void 0,i(s,p,d),a=u}c&&c.call(this,s,p,d)},m.shouldComponentUpdate=i}return o.__N||o.__}function Ae(e,t){var r=ze(q++,3);!x.__s&&ot(r.__H,t)&&(r.__=e,r.u=t,m.__H.__h.push(r))}function tt(){for(var e;e=je.shift();)if(e.__P&&e.__H)try{e.__H.__h.forEach(J),e.__H.__h.forEach(ie),e.__H.__h=[]}catch(t){e.__H.__h=[],x.__e(t,e.__v)}}x.__b=function(e){m=null,Te&&Te(e)},x.__=function(e,t){e&&t.__k&&t.__k.__m&&(e.__m=t.__k.__m),Ne&&Ne(e,t)},x.__r=function(e){Ue&&Ue(e),q=0;var t=(m=e.__c).__H;t&&(oe===m?(t.__h=[],m.__h=[],t.__.forEach(function(r){r.__N&&(r.__=r.__N),r.u=r.__N=void 0})):(t.__h.forEach(J),t.__h.forEach(ie),t.__h=[],q=0)),oe=m},x.diffed=function(e){Me&&Me(e);var t=e.__c;t&&t.__H&&(t.__H.__h.length&&(je.push(t)!==1&&Ce===x.requestAnimationFrame||((Ce=x.requestAnimationFrame)||rt)(tt)),t.__H.__.forEach(function(r){r.u&&(r.__H=r.u),r.u=void 0})),oe=m=null},x.__c=function(e,t){t.some(function(r){try{r.__h.forEach(J),r.__h=r.__h.filter(function(o){return!o.__||ie(o)})}catch(o){t.some(function(i){i.__h&&(i.__h=[])}),t=[],x.__e(o,r.__v)}}),Ie&&Ie(e,t)},x.unmount=function(e){Ee&&Ee(e);var t,r=e.__c;r&&r.__H&&(r.__H.__.forEach(function(o){try{J(o)}catch(i){t=i}}),r.__H=void 0,t&&x.__e(t,r.__v))};var Pe=typeof requestAnimationFrame=="function";function rt(e){var t,r=function(){clearTimeout(o),Pe&&cancelAnimationFrame(t),setTimeout(e)},o=setTimeout(r,35);Pe&&(t=requestAnimationFrame(r))}function J(e){var t=m,r=e.__c;typeof r=="function"&&(e.__c=void 0,r()),m=t}function ie(e){var t=m;e.__c=e.__(),m=t}function ot(e,t){return!e||e.length!==t.length||t.some(function(r,o){return r!==e[o]})}function He(e,t){return typeof t=="function"?t(e):t}const nt=(e,t)=>({init:async r=>{const o=await r.loadConfig(),i=r.getStats();e({configManager:r,config:o,stats:i})},updateConfig:(r,o)=>{e(i=>({config:{...i.config,[r]:o}}))},saveConfig:async()=>{const{configManager:r,config:o}=t();r&&await r.saveConfig(o)},resetConfig:async()=>{const{configManager:r}=t();if(r){await r.resetConfig();const o=r.getConfig();e({config:o})}},toggleSettings:r=>e(o=>({ui:{...o.ui,showSettings:r??!o.ui.showSettings}})),togglePanel:r=>e(o=>({ui:{...o.ui,showPanel:r??!o.ui.showPanel}})),showNotification:(r,o="info",i=3e3)=>{const a=Date.now().toString()+Math.random().toString(36).slice(2,9);e(c=>({ui:{...c.ui,notifications:[...c.ui.notifications,{id:a,type:o,message:r,duration:i}]}})),i>0&&setTimeout(()=>{t().hideNotification(a)},i)},hideNotification:r=>{e(o=>({ui:{...o.ui,notifications:o.ui.notifications.filter(i=>i.id!==r)}}))},refreshStats:()=>{const{configManager:r}=t();r&&e({stats:r.getStats()})},updateAvatar:async()=>{const{configManager:r,updateHandler:o}=t();if(!(!r||!o)){e(i=>({ui:{...i.ui,isUpdating:!0}}));try{console.log("[updateAvatar] Starting avatar update..."),await t().updateHandler?.(),console.log("[updateAvatar] Avatar update completed."),e({stats:r.getStats()})}catch(i){console.error("Update failed:",i)}finally{e(i=>({ui:{...i.ui,isUpdating:!1}}))}}},registerUpdateHandler:r=>{e({updateHandler:r})}}),it={configManager:null,config:{},stats:{},ui:{title:"Daily Avatar",showSettings:!1,showPanel:!1,isUpdating:!1,notifications:[]},updateHandler:null},at=(...e)=>({...it,...nt(...e)}),z=Ve()(Ze(Ye(at,{name:"daily_avatar_UI"}))),k=function(e){const[t,r]=$e(()=>e?e(z.getState()):z.getState());return Ae(()=>z.subscribe(i=>{const a=e?e(i):i;r(c=>c===a?c:a)}),[e]),t};k.getState=z.getState,k.setState=z.setState,k.subscribe=z.subscribe;function lt(){const{ui:{title:e},toggleSettings:t,togglePanel:r}=k();return n("div",{class:"flex items-center justify-between bg-gray-50/80 backdrop-blur-sm px-4 py-3 border-b border-gray-200",children:[n("div",{class:"flex items-center",children:[n("div",{class:"w-2.5 h-2.5 rounded-full bg-blue-500 mr-2.5"}),n("h3",{class:"font-semibold text-gray-700 text-sm tracking-wide",children:e})]}),n("div",{class:"flex space-x-1",children:[n("button",{onClick:()=>t(!0),class:"p-1.5 text-gray-400 hover:text-gray-600 hover:bg-gray-100 rounded-lg",title:"设置",children:n("svg",{class:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:[n("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"}),n("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M15 12a3 3 0 11-6 0 3 3 0 016 0z"})]})}),n("button",{onClick:()=>r(!1),class:"p-1.5 text-gray-400 hover:text-gray-600 hover:bg-gray-100 rounded-lg",title:"关闭",children:n("svg",{class:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:n("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M6 18L18 6M6 6l12 12"})})})]})]})}function st(){const{stats:e}=k(),t=r=>r?new Date(r).toLocaleTimeString("zh-CN",{hour:"2-digit",minute:"2-digit"}):"从未";return n("div",{class:"space-y-2.5",children:[n("div",{class:"flex items-center justify-between text-sm",children:[n("span",{class:"text-gray-500",children:"今日更新"}),n("span",{class:`font-medium px-2 py-0.5 rounded-full text-xs ${e.hasUpdatedToday?"bg-green-100 text-green-600 border border-green-200":"bg-red-100 text-red-600 border border-red-200"}`,children:e.hasUpdatedToday?"已完成":"未完成"})]}),n("div",{class:"flex items-center justify-between text-sm",children:[n("span",{class:"text-gray-500",children:"成功率"}),n("div",{class:"flex items-center space-x-2",children:[n("div",{class:"w-16 h-1.5 bg-gray-100 rounded-full overflow-hidden",children:n("div",{class:`h-full rounded-full ${e.successRate>=90?"bg-green-500":e.successRate>=70?"bg-yellow-500":"bg-red-500"}`,style:{width:`${e.successRate}%`}})}),n("span",{class:"font-medium text-gray-700 text-xs",children:[e.successRate,"%"]})]})]}),n("div",{class:"flex items-center justify-between text-sm",children:[n("span",{class:"text-gray-500",children:"上次更新"}),n("span",{class:"text-gray-700 font-medium text-xs bg-gray-50 px-2 py-0.5 rounded border border-gray-100",children:t(e.lastUpdateTime)})]}),n("div",{class:"flex items-center justify-between text-sm",children:[n("span",{class:"text-gray-500",children:"下次更新"}),n("span",{class:"text-gray-700 font-medium text-xs bg-gray-50 px-2 py-0.5 rounded border border-gray-100",children:t(e.nextUpdateTime)})]})]})}function ct(){const{config:e,stats:t}=k();return t.timeUntilNextUpdate<=0?null:n("div",{class:"bg-gray-50/50 rounded-xl p-3 border border-gray-100",children:[n("div",{class:"flex justify-between text-xs text-gray-500 mb-2",children:[n("span",{children:"等待下次更新"}),n("span",{class:"font-medium text-blue-600",children:[Math.round((1-t.timeUntilNextUpdate/e.updateInterval)*100),"%"]})]}),n("div",{class:"w-full bg-gray-200/50 rounded-full h-1.5 overflow-hidden",children:n("div",{class:"bg-gradient-to-r from-blue-400 to-blue-500 h-full rounded-full transition-all duration-500 ease-out shadow-[0_0_8px_rgba(59,130,246,0.3)]",style:{width:`${(1-t.timeUntilNextUpdate/e.updateInterval)*100}%`}})})]})}function dt(){const{ui:{isUpdating:e},updateAvatar:t}=k();return n("div",{class:"pt-1",children:n("button",{onClick:t,disabled:e,class:`w-full py-2.5 rounded-lg flex items-center justify-center space-x-2 border ${e?"bg-blue-50 border-blue-100 text-blue-400 cursor-not-allowed":"bg-blue-600 border-blue-600 hover:bg-blue-700 text-white active:bg-blue-800"} font-medium text-sm`,children:e?n(I,{children:[n("svg",{class:"animate-spin -ml-1 mr-2 h-4 w-4 text-white",xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",children:[n("circle",{class:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor","stroke-width":"4"}),n("path",{class:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"})]}),n("span",{children:"更新中..."})]}):n(I,{children:[n("svg",{class:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:n("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"})}),n("span",{children:"立即更新"})]})})})}function ut(){const{stats:e}=k();return n("div",{class:"px-4 py-2 bg-gray-50/30 backdrop-blur-sm border-t border-gray-100 text-[10px] text-gray-400 flex justify-between items-center",children:[n("span",{class:"font-medium",children:["成功: ",e.successCount," / 总计: ",e.totalUpdates]}),n("span",{class:"opacity-70",children:"v1.0.0"})]})}function pt(){return n("div",{class:"fixed bottom-4 right-4 z-50 w-64",children:n("div",{class:"bg-white/95 backdrop-blur-md rounded-xl panel-style overflow-hidden hover:bg-white",children:[n(lt,{}),n("div",{class:"p-4 space-y-4",children:[n(st,{}),n(ct,{}),n(dt,{})]}),n(ut,{})]})})}function ht(){const{config:e,updateConfig:t}=k();return n("div",{class:"space-y-4",children:[n("h3",{class:"text-xs font-bold text-gray-400 uppercase tracking-wider",children:"基本设置"}),n("div",{class:"space-y-4",children:[n("label",{class:"flex items-center justify-between group cursor-pointer p-3 rounded-xl hover:bg-gray-50 border border-transparent hover:border-gray-200",children:[n("span",{class:"text-gray-700 font-medium",children:"启用自动更新"}),n("div",{class:"relative inline-flex items-center cursor-pointer",children:[n("input",{type:"checkbox",checked:e.enabled,onChange:r=>t("enabled",r.currentTarget.checked),class:"sr-only"}),n("div",{class:`w-11 h-6 rounded-full border ${e.enabled?"bg-blue-600 border-blue-600":"bg-gray-200 border-gray-200"}`}),n("div",{class:`absolute top-1 bg-white border border-gray-300 rounded-full h-4 w-4 ${e.enabled?"left-[22px] border-white":"left-1"}`})]})]}),n("div",{class:"p-3 rounded-xl bg-gray-50/50 border border-gray-100 space-y-3",children:[n("label",{class:"block text-sm font-medium text-gray-700",children:"更新频率"}),n("div",{class:"space-y-2",children:[n("input",{type:"range",min:"1",max:"168",value:e.updateInterval/(3600*1e3),onChange:r=>t("updateInterval",parseInt(r.currentTarget.value)*60*60*1e3),class:"w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer accent-blue-600"}),n("div",{class:"flex justify-between text-xs text-gray-500 font-medium",children:[n("span",{children:"1小时"}),n("span",{class:"text-blue-600",children:(()=>{const r=Math.floor(e.updateInterval/36e5);if(r<24)return`${r}小时`;const o=Math.floor(r/24),i=r%24;return i>0?`${o}天${i}小时`:`${o}天`})()}),n("span",{children:"7天"})]})]})]}),n("label",{class:"block p-3 rounded-xl bg-gray-50/50 border border-gray-100 cursor-pointer hover:bg-gray-50",children:[n("span",{class:"block text-sm font-medium text-gray-700 mb-2",children:"每天更新时间"}),n("input",{type:"time",value:e.updateTime,onChange:r=>t("updateTime",r.currentTarget.value),class:"w-full px-3 py-2 bg-white border border-gray-200 rounded-lg focus:border-blue-500 outline-none text-sm cursor-pointer"})]})]})]})}function gt(){const{config:e,updateConfig:t}=k();return n("div",{class:"space-y-4",children:[n("h3",{class:"text-xs font-bold text-gray-400 uppercase tracking-wider",children:"头像来源"}),n("div",{class:"space-y-4",children:[n("div",{class:"p-3 rounded-xl bg-gray-50/50 border border-gray-100",children:[n("label",{class:"block text-sm font-medium text-gray-700 mb-2",children:"来源类型"}),n("select",{value:e.avatarSource,onChange:r=>t("avatarSource",r.currentTarget.value),class:"w-full px-3 py-2 bg-white border border-gray-200 rounded-lg focus:border-blue-500 outline-none text-sm appearance-none",children:[n("option",{value:"random",children:"随机头像"}),n("option",{value:"unsplash",children:"Unsplash API"}),n("option",{value:"api",children:"自定义API"}),n("option",{value:"local",children:"本地图片"})]})]}),e.avatarSource==="api"&&n("div",{class:"p-3 rounded-xl bg-gray-50/50 border border-gray-100",children:[n("label",{class:"block text-sm font-medium text-gray-700 mb-2",children:"API地址"}),n("input",{type:"text",value:e.apiUrl,onChange:r=>t("apiUrl",r.currentTarget.value),class:"w-full px-3 py-2 bg-white border border-gray-200 rounded-lg focus:border-blue-500 outline-none text-sm",placeholder:"https://api.example.com/random-avatar"})]}),e.avatarSource==="unsplash"&&n("div",{class:"p-3 rounded-xl bg-gray-50/50 border border-gray-100 space-y-2",children:[n("label",{class:"block text-sm font-medium text-gray-700",children:"Unsplash Access Key"}),n("input",{type:"password",value:e.unsplashKey||"",onChange:r=>t("unsplashKey",r.currentTarget.value),class:"w-full px-3 py-2 bg-white border border-gray-200 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 outline-none transition-all text-sm",placeholder:"输入你的Unsplash Access Key"}),n("p",{class:"text-xs text-gray-500",children:["获取地址: ",n("a",{href:"https://unsplash.com/developers",target:"_blank",rel:"noopener noreferrer",class:"text-blue-500 hover:underline",children:"unsplash.com/developers"})]})]})]})]})}function ft(){const{config:e,updateConfig:t}=k();return n("div",{class:"space-y-4",children:[n("h3",{class:"text-xs font-bold text-gray-400 uppercase tracking-wider",children:"通知设置"}),n("div",{class:"space-y-2 bg-gray-50/50 rounded-xl p-2 border border-gray-100",children:[n("label",{class:"flex items-center justify-between p-2 rounded-lg hover:bg-white cursor-pointer",children:[n("span",{class:"text-sm text-gray-700",children:"启用通知"}),n("input",{type:"checkbox",checked:e.enableNotifications,onChange:r=>t("enableNotifications",r.currentTarget.checked),class:"w-4 h-4 text-blue-600 rounded border-gray-300"})]}),n("label",{class:"flex items-center justify-between p-2 rounded-lg hover:bg-white cursor-pointer",children:[n("span",{class:"text-sm text-gray-700",children:"成功时通知"}),n("input",{type:"checkbox",checked:e.notifyOnSuccess,onChange:r=>t("notifyOnSuccess",r.currentTarget.checked),class:"w-4 h-4 text-blue-600 rounded border-gray-300"})]}),n("label",{class:"flex items-center justify-between p-2 rounded-lg hover:bg-white cursor-pointer",children:[n("span",{class:"text-sm text-gray-700",children:"失败时通知"}),n("input",{type:"checkbox",checked:e.notifyOnFailure,onChange:r=>t("notifyOnFailure",r.currentTarget.checked),class:"w-4 h-4 text-blue-600 rounded border-gray-300"})]})]})]})}function bt(){const{saveConfig:e,resetConfig:t,toggleSettings:r,showNotification:o}=k(),[i,a]=$e(!1);return n("div",{class:"fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/20 backdrop-blur-sm",children:[n("div",{class:"absolute inset-0",onClick:()=>r(!1)}),n("div",{class:"relative bg-white rounded-xl w-full max-w-md max-h-[90vh] overflow-hidden panel-style",children:[n("div",{class:"flex items-center justify-between px-6 py-4 border-b border-gray-200 bg-gray-50/50",children:[n("h2",{class:"text-lg font-semibold text-gray-800 tracking-tight",children:"设置"}),n("button",{onClick:()=>r(!1),class:"p-2 text-gray-400 hover:text-gray-600 hover:bg-gray-200 rounded-lg",children:n("svg",{class:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:n("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M6 18L18 6M6 6l12 12"})})})]}),n("div",{class:"overflow-y-auto custom-scrollbar",style:{maxHeight:"calc(90vh - 140px)"},children:n("div",{class:"px-6 py-6 space-y-8",children:[n(ht,{}),n(gt,{}),n(ft,{})]})}),n("div",{class:"px-6 py-4 border-t border-gray-200 bg-gray-50/50",children:n("div",{class:"flex justify-between items-center",children:[n("button",{onClick:async()=>{confirm("确定要重置为默认设置吗?")&&await t()},class:"text-sm text-red-600 hover:text-red-700 hover:bg-red-50 px-3 py-2 rounded-lg",children:"恢复默认"}),n("div",{class:"space-x-3 flex",children:[n("button",{onClick:()=>r(!1),class:"px-4 py-2 text-sm font-medium text-gray-600 hover:text-gray-800 hover:bg-gray-200 rounded-lg border border-transparent",children:"取消"}),n("button",{onClick:async()=>{a(!0);try{await e(),o("设置已保存","success")}catch(p){console.error("保存失败:",p),o("保存失败","error")}finally{a(!1)}},disabled:i,class:`px-5 py-2 text-sm font-medium text-white rounded-lg border ${i?"bg-blue-400 border-blue-400 cursor-not-allowed":"bg-blue-600 border-blue-600 hover:bg-blue-700 active:bg-blue-800"}`,children:i?"保存中...":"保存设置"})]})]})})]})]})}function vt(){const{refreshStats:e}=k();return Ae(()=>{e();const t=setInterval(()=>{e()},3e4);return()=>clearInterval(t)},[e]),null}const _t={success:"bg-green-500 text-white border-green-600",error:"bg-red-500 text-white border-red-600",warning:"bg-yellow-500 text-white border-yellow-600",info:"bg-blue-500 text-white border-blue-600"},yt={success:n("svg",{class:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:n("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M5 13l4 4L19 7"})}),error:n("svg",{class:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:n("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M6 18L18 6M6 6l12 12"})}),warning:n("svg",{class:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:n("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"})}),info:n("svg",{class:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:n("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"})})};function wt(){const{ui:{notifications:e},hideNotification:t}=k();return e.length===0?null:n("div",{class:"fixed top-4 right-4 z-[100] flex flex-col gap-2 pointer-events-none",children:e.map(r=>n("div",{class:`pointer-events-auto flex items-center gap-2 px-4 py-3 rounded-lg shadow-lg border ${_t[r.type]} animate-fadeIn transition-all duration-300`,style:{minWidth:"200px",maxWidth:"320px"},children:[n("div",{class:"flex-shrink-0",children:yt[r.type]}),n("div",{class:"flex-1 text-sm font-medium",children:r.message}),n("button",{onClick:()=>t(r.id),class:"flex-shrink-0 ml-2 opacity-70 hover:opacity-100 transition-opacity",children:n("svg",{class:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:n("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M6 18L18 6M6 6l12 12"})})})]},r.id))})}function mt(){const{ui:{showSettings:e,showPanel:t},togglePanel:r}=k();function o(){return t?e?n(bt,{}):n(pt,{}):n("div",{class:"fixed bottom-4 right-4 z-50",children:n("button",{onClick:()=>r(!0),class:"bg-blue-500 hover:bg-blue-600 text-white rounded-full p-3 shadow-lg transition duration-200",children:n("svg",{class:"w-6 h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:n("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"})})})})}return n(I,{children:[n(vt,{}),n(wt,{}),o()]})}function Oe(e,t="daily-avatar-ui"){k.getState().init(e);let r=document.getElementById(t);r||(r=document.createElement("div"),r.setAttribute("id",t),r.setAttribute("data-source","https://github.com"),r.style.position="absolute",r.style.top="0",r.style.left="0",r.style.width="0",r.style.height="0",r.style.overflow="visible",r.style.zIndex="2147483647",document.body.appendChild(r));const o=r.shadowRoot||r.attachShadow({mode:"open"});let i=o.querySelector("style");i||(i=document.createElement("style"),o.appendChild(i)),i.textContent=qe;let a=o.getElementById("root");return a||(a=document.createElement("div"),a.id="root",o.appendChild(a)),ke(he(mt,{}),a),{unmount:()=>{a&&ke(null,a),r&&r.remove()}}}typeof window<"u"&&(window.daily_avatar_UI={init:Oe,store:k}),U.init=Oe,Object.defineProperty(U,Symbol.toStringTag,{value:"Module"})}));
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@wuxh/daily-avatar",
|
|
3
|
+
"version": "0.0.1-alpha.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist",
|
|
8
|
+
"userscripts"
|
|
9
|
+
],
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"types": "./dist/index.d.ts"
|
|
14
|
+
},
|
|
15
|
+
"./configManager": {
|
|
16
|
+
"import": "./dist/configManager.mjs",
|
|
17
|
+
"types": "./dist/configManager.d.mts",
|
|
18
|
+
"browser": "./dist/configManager.umd.js"
|
|
19
|
+
},
|
|
20
|
+
"./userscripts/*": {
|
|
21
|
+
"default": "./userscripts/*.user.js"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"scripts": {
|
|
25
|
+
"dev": "vite",
|
|
26
|
+
"build": "npm run build:ui && npm run build:lib && npm run build:userscripts",
|
|
27
|
+
"build:ui": "vite build",
|
|
28
|
+
"build:lib": "tsdown -c ./tsdown.lib.ts",
|
|
29
|
+
"build:userscripts": "tsdown -c ./tsdown.user-scripts.ts",
|
|
30
|
+
"dev:lib": "tsdown --watch",
|
|
31
|
+
"dev:userscripts": "tsdown -c ./tsdown.user-scripts.ts --watch",
|
|
32
|
+
"prepublishOnly": "npm run build"
|
|
33
|
+
},
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"idb": "^8.0.3",
|
|
39
|
+
"preact": "^10.27.2",
|
|
40
|
+
"zustand": "^5.0.9"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@preact/preset-vite": "^2.10.2",
|
|
44
|
+
"@tailwindcss/vite": "^4.1.18",
|
|
45
|
+
"@types/node": "^24.10.1",
|
|
46
|
+
"tailwindcss": "^4.1.18",
|
|
47
|
+
"tsdown": "^0.18.3",
|
|
48
|
+
"typescript": "~5.9.3",
|
|
49
|
+
"vite": "^7.2.4"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
// ==UserScript==
|
|
2
|
+
// @name V2EX Daily Avatar
|
|
3
|
+
// @version 0.0.1-alpha.1
|
|
4
|
+
// @description Automatically update V2EX avatar daily.
|
|
5
|
+
// @grant unsafeWindow
|
|
6
|
+
// @author Wuxh <wuxh16144@qq.com>
|
|
7
|
+
// @homepage https://github.com/wxh16144/daily-avatar
|
|
8
|
+
// @supportURL https://github.com/wxh16144/daily-avatar/issues
|
|
9
|
+
// @license MIT
|
|
10
|
+
// @run-at document-start
|
|
11
|
+
// @noframes
|
|
12
|
+
// @include *
|
|
13
|
+
// ==/UserScript==
|
|
14
|
+
(function() {
|
|
15
|
+
const DEFAULT_CONFIG = {
|
|
16
|
+
enabled: true,
|
|
17
|
+
autoStart: true,
|
|
18
|
+
updateInterval: 1440 * 60 * 1e3,
|
|
19
|
+
updateTime: "09:00",
|
|
20
|
+
checkOnLoad: true,
|
|
21
|
+
enableNotifications: true,
|
|
22
|
+
notifyOnSuccess: true,
|
|
23
|
+
notifyOnFailure: true,
|
|
24
|
+
notifyOnStart: false,
|
|
25
|
+
retryOnFail: true,
|
|
26
|
+
maxRetries: 3,
|
|
27
|
+
retryInterval: 300 * 1e3,
|
|
28
|
+
debugMode: false,
|
|
29
|
+
logToConsole: true,
|
|
30
|
+
avatarSource: "api",
|
|
31
|
+
apiUrl: "",
|
|
32
|
+
unsplashKey: ""
|
|
33
|
+
};
|
|
34
|
+
const defaultState = {
|
|
35
|
+
lastUpdate: 0,
|
|
36
|
+
lastSuccess: 0,
|
|
37
|
+
lastError: null,
|
|
38
|
+
errorCount: 0,
|
|
39
|
+
successCount: 0,
|
|
40
|
+
totalUpdates: 0,
|
|
41
|
+
lastImageUrl: "",
|
|
42
|
+
isUpdating: false,
|
|
43
|
+
nextScheduledUpdate: 0,
|
|
44
|
+
updateHistory: []
|
|
45
|
+
};
|
|
46
|
+
var TampermonkeyConfigManager = class {
|
|
47
|
+
config;
|
|
48
|
+
state;
|
|
49
|
+
constructor() {
|
|
50
|
+
this.config = {};
|
|
51
|
+
this.state = {};
|
|
52
|
+
}
|
|
53
|
+
loadConfig() {
|
|
54
|
+
const savedConfig = GM_getValue("avatarConfig");
|
|
55
|
+
if (!savedConfig) {
|
|
56
|
+
GM_setValue("avatarConfig", DEFAULT_CONFIG);
|
|
57
|
+
return DEFAULT_CONFIG;
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
...DEFAULT_CONFIG,
|
|
61
|
+
...savedConfig
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
saveConfig(newConfig) {
|
|
65
|
+
this.config = {
|
|
66
|
+
...this.config,
|
|
67
|
+
...newConfig
|
|
68
|
+
};
|
|
69
|
+
GM_setValue("avatarConfig", this.config);
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
resetConfig() {
|
|
73
|
+
GM_setValue("avatarConfig", DEFAULT_CONFIG);
|
|
74
|
+
this.config = DEFAULT_CONFIG;
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
getConfig() {
|
|
78
|
+
return { ...this.config };
|
|
79
|
+
}
|
|
80
|
+
loadState() {
|
|
81
|
+
const savedState = GM_getValue("avatarState");
|
|
82
|
+
return savedState ? {
|
|
83
|
+
...defaultState,
|
|
84
|
+
...savedState
|
|
85
|
+
} : defaultState;
|
|
86
|
+
}
|
|
87
|
+
saveState(newState) {
|
|
88
|
+
this.state = {
|
|
89
|
+
...this.state,
|
|
90
|
+
...newState
|
|
91
|
+
};
|
|
92
|
+
if (this.state.updateHistory && this.state.updateHistory.length > 100) this.state.updateHistory = this.state.updateHistory.slice(-100);
|
|
93
|
+
GM_setValue("avatarState", this.state);
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
recordSuccess(imageUrl = "") {
|
|
97
|
+
const now = Date.now();
|
|
98
|
+
const newState = {
|
|
99
|
+
lastUpdate: now,
|
|
100
|
+
lastSuccess: now,
|
|
101
|
+
lastError: null,
|
|
102
|
+
successCount: this.state.successCount + 1,
|
|
103
|
+
totalUpdates: this.state.totalUpdates + 1,
|
|
104
|
+
lastImageUrl: imageUrl,
|
|
105
|
+
isUpdating: false,
|
|
106
|
+
nextScheduledUpdate: now + this.config.updateInterval,
|
|
107
|
+
updateHistory: [...this.state.updateHistory || [], {
|
|
108
|
+
timestamp: now,
|
|
109
|
+
status: "success",
|
|
110
|
+
imageUrl
|
|
111
|
+
}]
|
|
112
|
+
};
|
|
113
|
+
this.saveState(newState);
|
|
114
|
+
return this.state;
|
|
115
|
+
}
|
|
116
|
+
recordError(error) {
|
|
117
|
+
const now = Date.now();
|
|
118
|
+
const newState = {
|
|
119
|
+
lastUpdate: now,
|
|
120
|
+
lastError: {
|
|
121
|
+
message: error.message,
|
|
122
|
+
timestamp: now,
|
|
123
|
+
code: error.code || "UNKNOWN"
|
|
124
|
+
},
|
|
125
|
+
errorCount: this.state.errorCount + 1,
|
|
126
|
+
totalUpdates: this.state.totalUpdates + 1,
|
|
127
|
+
isUpdating: false,
|
|
128
|
+
updateHistory: [...this.state.updateHistory || [], {
|
|
129
|
+
timestamp: now,
|
|
130
|
+
status: "error",
|
|
131
|
+
error: error.message
|
|
132
|
+
}]
|
|
133
|
+
};
|
|
134
|
+
this.saveState(newState);
|
|
135
|
+
return this.state;
|
|
136
|
+
}
|
|
137
|
+
getStats() {
|
|
138
|
+
const now = Date.now();
|
|
139
|
+
const lastUpdate = this.state.lastSuccess;
|
|
140
|
+
const timeSinceLastUpdate = lastUpdate ? now - lastUpdate : null;
|
|
141
|
+
const total = this.state.totalUpdates;
|
|
142
|
+
const success = this.state.successCount;
|
|
143
|
+
const successRate = total > 0 ? Math.round(success / total * 100) : 0;
|
|
144
|
+
const nextUpdate = this.state.nextScheduledUpdate || (lastUpdate ? lastUpdate + this.config.updateInterval : now + this.config.updateInterval);
|
|
145
|
+
const timeUntilNextUpdate = Math.max(0, nextUpdate - now);
|
|
146
|
+
return {
|
|
147
|
+
totalUpdates: total,
|
|
148
|
+
successCount: success,
|
|
149
|
+
errorCount: this.state.errorCount,
|
|
150
|
+
successRate,
|
|
151
|
+
lastUpdateTime: lastUpdate,
|
|
152
|
+
timeSinceLastUpdate,
|
|
153
|
+
timeUntilNextUpdate,
|
|
154
|
+
nextUpdateTime: nextUpdate,
|
|
155
|
+
hasUpdatedToday: this.hasUpdatedToday(),
|
|
156
|
+
lastError: this.state.lastError
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
hasUpdatedToday() {
|
|
160
|
+
const state = GM_getValue("avatarState", {});
|
|
161
|
+
if (!state.lastUpdate) return false;
|
|
162
|
+
const last = new Date(state.lastUpdate);
|
|
163
|
+
const today = /* @__PURE__ */ new Date();
|
|
164
|
+
return last.getDate() === today.getDate() && last.getMonth() === today.getMonth() && last.getFullYear() === today.getFullYear();
|
|
165
|
+
}
|
|
166
|
+
cleanupOldData(daysToKeep = 30) {
|
|
167
|
+
const cutoff = Date.now() - daysToKeep * 24 * 60 * 60 * 1e3;
|
|
168
|
+
if (this.state.updateHistory) {
|
|
169
|
+
const filteredHistory = this.state.updateHistory.filter((entry) => entry.timestamp >= cutoff);
|
|
170
|
+
this.saveState({ updateHistory: filteredHistory });
|
|
171
|
+
}
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
exportData() {
|
|
175
|
+
return {
|
|
176
|
+
config: this.config,
|
|
177
|
+
state: this.state,
|
|
178
|
+
version: "1.0",
|
|
179
|
+
exportDate: (/* @__PURE__ */ new Date()).toISOString()
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
importData(data) {
|
|
183
|
+
if (data.config) this.saveConfig(data.config);
|
|
184
|
+
if (data.state) this.saveState(data.state);
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
listStorage() {
|
|
188
|
+
return GM_listValues();
|
|
189
|
+
}
|
|
190
|
+
clearAllData() {
|
|
191
|
+
GM_deleteValue("avatarConfig");
|
|
192
|
+
GM_deleteValue("avatarState");
|
|
193
|
+
this.config = DEFAULT_CONFIG;
|
|
194
|
+
this.state = this.loadState();
|
|
195
|
+
return true;
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
var AvatarUpdater = class {
|
|
199
|
+
configManager;
|
|
200
|
+
constructor(configManager) {
|
|
201
|
+
this.configManager = configManager;
|
|
202
|
+
}
|
|
203
|
+
isCrossOriginUrl(url) {
|
|
204
|
+
try {
|
|
205
|
+
const apiUrl = new URL(url);
|
|
206
|
+
const currentUrl = new URL(window.location.href);
|
|
207
|
+
return apiUrl.origin !== currentUrl.origin;
|
|
208
|
+
} catch {
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
async fetchAvatarImage() {
|
|
213
|
+
const config = this.configManager.getConfig();
|
|
214
|
+
let url = "";
|
|
215
|
+
switch (config.avatarSource) {
|
|
216
|
+
case "unsplash":
|
|
217
|
+
url = `https://source.unsplash.com/random/128x128?sig=${Date.now()}`;
|
|
218
|
+
break;
|
|
219
|
+
case "api":
|
|
220
|
+
url = config.apiUrl;
|
|
221
|
+
break;
|
|
222
|
+
case "random":
|
|
223
|
+
default:
|
|
224
|
+
url = `https://api.dicebear.com/7.x/avataaars/svg?seed=${Date.now()}`;
|
|
225
|
+
break;
|
|
226
|
+
}
|
|
227
|
+
if (!url) throw new Error("未配置头像源");
|
|
228
|
+
console.log("Fetching avatar from:", url);
|
|
229
|
+
if (this.isCrossOriginUrl(url)) return this.fetchWithGM(url);
|
|
230
|
+
else {
|
|
231
|
+
const response = await fetch(url);
|
|
232
|
+
if (!response.ok) throw new Error(`获取图片失败: ${response.status}`);
|
|
233
|
+
return await response.blob();
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
async uploadAvatar(blob) {
|
|
237
|
+
new FormData().append("avatar", blob, "avatar.png");
|
|
238
|
+
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
239
|
+
return { success: true };
|
|
240
|
+
}
|
|
241
|
+
async uploadWithFetch(formData) {
|
|
242
|
+
const response = await fetch("/settings/avatar", {
|
|
243
|
+
method: "POST",
|
|
244
|
+
body: formData,
|
|
245
|
+
credentials: "include"
|
|
246
|
+
});
|
|
247
|
+
if (!response.ok) throw new Error(`上传失败: ${response.status}`);
|
|
248
|
+
return await response.json();
|
|
249
|
+
}
|
|
250
|
+
fetchWithGM(url) {
|
|
251
|
+
return new Promise((resolve, reject) => {
|
|
252
|
+
GM_xmlhttpRequest({
|
|
253
|
+
method: "GET",
|
|
254
|
+
url,
|
|
255
|
+
responseType: "blob",
|
|
256
|
+
onload: (response) => {
|
|
257
|
+
if (response.status === 200) resolve(response.response);
|
|
258
|
+
else reject(/* @__PURE__ */ new Error(`GM请求失败: ${response.status}`));
|
|
259
|
+
},
|
|
260
|
+
onerror: (error) => {
|
|
261
|
+
reject(error);
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
async execute() {
|
|
267
|
+
try {
|
|
268
|
+
const blob = await this.fetchAvatarImage();
|
|
269
|
+
await this.uploadAvatar(blob);
|
|
270
|
+
this.configManager.recordSuccess();
|
|
271
|
+
} catch (error) {
|
|
272
|
+
throw error;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
const waitForUI = () => {
|
|
277
|
+
return new Promise((resolve) => {
|
|
278
|
+
if (window.daily_avatar_UI) resolve();
|
|
279
|
+
else {
|
|
280
|
+
const check = setInterval(() => {
|
|
281
|
+
if (window.daily_avatar_UI) {
|
|
282
|
+
clearInterval(check);
|
|
283
|
+
resolve();
|
|
284
|
+
}
|
|
285
|
+
}, 100);
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
};
|
|
289
|
+
async function main() {
|
|
290
|
+
await waitForUI();
|
|
291
|
+
const configManager = new TampermonkeyConfigManager();
|
|
292
|
+
const updater = new AvatarUpdater(configManager);
|
|
293
|
+
const { init, store } = window.daily_avatar_UI;
|
|
294
|
+
init(configManager);
|
|
295
|
+
store.getState().registerUpdateHandler(async () => {
|
|
296
|
+
await updater.execute();
|
|
297
|
+
});
|
|
298
|
+
console.log("V2EX Daily Avatar initialized");
|
|
299
|
+
}
|
|
300
|
+
main();
|
|
301
|
+
})();
|