w-web-sso 1.1.11 → 1.1.13

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.
Files changed (45) hide show
  1. package/README.md +28 -2
  2. package/dist/css/{app.b17b0ba0.css → app.f000459f.css} +1 -1
  3. package/dist/index.tmp +1 -1
  4. package/dist/js/{app-legacy.bee6840f.js → app-legacy.7c006893.js} +1 -1
  5. package/dist/js/{app.bee6840f.js → app.7c006893.js} +1 -1
  6. package/dist/js/{chunk-vendors.0492b6f5.js → chunk-vendors-legacy.97013ddc.js} +5 -5
  7. package/dist/js/{chunk-vendors-legacy.0492b6f5.js → chunk-vendors.97013ddc.js} +5 -5
  8. package/dist/w-web-sso.umd.js +4 -4
  9. package/dist/w-web-sso.umd.js.map +1 -1
  10. package/docs/WWebSso.html +5 -4
  11. package/docs/global.html +3 -3
  12. package/docs/index.html +1 -1
  13. package/docs/server_WWebSso.mjs.html +24 -16
  14. package/docs/server_getIgnoredOrmKeys.mjs.html +1 -1
  15. package/docs/server_lockSave.mjs.html +1 -1
  16. package/docs/server_ormWrite.mjs.html +1 -1
  17. package/docs/server_staLogs_resolveShellWorker.mjs.html +1 -1
  18. package/docs/server_wrapTimer.mjs.html +1 -1
  19. package/docs/src_components_Common_CheckYesNo.vue.html +1 -1
  20. package/docs/src_fetchSsoMsg.mjs.html +15 -2
  21. package/docs/src_httpGetJson.mjs.html +1 -1
  22. package/docs/src_maskUrl.mjs.html +1 -1
  23. package/docs/src_plugins_staUsage.mjs.html +1 -1
  24. package/docs/src_plugins_submitGuard.mjs.html +1 -1
  25. package/package.json +2 -2
  26. package/server/WWebSso.mjs +23 -15
  27. package/server/procCore.mjs +800 -382
  28. package/server/procLang.mjs +23 -0
  29. package/server/procProtect.mjs +300 -117
  30. package/server/srLog.mjs +31 -8
  31. package/src/baselineOf.mjs +76 -0
  32. package/src/components/LayoutContentIps.vue +24 -2
  33. package/src/components/LayoutContentTokens.vue +24 -2
  34. package/src/components/LayoutContentUsers.vue +9 -3
  35. package/src/fetchSsoMsg.mjs +14 -1
  36. package/src/getUserByToken.mjs +2 -2
  37. package/src/getUserByUserId.mjs +2 -2
  38. package/src/getUsersByToken.mjs +2 -2
  39. package/src/schema/tables/ips.mjs +4 -0
  40. package/src/schema/tables/tokens.mjs +4 -0
  41. package/src/writeContracts/index.mjs +9 -0
  42. package/src/writeContracts/ips.mjs +9 -0
  43. package/src/writeContracts/tokens.mjs +12 -0
  44. package/src/writeContracts/tokensSession.mjs +10 -0
  45. package/src/writeContracts/users.mjs +15 -0
package/README.md CHANGED
@@ -13,6 +13,32 @@ To view documentation or get support, visit [docs](https://yuda-lyu.github.io/w-
13
13
 
14
14
  ## Upgrade Notes
15
15
 
16
+ ### Upgrading from 1.1.12 and earlier
17
+
18
+ **多人同時編輯之寫入契約(行為變更)**:多位管理員可同時開啟後台使用者/金鑰/IP 清單,過去先存者之修改會被持舊畫面者整份蓋回(含系統另行寫入之驗證時間、封鎖時間、強制變更密碼旗標、密碼雜湊、續期後之到期時間),載入後新增之使用者/IP/登入中之 session 金鑰會被誤刪,已登出或被封鎖撤銷之 session 金鑰會復活。本版起(依 w-serv-orm 1.1.17,部署前提:單一行程、同表只由同一個 ORM 實例寫入):
19
+
20
+ - **先動先贏、整次拒收、零寫入**:後台三個清單頁於載入時以畫面所見之列自算基準(`buildBaseline`,前後端共用 `src/writeContracts/` 之寫入契約),存檔時連同送出;後端於該表之表鎖內新鮮讀取並比對,不符整次拒收(不部分寫入),草稿保留並提示重新載入,回語系鍵 `saveStale`(載入後資料已被更動)、`saveRowNotFound`(要改或刪之資料已不存在)、`saveBaselineFormat`(基準格式或版本不識;不會降級為不帶基準)。存檔成功後前端重新讀取清單作為新基準(不以自己送出之值當基準)。基準比對之欄位為契約 `fields`(使用者清單另含列序名次);伺服器專有欄位不入基準。
21
+ - **RPC 簽章**:`updateUsersList`/`updateIpsList` 新增選用第 4 參數 `{ baseline }`,`updateTokensList` 為 `{ baseline, baselineSession }`(`baseline`:應用系統金鑰列〔`isApp='y'`〕嚴格整表比對;`baselineSession`:session 列逐列寬鬆比對)。第 4 參數只接受此白名單鍵;不是純物件、多餘鍵、缺鍵或格式不識皆回 `saveBaselineFormat`。回傳形狀不變。
22
+ - **金鑰清單之 session 列(選項 P)**:session 列由登入新增、續期改 `timeEnd`、登出或封鎖刪除,變動頻繁,不採整表比對。只比對管理員有修改或刪除之列;載入後才登入之 session 不被刪;載入後已登出或被封鎖撤銷者不復活;系統續期而管理員未動之列不寫(到期時間不被舊值蓋回);管理員有動而庫內已變者(如刪除或修改一個剛被續期之 session)整次拒收,重新載入後再操作。
23
+ - **不帶基準之寫入**(app 權杖直呼、升級前已開啟而未重新載入之舊版頁面)本 major 仍允許,後者蓋前者,但:一律取表鎖、修改只改不增、伺服器專有欄位(`password`、`tokenVerify`、`userId`、`timeCreate`、稽核欄、tokens 之 `timeUpdate`)不採用客戶端值(舊版頁面整列送回之舊值不再回寫);金鑰清單只刪/改應用系統金鑰列,**session 列不刪、不以送入值覆蓋**(原會刪除載入後才登入者、以舊到期時間蓋回續期);新增列僅限應用系統金鑰(`isApp='y'`,含直打 API 鑄造應用系統金鑰)。若要刪除某 session 以強制登出,請用後台頁(帶基準)。**下一個 major 起後台一律必帶基準,未帶者拒收。**
24
+ - **金鑰清單存檔不得新增 session 列(行為變更;帶或不帶基準皆然)**:session 金鑰(`isApp` 非 `'y'`)只由登入產生。`updateTokensList` 送出之列若庫內不存在且 `isApp` 非 `'y'`,整次拒收(零寫入,同批之其他變更亦不寫),回語系鍵 `tokenSessionAddNotAllowed`(「不可新增登入權杖」),不回顯值。因此以 app 權杖直呼、或升級前已開啟而未重新載入之舊版頁面,送回已被登出或自動封鎖撤銷之 session 列時,不會使其復活(繞過自動封鎖);舊版頁面遇此情形須重新載入。不受影響:新增應用系統金鑰列、管理員(帶基準)對既有 session 列之刪除(強制登出)、將既有 session 列升級為應用系統金鑰、帶基準時基準內而管理員未動且已被撤銷之 session 列(略過、不復活)。原先「直打 API 以清單鑄造使用者 session 金鑰」之能力一併收回;需要以應用系統身分呼叫者請鑄造應用系統金鑰。
25
+ - **雙方欄位**(後台可改、系統亦會寫)入基準:`timeVerified`、`timeBlocked`、`isForceChangePw`、金鑰之 `timeEnd`、IP 之 `timeBlocked`。系統於持舊畫面者載入後改動這些欄位(驗證信、自動封鎖、重設密碼、app 權杖續期、IP 封鎖),其存檔即被拒。IP 清單另有:自動偵測計時器每 2 秒登錄新 IP,繁忙系統上舊畫面存檔較常需重新載入。
26
+ - **表鎖**:users/tokens/ips 每表一把;server 端全部 19 個寫入站點(後台存檔、登入新增金鑰、續期、登出、自助註冊、驗證信、改密碼、重設密碼、自動封鎖帳號/權杖、計時器登錄與封鎖 IP 等)皆在該表表鎖內執行,系統直寫改為只改不增(讀到後該列被刪,不再把只含被寫欄位之殘缺列新增回庫);使用者清單存檔與帳號封鎖在 `[tokens, users]` 兩把鎖內同鎖撤銷名下金鑰;自助註冊與後台清單新增同帳號不再可同時成功(帳號唯一性檢查與新增同在 users 表鎖內);登入於 tokens 表鎖內重讀使用者狀態,已被停用、刪除或封鎖、密碼已被變更(如管理員重設)、驗證被清除或已到期者不再鑄出金鑰,登入回傳之使用者資料取自該次新鮮讀取;自動封鎖(登入失敗、權杖呼叫超限)於鎖內再驗帳號仍屬該使用者、token 仍是其名下使用者 token,等鎖期間已被改名、升為應用系統金鑰或登出者不封鎖。
27
+ - **最後修改者**:tokens、ips 新增欄位 `userIdUpdate`(既有資料不回填,無須遷移);後台存檔記操作管理員,app 權杖記其虛擬使用者 id,使用者自助流程(驗證信、改密碼)記該使用者,登入/續期記金鑰擁有者,系統計時器與自動封鎖記常數 `system`。tokens 新增列之擁有者 `userId` 保留送入值(擁有者為空者以操作者補),不被操作者覆寫。
28
+ - **`getUsersList` 不再回傳 `tokenVerify`(憑證類欄位收回)**:後台使用者清單原連同註冊驗證用 token 一併回傳並整列存回;契約生效後它屬伺服器專有欄位(存檔取庫內值),前端不再需要。對外 `getSsoUsersList` 原即不輸出。
29
+ - **log/錯誤文字**:基準不符等拒收於 srLog 記 warn(`fun-updateTabItems-reject`,帶語系鍵);庫內列主鍵重複或缺漏(`rowsInvalid`,屬資料錯誤)回 `anUnexpectedErrorOccurred` 並記 error。帳號封鎖寫入失敗之 log 因改經 w-serv-orm 寫入,錯誤文字為其固定字串(如 `failed to save data`),原例外文字只進 console。
30
+ - 新增語系鍵:`saveStale`、`saveRowNotFound`、`saveBaselineFormat`、`tokenSessionAddNotAllowed`(eng/cht)。
31
+
32
+ ### Upgrading from 1.1.11 and earlier
33
+
34
+ **來源 IP 須為合法 IP(行為變更)**:資料通道的來源 IP 仍取請求標頭 `X-Forwarded-For` 以逗號分隔之第一個非空段(最左),但取得之值現須通過 `net.isIP`(IPv4 或 IPv6;帶 zone 識別碼者總長度不得超過 64 字元)才採用,且**原樣使用、不改寫**(不剝除 `::ffff:` 前綴、不改大小寫),因此以原字串寫入 `ips` 表之既有封鎖列照常命中。唯一之正規化是去除 port:`IPv4:port`(如 `203.0.113.9:8080`)與括號形式 `[IPv6]:port`(如 `[2001:db8::1]:443`)取其 IP 本身(部分雲端閘道會在標頭附帶來源 port;同一 IP 不同 port 計為同一 IP,不會退回連線位址而使全部使用者呈現為閘道位址),port 須為 1~5 位數字且不超過 65535,去除後之 IP 同樣原樣使用。去除後仍非 IP(如 `256.1.1.1:80`、`1.2.3.4:abc`)或標頭值本身非 IP(如 `length`、`constructor`、含標記之字串、`unknown`、超長字串)時不採用,改取連線位址並記一筆 `warn`(`event` 為 `fun-getIpByHeaders`、`key` 為 `invalidForwardedFor`,至多每 10 秒一筆,`suppressed` 為期間被略過之次數,只記長度與前 64 字元);標頭不存在或為空時仍靜默取連線位址。退回連線位址者,其 IP 封鎖與頻率限制一併改以連線位址計算:若該位址(例如反向代理 IP)已被封鎖,這些請求將被拒;`ips` 表中既有的非 IP 字串列(修改前由任意標頭值登錄而來,含其封鎖列;帶 port 者如 `203.0.113.9:8080` 亦同,新請求改以去 port 後之 `203.0.113.9` 判定並另登新列)不會再被命中,建議管理端檢視並清除。
35
+
36
+ **計數容器之鍵於窗口過後清除(修正)**:權杖與來源 IP 的調用次數紀錄原只在剪枝時移除窗外之紀錄,鍵本身永久殘留;未登入請求每換一個權杖參數或標頭值就多一個永久殘留之空鍵(長時間運行記憶體無上限成長,且每 2 秒的剪枝與偵測計時器都要走訪全部鍵)。本版起 `minForTokenCallApi`/`minForIpCallApi` 窗口內無新請求之鍵即刪除(登入失敗紀錄原即如此)。連帶行為:管理者自 IP 清單刪除某 IP 後,窗口(預設 10 分鐘)過後不再被偵測計時器自動復活(修改前每 2 秒復活一次);偵測新 IP 之計時器若連續失敗超過整個窗口,窗內只請求過一次之 IP 不會補登,該 IP 再次請求即重新登錄。
37
+
38
+ **來源 IP 之信任邊界(維持;不提供 `trustProxy`)**:本套件信任 `X-Forwarded-For` 最左段且不做防偽造——線上系統常有多層反向代理、使用者 IP 由反代提供,能經跳板偽造者,反代拿到的也是偽造值,此類防護屬防火牆/反向代理之責。部署於反向代理後時,請由最外層受信任之代理覆寫(而非附加)該標頭;直接對外提供服務(前方無反向代理)時,用戶端可填寫任意合法格式之 IP 以規避 IP 封鎖與頻率限制、冒用他人 IP(可使他人 IP 遭自動封鎖),大量互異之合法 IP 亦會使 `ips` 表列數成長。`/api/cleanKpIpCallApi`、`/api/cleanKpAccountLoginFailed` 不讀標頭,只取連線位址。
39
+
40
+ **查詢使用者之欄位名限 `id`/`account`/`email`/`name`(行為變更)**:`/api/getSsoUserInfor`(`key` 參數)與後台 `getUserInfor`(第 3 個參數)原由呼叫端任意指定欄位名並直接作為資料庫查詢欄位,誤用 `key=userId`(建立者欄)不報錯而查到建立者,亦可對憑證欄(如 `tokenVerify`)探測值是否存在。本版起欄位名須為 `id`、`account`、`email`、`name` 其一,其餘(含大小寫不同者)回 `invalidUserQueryKey`(不回顯欄位名與查詢值,權限檢查仍在先:無權限者先得 `tokenExpired`);欄位名或查詢值為空字串、重複參數(陣列)等格式不符者,仍由既有的入口檢查先回 `tokenExpired`。HTTP `key=token`(以權杖查使用者)不受影響;後台 `getUserInfor` 傳 `key='token'` 亦屬白名單外而被拒(原即無此用法,以權杖查請走 HTTP `key=token` 或 `getUserByToken`)。被拒之查詢仍寫一筆稽核紀錄(`api/getSsoUserInfor`/`kpfun-getUserInfor`,查詢值已遮罩;使用端可自填之欄位名與識別欄查詢值寫入 log 前置換控制字元,超過 256 字元者截斷並附 `...(len=原長)`)。對外查詢 helper(`getUserByToken`、`getUserByUserId`、`getUsersByToken`)之網址範本檢查改為完整參數比對:`key=tokenVerify`、`xkey=token`、`token={sysToken}x` 等僅子字串相符者不再通過(回 `noTokenKeyValueInUrl`/`noTokenKeyUserIdInUrl`/`noTokenInUrl`);`token={sysToken}`、`key=token`(或 `key=id`)、`value={token}`(或 `value={userId}`)須各為網址查詢字串中恰出現一次的完整參數(以 `?`、`&` 定界;出現在路徑、片段、參數值內或重複者不算,如 `key=token&key=id`、`#key=token`、`key=token+`),順序與其他參數不限。
41
+
16
42
  ### Upgrading from 1.1.10 and earlier
17
43
 
18
44
  **未登入請求可使後端結束(修正)**:來源 IP(`X-Forwarded-For` 標頭第一段)、權杖參數與登入帳號原以一般物件為鍵記錄調用/失敗次數;值為 `constructor`、`__proto__`、`toString` 等原型鍵名時,記錄函數拋出 `TypeError`(`verifyConn` 與 HTTP 路由內未被接住之 async 呼叫),在 Node 預設設定下使後端行程結束(`X-Forwarded-For: constructor` 或 `/api/checkToken?token=constructor` 單一請求即可);帳號為該類名稱之既存使用者,登入失敗亦不計次、不會被封鎖。本版起以無原型容器記錄,這些字串與其他字串同為一般鍵。
@@ -23,7 +49,7 @@ To view documentation or get support, visit [docs](https://yuda-lyu.github.io/w-
23
49
 
24
50
  **後台清單儲存之主鍵/帳號為原型鍵名(修正)**:主鍵或帳號為 `constructor`、`__proto__`、`toString` 等時,原誤判為重複(`invalidRows`/`accountDuplicate`);新增之使用者其明文密碼被清為空。本版起照常驗證與儲存;後台使用者清單頁之前端預檢(帳號/email 重複、空值)原亦以一般物件判重,帳號為 `constructor` 等時誤判重複而擋下整份清單儲存,一併修正。`checkTokenAndUpdateUsersList`、`checkTokenAndUpdateTokensList` 之 `rows` 非陣列時回 `invalidRows`(資料通道入口原已以陣列檢查拒絕;原權杖清單遇非陣列於內部拋 `TypeError`)。
25
51
 
26
- **來源 IP 之信任邊界(未變更,評估見 `CLAUDE_rulebook.md`〈已知缺口〉)**:`X-Forwarded-For` 第一段仍被信任且未驗證格式。直接對外提供服務時,用戶端可任意填寫此標頭以規避 IP 封鎖與頻率限制、冒用他人 IP(可使他人 IP 遭自動封鎖)、以任意字串登錄 `ips` 表與統計;部署於反向代理後時,請由最外層受信任之代理覆寫(而非附加)該標頭。後續版本擬提供 `trustProxy` 設定與 IP 格式驗證。
52
+ **來源 IP 之信任邊界(2026-10-20 更正)**:本條原載「後續版本擬提供 `trustProxy` 設定與 IP 格式驗證」。IP 格式驗證已於上一節(Upgrading from 1.1.11 and earlier)實作;`trustProxy` 經使用者裁示不提供——偽造防護屬防火牆/反向代理之責,本套件維持信任 `X-Forwarded-For` 最左段。
27
53
 
28
54
  ### Upgrading from 1.1.8 and earlier
29
55
 
@@ -94,7 +120,7 @@ To view documentation or get support, visit [docs](https://yuda-lyu.github.io/w-
94
120
 
95
121
  **`/api/getSsoUsersList`(及 `getUsersByToken`)不再輸出 `tokenVerify`**(憑證欄;`password` 原即不輸出)。後台使用者清單不受影響。
96
122
 
97
- **log**:權杖遮罩對 16 字元以下之權杖露出更少字元(36 字元 session token 格式不變),陣列與非字串一律遮罩;資料通道之 `referer` 只記 origin + pathname;`getSsoUserInfor` 以非識別欄(id / account / email / name 以外)查詢時之查詢值遮罩。
123
+ **log**:權杖遮罩對 16 字元以下之權杖露出更少字元(36 字元 session token 格式不變),陣列與非字串一律遮罩;資料通道之 `referer` 只記 origin + pathname;`getSsoUserInfor` 以非識別欄(id / account / email / name 以外)查詢時之查詢值遮罩(欄位名限白名單後,此類查詢被拒,稽核紀錄之查詢值仍遮罩)。
98
124
 
99
125
  ### Upgrading from 1.0.3x / 1.0.5x
100
126
 
@@ -1 +1 @@
1
- .bg-blue-100[data-v-a0ffaf3e]{--tw-bg-opacity:1;background-color:rgb(219 234 254/var(--tw-bg-opacity,1))}.bg-gray-100[data-v-a0ffaf3e]{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity,1))}.bg-gray-50[data-v-a0ffaf3e]{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity,1))}.bg-green-100[data-v-a0ffaf3e]{--tw-bg-opacity:1;background-color:rgb(220 252 231/var(--tw-bg-opacity,1))}.bg-red-100[data-v-a0ffaf3e]{--tw-bg-opacity:1;background-color:rgb(254 226 226/var(--tw-bg-opacity,1))}.bg-white[data-v-a0ffaf3e]{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.bg-yellow-100[data-v-a0ffaf3e]{--tw-bg-opacity:1;background-color:rgb(254 249 195/var(--tw-bg-opacity,1))}.border[data-v-a0ffaf3e]{border-width:1px}.border-collapse[data-v-a0ffaf3e]{border-collapse:collapse}.border-gray-200[data-v-a0ffaf3e]{--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity,1))}.border-gray-300[data-v-a0ffaf3e]{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity,1))}.border-solid[data-v-a0ffaf3e]{border-style:solid}.cursor-pointer[data-v-a0ffaf3e]{cursor:pointer}.flex[data-v-a0ffaf3e]{display:-webkit-box;display:-ms-flexbox;display:flex}.focus\:ring-blue-500[data-v-a0ffaf3e]:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(59 130 246/var(--tw-ring-opacity,1))}.font-bold[data-v-a0ffaf3e]{font-weight:700}.font-medium[data-v-a0ffaf3e]{font-weight:500}.font-semibold[data-v-a0ffaf3e]{font-weight:600}.gap-5[data-v-a0ffaf3e]{gap:1.25rem}.gap-6[data-v-a0ffaf3e]{gap:1.5rem}.h-4[data-v-a0ffaf3e]{height:1rem}.hover\:bg-gray-50[data-v-a0ffaf3e]:hover{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity,1))}.hover\:underline[data-v-a0ffaf3e]:hover{text-decoration-line:underline}.items-center[data-v-a0ffaf3e]{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.justify-between[data-v-a0ffaf3e]{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.mb-2[data-v-a0ffaf3e]{margin-bottom:.5rem}.mb-4[data-v-a0ffaf3e]{margin-bottom:1rem}.mb-8[data-v-a0ffaf3e]{margin-bottom:2rem}.ml-2[data-v-a0ffaf3e]{margin-left:.5rem}.ml-4[data-v-a0ffaf3e]{margin-left:1rem}.mr-2[data-v-a0ffaf3e]{margin-right:.5rem}.mt-2[data-v-a0ffaf3e]{margin-top:.5rem}.mt-4[data-v-a0ffaf3e]{margin-top:1rem}.overflow-x-auto[data-v-a0ffaf3e]{overflow-x:auto}.p-3[data-v-a0ffaf3e]{padding:.75rem}.p-5[data-v-a0ffaf3e]{padding:1.25rem}.pb-1[data-v-a0ffaf3e]{padding-bottom:.25rem}.pb-2[data-v-a0ffaf3e]{padding-bottom:.5rem}.pb-3[data-v-a0ffaf3e]{padding-bottom:.75rem}.px-2[data-v-a0ffaf3e]{padding-left:.5rem;padding-right:.5rem}.px-6[data-v-a0ffaf3e]{padding-left:1.5rem;padding-right:1.5rem}.py-1[data-v-a0ffaf3e]{padding-top:.25rem;padding-bottom:.25rem}.py-3[data-v-a0ffaf3e]{padding-top:.75rem;padding-bottom:.75rem}.py-4[data-v-a0ffaf3e]{padding-top:1rem;padding-bottom:1rem}.relative[data-v-a0ffaf3e]{position:relative}.rounded[data-v-a0ffaf3e]{border-radius:.25rem}.rounded-full[data-v-a0ffaf3e]{border-radius:9999px}.rounded-lg[data-v-a0ffaf3e]{border-radius:.5rem}.shadow-md[data-v-a0ffaf3e]{--tw-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1);--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color)}.shadow-md[data-v-a0ffaf3e],.shadow-sm[data-v-a0ffaf3e]{-webkit-box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-sm[data-v-a0ffaf3e]{--tw-shadow:0 1px 2px 0 rgba(0,0,0,.05);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color)}.space-x-4[data-v-a0ffaf3e]>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(1rem*var(--tw-space-x-reverse));margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)))}.space-y-2[data-v-a0ffaf3e]>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem*var(--tw-space-y-reverse))}.space-y-8[data-v-a0ffaf3e]>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(2rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem*var(--tw-space-y-reverse))}.sticky[data-v-a0ffaf3e]{position:sticky}.text-2xl[data-v-a0ffaf3e]{font-size:1.5rem;line-height:2rem}.text-blue-600[data-v-a0ffaf3e]{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity,1))}.text-gray-500[data-v-a0ffaf3e]{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}.text-gray-700[data-v-a0ffaf3e]{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity,1))}.text-gray-900[data-v-a0ffaf3e]{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity,1))}.text-green-600[data-v-a0ffaf3e]{--tw-text-opacity:1;color:rgb(22 163 74/var(--tw-text-opacity,1))}.text-indigo-600[data-v-a0ffaf3e]{--tw-text-opacity:1;color:rgb(79 70 229/var(--tw-text-opacity,1))}.text-left[data-v-a0ffaf3e]{text-align:left}.text-lg[data-v-a0ffaf3e]{font-size:1.125rem;line-height:1.75rem}.text-purple-600[data-v-a0ffaf3e]{--tw-text-opacity:1;color:rgb(147 51 234/var(--tw-text-opacity,1))}.text-red-600[data-v-a0ffaf3e]{--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity,1))}.text-right[data-v-a0ffaf3e]{text-align:right}.text-sm[data-v-a0ffaf3e]{font-size:.875rem;line-height:1.25rem}.text-teal-600[data-v-a0ffaf3e]{--tw-text-opacity:1;color:rgb(13 148 136/var(--tw-text-opacity,1))}.text-xs[data-v-a0ffaf3e]{font-size:.75rem;line-height:1rem}.text-yellow-600[data-v-a0ffaf3e]{--tw-text-opacity:1;color:rgb(202 138 4/var(--tw-text-opacity,1))}.top-0[data-v-a0ffaf3e]{top:0}.transition-colors[data-v-a0ffaf3e]{-webkit-transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;-webkit-transition-timing-function:cubic-bezier(.4,0,.2,1);transition-timing-function:cubic-bezier(.4,0,.2,1);-webkit-transition-duration:.15s;transition-duration:.15s}.w-4[data-v-a0ffaf3e]{width:1rem}.w-7[data-v-a0ffaf3e]{width:1.75rem}.w-full[data-v-a0ffaf3e]{width:100%}.z-10[data-v-a0ffaf3e]{z-index:10}.grid[data-v-a0ffaf3e]{display:grid}.grid-cols-1[data-v-a0ffaf3e]{grid-template-columns:repeat(1,minmax(0,1fr))}@media (min-width:640px){.sm\:grid-cols-2[data-v-a0ffaf3e]{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:1024px){.lg\:grid-cols-1[data-v-a0ffaf3e]{grid-template-columns:repeat(1,minmax(0,1fr))}.lg\:grid-cols-3[data-v-a0ffaf3e]{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4[data-v-a0ffaf3e]{grid-template-columns:repeat(4,minmax(0,1fr))}}.bg-blue-100[data-v-3796caa5]{--tw-bg-opacity:1;background-color:rgb(219 234 254/var(--tw-bg-opacity,1))}.bg-gray-100[data-v-3796caa5]{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity,1))}.border-gray-200[data-v-3796caa5]{--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity,1))}.border-t[data-v-3796caa5]{border-top-width:1px}.break-all[data-v-3796caa5]{word-break:break-all}.flex[data-v-3796caa5]{display:-webkit-box;display:-ms-flexbox;display:flex}.flex-shrink-0[data-v-3796caa5]{-ms-flex-negative:0;flex-shrink:0}.font-medium[data-v-3796caa5]{font-weight:500}.font-semibold[data-v-3796caa5]{font-weight:600}.gap-3[data-v-3796caa5]{gap:.75rem}.gap-4[data-v-3796caa5]{gap:1rem}.gap-x-8[data-v-3796caa5]{-webkit-column-gap:2rem;-moz-column-gap:2rem;column-gap:2rem}.gap-y-6[data-v-3796caa5]{row-gap:1.5rem}.inline-block[data-v-3796caa5]{display:inline-block}.items-center[data-v-3796caa5]{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.items-start[data-v-3796caa5]{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.mb-2[data-v-3796caa5]{margin-bottom:.5rem}.mr-3[data-v-3796caa5]{margin-right:.75rem}.mt-1[data-v-3796caa5]{margin-top:.25rem}.p-3[data-v-3796caa5]{padding:.75rem}.pt-6[data-v-3796caa5]{padding-top:1.5rem}.px-2[data-v-3796caa5]{padding-left:.5rem;padding-right:.5rem}.py-1[data-v-3796caa5]{padding-top:.25rem;padding-bottom:.25rem}.rounded-lg[data-v-3796caa5]{border-radius:.5rem}.rounded-md[data-v-3796caa5]{border-radius:.375rem}.space-y-8[data-v-3796caa5]>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(2rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem*var(--tw-space-y-reverse))}.text-base[data-v-3796caa5]{font-size:1rem;line-height:1.5rem}.text-blue-700[data-v-3796caa5]{--tw-text-opacity:1;color:rgb(29 78 216/var(--tw-text-opacity,1))}.text-gray-400[data-v-3796caa5]{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity,1))}.text-gray-500[data-v-3796caa5]{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}.text-gray-700[data-v-3796caa5]{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity,1))}.text-gray-900[data-v-3796caa5]{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity,1))}.text-sm[data-v-3796caa5]{font-size:.875rem;line-height:1.25rem}.text-xs[data-v-3796caa5]{font-size:.75rem;line-height:1rem}.text-red-800\/80[data-v-3796caa5]{color:rgba(153,27,27,.8)}.text-green-800\/80[data-v-3796caa5]{color:rgba(22,101,52,.8)}.grid[data-v-3796caa5]{display:grid}.grid-cols-1[data-v-3796caa5]{grid-template-columns:repeat(1,minmax(0,1fr))}@media (min-width:640px){.sm\:grid-cols-2[data-v-3796caa5]{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:768px){.md\:grid-cols-2[data-v-3796caa5]{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:col-span-2[data-v-3796caa5]{grid-column:span 2/span 2}}@media (min-width:1024px){.lg\:grid-cols-4[data-v-3796caa5]{grid-template-columns:repeat(4,minmax(0,1fr))}}.status-danger[data-v-3796caa5]{background-color:#fef2f2;color:#b91c1c;border:1px solid #fecaca}.status-warning[data-v-3796caa5]{background-color:#fffbeb;color:#b45309;border:1px solid #fde68a}.status-success[data-v-3796caa5]{background-color:#f0fdf4;color:#15803d;border:1px solid #bbf7d0}.status-info[data-v-3796caa5]{background-color:#f8fafc;color:#475569;border:1px solid #e2e8f0}.perms-trigger[data-v-76dabe06]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:2px;border:1px solid #767676;border-radius:4px;background:#f0f0f0;cursor:pointer;-webkit-transition:background-color .2s;transition:background-color .2s}.perms-trigger[data-v-76dabe06]:hover{background:#e5e5e5}.menu-row-click[data-v-4501b18f]{-webkit-transition:background .2s;transition:background .2s}.menu-row-click[data-v-4501b18f]:focus,.menu-row-click[data-v-4501b18f]:hover{background:#f2f2f2}body,html{font-family:微軟正黑體,Microsoft JhengHei,MicrosoftJhengHeiRegular,Avenir,Helvetica,Arial,sans-serif;overflow-y:hidden}a,button,div,input,p,pre,span,textarea{font-family:inherit}.sb{-webkit-transition:opacity .3s;transition:opacity .3s;scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.3) transparent}.sb::-webkit-scrollbar{width:8px;height:8px}.sb::-webkit-scrollbar-track{background:transparent}.sb::-webkit-scrollbar-thumb{background:rgba(0,0,0,.3);border-radius:20px;border:3px solid transparent}
1
+ .bg-blue-100[data-v-a0ffaf3e]{--tw-bg-opacity:1;background-color:rgb(219 234 254/var(--tw-bg-opacity,1))}.bg-gray-100[data-v-a0ffaf3e]{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity,1))}.bg-gray-50[data-v-a0ffaf3e]{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity,1))}.bg-green-100[data-v-a0ffaf3e]{--tw-bg-opacity:1;background-color:rgb(220 252 231/var(--tw-bg-opacity,1))}.bg-red-100[data-v-a0ffaf3e]{--tw-bg-opacity:1;background-color:rgb(254 226 226/var(--tw-bg-opacity,1))}.bg-white[data-v-a0ffaf3e]{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.bg-yellow-100[data-v-a0ffaf3e]{--tw-bg-opacity:1;background-color:rgb(254 249 195/var(--tw-bg-opacity,1))}.border[data-v-a0ffaf3e]{border-width:1px}.border-collapse[data-v-a0ffaf3e]{border-collapse:collapse}.border-gray-200[data-v-a0ffaf3e]{--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity,1))}.border-gray-300[data-v-a0ffaf3e]{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity,1))}.border-solid[data-v-a0ffaf3e]{border-style:solid}.cursor-pointer[data-v-a0ffaf3e]{cursor:pointer}.flex[data-v-a0ffaf3e]{display:-webkit-box;display:-ms-flexbox;display:flex}.focus\:ring-blue-500[data-v-a0ffaf3e]:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(59 130 246/var(--tw-ring-opacity,1))}.font-bold[data-v-a0ffaf3e]{font-weight:700}.font-medium[data-v-a0ffaf3e]{font-weight:500}.font-semibold[data-v-a0ffaf3e]{font-weight:600}.gap-5[data-v-a0ffaf3e]{gap:1.25rem}.gap-6[data-v-a0ffaf3e]{gap:1.5rem}.h-4[data-v-a0ffaf3e]{height:1rem}.hover\:bg-gray-50[data-v-a0ffaf3e]:hover{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity,1))}.hover\:underline[data-v-a0ffaf3e]:hover{text-decoration-line:underline}.items-center[data-v-a0ffaf3e]{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.justify-between[data-v-a0ffaf3e]{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.mb-2[data-v-a0ffaf3e]{margin-bottom:.5rem}.mb-4[data-v-a0ffaf3e]{margin-bottom:1rem}.mb-8[data-v-a0ffaf3e]{margin-bottom:2rem}.ml-2[data-v-a0ffaf3e]{margin-left:.5rem}.ml-4[data-v-a0ffaf3e]{margin-left:1rem}.mr-2[data-v-a0ffaf3e]{margin-right:.5rem}.mt-2[data-v-a0ffaf3e]{margin-top:.5rem}.mt-4[data-v-a0ffaf3e]{margin-top:1rem}.overflow-x-auto[data-v-a0ffaf3e]{overflow-x:auto}.p-3[data-v-a0ffaf3e]{padding:.75rem}.p-5[data-v-a0ffaf3e]{padding:1.25rem}.pb-1[data-v-a0ffaf3e]{padding-bottom:.25rem}.pb-2[data-v-a0ffaf3e]{padding-bottom:.5rem}.pb-3[data-v-a0ffaf3e]{padding-bottom:.75rem}.px-2[data-v-a0ffaf3e]{padding-left:.5rem;padding-right:.5rem}.px-6[data-v-a0ffaf3e]{padding-left:1.5rem;padding-right:1.5rem}.py-1[data-v-a0ffaf3e]{padding-top:.25rem;padding-bottom:.25rem}.py-3[data-v-a0ffaf3e]{padding-top:.75rem;padding-bottom:.75rem}.py-4[data-v-a0ffaf3e]{padding-top:1rem;padding-bottom:1rem}.relative[data-v-a0ffaf3e]{position:relative}.rounded[data-v-a0ffaf3e]{border-radius:.25rem}.rounded-full[data-v-a0ffaf3e]{border-radius:9999px}.rounded-lg[data-v-a0ffaf3e]{border-radius:.5rem}.shadow-md[data-v-a0ffaf3e]{--tw-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1);--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color)}.shadow-md[data-v-a0ffaf3e],.shadow-sm[data-v-a0ffaf3e]{-webkit-box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-sm[data-v-a0ffaf3e]{--tw-shadow:0 1px 2px 0 rgba(0,0,0,.05);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color)}.space-x-4[data-v-a0ffaf3e]>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(1rem*var(--tw-space-x-reverse));margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)))}.space-y-2[data-v-a0ffaf3e]>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem*var(--tw-space-y-reverse))}.space-y-8[data-v-a0ffaf3e]>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(2rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem*var(--tw-space-y-reverse))}.sticky[data-v-a0ffaf3e]{position:sticky}.text-2xl[data-v-a0ffaf3e]{font-size:1.5rem;line-height:2rem}.text-blue-600[data-v-a0ffaf3e]{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity,1))}.text-gray-500[data-v-a0ffaf3e]{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}.text-gray-700[data-v-a0ffaf3e]{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity,1))}.text-gray-900[data-v-a0ffaf3e]{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity,1))}.text-green-600[data-v-a0ffaf3e]{--tw-text-opacity:1;color:rgb(22 163 74/var(--tw-text-opacity,1))}.text-indigo-600[data-v-a0ffaf3e]{--tw-text-opacity:1;color:rgb(79 70 229/var(--tw-text-opacity,1))}.text-left[data-v-a0ffaf3e]{text-align:left}.text-lg[data-v-a0ffaf3e]{font-size:1.125rem;line-height:1.75rem}.text-purple-600[data-v-a0ffaf3e]{--tw-text-opacity:1;color:rgb(147 51 234/var(--tw-text-opacity,1))}.text-red-600[data-v-a0ffaf3e]{--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity,1))}.text-right[data-v-a0ffaf3e]{text-align:right}.text-sm[data-v-a0ffaf3e]{font-size:.875rem;line-height:1.25rem}.text-teal-600[data-v-a0ffaf3e]{--tw-text-opacity:1;color:rgb(13 148 136/var(--tw-text-opacity,1))}.text-xs[data-v-a0ffaf3e]{font-size:.75rem;line-height:1rem}.text-yellow-600[data-v-a0ffaf3e]{--tw-text-opacity:1;color:rgb(202 138 4/var(--tw-text-opacity,1))}.top-0[data-v-a0ffaf3e]{top:0}.transition-colors[data-v-a0ffaf3e]{-webkit-transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;-webkit-transition-timing-function:cubic-bezier(.4,0,.2,1);transition-timing-function:cubic-bezier(.4,0,.2,1);-webkit-transition-duration:.15s;transition-duration:.15s}.w-4[data-v-a0ffaf3e]{width:1rem}.w-7[data-v-a0ffaf3e]{width:1.75rem}.w-full[data-v-a0ffaf3e]{width:100%}.z-10[data-v-a0ffaf3e]{z-index:10}.grid[data-v-a0ffaf3e]{display:grid}.grid-cols-1[data-v-a0ffaf3e]{grid-template-columns:repeat(1,minmax(0,1fr))}@media (min-width:640px){.sm\:grid-cols-2[data-v-a0ffaf3e]{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:1024px){.lg\:grid-cols-1[data-v-a0ffaf3e]{grid-template-columns:repeat(1,minmax(0,1fr))}.lg\:grid-cols-3[data-v-a0ffaf3e]{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4[data-v-a0ffaf3e]{grid-template-columns:repeat(4,minmax(0,1fr))}}.bg-blue-100[data-v-3796caa5]{--tw-bg-opacity:1;background-color:rgb(219 234 254/var(--tw-bg-opacity,1))}.bg-gray-100[data-v-3796caa5]{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity,1))}.border-gray-200[data-v-3796caa5]{--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity,1))}.border-t[data-v-3796caa5]{border-top-width:1px}.break-all[data-v-3796caa5]{word-break:break-all}.flex[data-v-3796caa5]{display:-webkit-box;display:-ms-flexbox;display:flex}.flex-shrink-0[data-v-3796caa5]{-ms-flex-negative:0;flex-shrink:0}.font-medium[data-v-3796caa5]{font-weight:500}.font-semibold[data-v-3796caa5]{font-weight:600}.gap-3[data-v-3796caa5]{gap:.75rem}.gap-4[data-v-3796caa5]{gap:1rem}.gap-x-8[data-v-3796caa5]{-webkit-column-gap:2rem;-moz-column-gap:2rem;column-gap:2rem}.gap-y-6[data-v-3796caa5]{row-gap:1.5rem}.inline-block[data-v-3796caa5]{display:inline-block}.items-center[data-v-3796caa5]{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.items-start[data-v-3796caa5]{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.mb-2[data-v-3796caa5]{margin-bottom:.5rem}.mr-3[data-v-3796caa5]{margin-right:.75rem}.mt-1[data-v-3796caa5]{margin-top:.25rem}.p-3[data-v-3796caa5]{padding:.75rem}.pt-6[data-v-3796caa5]{padding-top:1.5rem}.px-2[data-v-3796caa5]{padding-left:.5rem;padding-right:.5rem}.py-1[data-v-3796caa5]{padding-top:.25rem;padding-bottom:.25rem}.rounded-lg[data-v-3796caa5]{border-radius:.5rem}.rounded-md[data-v-3796caa5]{border-radius:.375rem}.space-y-8[data-v-3796caa5]>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(2rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem*var(--tw-space-y-reverse))}.text-base[data-v-3796caa5]{font-size:1rem;line-height:1.5rem}.text-blue-700[data-v-3796caa5]{--tw-text-opacity:1;color:rgb(29 78 216/var(--tw-text-opacity,1))}.text-gray-400[data-v-3796caa5]{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity,1))}.text-gray-500[data-v-3796caa5]{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}.text-gray-700[data-v-3796caa5]{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity,1))}.text-gray-900[data-v-3796caa5]{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity,1))}.text-sm[data-v-3796caa5]{font-size:.875rem;line-height:1.25rem}.text-xs[data-v-3796caa5]{font-size:.75rem;line-height:1rem}.text-red-800\/80[data-v-3796caa5]{color:rgba(153,27,27,.8)}.text-green-800\/80[data-v-3796caa5]{color:rgba(22,101,52,.8)}.grid[data-v-3796caa5]{display:grid}.grid-cols-1[data-v-3796caa5]{grid-template-columns:repeat(1,minmax(0,1fr))}@media (min-width:640px){.sm\:grid-cols-2[data-v-3796caa5]{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:768px){.md\:grid-cols-2[data-v-3796caa5]{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:col-span-2[data-v-3796caa5]{grid-column:span 2/span 2}}@media (min-width:1024px){.lg\:grid-cols-4[data-v-3796caa5]{grid-template-columns:repeat(4,minmax(0,1fr))}}.status-danger[data-v-3796caa5]{background-color:#fef2f2;color:#b91c1c;border:1px solid #fecaca}.status-warning[data-v-3796caa5]{background-color:#fffbeb;color:#b45309;border:1px solid #fde68a}.status-success[data-v-3796caa5]{background-color:#f0fdf4;color:#15803d;border:1px solid #bbf7d0}.status-info[data-v-3796caa5]{background-color:#f8fafc;color:#475569;border:1px solid #e2e8f0}.perms-trigger[data-v-3d1cbcc4]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:2px;border:1px solid #767676;border-radius:4px;background:#f0f0f0;cursor:pointer;-webkit-transition:background-color .2s;transition:background-color .2s}.perms-trigger[data-v-3d1cbcc4]:hover{background:#e5e5e5}.menu-row-click[data-v-4501b18f]{-webkit-transition:background .2s;transition:background .2s}.menu-row-click[data-v-4501b18f]:focus,.menu-row-click[data-v-4501b18f]:hover{background:#f2f2f2}body,html{font-family:微軟正黑體,Microsoft JhengHei,MicrosoftJhengHeiRegular,Avenir,Helvetica,Arial,sans-serif;overflow-y:hidden}a,button,div,input,p,pre,span,textarea{font-family:inherit}.sb{-webkit-transition:opacity .3s;transition:opacity .3s;scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.3) transparent}.sb::-webkit-scrollbar{width:8px;height:8px}.sb::-webkit-scrollbar-track{background:transparent}.sb::-webkit-scrollbar-thumb{background:rgba(0,0,0,.3);border-radius:20px;border:3px solid transparent}
package/dist/index.tmp CHANGED
@@ -1,3 +1,3 @@
1
1
  <!doctype html><html xmlns="http://www.w3.org/1999/xhtml" lang="zh-tw"><head><meta http-equiv="content-type" content="text/html; charset=UTF-8"/><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no,minimal-ui"><meta http-equiv="X-UA-Compatible" content="ie=edge"><meta name="referrer" content="strict-origin"><title></title><link _href="https://cdn.jsdelivr.net/npm/@mdi/font@7.4.47/css/materialdesignicons.min.css" rel="stylesheet"><link _href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.4.2/css/all.min.css" rel="stylesheet"><script>window.___pmwsso___={
2
2
  language: '{language}',
3
- }</script><script defer="defer" src="{sfd}/js/chunk-vendors.0492b6f5.js" type="module"></script><script defer="defer" src="{sfd}/js/app.bee6840f.js" type="module"></script><link href="{sfd}/css/chunk-vendors.5c06be05.css" rel="stylesheet"><link href="{sfd}/css/app.b17b0ba0.css" rel="stylesheet"><script defer="defer" src="{sfd}/js/chunk-vendors-legacy.0492b6f5.js" nomodule></script><script defer="defer" src="{sfd}/js/app-legacy.bee6840f.js" nomodule></script></head><body style="font-family:'Microsoft JhengHei','Avenir','Helvetica', 'Arial', 'sans-serif'; padding:0px; margin:0px;"><noscript><strong>We're sorry but w-component-vue doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
3
+ }</script><script defer="defer" src="{sfd}/js/chunk-vendors.97013ddc.js" type="module"></script><script defer="defer" src="{sfd}/js/app.7c006893.js" type="module"></script><link href="{sfd}/css/chunk-vendors.5c06be05.css" rel="stylesheet"><link href="{sfd}/css/app.f000459f.css" rel="stylesheet"><script defer="defer" src="{sfd}/js/chunk-vendors-legacy.97013ddc.js" nomodule></script><script defer="defer" src="{sfd}/js/app-legacy.7c006893.js" nomodule></script></head><body style="font-family:'Microsoft JhengHei','Avenir','Helvetica', 'Arial', 'sans-serif'; padding:0px; margin:0px;"><noscript><strong>We're sorry but w-component-vue doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>