asai-vue-host 0.2.59 → 0.2.60

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 CHANGED
@@ -2,109 +2,189 @@
2
2
 
3
3
  ## 包信息
4
4
 
5
- | 建议 npm 名 | 入口文件 | $fn / 注入键 | 类型 |
5
+ | 建议 npm 名 | 入口文件 | 注入键 | 类型 |
6
6
  |------------|---------|-------------|------|
7
- | `@estun/asai-vue-host` | `src/components/index.ts` | `$engineasai`(provide/inject) | Host |
7
+ | `@estun/asai-vue-host` | `src/components/index.ts` | `$engineasai`(loadts)/ `$ujtasai`(provide/inject) | Host |
8
8
 
9
9
  ## 概述
10
10
 
11
- `asai-vue-host` 是 AsaiWeb CMS 的**核心应用宿主框架**,提供应用加载、模块管理、Hash 路由分发、WebSocket 通信和数据库响应式 Provide。是整个前端架构的运行容器。
11
+ `asai-vue-host` 是 AsaiWeb CMS 的**核心应用宿主框架**,是整个前端架构的运行容器。职责:
12
+
13
+ - 装配并 `provide('$ujtasai')` 全局运行时上下文(`$db / $dbwork / $ws / $global / $model / $fn`)
14
+ - 应用启动流程(`initweb`):加载 webmodel、解析路由配置、建立连接、初始化国际化
15
+ - 无框架 **Hash / History 路由**分发(`AsRouter` + `RouterView.vue`),不依赖 vue-router
16
+ - 通用工具集(`As`):URL、Cookie、本地缓存、时间、序列化、节流防抖、深拷贝等
17
+ - 全局组件懒加载注册(`asui/*/*.vue`:模块容器、加载/错误页、404 等)
18
+
19
+ > 配套宿主插件:`asai-vue-host-base`(`$engineasai1`:API/WS/心跳/AES)、`asai-vue-host-channel`(`$engineasai2`:频道)、`-form` / `-popbox` / `-directives`(全局组件与指令)。它们在 `$fn.initweb()` 时被合并进 `$fn`。
12
20
 
13
21
  ## 集成方式
14
22
 
15
23
  ```typescript
16
24
  // monorepo — webclient/src/utils/index.ts
17
25
  import AsaiVueHost from '../plugs/asai-vue-host/src/components/index';
18
- // import '/node_modules/asai-vue-host/dist/asai-vue-host.css';
19
- // npm
20
- // import AsaiVueHost from '@estun/asai-vue-host';
26
+ // npm: import AsaiVueHost from '@estun/asai-vue-host';
21
27
 
22
- installModules.forEach((module) => module.install(app, lib));
28
+ installModules.forEach((module) => module.install(app, lib)); // lib 由 LibInit() 提供 loadts/loadvue/loadfn
23
29
  ```
24
30
 
25
- ## 独立性约束
26
-
27
- - **禁止** cross-import 其它 `plugs/*`。
28
- - 通过 `LibInit` 传入的 `loadts` / `loadvue` / `loadfn` 与宿主 app 耦合,不反向依赖 Feature 插件。
31
+ ```typescript
32
+ // App.vue —— 仅执行一次,注入全局上下文
33
+ import useProvide from '../plugs/asai-vue-host/.../asengine/provide/useProvide';
34
+ const { $ujtasai } = useProvide({ plugs: { /* 同步功能插件 */ } });
35
+ ```
29
36
 
30
- ## 主要 API / 导出
37
+ ## 独立性约束
31
38
 
32
- | 导出 | 说明 |
33
- |------|------|
34
- | `install(app, opt)` | Vue 插件安装入口 |
35
- | Provide `$engineasai` | 主引擎 composable 与工具 |
36
- | `providedb` / `providews` / `providefn` / `providedbwork` | 全局 Provide 键 |
37
- | 全局组件 | `asui/*/*.vue` 懒加载注册(AsaiWebModule、PageLoad* 等) |
39
+ - **禁止** cross-import 其它 `plugs/*`;仅通过运行时 `$fn` / `$global` 协作。
40
+ - 通过 `LibInit` 传入的 `loadts` / `loadvue` / `loadfn` 与宿主 app 解耦,不反向依赖 Feature 插件。
41
+ - ⚠️ `loadts` 按**文件名**注册键(`path.split('/').pop().slice(0,-3)`)。`asengine/common/*.ts` 会被 eager glob 注册为 `$engineasai.<文件名>`,故**不要**在该目录放置临时/重命名副本文件(如 `AsAES copy.ts`),否则会污染 `$fn` 键空间。
38
42
 
39
- ## 性能说明
43
+ ## 文件结构
40
44
 
41
- - TS 模块(`asengine`)**eager** 加载;Vue 组件 **lazy**(`eager: false`),首次渲染拉 chunk。
42
- - 核心首屏组件若出现白屏闪烁,可在业务侧对关键组件单独 eager。
45
+ ```
46
+ asai-vue-host/src/components/
47
+ ├── index.ts # install 入口(loadts $engineasai + loadvue asui)
48
+ ├── asengine/
49
+ │ ├── common/
50
+ │ │ ├── As.ts # → $fn.As 通用工具集(无状态)
51
+ │ │ └── AsRouter.ts # → $fn.AsRouter Hash/History 路由器
52
+ │ ├── init/useInitApp.ts # → $fn.useInitApp 业务模块按需安装
53
+ │ └── provide/
54
+ │ ├── useProvide.ts # 装配 $ujtasai 并 provide(核心启动)
55
+ │ ├── providedb / providedbwork / providews / provideglobal / providefn
56
+ │ └── (响应式数据域默认值)
57
+ └── asui/ # 全局组件(loadvue 懒加载,按文件名注册)
58
+ ├── app/ AsaiWebServer / AsaiWebModule / AsaiWebItemIndex …
59
+ ├── common/ RouterView / RouterMap / AsPageBusy / AsSvg / VirtualList …
60
+ └── page/ PageLoadWs / PageLoadErr / PageLoadServer …
61
+ ```
43
62
 
44
- ## peerDependencies 建议
63
+ ## 安装入口(install)
45
64
 
46
- ```json
47
- {
48
- "peerDependencies": {
49
- "vue": "^3.4.0",
50
- "vue-router": "^4.0.0"
51
- }
65
+ ```typescript
66
+ install(app, opt) {
67
+ opt.loadts({ app, key: '$engineasai', eager: true,
68
+ files: import.meta.glob(['./asengine/common/*.ts', './asengine/*/use*.ts'], { eager: true }) });
69
+ opt.loadvue({ loadfn: opt.loadfn, app, eager: false,
70
+ files: import.meta.glob(['./asui/*/*.vue']) }); // 首次渲染才拉 chunk
52
71
  }
53
72
  ```
54
73
 
55
- ---
56
-
57
- ## 功能
74
+ ## 全局上下文 `$ujtasai`
75
+
76
+ | 域 | 来源 | 说明 |
77
+ |----|------|------|
78
+ | `$db` | providedb | IndexedDB / 业务响应式数据 |
79
+ | `$dbwork` | providedbwork | 数据库工作态 |
80
+ | `$ws` | providews | WebSocket 响应式数据 |
81
+ | `$global` | provideglobal | `sys / config / user / code / location / pop / link / theme / keyboard …` |
82
+ | `$model` | `window.$GYS.$webmodel` | webmodel 模型与组件表(`comps`) |
83
+ | `$fn` | providefn + 各插件合并 | 全部平台功能函数(见下) |
84
+
85
+ ## 核心 API:`$fn`(useProvide 挂载)
86
+
87
+ | 函数 | 签名 | 说明 |
88
+ |------|------|------|
89
+ | `initweb(insProxy)` | `async (insProxy) => void` | **应用启动**:合并引擎、加载 `sys/dirglobal.json`、版本校验、`dirmodel.json`、路由配置合并、`initLink`、初始化 hash 路由 |
90
+ | `offweb()` | `() => void` | 卸载路由监听 |
91
+ | `initLink(type?)` | `(0\|1) => Promise<link>` | 解析 `sys/server.json` 为 `$global.link`(含缓存 `as-link`) |
92
+ | `startLink()` / `saveLink(data)` | — | 强制重新解析 / 直接写入连接表 |
93
+ | `lg(path, params?)` | `(string, string\|string[]) => string` | 取国际化文案,`$1/$2` 占位符替换(路径解析带 Map 缓存) |
94
+ | `initlang(langty?)` / `changelang(langty?)` | `=> Promise` | 初始化 / 切换语言包(`auto` 在两语言间切换) |
95
+ | `initver()` | `() => boolean` | `$global.sys.webver` 变化时清缓存刷新 |
96
+ | `lo(...args)` / `$log(data)` / `logSave(data)` | — | 带样式 console / 写入后端日志(`/api/asailog/manage/addclient/`) |
97
+ | `inittoken()` / `gettoken(type?)` | — | 由 `code.pri/pub` + 用户信息生成 `us##lv##pub` token |
98
+ | `login()` / `exit(type?)` | — | 清空 `as-user-info` 与会话,跳登录 / 退出 |
99
+ | `checkOnline()` | `=> Promise` | WS `ping/pong` 在线探测 |
100
+ | `setquery(value, type?)` / `sethash(value)` | — | 改写地址栏 query / hash(History 模式用 pushState) |
101
+ | `getWebPath(path)` | `(string) => string` | 拼接 `$cfg.webpath` 前缀 |
102
+ | `initmodel(url, prefix?)` | — | 由 `AsaiModel` 拉取 `webmodel/` 模型 |
103
+
104
+ ## 核心 API:`$fn.As`(通用工具集)
105
+
106
+ | 分组 | 方法 |
107
+ |------|------|
108
+ | URL/链接 | `getUrlByCfg(cfg, type)` |
109
+ | Cookie | `cookiesSet/Get/Del/Clear`、`cookiesSetByEncodeURI` |
110
+ | 文件 | `readFile(file, ty)`、`downloadTxt(data, name)`、`downloadFile(url, name)` |
111
+ | 本地缓存 | `localSet/Get/Remove/Clear/Clears`、`localInit`(清空+刷新)、`localReload`、`localTime` |
112
+ | DOM/全屏 | `fullScreen/fullScreenExit/fullScreenDo`、`eStop(e)` |
113
+ | 数据结构 | `treeToMap(tree, opt)`(迭代平铺为 `{nodeMap, depthMap}`,支持过滤)、`arrLenMax`、`toArr` |
114
+ | 路径/校验 | `getPath` / `getName`(白名单过滤)、`isValidFileName`、`setObjValByPath`(**已防原型链污染**) |
115
+ | 时间 | `getTime(type, timenow)`、`toFormTime` / `fromFormTime` |
116
+ | 序列化 | `toObj` / `toStr`(防循环引用)、`toNum` / `toNums` |
117
+ | 唯一 ID | `Uuid(prefix, index, hex)`(`crypto.getRandomValues` 随机位,16 位) |
118
+ | 性能 | `debounce(fn, opt)`、`throttle(fn, opt)`(`opt` 持有 `timeout/wait/immediate`) |
119
+ | 剪贴板 | `copyToClipboard` / `readFromClipboard`(localStorage 兼容方案) |
120
+ | 深拷贝 | `DeepClone(obj)`(WeakMap 防环,支持 Date/RegExp/Map/Set) |
121
+ | 远程 | `apiJsonp(url, callback)`(script 标签 JSONP,回调名随机,完成后清理) |
122
+
123
+ ## 核心 API:`$fn.AsRouter`(无框架路由)
124
+
125
+ | 方法 | 说明 |
126
+ |------|------|
127
+ | `initHash(routerdata)` / `offHash()` | 绑定 / 移除 `popstate`(History)或 `hashchange`(Hash)监听 |
128
+ | `setHash(routerdata, value)` | 改写地址(History `pushState` 或 `location.hash`) |
129
+ | `setHref / getHref` | 整页跳转 / 读取 URL |
130
+ | `getQuery(routerdata, str?)` | 解析 query(**已修正含 `=` 的值截断与非法编码**) |
131
+ | `getHasharr(routerdata)` | hash → 路径数组(去尾空段、分离 query) |
132
+ | `setRouter(routerdata)` | hash → comps:`#/a/b/c` → [`a/index`, `a/b/index`, `a/b/c/default`] |
133
+ | `setTitle(title, ujt)` | 设置文档标题(拼接站点大标题) |
58
134
 
59
- - 应用启动、模块管理、Hash 路由分发
60
- - WebSocket 连接管理与事件系统
61
- - IndexedDB / 本地数据响应式 Provide
62
- - 加载状态与错误页面(404、PageLoadErr 等)
135
+ 路由组件由 `RouterView.vue` 依 `$global.location.comps[ty]` 经 `$fn.getcomp` 动态加载,缺失回退 `Asai404.vue`。
63
136
 
64
- ## 文件结构
137
+ ## 全局组件
65
138
 
66
- ```
67
- asai-vue-host/
68
- ├── src/components/
69
- │ ├── index.ts # install 入口
70
- │ ├── asengine/provide/ # providedb / providews / providefn
71
- │ └── asui/ # app / common / page 组件
72
- └── README.md
73
- ```
139
+ | 组件 | 说明 |
140
+ |------|------|
141
+ | `RouterView` / `RouterMap` | Hash 路由视图 / 路由映射 |
142
+ | `AsaiWebServer` / `AsaiWebModule` / `AsaiWebItemIndex` | 服务器连接 / 模块容器 / 应用主入口 |
143
+ | `PageLoadWs` / `PageLoadServer` / `PageLoadErr` / `PageErr` | 连接与错误页 |
144
+ | `AsPageBusy` / `AsLoadingCircle` / `AsLoadingA3d` / `AsPageBusyGif` | 加载动画 |
145
+ | `Asai404` | 404 页面 |
146
+ | `AsSvg` / `VirtualList` / `MenuShowFix` / `AsReset` | SVG / 虚拟列表 / 菜单 / 样式重置 |
74
147
 
75
- ## 安装方式
148
+ ## 使用示例
76
149
 
77
150
  ```typescript
78
- app.use(AsaiVueHost, {
79
- loadts: (options) => { /* 加载 TypeScript 模块 */ },
80
- loadvue: (options) => { /* 加载 Vue 组件 */ },
81
- loadfn: (path) => { /* 加载函数 */ },
82
- });
151
+ const { $fn, $global } = ujt;
152
+
153
+ // 路由
154
+ $fn.sethash('user/login');
155
+ $fn.setquery({ id: 1 }, 1); // 合并 query
156
+
157
+ // 国际化
158
+ $fn.lg('sys.webtit'); // 取词
159
+ $fn.lg('user.hello', [name]); // 占位符 $1 → name
160
+ await $fn.changelang('auto');
161
+
162
+ // 工具
163
+ const { nodeMap, depthMap } = $fn.As.treeToMap(tree, { id: 'sn', ch: 'children' });
164
+ $fn.As.localSet('k', { a: 1 });
165
+ $fn.As.debounce(save, opt); // opt = { wait: 300 }
83
166
  ```
84
167
 
85
- ## Provide 系统
168
+ ```vue
169
+ <RouterView :ujt="ujt" :ty="0" />
170
+ <AsaiWebModule :ujt="ujt" />
171
+ ```
86
172
 
87
- | Provide Key | 说明 |
88
- |-------------|------|
89
- | `$engineasai` | 主引擎上下文 |
90
- | `providedb` | 数据库响应式数据 |
91
- | `providews` | WebSocket 数据 |
92
- | `providefn` | 功能函数 |
93
- | `providedbwork` | 数据库工作线程 |
173
+ ## 性能说明
94
174
 
95
- ## 核心组件
175
+ - TS 模块(`asengine`)**eager** 加载(启动即需);Vue 组件 **lazy**(`eager: false`),首次渲染拉 chunk。
176
+ - `useProvide` 全应用**仅执行一次**;`lg` 路径解析与正则均预编译/缓存。
177
+ - `AsRouter` 监听器引用单独保存,`offHash` 精确移除,避免重复绑定与泄漏。
178
+ - 核心首屏组件若白屏闪烁,可在业务侧对关键组件单独 eager。
96
179
 
97
- | 组件 | 说明 |
98
- |------|------|
99
- | `AsaiWebServer` | 服务器连接管理 |
100
- | `AsaiWebModule` | 模块容器 |
101
- | `AsaiWebItemIndex` | 应用主入口 |
102
- | `AsPageBusy` / `AsLoadingCircle` | 加载动画 |
103
- | `PageLoadWs` / `PageLoadErr` | 连接/错误页 |
104
- | `Asai404` | 404 页面 |
180
+ ## 安全说明
105
181
 
106
- ## 技术细节
182
+ - `setObjValByPath` 拒绝 `__proto__` / `prototype` / `constructor` 键,防原型链污染。
183
+ - `apiJsonp` 用 `script.src` + 随机回调名,避免 `innerHTML` 注入;完成/失败均清理回调与节点。
184
+ - `getPath` / `getName` / `isValidFileName` 对外部输入做白名单与非法字符过滤。
107
185
 
108
- - Vue 插件 `install(app, opt)` 模式
109
- - `import.meta.glob` 自动发现并注册组件
110
- - 异步组件按需加载减少首屏体积
186
+ ## peerDependencies 建议
187
+
188
+ ```json
189
+ { "peerDependencies": { "vue": "^3.4.0" } }
190
+ ```
@@ -0,0 +1,51 @@
1
+ import { defineComponent as g, useCssVars as v, computed as y, resolveComponent as f, resolveDirective as b, withDirectives as x, createCommentVNode as u, unref as s, createElementBlock as r, openBlock as d, createElementVNode as o, withModifiers as B, createVNode as h, toDisplayString as k } from "vue";
2
+ import { _ as C } from "./_plugin-vue_export-helper-CHgC5LLL.mjs";
3
+ const j = {
4
+ key: 0,
5
+ class: "as-pagebusy-area touch-none"
6
+ }, A = { class: "as-pagebusy" }, w = { class: "as-load-icon" }, P = {
7
+ key: 0,
8
+ class: "as-load-msg"
9
+ }, V = /* @__PURE__ */ g({
10
+ __name: "AsPageBusy",
11
+ props: {
12
+ ujt: {}
13
+ },
14
+ setup(t) {
15
+ v((p) => ({
16
+ v7d9d0622: a.value
17
+ }));
18
+ const l = t, { $global: e, $fn: n } = l.ujt, a = y(() => e.pagebusy?.zindex || 9999);
19
+ function c() {
20
+ n.popConfirm({
21
+ con: e.lang.asai.resetconfirm,
22
+ zindex: a.value + 1,
23
+ fn: () => {
24
+ e.pagebusy = null, n.As.localInit();
25
+ }
26
+ });
27
+ }
28
+ return (p, i) => {
29
+ const _ = f("AsPageBusyGif"), m = b("dbpointerdown");
30
+ return s(e).pagebusy ? x((d(), r("div", j, [
31
+ o("div", {
32
+ class: "as-pagebusy-close",
33
+ onClick: i[0] || (i[0] = B((D) => c(), ["stop"]))
34
+ }),
35
+ o("div", A, [
36
+ o("div", w, [
37
+ h(_, { ujt: t.ujt }, null, 8, ["ujt"])
38
+ ]),
39
+ s(e).pagebusy?.v ? (d(), r("div", P, k(s(e).pagebusy?.v), 1)) : u("", !0)
40
+ ])
41
+ ])), [
42
+ [m, () => {
43
+ s(e).pagebusy?.keep || c();
44
+ }]
45
+ ]) : u("", !0);
46
+ };
47
+ }
48
+ }), z = /* @__PURE__ */ C(V, [["__scopeId", "data-v-a9b32b31"]]);
49
+ export {
50
+ z as default
51
+ };
@@ -1,6 +1,6 @@
1
- import { defineComponent as c, createElementBlock as l, openBlock as t, normalizeStyle as o, createStaticVNode as n, createBlock as i, unref as s } from "vue";
2
- import { _ as u } from "./_plugin-vue_export-helper-CHgC5LLL.mjs";
3
- const f = /* @__PURE__ */ c({
1
+ import { defineComponent as i, createElementBlock as l, openBlock as t, normalizeStyle as u, createStaticVNode as o, createBlock as c, unref as s } from "vue";
2
+ import { _ as n } from "./_plugin-vue_export-helper-CHgC5LLL.mjs";
3
+ const f = /* @__PURE__ */ i({
4
4
  __name: "AsLoadingCircle",
5
5
  props: {
6
6
  ujt: {
@@ -16,10 +16,10 @@ const f = /* @__PURE__ */ c({
16
16
  setup(e) {
17
17
  return (d, a) => (t(), l("div", {
18
18
  class: "as-load-gif",
19
- style: o({ width: e.size + "px", height: e.size + "px" })
19
+ style: u({ width: e.size + "px", height: e.size + "px" })
20
20
  }, null, 4));
21
21
  }
22
- }), r = /* @__PURE__ */ u(f, [["__scopeId", "data-v-c5bf2081"]]), v = /* @__PURE__ */ c({
22
+ }), r = /* @__PURE__ */ i({
23
23
  __name: "AsLoadingA3d",
24
24
  props: {
25
25
  ujt: {
@@ -35,12 +35,12 @@ const f = /* @__PURE__ */ c({
35
35
  setup(e) {
36
36
  return (d, a) => (t(), l("div", {
37
37
  class: "a3d-wrapper",
38
- style: o({ "--cube-size": `${e.size}px`, "--half-size": `${e.size / 2}px` })
38
+ style: u({ "--cube-size": `${e.size}px`, "--half-size": `${e.size / 2}px` })
39
39
  }, [...a[0] || (a[0] = [
40
- n('<div class="a3d" data-v-4d1d2b0e><div class="a3d-face a3d-face-front" data-v-4d1d2b0e></div><div class="a3d-face a3d-face-back" data-v-4d1d2b0e></div><div class="a3d-face a3d-face-left" data-v-4d1d2b0e></div><div class="a3d-face a3d-face-right" data-v-4d1d2b0e></div><div class="a3d-face a3d-face-top" data-v-4d1d2b0e></div><div class="a3d-face a3d-face-bottom" data-v-4d1d2b0e></div></div>', 1)
40
+ o('<div class="a3d" data-v-4d1d2b0e><div class="a3d-face a3d-face-front" data-v-4d1d2b0e></div><div class="a3d-face a3d-face-back" data-v-4d1d2b0e></div><div class="a3d-face a3d-face-left" data-v-4d1d2b0e></div><div class="a3d-face a3d-face-right" data-v-4d1d2b0e></div><div class="a3d-face a3d-face-top" data-v-4d1d2b0e></div><div class="a3d-face a3d-face-bottom" data-v-4d1d2b0e></div></div>', 1)
41
41
  ])], 4));
42
42
  }
43
- }), p = /* @__PURE__ */ u(v, [["__scopeId", "data-v-4d1d2b0e"]]), g = /* @__PURE__ */ c({
43
+ }), v = /* @__PURE__ */ n(r, [["__scopeId", "data-v-4d1d2b0e"]]), y = /* @__PURE__ */ i({
44
44
  __name: "AsPageBusyGif",
45
45
  props: {
46
46
  ujt: {},
@@ -48,11 +48,11 @@ const f = /* @__PURE__ */ c({
48
48
  },
49
49
  setup(e) {
50
50
  const d = e, { $global: a } = d.ujt;
51
- return (b, z) => e.opt?.ty || s(a).pagebusy?.ty ? (t(), i(p, {
51
+ return (p, b) => e.opt?.ty || s(a).pagebusy?.ty ? (t(), c(v, {
52
52
  key: 0,
53
53
  size: e.opt?.size || s(a).pagebusy?.size,
54
54
  ujt: e.ujt
55
- }, null, 8, ["size", "ujt"])) : (t(), i(r, {
55
+ }, null, 8, ["size", "ujt"])) : (t(), c(f, {
56
56
  key: 1,
57
57
  size: e.opt?.size || s(a).pagebusy?.size,
58
58
  ujt: e.ujt
@@ -60,5 +60,5 @@ const f = /* @__PURE__ */ c({
60
60
  }
61
61
  });
62
62
  export {
63
- g as default
63
+ y as default
64
64
  };
@@ -0,0 +1,4 @@
1
+ import { _ as f } from "./AsPageLoading.vue_vue_type_script_setup_true_lang-D6ucjG6K.mjs";
2
+ export {
3
+ f as default
4
+ };
@@ -0,0 +1,49 @@
1
+ import { defineComponent as d, ref as g, onMounted as u, createElementBlock as a, openBlock as c, createCommentVNode as m, createElementVNode as l, createTextVNode as f, renderSlot as p, toDisplayString as w } from "vue";
2
+ const v = { class: "as-load-area" }, _ = ["src"], $ = { class: "as-load-msg" }, k = /* @__PURE__ */ d({
3
+ __name: "AsPageLoading",
4
+ props: {
5
+ ujt: {},
6
+ msg: {}
7
+ },
8
+ setup(n) {
9
+ const s = n, t = g("");
10
+ u(() => {
11
+ const e = window;
12
+ t.value = s.ujt?.$global?.$cfg?.logo || e?.$CFG?.logo || "/webmodel/files/logo.png";
13
+ });
14
+ function i() {
15
+ const e = window, o = s.ujt?.$fn;
16
+ if (o?.As?.localInit) {
17
+ o.As.localInit();
18
+ return;
19
+ }
20
+ try {
21
+ e?.localStorage?.clear();
22
+ } catch {
23
+ console.warn("Failed to clear localStorage");
24
+ }
25
+ e?.location?.reload();
26
+ }
27
+ return (e, o) => (c(), a("div", v, [
28
+ t.value ? (c(), a("img", {
29
+ key: 0,
30
+ src: t.value,
31
+ width: "200",
32
+ onDblclick: o[0] || (o[0] = (r) => i())
33
+ }, null, 40, _)) : m("", !0),
34
+ o[1] || (o[1] = l("div", { class: "as-load-icon" }, [
35
+ l("div", {
36
+ class: "as-load-gif",
37
+ style: { width: "68px", height: "68px" }
38
+ })
39
+ ], -1)),
40
+ l("div", $, [
41
+ f(w(n.msg || "Loading...") + " ", 1),
42
+ p(e.$slots, "default")
43
+ ])
44
+ ]));
45
+ }
46
+ });
47
+ export {
48
+ k as _
49
+ };
@@ -0,0 +1,21 @@
1
+ import { defineComponent as o, computed as a, createBlock as c, openBlock as s } from "vue";
2
+ import { _ as m } from "./AsPageLoading.vue_vue_type_script_setup_true_lang-D6ucjG6K.mjs";
3
+ const _ = /* @__PURE__ */ o({
4
+ __name: "PageErr",
5
+ props: {
6
+ ujt: {}
7
+ },
8
+ setup(t) {
9
+ const n = window, r = a(() => {
10
+ const e = n.$GYS?.$webmodel?.lang;
11
+ return e?.[e?.langty]?.pageerr || "";
12
+ });
13
+ return (e, u) => (s(), c(m, {
14
+ ujt: t.ujt,
15
+ msg: r.value
16
+ }, null, 8, ["ujt", "msg"]));
17
+ }
18
+ });
19
+ export {
20
+ _ as default
21
+ };
@@ -0,0 +1,14 @@
1
+ import { defineComponent as e, createBlock as o, openBlock as n } from "vue";
2
+ import { _ as r } from "./AsPageLoading.vue_vue_type_script_setup_true_lang-D6ucjG6K.mjs";
3
+ const m = /* @__PURE__ */ e({
4
+ __name: "PageLoadClient",
5
+ props: {
6
+ ujt: {}
7
+ },
8
+ setup(t) {
9
+ return (a, c) => (n(), o(r, { ujt: t.ujt }, null, 8, ["ujt"]));
10
+ }
11
+ });
12
+ export {
13
+ m as default
14
+ };
@@ -0,0 +1,28 @@
1
+ import { defineComponent as s, resolveComponent as r, createBlock as c, openBlock as o, unref as u, withCtx as m, createElementBlock as l, createCommentVNode as p, createVNode as i, toDisplayString as _ } from "vue";
2
+ import { _ as d } from "./AsPageLoading.vue_vue_type_script_setup_true_lang-D6ucjG6K.mjs";
3
+ const f = { key: 0 }, k = /* @__PURE__ */ s({
4
+ __name: "PageLoadErr",
5
+ props: {
6
+ ujt: {},
7
+ type: {}
8
+ },
9
+ setup(e) {
10
+ const t = e, { $global: n } = t.ujt;
11
+ return (g, j) => {
12
+ const a = r("AsReset");
13
+ return o(), c(d, {
14
+ ujt: e.ujt,
15
+ msg: u(n).lang?.asai?.page?.loadws || "Loading..."
16
+ }, {
17
+ default: m(() => [
18
+ t.type ? (o(), l("h3", f, _(t.type), 1)) : p("", !0),
19
+ i(a, { ujt: e.ujt }, null, 8, ["ujt"])
20
+ ]),
21
+ _: 1
22
+ }, 8, ["ujt", "msg"]);
23
+ };
24
+ }
25
+ });
26
+ export {
27
+ k as default
28
+ };
@@ -0,0 +1,14 @@
1
+ import { defineComponent as t, createBlock as o, openBlock as r } from "vue";
2
+ import { _ as n } from "./AsPageLoading.vue_vue_type_script_setup_true_lang-D6ucjG6K.mjs";
3
+ const m = /* @__PURE__ */ t({
4
+ __name: "PageLoadServer",
5
+ props: {
6
+ ujt: {}
7
+ },
8
+ setup(e) {
9
+ return (a, c) => (r(), o(n, { ujt: e.ujt }, null, 8, ["ujt"]));
10
+ }
11
+ });
12
+ export {
13
+ m as default
14
+ };
@@ -0,0 +1,26 @@
1
+ import { defineComponent as s, resolveComponent as a, createBlock as u, openBlock as r, unref as c, withCtx as m, createVNode as l } from "vue";
2
+ import { _ as p } from "./AsPageLoading.vue_vue_type_script_setup_true_lang-D6ucjG6K.mjs";
3
+ const d = /* @__PURE__ */ s({
4
+ __name: "PageLoadUserToken",
5
+ props: {
6
+ ujt: {}
7
+ },
8
+ setup(e) {
9
+ const t = e, { $global: o } = t.ujt;
10
+ return (f, i) => {
11
+ const n = a("AsReset");
12
+ return r(), u(p, {
13
+ ujt: e.ujt,
14
+ msg: c(o).lang.asai?.page?.loadusertoken || "Loading user token..."
15
+ }, {
16
+ default: m(() => [
17
+ l(n, { ujt: e.ujt }, null, 8, ["ujt"])
18
+ ]),
19
+ _: 1
20
+ }, 8, ["ujt", "msg"]);
21
+ };
22
+ }
23
+ });
24
+ export {
25
+ d as default
26
+ };
@@ -0,0 +1,26 @@
1
+ import { defineComponent as s, resolveComponent as a, createBlock as u, openBlock as r, unref as c, withCtx as l, createVNode as m } from "vue";
2
+ import { _ as i } from "./AsPageLoading.vue_vue_type_script_setup_true_lang-D6ucjG6K.mjs";
3
+ const d = /* @__PURE__ */ s({
4
+ __name: "PageLoadUserTokenOnline",
5
+ props: {
6
+ ujt: {}
7
+ },
8
+ setup(e) {
9
+ const t = e, { $global: n } = t.ujt;
10
+ return (p, f) => {
11
+ const o = a("AsReset");
12
+ return r(), u(i, {
13
+ ujt: e.ujt,
14
+ msg: c(n).lang.asai?.page?.loaduseronline || "Loading user token online..."
15
+ }, {
16
+ default: l(() => [
17
+ m(o, { ujt: e.ujt }, null, 8, ["ujt"])
18
+ ]),
19
+ _: 1
20
+ }, 8, ["ujt", "msg"]);
21
+ };
22
+ }
23
+ });
24
+ export {
25
+ d as default
26
+ };
@@ -0,0 +1,28 @@
1
+ import { defineComponent as s, resolveComponent as c, createBlock as r, openBlock as o, unref as u, withCtx as m, createElementBlock as l, createCommentVNode as p, createVNode as i, toDisplayString as _ } from "vue";
2
+ import { _ as d } from "./AsPageLoading.vue_vue_type_script_setup_true_lang-D6ucjG6K.mjs";
3
+ const f = { key: 0 }, k = /* @__PURE__ */ s({
4
+ __name: "PageLoadWs",
5
+ props: {
6
+ ujt: {},
7
+ type: {}
8
+ },
9
+ setup(e) {
10
+ const t = e, { $global: n } = t.ujt;
11
+ return (g, j) => {
12
+ const a = c("AsReset");
13
+ return o(), r(d, {
14
+ ujt: e.ujt,
15
+ msg: u(n).lang?.asai?.page?.loadws || "Loading..."
16
+ }, {
17
+ default: m(() => [
18
+ t.type ? (o(), l("h3", f, _(t.type), 1)) : p("", !0),
19
+ i(a, { ujt: e.ujt }, null, 8, ["ujt"])
20
+ ]),
21
+ _: 1
22
+ }, 8, ["ujt", "msg"]);
23
+ };
24
+ }
25
+ });
26
+ export {
27
+ k as default
28
+ };
@@ -1 +1 @@
1
- @charset "UTF-8";.app-area[data-v-bba548d2]{display:flex;flex-direction:column;height:calc(100% - 60px);padding:20px}.app-area .app-menu-area[data-v-bba548d2]{flex-grow:1;display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:20px;padding:20px;align-content:flex-start;overflow-y:auto;max-height:100%;scrollbar-width:thin;scrollbar-color:var(--cv5) var(--cv1)}.app-area .app-menu-area[data-v-bba548d2]::-webkit-scrollbar{width:8px}.app-area .app-menu-area[data-v-bba548d2]::-webkit-scrollbar-track{background:var(--cv1);border-radius:4px}.app-area .app-menu-area[data-v-bba548d2]::-webkit-scrollbar-thumb{background-color:var(--cv5);border-radius:4px}.app-area .app-menu-area .module[data-v-bba548d2]{background:var(--cu6)!important;color:var(--cr0)!important}.app-area .app-menu-area .app-menu[data-v-bba548d2]{display:flex;align-items:center;justify-content:center;min-height:var(--sa1);background:linear-gradient(135deg,var(--cv0) 0%,var(--cv1) 100%);color:var(--cv8);border-radius:12px;cursor:pointer;transition:all .3s ease;box-shadow:0 4px 6px #0000001a;padding:var(--sa0);position:relative;overflow:hidden}.app-area .app-menu-area .app-menu[data-v-bba548d2]:before{content:"";position:absolute;top:0;left:0;width:100%;height:100%;background:#ffffff1a;opacity:0;transition:opacity .3s ease}.app-area .app-menu-area .app-menu[data-v-bba548d2]:hover{transform:translateY(-5px);box-shadow:0 12px 20px #00000026}.app-area .app-menu-area .app-menu[data-v-bba548d2]:hover:before{opacity:1}.app-area .app-menu-area .app-menu[data-v-bba548d2]:active{transform:translateY(0)}.app-area .app-menu-area .app-menu .menu-text[data-v-bba548d2]{font-size:var(--sa0);font-weight:500;text-align:center;width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;direction:rtl;padding:0 10px}.app-area .app-logo[data-v-bba548d2]{height:auto;padding:20px 10px;display:flex;justify-content:center}.app-area .app-logo img[data-v-bba548d2]{max-width:100%;height:auto}.app-area .app-login[data-v-bba548d2]{height:auto;padding:20px 10px;display:flex;justify-content:flex-end}@media (max-width: 768px){.app-area .app-menu-area[data-v-bba548d2]{grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:15px;padding:15px}.app-area .app-menu-area .app-menu[data-v-bba548d2]{min-height:70px}.app-area .app-menu-area .app-menu .menu-text[data-v-bba548d2]{font-size:var(--sa0)}}@media (max-width: 480px){.app-area[data-v-bba548d2]{padding:10px}.app-area .app-menu-area[data-v-bba548d2]{grid-template-columns:repeat(auto-fill,minmax(130px,1fr));gap:10px;padding:10px}.app-area .app-menu-area .app-menu[data-v-bba548d2]{min-height:60px;padding:10px}.app-area .app-menu-area .app-menu .menu-text[data-v-bba548d2]{font-size:var(--sa0)}}#asaiwebserver[data-v-7d8d7f46]{width:100%;height:100%;overflow:hidden}#asaiwebservernode[data-v-fc74998b],#asaiwebserveruser[data-v-d2483ecb],#asaiwebserveruseronline[data-v-13dc3fec]{width:100%;height:100vh;overflow:hidden}.as-pagebusy-area[data-v-3b86e9a1]{cursor:not-allowed;display:flex;flex-direction:column;align-items:center;justify-content:center;width:100vw;height:100vh;background-color:#0000001a;position:fixed;inset:0;z-index:var(--v2189716e)}.as-pagebusy-area .as-pagebusy-close[data-v-3b86e9a1]{position:absolute;right:0;top:0;display:inline-block;width:10px;height:10px;cursor:none}.as-pagebusy-area .as-pagebusy[data-v-3b86e9a1]{display:inline-flex;justify-content:center;align-items:center;flex-direction:column;background-color:#ffffff4d;max-width:80%;padding:20px 40px;border-radius:20px;box-shadow:0 8px 24px #0000001a}.as-pagebusy-area .as-pagebusy .as-pagebusy-v[data-v-3b86e9a1]{padding-top:20px;color:var(--cu8);text-align:center}.as-load-gif[data-v-c5bf2081],.as-load-gif[data-v-c5bf2081]:after{border-top-color:var(--cv4);border-right-color:var(--cv6);border-bottom-color:var(--cv8)}.a3d-wrapper[data-v-4d1d2b0e]{perspective:1800px;width:calc(var(--cube-size) * 2);height:calc(var(--cube-size) * 2);display:inline-flex;justify-content:center;align-items:center;contain:layout paint;overflow:visible}.a3d[data-v-4d1d2b0e]{width:var(--cube-size);height:var(--cube-size);position:relative;transform-style:preserve-3d;transform-origin:center center;transform:translateZ(0) rotateX(20deg) rotateY(20deg);animation:a3d-rotate-4d1d2b0e 4s linear infinite;will-change:transform;backface-visibility:visible}.a3d-face[data-v-4d1d2b0e]{position:absolute;top:0;left:0;width:100%;height:100%;border-radius:8px;backface-visibility:visible;box-shadow:0 0 10px #0000000d inset}.a3d-face-front[data-v-4d1d2b0e]{transform:translateZ(var(--half-size));border:1px solid rgba(198,67,69,.85);background:linear-gradient(135deg,#c6434533,#c6434566)}.a3d-face-back[data-v-4d1d2b0e]{transform:translateZ(calc(-1 * var(--half-size))) rotateY(180deg);border:1px solid rgba(198,67,69,.85);background:linear-gradient(135deg,#c6434533,#c6434566)}.a3d-face-left[data-v-4d1d2b0e]{transform:translate(calc(-1 * var(--half-size))) rotateY(-90deg);border:1px solid rgba(76,198,72,.85);background:linear-gradient(135deg,#4cc64833,#4cc64866)}.a3d-face-right[data-v-4d1d2b0e]{transform:translate(var(--half-size)) rotateY(90deg);border:1px solid rgba(76,198,72,.85);background:linear-gradient(135deg,#4cc64833,#4cc64866)}.a3d-face-top[data-v-4d1d2b0e]{transform:translateY(calc(-1 * var(--half-size))) rotateX(90deg);border:1px solid rgba(109,136,233,.85);background:linear-gradient(135deg,#6d88e933,#6d88e966)}.a3d-face-bottom[data-v-4d1d2b0e]{transform:translateY(var(--half-size)) rotateX(-90deg);border:1px solid rgba(109,136,233,.85);background:linear-gradient(135deg,#6d88e933,#6d88e966)}@keyframes a3d-rotate-4d1d2b0e{0%{transform:rotateX(20deg) rotateY(20deg) rotate(0)}25%{transform:rotateX(110deg) rotateY(110deg) rotate(90deg)}50%{transform:rotateX(200deg) rotateY(200deg) rotate(180deg)}75%{transform:rotateX(290deg) rotateY(290deg) rotate(270deg)}to{transform:rotateX(380deg) rotateY(380deg) rotate(360deg)}}.as-usercard[data-v-a12ce8ac]{display:inline-flex}.as-usercard>div[data-v-a12ce8ac]{text-align:center;border:1px solid var(--cu4);color:var(--cu6);border-radius:var(--radius);margin:0 10px;padding:5px 12px;cursor:pointer}.as-usercard>div[data-v-a12ce8ac]:hover{background-color:var(--cu2)}.as-icon[data-v-d9bafe22]{line-height:0;display:inline-block}.as-icon .as-icon-filter[data-v-d9bafe22]{font-style:normal;overflow:hidden;display:inline-flex;align-items:center;justify-content:center}.as-icon .as-icon-filter>img[data-v-d9bafe22]{position:relative;display:inline-block}.as-icon .as-icon-mask[data-v-d9bafe22]{display:inline-block;mask-size:100% 100%;-webkit-mask-size:100% 100%;mask-position:center center;-webkit-mask-position:center center;mask-repeat:no-repeat;-webkit-mask-repeat:no-repeat;vertical-align:middle}.as-floating-menu[data-v-162e1725]{position:fixed;bottom:20px;left:20px;z-index:9999}.as-floating-button[data-v-162e1725]{background-color:var(--cu8);color:var(--cr0);border:none;border-radius:50%;width:40px;height:40px;font-size:var(--sa3);cursor:pointer;transition:background-color .3s ease}.as-floating-button[data-v-162e1725]:hover{background-color:var(--cv8);color:var(--cv0)}.as-floating-menus[data-v-162e1725]{font-size:var(--sa0);background-color:var(--cu8);color:var(--cr0);box-shadow:var(--shadow);border-radius:var(--radius);min-width:200px;max-width:calc(100vw - 120px);max-height:calc(100vh - 120px);list-style-type:none;margin:0;padding:0;position:fixed;bottom:66px;left:0;opacity:0;visibility:hidden;transform:translateY(-10px);transition:all .3s ease;overflow-y:auto}.as-floating-menus.open[data-v-162e1725]{opacity:1;visibility:visible;transform:translateY(0)}.as-floating-menus li[data-v-162e1725]{color:var(--cv0);padding:10px 20px;text-decoration:none;display:block;transition:color .3s ease;cursor:pointer}.as-floating-menus li.module[data-v-162e1725]{background-color:var(--cu6);color:var(--cr0)}.as-floating-menus li.active[data-v-162e1725],.as-floating-menus li[data-v-162e1725]:hover{background-color:var(--cv8);color:var(--cv0)}.as-floating-menus li.active[data-v-162e1725]{font-weight:700}.app-menu-area[data-v-6d15bb32]{display:block;width:100%}.app-menu-area .app-menu[data-v-6d15bb32]{display:inline-flex;align-items:center;justify-content:center;width:100px;height:80px;background-color:beige;margin:3px;cursor:pointer}.virtual-list-container[data-v-b613b7a8]{height:100%;overflow-y:auto;position:relative;contain:layout size;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;transform:translateZ(0);backface-visibility:hidden}.virtual-list-wrapper[data-v-b613b7a8]{position:relative;width:100%}.virtual-list-item[data-v-b613b7a8]{position:absolute;left:0;right:0;box-sizing:border-box;will-change:transform}.page-404[data-v-999cd3d9]{display:flex;flex-direction:column;justify-content:center;align-items:center;width:100%;height:100%;background-color:var(--cr0);color:var(--cu6);text-align:center}.page-404 .content[data-v-999cd3d9]{flex:1;display:flex;flex-direction:column;justify-content:center;align-items:center;max-width:600px;padding:20px}.page-404 .content .error-code[data-v-999cd3d9]{font-size:8rem;font-weight:800;line-height:1;margin-bottom:20px;color:var(--cv0);text-shadow:4px 4px 0 var(--cv6)}@media (max-width: 768px){.page-404 .content .error-code[data-v-999cd3d9]{font-size:6rem}}@media (max-width: 480px){.page-404 .content .error-code[data-v-999cd3d9]{font-size:4rem}}.page-404 .content .title[data-v-999cd3d9]{font-size:2rem;font-weight:600;margin-bottom:15px;color:var(--cu8)}@media (max-width: 768px){.page-404 .content .title[data-v-999cd3d9]{font-size:1.75rem}}.page-404 .content .description[data-v-999cd3d9]{font-size:1.1rem;margin-bottom:30px;color:var(--cu6);line-height:1.6}@media (max-width: 768px){.page-404 .content .description[data-v-999cd3d9]{font-size:1rem}}.page-404 .footer[data-v-999cd3d9]{margin-top:auto;padding:20px}
1
+ @charset "UTF-8";.app-area[data-v-bba548d2]{display:flex;flex-direction:column;height:calc(100% - 60px);padding:20px}.app-area .app-menu-area[data-v-bba548d2]{flex-grow:1;display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:20px;padding:20px;align-content:flex-start;overflow-y:auto;max-height:100%;scrollbar-width:thin;scrollbar-color:var(--cv5) var(--cv1)}.app-area .app-menu-area[data-v-bba548d2]::-webkit-scrollbar{width:8px}.app-area .app-menu-area[data-v-bba548d2]::-webkit-scrollbar-track{background:var(--cv1);border-radius:4px}.app-area .app-menu-area[data-v-bba548d2]::-webkit-scrollbar-thumb{background-color:var(--cv5);border-radius:4px}.app-area .app-menu-area .module[data-v-bba548d2]{background:var(--cu6)!important;color:var(--cr0)!important}.app-area .app-menu-area .app-menu[data-v-bba548d2]{display:flex;align-items:center;justify-content:center;min-height:var(--sa1);background:linear-gradient(135deg,var(--cv0) 0%,var(--cv1) 100%);color:var(--cv8);border-radius:12px;cursor:pointer;transition:all .3s ease;box-shadow:0 4px 6px #0000001a;padding:var(--sa0);position:relative;overflow:hidden}.app-area .app-menu-area .app-menu[data-v-bba548d2]:before{content:"";position:absolute;top:0;left:0;width:100%;height:100%;background:#ffffff1a;opacity:0;transition:opacity .3s ease}.app-area .app-menu-area .app-menu[data-v-bba548d2]:hover{transform:translateY(-5px);box-shadow:0 12px 20px #00000026}.app-area .app-menu-area .app-menu[data-v-bba548d2]:hover:before{opacity:1}.app-area .app-menu-area .app-menu[data-v-bba548d2]:active{transform:translateY(0)}.app-area .app-menu-area .app-menu .menu-text[data-v-bba548d2]{font-size:var(--sa0);font-weight:500;text-align:center;width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;direction:rtl;padding:0 10px}.app-area .app-logo[data-v-bba548d2]{height:auto;padding:20px 10px;display:flex;justify-content:center}.app-area .app-logo img[data-v-bba548d2]{max-width:100%;height:auto}.app-area .app-login[data-v-bba548d2]{height:auto;padding:20px 10px;display:flex;justify-content:flex-end}@media (max-width: 768px){.app-area .app-menu-area[data-v-bba548d2]{grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:15px;padding:15px}.app-area .app-menu-area .app-menu[data-v-bba548d2]{min-height:70px}.app-area .app-menu-area .app-menu .menu-text[data-v-bba548d2]{font-size:var(--sa0)}}@media (max-width: 480px){.app-area[data-v-bba548d2]{padding:10px}.app-area .app-menu-area[data-v-bba548d2]{grid-template-columns:repeat(auto-fill,minmax(130px,1fr));gap:10px;padding:10px}.app-area .app-menu-area .app-menu[data-v-bba548d2]{min-height:60px;padding:10px}.app-area .app-menu-area .app-menu .menu-text[data-v-bba548d2]{font-size:var(--sa0)}}#asaiwebserver[data-v-7d8d7f46]{width:100%;height:100%;overflow:hidden}#asaiwebservernode[data-v-fc74998b],#asaiwebserveruser[data-v-d2483ecb],#asaiwebserveruseronline[data-v-13dc3fec]{width:100%;height:100vh;overflow:hidden}.as-pagebusy-area[data-v-a9b32b31]{cursor:not-allowed;display:flex;flex-direction:column;align-items:center;justify-content:center;width:100vw;height:100vh;background-color:#0000001a;position:fixed;inset:0;z-index:var(--v7d9d0622)}.as-pagebusy-area .as-pagebusy-close[data-v-a9b32b31]{position:absolute;right:0;top:0;display:inline-block;width:10px;height:10px;cursor:none}.as-pagebusy-area .as-pagebusy[data-v-a9b32b31]{display:inline-flex;justify-content:center;align-items:center;flex-direction:column;background-color:#ffffff4d;max-width:80%;padding:20px 40px;border-radius:20px;box-shadow:0 8px 24px #0000001a}.a3d-wrapper[data-v-4d1d2b0e]{perspective:1800px;width:calc(var(--cube-size) * 2);height:calc(var(--cube-size) * 2);display:inline-flex;justify-content:center;align-items:center;contain:layout paint;overflow:visible}.a3d[data-v-4d1d2b0e]{width:var(--cube-size);height:var(--cube-size);position:relative;transform-style:preserve-3d;transform-origin:center center;transform:translateZ(0) rotateX(20deg) rotateY(20deg);animation:a3d-rotate-4d1d2b0e 4s linear infinite;will-change:transform;backface-visibility:visible}.a3d-face[data-v-4d1d2b0e]{position:absolute;top:0;left:0;width:100%;height:100%;border-radius:8px;backface-visibility:visible;box-shadow:0 0 10px #0000000d inset}.a3d-face-front[data-v-4d1d2b0e]{transform:translateZ(var(--half-size));border:1px solid rgba(198,67,69,.85);background:linear-gradient(135deg,#c6434533,#c6434566)}.a3d-face-back[data-v-4d1d2b0e]{transform:translateZ(calc(-1 * var(--half-size))) rotateY(180deg);border:1px solid rgba(198,67,69,.85);background:linear-gradient(135deg,#c6434533,#c6434566)}.a3d-face-left[data-v-4d1d2b0e]{transform:translate(calc(-1 * var(--half-size))) rotateY(-90deg);border:1px solid rgba(76,198,72,.85);background:linear-gradient(135deg,#4cc64833,#4cc64866)}.a3d-face-right[data-v-4d1d2b0e]{transform:translate(var(--half-size)) rotateY(90deg);border:1px solid rgba(76,198,72,.85);background:linear-gradient(135deg,#4cc64833,#4cc64866)}.a3d-face-top[data-v-4d1d2b0e]{transform:translateY(calc(-1 * var(--half-size))) rotateX(90deg);border:1px solid rgba(109,136,233,.85);background:linear-gradient(135deg,#6d88e933,#6d88e966)}.a3d-face-bottom[data-v-4d1d2b0e]{transform:translateY(var(--half-size)) rotateX(-90deg);border:1px solid rgba(109,136,233,.85);background:linear-gradient(135deg,#6d88e933,#6d88e966)}@keyframes a3d-rotate-4d1d2b0e{0%{transform:rotateX(20deg) rotateY(20deg) rotate(0)}25%{transform:rotateX(110deg) rotateY(110deg) rotate(90deg)}50%{transform:rotateX(200deg) rotateY(200deg) rotate(180deg)}75%{transform:rotateX(290deg) rotateY(290deg) rotate(270deg)}to{transform:rotateX(380deg) rotateY(380deg) rotate(360deg)}}.as-usercard[data-v-a12ce8ac]{display:inline-flex}.as-usercard>div[data-v-a12ce8ac]{text-align:center;border:1px solid var(--cu4);color:var(--cu6);border-radius:var(--radius);margin:0 10px;padding:5px 12px;cursor:pointer}.as-usercard>div[data-v-a12ce8ac]:hover{background-color:var(--cu2)}.as-icon[data-v-d9bafe22]{line-height:0;display:inline-block}.as-icon .as-icon-filter[data-v-d9bafe22]{font-style:normal;overflow:hidden;display:inline-flex;align-items:center;justify-content:center}.as-icon .as-icon-filter>img[data-v-d9bafe22]{position:relative;display:inline-block}.as-icon .as-icon-mask[data-v-d9bafe22]{display:inline-block;mask-size:100% 100%;-webkit-mask-size:100% 100%;mask-position:center center;-webkit-mask-position:center center;mask-repeat:no-repeat;-webkit-mask-repeat:no-repeat;vertical-align:middle}.as-floating-menu[data-v-162e1725]{position:fixed;bottom:20px;left:20px;z-index:9999}.as-floating-button[data-v-162e1725]{background-color:var(--cu8);color:var(--cr0);border:none;border-radius:50%;width:40px;height:40px;font-size:var(--sa3);cursor:pointer;transition:background-color .3s ease}.as-floating-button[data-v-162e1725]:hover{background-color:var(--cv8);color:var(--cv0)}.as-floating-menus[data-v-162e1725]{font-size:var(--sa0);background-color:var(--cu8);color:var(--cr0);box-shadow:var(--shadow);border-radius:var(--radius);min-width:200px;max-width:calc(100vw - 120px);max-height:calc(100vh - 120px);list-style-type:none;margin:0;padding:0;position:fixed;bottom:66px;left:0;opacity:0;visibility:hidden;transform:translateY(-10px);transition:all .3s ease;overflow-y:auto}.as-floating-menus.open[data-v-162e1725]{opacity:1;visibility:visible;transform:translateY(0)}.as-floating-menus li[data-v-162e1725]{color:var(--cv0);padding:10px 20px;text-decoration:none;display:block;transition:color .3s ease;cursor:pointer}.as-floating-menus li.module[data-v-162e1725]{background-color:var(--cu6);color:var(--cr0)}.as-floating-menus li.active[data-v-162e1725],.as-floating-menus li[data-v-162e1725]:hover{background-color:var(--cv8);color:var(--cv0)}.as-floating-menus li.active[data-v-162e1725]{font-weight:700}.app-menu-area[data-v-6d15bb32]{display:block;width:100%}.app-menu-area .app-menu[data-v-6d15bb32]{display:inline-flex;align-items:center;justify-content:center;width:100px;height:80px;background-color:beige;margin:3px;cursor:pointer}.virtual-list-container[data-v-b613b7a8]{height:100%;overflow-y:auto;position:relative;contain:layout size;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;transform:translateZ(0);backface-visibility:hidden}.virtual-list-wrapper[data-v-b613b7a8]{position:relative;width:100%}.virtual-list-item[data-v-b613b7a8]{position:absolute;left:0;right:0;box-sizing:border-box;will-change:transform}.page-404[data-v-999cd3d9]{display:flex;flex-direction:column;justify-content:center;align-items:center;width:100%;height:100%;background-color:var(--cr0);color:var(--cu6);text-align:center}.page-404 .content[data-v-999cd3d9]{flex:1;display:flex;flex-direction:column;justify-content:center;align-items:center;max-width:600px;padding:20px}.page-404 .content .error-code[data-v-999cd3d9]{font-size:8rem;font-weight:800;line-height:1;margin-bottom:20px;color:var(--cv0);text-shadow:4px 4px 0 var(--cv6)}@media (max-width: 768px){.page-404 .content .error-code[data-v-999cd3d9]{font-size:6rem}}@media (max-width: 480px){.page-404 .content .error-code[data-v-999cd3d9]{font-size:4rem}}.page-404 .content .title[data-v-999cd3d9]{font-size:2rem;font-weight:600;margin-bottom:15px;color:var(--cu8)}@media (max-width: 768px){.page-404 .content .title[data-v-999cd3d9]{font-size:1.75rem}}.page-404 .content .description[data-v-999cd3d9]{font-size:1.1rem;margin-bottom:30px;color:var(--cu6);line-height:1.6}@media (max-width: 768px){.page-404 .content .description[data-v-999cd3d9]{font-size:1rem}}.page-404 .footer[data-v-999cd3d9]{margin-top:auto;padding:20px}