dsh-vault 1.3.0-rc.9 → 1.3.0

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/lib/client.js CHANGED
@@ -7,7 +7,7 @@ window.__ModuleLoader__.load({
7
7
  let react = require("react");
8
8
  let react_jsx_runtime = require("react/jsx-runtime");
9
9
  //#region \0dsh-css:/Users/zhipeng/Desktop/work/dsh test/dsh-vault/src/client/VaultSection.module.css.mjs
10
- const css = ".t_j5va_section{flex-direction:column;gap:12px;padding:16px 0;display:flex}.t_j5va_intro{opacity:.75;margin:0;font-size:13px}.t_j5va_srOnly{clip-path:inset(50%);white-space:nowrap;width:1px;height:1px;position:absolute;overflow:hidden}.t_j5va_toolbar{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.t_j5va_searchBox{flex:150px;min-width:150px;display:flex}.t_j5va_searchBox input{border:1px solid var(--color-border,#444);color:inherit;background:0 0;border-radius:6px;flex:1;padding:6px 10px;font-size:13px}.t_j5va_addButton,.t_j5va_saveButton{background:var(--color-accent,#4f8cff);color:#fff;cursor:pointer;border:1px solid #0000;border-radius:6px;padding:6px 12px;font-size:13px}.t_j5va_addButton:disabled,.t_j5va_saveButton:disabled,.t_j5va_rowActions button:disabled{opacity:.5;cursor:not-allowed}.t_j5va_list{flex-direction:column;gap:6px;margin:0;padding:0;list-style:none;display:flex}.t_j5va_row{border:1px solid var(--color-border,#333);border-radius:8px;justify-content:space-between;align-items:center;gap:12px;padding:8px 10px;display:flex}.t_j5va_rowMain{flex-direction:column;gap:2px;min-width:0;display:flex}.t_j5va_title{font-size:14px;font-weight:600}.t_j5va_identity{opacity:.7;text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}.t_j5va_totp{font-family:var(--font-mono,monospace);color:var(--color-accent,#4f8cff);font-size:13px}.t_j5va_totpRing{vertical-align:-2px;margin-right:4px;display:inline-block}.t_j5va_rowActions{flex-shrink:0;align-items:center;gap:6px;display:flex}.t_j5va_rowActions button{border:1px solid var(--color-border,#444);color:inherit;cursor:pointer;background:0 0;border-radius:6px;padding:4px 8px;font-size:12px}.t_j5va_deleteButton{color:#e5484d}.t_j5va_copied{color:#30a46c;font-size:12px}.t_j5va_empty,.t_j5va_status,.t_j5va_error{opacity:.8;font-size:13px}.t_j5va_lockedBanner{color:#8a5a00;background:#fff4e5;border:1px solid #e0a83a;border-radius:6px;margin:0 0 10px;padding:8px 12px;font-size:13px}.t_j5va_modeReadonly,.t_j5va_modeAsk,.t_j5va_modeAuto{border-radius:999px;width:fit-content;margin:0;padding:4px 10px;font-size:12px;display:inline-block}.t_j5va_modeReadonly{color:#e5484d;border:1px solid #e5484d80}.t_j5va_modeAsk{color:#f5a524;border:1px solid #f5a52480}.t_j5va_modeAuto{color:#30a46c;border:1px solid #30a46c80}.t_j5va_policyBar{flex-direction:column;align-items:flex-start;gap:6px;display:flex}.t_j5va_policyField{align-items:center;gap:8px;font-size:13px;display:flex}.t_j5va_policyField select{border:1px solid var(--color-border,#444);color:inherit;background:0 0;border-radius:6px;padding:4px 8px;font-size:13px}.t_j5va_emptyBox{flex-direction:column;gap:4px;display:flex}.t_j5va_emptyHint{opacity:.65;margin:0;font-size:12px}.t_j5va_error{color:#e5484d}.t_j5va_editor{border:1px solid var(--color-border,#444);border-radius:8px;padding:12px}.t_j5va_editorBody{grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:8px 12px;display:grid}.t_j5va_checkField{align-items:center;gap:8px;font-size:13px;display:inline-flex}.t_j5va_field{flex-direction:column;gap:4px;font-size:12px;display:flex}.t_j5va_field input,.t_j5va_field select{border:1px solid var(--color-border,#444);color:inherit;background:0 0;border-radius:6px;padding:5px 8px;font-size:13px}.t_j5va_editorActions{justify-content:flex-end;gap:8px;margin-top:12px;display:flex}.t_j5va_editorActions button{border:1px solid var(--color-border,#444);color:inherit;cursor:pointer;background:0 0;border-radius:6px;padding:6px 12px;font-size:13px}.t_j5va_reportBox{border:1px solid #f5a52466;border-radius:8px;flex-direction:column;gap:2px;padding:8px 10px;font-size:12px;display:flex}.t_j5va_reportTitle{margin:0;font-weight:600}.t_j5va_reportLine{opacity:.8;margin:0}.t_j5va_reportSub{color:var(--dsh-color-text-2,#666);margin:2px 0 0 10px;font-size:12px}.t_j5va_trashButton{border:1px solid var(--color-border,#444);color:inherit;cursor:pointer;background:0 0;border-radius:6px;align-self:flex-start;padding:4px 8px;font-size:12px}.t_j5va_secretField{gap:4px;display:flex}.t_j5va_secretField input{flex:1;min-width:0}.t_j5va_revealButton{border:1px solid var(--color-border,#444);color:inherit;cursor:pointer;background:0 0;border-radius:6px;padding:0 8px;font-size:12px}.t_j5va_kindFilter{border:1px solid var(--color-border,#444);color:inherit;background:0 0;border-radius:6px;padding:6px 8px;font-size:13px}.t_j5va_highBadge{color:#e5484d;vertical-align:middle;background:#e5484d26;border-radius:4px;margin-left:6px;padding:1px 6px;font-size:10px;font-weight:600}.t_j5va_pinStar{color:#f5a524;margin-right:4px}.t_j5va_clearButton{color:inherit;cursor:pointer;opacity:.6;background:0 0;border:none;padding:0 8px;font-size:16px}.t_j5va_field textarea{border:1px solid var(--color-border,#444);color:inherit;resize:vertical;background:0 0;border-radius:6px;padding:5px 8px;font-family:inherit;font-size:13px}.t_j5va_row{transition:background .12s}.t_j5va_row:hover{background:var(--color-hover,#80808014)}.t_j5va_healthBar{flex-wrap:wrap;gap:6px;margin:0 0 10px;display:flex}.t_j5va_badge{border:1px solid var(--dsh-color-border,#ddd);background:var(--dsh-color-surface-2,#f7f7f8);color:var(--dsh-color-text-2,#555);border-radius:999px;padding:4px 10px;font-size:12px;line-height:1}.t_j5va_backupButton{border:1px solid var(--dsh-color-border,#ccc);background:var(--dsh-color-surface-2,#f7f7f8);cursor:pointer;border-radius:999px;padding:4px 10px;font-size:12px;line-height:1}.t_j5va_badgeOk{color:#2e9e5b;border-color:#2e9e5b}.t_j5va_badgeWarn{color:#b57f1a;border-color:#c98a1b}.t_j5va_rowDue{border-left:3px solid #c98a1b}.t_j5va_rowExpired{border-left:3px solid #cf3d3d}.t_j5va_dueBadge{border-radius:999px;margin-left:6px;padding:3px 8px;font-size:11px;font-weight:600;line-height:1}.t_j5va_badgeDanger{color:#c03a3a;border-color:#cf3d3d}.t_j5va_footer{opacity:.6;margin:0;font-size:12px}.t_j5va_kindIcon{margin-right:4px;font-size:12px}.t_j5va_dangerButton{color:#e5484d;cursor:pointer;background:0 0;border:1px solid #e5484d80;border-radius:6px;align-self:flex-start;padding:4px 8px;font-size:12px}.t_j5va_rowMain{cursor:pointer}.t_j5va_detailBox{background:var(--color-hover,#8080800f);border-radius:6px;flex-wrap:wrap;grid-column:1/-1;gap:4px 12px;padding:6px 8px;font-size:12px;display:flex}.t_j5va_detailItem{opacity:.85}.t_j5va_sortButton{border:1px solid var(--color-border,#444);color:inherit;cursor:pointer;background:0 0;border-radius:6px;padding:6px 10px;font-size:13px}.t_j5va_dupGroup{justify-content:space-between;align-items:center;gap:8px;margin:4px 0;display:flex}.t_j5va_dupNames{text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}.t_j5va_dupMerge{border:1px solid var(--dsh-color-border,#ccc);cursor:pointer;border-radius:6px;flex-shrink:0;padding:2px 8px;font-size:12px}.t_j5va_auditRow{align-items:center;gap:8px;margin:4px 0;display:flex}.t_j5va_auditIssues{color:var(--dsh-color-text-2,#666);text-overflow:ellipsis;white-space:nowrap;flex:1;font-size:12px;overflow:hidden}.t_j5va_retryButton{border:1px solid var(--dsh-color-border,#ccc);cursor:pointer;border-radius:6px;margin-left:6px;padding:2px 8px;font-size:12px}.t_j5va_scoreRing{vertical-align:-2px;margin-right:4px;display:inline-block}.t_j5va_genOpts{border:1px solid var(--dsh-color-border,#ddd);border-radius:8px;flex-direction:column;gap:6px;padding:8px 10px;display:flex}.t_j5va_genOptRow{justify-content:space-between;align-items:center;gap:8px;font-size:13px;display:flex}.t_j5va_genOptRow input[type=number]{width:64px}.t_j5va_pwMeter{align-items:center;gap:8px;font-size:12px;display:flex}.t_j5va_pwBar{border-radius:999px;height:6px;transition:width .2s}.t_j5va_pwWeak{background:#cf3d3d}.t_j5va_pwFair{background:#c98a1b}.t_j5va_pwStrong{background:#2e9e5b}.t_j5va_pwLabel{color:var(--dsh-color-text-2,#666)}.t_j5va_resultCount{color:var(--dsh-color-text-2,#666);flex-wrap:wrap;align-items:center;gap:6px;margin:0 0 6px;font-size:12px;display:flex}.t_j5va_kindChip{border:1px solid var(--dsh-color-border,#ddd);border-radius:999px;padding:2px 8px;font-size:11px}.t_j5va_uriCode{overflow-wrap:anywhere;opacity:.85;font-size:10px}.t_j5va_genHist{flex-wrap:wrap;gap:4px;font-size:12px;display:flex}.t_j5va_genHist span{align-self:center}.t_j5va_lockedTag{color:#c98a1b;font-size:12px;font-weight:600}.t_j5va_tabs{flex-wrap:wrap;gap:6px;margin:0 0 12px;display:flex}.t_j5va_tab{border:1px solid var(--dsh-color-border,#ccc);color:inherit;cursor:pointer;background:0 0;border-radius:999px;padding:5px 14px;font-size:13px}.t_j5va_tabActive{background:var(--dsh-color-primary,#4a6cf7);color:#fff;border-color:#0000}.t_j5va_tabPane{margin-top:2px}";
10
+ const css = ".t_j5va_section{flex-direction:column;gap:12px;padding:16px 0;display:flex}.t_j5va_intro{opacity:.75;margin:0;font-size:13px}.t_j5va_srOnly{clip-path:inset(50%);white-space:nowrap;width:1px;height:1px;position:absolute;overflow:hidden}.t_j5va_toolbar{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.t_j5va_searchBox{flex:150px;min-width:150px;display:flex}.t_j5va_searchBox input{border:1px solid var(--color-border,#444);color:inherit;background:0 0;border-radius:6px;flex:1;padding:6px 10px;font-size:13px}.t_j5va_addButton,.t_j5va_saveButton{background:var(--color-accent,#4f8cff);color:#fff;cursor:pointer;border:1px solid #0000;border-radius:6px;padding:6px 12px;font-size:13px}.t_j5va_addButton:disabled,.t_j5va_saveButton:disabled,.t_j5va_rowActions button:disabled{opacity:.5;cursor:not-allowed}.t_j5va_list{flex-direction:column;gap:6px;margin:0;padding:0;list-style:none;display:flex}.t_j5va_row{border:1px solid var(--color-border,#333);border-radius:8px;justify-content:space-between;align-items:center;gap:12px;padding:8px 10px;display:flex}.t_j5va_rowMain{flex-direction:column;gap:2px;min-width:0;display:flex}.t_j5va_title{font-size:14px;font-weight:600}.t_j5va_identity{opacity:.7;text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}.t_j5va_totp{font-family:var(--font-mono,monospace);color:var(--color-accent,#4f8cff);font-size:13px}.t_j5va_totpRing{vertical-align:-2px;margin-right:4px;display:inline-block}.t_j5va_rowActions{flex-shrink:0;align-items:center;gap:6px;display:flex}.t_j5va_rowActions button{border:1px solid var(--color-border,#444);color:inherit;cursor:pointer;background:0 0;border-radius:6px;padding:4px 8px;font-size:12px}.t_j5va_deleteButton{color:#e5484d}.t_j5va_copied{color:#30a46c;font-size:12px}.t_j5va_empty,.t_j5va_status,.t_j5va_error{opacity:.8;font-size:13px}.t_j5va_lockedBanner{color:#8a5a00;background:#fff4e5;border:1px solid #e0a83a;border-radius:6px;margin:0 0 10px;padding:8px 12px;font-size:13px}.t_j5va_modeReadonly,.t_j5va_modeAsk,.t_j5va_modeAuto{border-radius:999px;width:fit-content;margin:0;padding:4px 10px;font-size:12px;display:inline-block}.t_j5va_modeReadonly{color:#e5484d;border:1px solid #e5484d80}.t_j5va_modeAsk{color:#f5a524;border:1px solid #f5a52480}.t_j5va_modeAuto{color:#30a46c;border:1px solid #30a46c80}.t_j5va_policyBar{flex-direction:column;align-items:flex-start;gap:6px;display:flex}.t_j5va_policyField{align-items:center;gap:8px;font-size:13px;display:flex}.t_j5va_policyField select{border:1px solid var(--color-border,#444);color:inherit;background:0 0;border-radius:6px;padding:4px 8px;font-size:13px}.t_j5va_emptyBox{flex-direction:column;gap:4px;display:flex}.t_j5va_emptyHint{opacity:.65;margin:0;font-size:12px}.t_j5va_error{color:#e5484d}.t_j5va_editor{border:1px solid var(--color-border,#444);border-radius:8px;padding:12px}.t_j5va_editorBody{grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:8px 12px;display:grid}.t_j5va_checkField{align-items:center;gap:8px;font-size:13px;display:inline-flex}.t_j5va_field{flex-direction:column;gap:4px;font-size:12px;display:flex}.t_j5va_field input,.t_j5va_field select{border:1px solid var(--color-border,#444);color:inherit;background:0 0;border-radius:6px;padding:5px 8px;font-size:13px}.t_j5va_editorActions{justify-content:flex-end;gap:8px;margin-top:12px;display:flex}.t_j5va_editorActions button{border:1px solid var(--color-border,#444);color:inherit;cursor:pointer;background:0 0;border-radius:6px;padding:6px 12px;font-size:13px}.t_j5va_reportBox{border:1px solid #f5a52466;border-radius:8px;flex-direction:column;gap:2px;padding:8px 10px;font-size:12px;display:flex}.t_j5va_reportTitle{margin:0;font-weight:600}.t_j5va_reportLine{opacity:.8;margin:0}.t_j5va_reportSub{color:var(--dsh-color-text-2,#666);margin:2px 0 0 10px;font-size:12px}.t_j5va_trashButton{border:1px solid var(--color-border,#444);color:inherit;cursor:pointer;background:0 0;border-radius:6px;align-self:flex-start;padding:4px 8px;font-size:12px}.t_j5va_secretField{gap:4px;display:flex}.t_j5va_secretField input{flex:1;min-width:0}.t_j5va_revealButton{border:1px solid var(--color-border,#444);color:inherit;cursor:pointer;background:0 0;border-radius:6px;padding:0 8px;font-size:12px}.t_j5va_kindFilter{border:1px solid var(--color-border,#444);color:inherit;background:0 0;border-radius:6px;padding:6px 8px;font-size:13px}.t_j5va_highBadge{color:#e5484d;vertical-align:middle;background:#e5484d26;border-radius:4px;margin-left:6px;padding:1px 6px;font-size:10px;font-weight:600}.t_j5va_pinStar{color:#f5a524;margin-right:4px}.t_j5va_clearButton{color:inherit;cursor:pointer;opacity:.6;background:0 0;border:none;padding:0 8px;font-size:16px}.t_j5va_field textarea{border:1px solid var(--color-border,#444);color:inherit;resize:vertical;background:0 0;border-radius:6px;padding:5px 8px;font-family:inherit;font-size:13px}.t_j5va_row{transition:background .12s}.t_j5va_row:hover{background:var(--color-hover,#80808014)}.t_j5va_healthBar{flex-wrap:wrap;gap:6px;margin:0 0 10px;display:flex}.t_j5va_badge{border:1px solid var(--dsh-color-border,#ddd);background:var(--dsh-color-surface-2,#f7f7f8);color:var(--dsh-color-text-2,#555);border-radius:999px;padding:4px 10px;font-size:12px;line-height:1}.t_j5va_backupButton{border:1px solid var(--dsh-color-border,#ccc);background:var(--dsh-color-surface-2,#f7f7f8);cursor:pointer;border-radius:999px;padding:4px 10px;font-size:12px;line-height:1}.t_j5va_badgeOk{color:#2e9e5b;border-color:#2e9e5b}.t_j5va_badgeWarn{color:#b57f1a;border-color:#c98a1b}.t_j5va_rowDue{border-left:3px solid #c98a1b}.t_j5va_rowExpired{border-left:3px solid #cf3d3d}.t_j5va_dueBadge{border-radius:999px;margin-left:6px;padding:3px 8px;font-size:11px;font-weight:600;line-height:1}.t_j5va_badgeDanger{color:#c03a3a;border-color:#cf3d3d}.t_j5va_footer{opacity:.6;margin:0;font-size:12px}.t_j5va_kindIcon{margin-right:4px;font-size:12px}.t_j5va_dangerButton{color:#e5484d;cursor:pointer;background:0 0;border:1px solid #e5484d80;border-radius:6px;align-self:flex-start;padding:4px 8px;font-size:12px}.t_j5va_rowMain{cursor:pointer}.t_j5va_detailBox{background:var(--color-hover,#8080800f);border-radius:6px;flex-wrap:wrap;grid-column:1/-1;gap:4px 12px;padding:6px 8px;font-size:12px;display:flex}.t_j5va_detailItem{opacity:.85}.t_j5va_sortButton{border:1px solid var(--color-border,#444);color:inherit;cursor:pointer;background:0 0;border-radius:6px;padding:6px 10px;font-size:13px}.t_j5va_dupGroup{justify-content:space-between;align-items:center;gap:8px;margin:4px 0;display:flex}.t_j5va_dupNames{text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}.t_j5va_dupMerge{border:1px solid var(--dsh-color-border,#ccc);cursor:pointer;border-radius:6px;flex-shrink:0;padding:2px 8px;font-size:12px}.t_j5va_auditRow{align-items:center;gap:8px;margin:4px 0;display:flex}.t_j5va_auditIssues{color:var(--dsh-color-text-2,#666);text-overflow:ellipsis;white-space:nowrap;flex:1;font-size:12px;overflow:hidden}.t_j5va_retryButton{border:1px solid var(--dsh-color-border,#ccc);cursor:pointer;border-radius:6px;margin-left:6px;padding:2px 8px;font-size:12px}.t_j5va_scoreRing{vertical-align:-2px;margin-right:4px;display:inline-block}.t_j5va_genOpts{border:1px solid var(--dsh-color-border,#ddd);border-radius:8px;flex-direction:column;gap:6px;padding:8px 10px;display:flex}.t_j5va_genOptRow{justify-content:space-between;align-items:center;gap:8px;font-size:13px;display:flex}.t_j5va_genOptRow input[type=number]{width:64px}.t_j5va_pwMeter{align-items:center;gap:8px;font-size:12px;display:flex}.t_j5va_pwBar{border-radius:999px;height:6px;transition:width .2s}.t_j5va_pwWeak{background:#cf3d3d}.t_j5va_pwFair{background:#c98a1b}.t_j5va_pwStrong{background:#2e9e5b}.t_j5va_pwLabel{color:var(--dsh-color-text-2,#666)}.t_j5va_resultCount{color:var(--dsh-color-text-2,#666);flex-wrap:wrap;align-items:center;gap:6px;margin:0 0 6px;font-size:12px;display:flex}.t_j5va_kindChip{border:1px solid var(--dsh-color-border,#ddd);border-radius:999px;padding:2px 8px;font-size:11px}.t_j5va_uriCode{overflow-wrap:anywhere;opacity:.85;font-size:10px}.t_j5va_genHist{flex-wrap:wrap;gap:4px;font-size:12px;display:flex}.t_j5va_genHist span{align-self:center}.t_j5va_lockedTag{color:#c98a1b;font-size:12px;font-weight:600}";
11
11
  const tagId = "dsh-vault/VaultSection.module.css";
12
12
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
13
13
  const tag = document.createElement("style");
@@ -17,89 +17,85 @@ window.__ModuleLoader__.load({
17
17
  document.head.appendChild(tag);
18
18
  }
19
19
  var VaultSection_module_css_default = {
20
+ "rowActions": "t_j5va_rowActions",
20
21
  "error": "t_j5va_error",
21
- "status": "t_j5va_status",
22
- "searchBox": "t_j5va_searchBox",
23
- "secretField": "t_j5va_secretField",
24
- "lockedTag": "t_j5va_lockedTag",
25
- "rowMain": "t_j5va_rowMain",
26
- "totpRing": "t_j5va_totpRing",
27
- "empty": "t_j5va_empty",
28
- "scoreRing": "t_j5va_scoreRing",
29
- "pwWeak": "t_j5va_pwWeak",
30
- "modeAuto": "t_j5va_modeAuto",
31
- "reportLine": "t_j5va_reportLine",
32
- "footer": "t_j5va_footer",
22
+ "list": "t_j5va_list",
23
+ "policyBar": "t_j5va_policyBar",
33
24
  "identity": "t_j5va_identity",
34
- "revealButton": "t_j5va_revealButton",
25
+ "pinStar": "t_j5va_pinStar",
26
+ "addButton": "t_j5va_addButton",
27
+ "genOptRow": "t_j5va_genOptRow",
28
+ "backupButton": "t_j5va_backupButton",
29
+ "lockedBanner": "t_j5va_lockedBanner",
30
+ "editorBody": "t_j5va_editorBody",
31
+ "empty": "t_j5va_empty",
32
+ "searchBox": "t_j5va_searchBox",
33
+ "auditRow": "t_j5va_auditRow",
34
+ "policyField": "t_j5va_policyField",
35
+ "resultCount": "t_j5va_resultCount",
36
+ "emptyHint": "t_j5va_emptyHint",
37
+ "checkField": "t_j5va_checkField",
35
38
  "healthBar": "t_j5va_healthBar",
39
+ "field": "t_j5va_field",
40
+ "genOpts": "t_j5va_genOpts",
41
+ "clearButton": "t_j5va_clearButton",
36
42
  "kindIcon": "t_j5va_kindIcon",
43
+ "detailBox": "t_j5va_detailBox",
44
+ "srOnly": "t_j5va_srOnly",
45
+ "footer": "t_j5va_footer",
46
+ "totp": "t_j5va_totp",
47
+ "status": "t_j5va_status",
48
+ "pwWeak": "t_j5va_pwWeak",
49
+ "kindChip": "t_j5va_kindChip",
50
+ "genHist": "t_j5va_genHist",
51
+ "totpRing": "t_j5va_totpRing",
52
+ "rowExpired": "t_j5va_rowExpired",
53
+ "row": "t_j5va_row",
54
+ "dupMerge": "t_j5va_dupMerge",
55
+ "badgeOk": "t_j5va_badgeOk",
56
+ "saveButton": "t_j5va_saveButton",
57
+ "kindFilter": "t_j5va_kindFilter",
37
58
  "badgeWarn": "t_j5va_badgeWarn",
38
- "backupButton": "t_j5va_backupButton",
59
+ "intro": "t_j5va_intro",
60
+ "detailItem": "t_j5va_detailItem",
61
+ "pwStrong": "t_j5va_pwStrong",
62
+ "emptyBox": "t_j5va_emptyBox",
63
+ "scoreRing": "t_j5va_scoreRing",
64
+ "rowMain": "t_j5va_rowMain",
65
+ "modeAsk": "t_j5va_modeAsk",
66
+ "editorActions": "t_j5va_editorActions",
67
+ "pwBar": "t_j5va_pwBar",
39
68
  "pwMeter": "t_j5va_pwMeter",
69
+ "pwLabel": "t_j5va_pwLabel",
70
+ "modeAuto": "t_j5va_modeAuto",
71
+ "lockedTag": "t_j5va_lockedTag",
40
72
  "dupNames": "t_j5va_dupNames",
41
- "deleteButton": "t_j5va_deleteButton",
42
- "dangerButton": "t_j5va_dangerButton",
43
73
  "copied": "t_j5va_copied",
44
- "kindChip": "t_j5va_kindChip",
45
- "auditRow": "t_j5va_auditRow",
46
- "clearButton": "t_j5va_clearButton",
47
- "reportBox": "t_j5va_reportBox",
48
- "sortButton": "t_j5va_sortButton",
49
- "tabActive": "t_j5va_tabActive",
50
- "pinStar": "t_j5va_pinStar",
51
- "detailItem": "t_j5va_detailItem",
52
- "genOpts": "t_j5va_genOpts",
53
- "editorActions": "t_j5va_editorActions",
54
- "emptyHint": "t_j5va_emptyHint",
74
+ "reportTitle": "t_j5va_reportTitle",
75
+ "highBadge": "t_j5va_highBadge",
55
76
  "badge": "t_j5va_badge",
56
- "tabPane": "t_j5va_tabPane",
57
- "pwBar": "t_j5va_pwBar",
58
- "dupMerge": "t_j5va_dupMerge",
59
- "saveButton": "t_j5va_saveButton",
60
- "rowExpired": "t_j5va_rowExpired",
61
77
  "section": "t_j5va_section",
62
- "list": "t_j5va_list",
63
- "dueBadge": "t_j5va_dueBadge",
64
- "reportSub": "t_j5va_reportSub",
65
- "genOptRow": "t_j5va_genOptRow",
66
- "policyField": "t_j5va_policyField",
67
- "title": "t_j5va_title",
68
- "modeAsk": "t_j5va_modeAsk",
69
- "intro": "t_j5va_intro",
70
- "addButton": "t_j5va_addButton",
71
- "row": "t_j5va_row",
72
- "policyBar": "t_j5va_policyBar",
73
78
  "auditIssues": "t_j5va_auditIssues",
74
- "rowActions": "t_j5va_rowActions",
75
- "resultCount": "t_j5va_resultCount",
76
- "reportTitle": "t_j5va_reportTitle",
77
- "field": "t_j5va_field",
78
- "kindFilter": "t_j5va_kindFilter",
79
- "totp": "t_j5va_totp",
80
- "dupGroup": "t_j5va_dupGroup",
81
- "editor": "t_j5va_editor",
82
79
  "pwFair": "t_j5va_pwFair",
83
- "tab": "t_j5va_tab",
84
- "checkField": "t_j5va_checkField",
80
+ "deleteButton": "t_j5va_deleteButton",
81
+ "editor": "t_j5va_editor",
82
+ "reportBox": "t_j5va_reportBox",
83
+ "revealButton": "t_j5va_revealButton",
84
+ "badgeDanger": "t_j5va_badgeDanger",
85
+ "rowDue": "t_j5va_rowDue",
86
+ "secretField": "t_j5va_secretField",
87
+ "uriCode": "t_j5va_uriCode",
88
+ "reportLine": "t_j5va_reportLine",
85
89
  "trashButton": "t_j5va_trashButton",
86
- "emptyBox": "t_j5va_emptyBox",
87
- "pwStrong": "t_j5va_pwStrong",
88
- "retryButton": "t_j5va_retryButton",
89
90
  "toolbar": "t_j5va_toolbar",
90
- "genHist": "t_j5va_genHist",
91
- "tabs": "t_j5va_tabs",
92
- "badgeOk": "t_j5va_badgeOk",
93
- "highBadge": "t_j5va_highBadge",
94
91
  "modeReadonly": "t_j5va_modeReadonly",
95
- "lockedBanner": "t_j5va_lockedBanner",
96
- "editorBody": "t_j5va_editorBody",
97
- "badgeDanger": "t_j5va_badgeDanger",
98
- "pwLabel": "t_j5va_pwLabel",
99
- "uriCode": "t_j5va_uriCode",
100
- "srOnly": "t_j5va_srOnly",
101
- "detailBox": "t_j5va_detailBox",
102
- "rowDue": "t_j5va_rowDue"
92
+ "sortButton": "t_j5va_sortButton",
93
+ "dupGroup": "t_j5va_dupGroup",
94
+ "reportSub": "t_j5va_reportSub",
95
+ "title": "t_j5va_title",
96
+ "dueBadge": "t_j5va_dueBadge",
97
+ "dangerButton": "t_j5va_dangerButton",
98
+ "retryButton": "t_j5va_retryButton"
103
99
  };
104
100
  //#endregion
105
101
  //#region src/client/VaultSection.tsx
@@ -199,12 +195,6 @@ window.__ModuleLoader__.load({
199
195
  fair: "verdictFair",
200
196
  poor: "verdictPoor"
201
197
  };
202
- const TAB_KEYS = {
203
- entries: "tabEntries",
204
- security: "tabSecurity",
205
- transfer: "tabTransfer",
206
- organize: "tabOrganize"
207
- };
208
198
  const VERDICT_KEYS_SHORT = {
209
199
  weak: "verdictPoor",
210
200
  fair: "verdictFair",
@@ -282,7 +272,6 @@ window.__ModuleLoader__.load({
282
272
  const [expandedId, setExpandedId] = (0, react.useState)(null);
283
273
  const [visibleCount, setVisibleCount] = (0, react.useState)(50);
284
274
  const [sortBy, setSortBy] = (0, react.useState)("alpha");
285
- const [activeTab, setActiveTab] = (0, react.useState)("entries");
286
275
  const [policy, setPolicy] = (0, react.useState)(null);
287
276
  const [showTrash, setShowTrash] = (0, react.useState)(false);
288
277
  const [trashEntries, setTrashEntries] = (0, react.useState)([]);
@@ -896,128 +885,110 @@ window.__ModuleLoader__.load({
896
885
  className: VaultSection_module_css_default.lockedBanner,
897
886
  children: t("lockedBanner")
898
887
  }),
899
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("nav", {
900
- className: VaultSection_module_css_default.tabs,
901
- "aria-label": t("sectionTabs"),
888
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
889
+ className: VaultSection_module_css_default.toolbar,
902
890
  children: [
903
- "entries",
904
- "security",
905
- "transfer",
906
- "organize"
907
- ].map((tab) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
908
- type: "button",
909
- className: `${VaultSection_module_css_default.tab}${activeTab === tab ? ` ${VaultSection_module_css_default.tabActive}` : ""}`,
910
- onClick: () => setActiveTab(tab),
911
- children: t(TAB_KEYS[tab])
912
- }, tab))
913
- }),
914
- activeTab === "entries" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
915
- className: VaultSection_module_css_default.tabPane,
916
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
917
- className: VaultSection_module_css_default.toolbar,
918
- children: [
919
- locked && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
920
- className: VaultSection_module_css_default.lockedTag,
921
- children: t("lockedShort")
922
- }),
923
- vaults.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
924
- className: VaultSection_module_css_default.kindFilter,
925
- value: vaults.find((v) => v.active)?.name ?? "",
926
- onChange: (event) => void switchVaultTo(event.target.value),
927
- "aria-label": t("vaultSelect"),
928
- disabled: locked,
929
- children: vaults.map((v) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("option", {
930
- value: v.name,
931
- children: [
932
- v.name,
933
- v.active ? " *" : "",
934
- v.entries !== void 0 ? ` (${v.entries})` : ""
935
- ]
936
- }, v.name))
937
- }),
938
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
939
- className: VaultSection_module_css_default.searchBox,
940
- children: [
941
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
942
- className: VaultSection_module_css_default.srOnly,
943
- children: t("searchPlaceholder")
944
- }),
945
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
946
- id: searchId,
947
- type: "search",
948
- placeholder: t("searchPlaceholder"),
949
- value: query,
950
- onChange: (event) => setQuery(event.target.value),
951
- disabled: locked
952
- }),
953
- query.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
954
- type: "button",
955
- className: VaultSection_module_css_default.clearButton,
956
- onClick: () => setQuery(""),
957
- "aria-label": t("clearSearch"),
958
- children: "×"
959
- })
960
- ]
961
- }),
962
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
963
- className: VaultSection_module_css_default.kindFilter,
964
- value: kindFilter,
965
- onChange: (e) => setKindFilter(e.target.value),
966
- "aria-label": t("fieldKind"),
967
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
968
- value: "",
969
- children: t("allKinds")
970
- }), Object.entries(KIND_KEYS).map(([value, key]) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
971
- value,
972
- children: t(key)
973
- }, value))]
974
- }),
975
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
976
- className: VaultSection_module_css_default.kindFilter,
977
- value: tagFilter,
978
- onChange: (e) => setTagFilter(e.target.value),
979
- "aria-label": t("fieldTags"),
980
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
981
- value: "",
982
- children: t("allTags")
983
- }), [...new Set(state.status === "ready" ? state.entries.flatMap((e) => e.tags ?? []) : [])].sort().map((tag) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
984
- value: tag,
985
- children: tag
986
- }, tag))]
987
- }),
988
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
989
- className: VaultSection_module_css_default.sortButton,
990
- value: sortBy,
991
- onChange: (event) => setSortBy(event.target.value),
992
- "aria-label": t("sortBy"),
891
+ locked && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
892
+ className: VaultSection_module_css_default.lockedTag,
893
+ children: t("lockedShort")
894
+ }),
895
+ vaults.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
896
+ className: VaultSection_module_css_default.kindFilter,
897
+ value: vaults.find((v) => v.active)?.name ?? "",
898
+ onChange: (event) => void switchVaultTo(event.target.value),
899
+ "aria-label": t("vaultSelect"),
900
+ disabled: locked,
901
+ children: vaults.map((v) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("option", {
902
+ value: v.name,
993
903
  children: [
994
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
995
- value: "alpha",
996
- children: t("sortAlpha")
997
- }),
998
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
999
- value: "recent",
1000
- children: t("sortRecent")
1001
- }),
1002
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1003
- value: "favorite",
1004
- children: t("sortFavorite")
1005
- }),
1006
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1007
- value: "smart",
1008
- children: t("sortSmart")
1009
- })
904
+ v.name,
905
+ v.active ? " *" : "",
906
+ v.entries !== void 0 ? ` (${v.entries})` : ""
1010
907
  ]
1011
- }),
1012
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
1013
- type: "button",
1014
- className: VaultSection_module_css_default.addButton,
1015
- onClick: startCreate,
1016
- disabled: busy || readonly || locked,
1017
- children: ["+ ", t("add")]
1018
- })
1019
- ]
1020
- })
908
+ }, v.name))
909
+ }),
910
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
911
+ className: VaultSection_module_css_default.searchBox,
912
+ children: [
913
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
914
+ className: VaultSection_module_css_default.srOnly,
915
+ children: t("searchPlaceholder")
916
+ }),
917
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
918
+ id: searchId,
919
+ type: "search",
920
+ placeholder: t("searchPlaceholder"),
921
+ value: query,
922
+ onChange: (event) => setQuery(event.target.value),
923
+ disabled: locked
924
+ }),
925
+ query.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
926
+ type: "button",
927
+ className: VaultSection_module_css_default.clearButton,
928
+ onClick: () => setQuery(""),
929
+ "aria-label": t("clearSearch"),
930
+ children: "×"
931
+ })
932
+ ]
933
+ }),
934
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
935
+ className: VaultSection_module_css_default.kindFilter,
936
+ value: kindFilter,
937
+ onChange: (e) => setKindFilter(e.target.value),
938
+ "aria-label": t("fieldKind"),
939
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
940
+ value: "",
941
+ children: t("allKinds")
942
+ }), Object.entries(KIND_KEYS).map(([value, key]) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
943
+ value,
944
+ children: t(key)
945
+ }, value))]
946
+ }),
947
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
948
+ className: VaultSection_module_css_default.kindFilter,
949
+ value: tagFilter,
950
+ onChange: (e) => setTagFilter(e.target.value),
951
+ "aria-label": t("fieldTags"),
952
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
953
+ value: "",
954
+ children: t("allTags")
955
+ }), [...new Set(state.status === "ready" ? state.entries.flatMap((e) => e.tags ?? []) : [])].sort().map((tag) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
956
+ value: tag,
957
+ children: tag
958
+ }, tag))]
959
+ }),
960
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
961
+ className: VaultSection_module_css_default.sortButton,
962
+ value: sortBy,
963
+ onChange: (event) => setSortBy(event.target.value),
964
+ "aria-label": t("sortBy"),
965
+ children: [
966
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
967
+ value: "alpha",
968
+ children: t("sortAlpha")
969
+ }),
970
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
971
+ value: "recent",
972
+ children: t("sortRecent")
973
+ }),
974
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
975
+ value: "favorite",
976
+ children: t("sortFavorite")
977
+ }),
978
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
979
+ value: "smart",
980
+ children: t("sortSmart")
981
+ })
982
+ ]
983
+ }),
984
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
985
+ type: "button",
986
+ className: VaultSection_module_css_default.addButton,
987
+ onClick: startCreate,
988
+ disabled: busy || readonly || locked,
989
+ children: ["+ ", t("add")]
990
+ })
991
+ ]
1021
992
  }),
1022
993
  policy !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1023
994
  className: VaultSection_module_css_default.policyBar,
@@ -1104,823 +1075,798 @@ window.__ModuleLoader__.load({
1104
1075
  })
1105
1076
  ]
1106
1077
  }),
1107
- activeTab === "entries" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1108
- className: VaultSection_module_css_default.tabPane,
1109
- children: state.status === "ready" && state.entries.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1110
- className: VaultSection_module_css_default.emptyBox,
1078
+ state.status === "ready" && state.entries.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1079
+ className: VaultSection_module_css_default.emptyBox,
1080
+ children: [
1081
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1082
+ className: VaultSection_module_css_default.empty,
1083
+ children: t("empty")
1084
+ }),
1085
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1086
+ className: VaultSection_module_css_default.emptyHint,
1087
+ children: readonly ? t("emptyHintReadonly") : t("emptyHint")
1088
+ }),
1089
+ !readonly && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1090
+ type: "button",
1091
+ className: VaultSection_module_css_default.addButton,
1092
+ onClick: startCreate,
1093
+ children: t("quickAdd")
1094
+ })
1095
+ ]
1096
+ }),
1097
+ recentEntries.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1098
+ className: VaultSection_module_css_default.reportBox,
1099
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1100
+ className: VaultSection_module_css_default.reportTitle,
1101
+ children: t("recentlyAdded")
1102
+ }), recentEntries.map((e, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1103
+ className: VaultSection_module_css_default.reportLine,
1104
+ children: [String(e.title ?? ""), relTime(e.updatedAt) !== "" && ` · ${relTime(e.updatedAt)}`]
1105
+ }, i))]
1106
+ }),
1107
+ recentEvents.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1108
+ className: VaultSection_module_css_default.reportBox,
1109
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1110
+ className: VaultSection_module_css_default.reportTitle,
1111
+ children: t("recentActivity")
1112
+ }), recentEvents.map((ev, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1113
+ className: VaultSection_module_css_default.reportLine,
1114
+ children: [
1115
+ String(ev.action ?? ""),
1116
+ " · ",
1117
+ String(ev.title ?? ev.id ?? ""),
1118
+ relTime(ev.at) !== "" && ` · ${relTime(ev.at)}`
1119
+ ]
1120
+ }, i))]
1121
+ }),
1122
+ report !== null && (report.rotation.length > 0 || report.weak.length > 0 || report.reused.length > 0) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1123
+ className: VaultSection_module_css_default.reportBox,
1124
+ children: [
1125
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1126
+ className: VaultSection_module_css_default.reportTitle,
1127
+ children: t("reportTitle")
1128
+ }),
1129
+ report.rotation.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1130
+ className: VaultSection_module_css_default.reportLine,
1131
+ children: [
1132
+ t("reportRotation"),
1133
+ ": ",
1134
+ report.rotation.length
1135
+ ]
1136
+ }), report.rotation.slice(0, 8).map((item, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1137
+ className: VaultSection_module_css_default.reportSub,
1138
+ children: [
1139
+ "· ",
1140
+ String(item.title ?? "?"),
1141
+ item.due === "expired" ? ` (${t("dueExpired")})` : item.due === "soon" ? ` (${t("dueExpiring")} ${item.daysLeft ?? 0}d)` : ` (${t("dueNow")})`
1142
+ ]
1143
+ }, i))] }),
1144
+ report.weak.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1145
+ className: VaultSection_module_css_default.reportLine,
1146
+ children: [
1147
+ t("reportWeak"),
1148
+ ": ",
1149
+ report.weak.length
1150
+ ]
1151
+ }), report.weak.slice(0, 5).map((item, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1152
+ className: VaultSection_module_css_default.reportSub,
1153
+ children: ["· ", String(item.title ?? "?")]
1154
+ }, i))] }),
1155
+ report.reused.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1156
+ className: VaultSection_module_css_default.reportLine,
1157
+ children: [
1158
+ t("reportReused"),
1159
+ ": ",
1160
+ report.reused.length
1161
+ ]
1162
+ }), report.reused.slice(0, 3).map((group, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1163
+ className: VaultSection_module_css_default.reportSub,
1164
+ children: ["· ", (group.entries ?? []).slice(0, 3).map((e) => String(e.title ?? "?")).join(" / ")]
1165
+ }, i))] }),
1166
+ report.no2fa.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1167
+ className: VaultSection_module_css_default.reportLine,
1168
+ children: [
1169
+ t("no2fa"),
1170
+ ": ",
1171
+ report.no2fa.length
1172
+ ]
1173
+ }), report.no2fa.slice(0, 5).map((item, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1174
+ className: VaultSection_module_css_default.reportSub,
1175
+ children: ["· ", String(item.title ?? "?")]
1176
+ }, i))] }),
1177
+ report.httpSites.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1178
+ className: VaultSection_module_css_default.reportLine,
1179
+ children: [
1180
+ t("httpSites"),
1181
+ ": ",
1182
+ report.httpSites.length
1183
+ ]
1184
+ }), report.httpSites.slice(0, 5).map((item, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1185
+ className: VaultSection_module_css_default.reportSub,
1186
+ children: ["· ", String(item.title ?? "?")]
1187
+ }, i))] })
1188
+ ]
1189
+ }),
1190
+ audit.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1191
+ className: VaultSection_module_css_default.reportBox,
1192
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1193
+ className: VaultSection_module_css_default.reportTitle,
1111
1194
  children: [
1112
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1113
- className: VaultSection_module_css_default.empty,
1114
- children: t("empty")
1195
+ t("auditTitle"),
1196
+ " (",
1197
+ audit.length,
1198
+ ")"
1199
+ ]
1200
+ }), audit.slice(0, 6).map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1201
+ className: VaultSection_module_css_default.auditRow,
1202
+ children: [
1203
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1204
+ className: VaultSection_module_css_default.dupNames,
1205
+ children: item.title
1115
1206
  }),
1116
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1117
- className: VaultSection_module_css_default.emptyHint,
1118
- children: readonly ? t("emptyHintReadonly") : t("emptyHint")
1207
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1208
+ className: VaultSection_module_css_default.auditIssues,
1209
+ children: item.issues.join("; ")
1119
1210
  }),
1120
- !readonly && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1211
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1121
1212
  type: "button",
1122
- className: VaultSection_module_css_default.addButton,
1123
- onClick: startCreate,
1124
- children: t("quickAdd")
1213
+ className: VaultSection_module_css_default.dupMerge,
1214
+ onClick: () => void startEdit(item.id),
1215
+ disabled: busy,
1216
+ children: t("auditEdit")
1125
1217
  })
1126
1218
  ]
1127
- })
1219
+ }, item.id))]
1128
1220
  }),
1129
- activeTab === "security" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1130
- className: VaultSection_module_css_default.tabPane,
1221
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1222
+ className: VaultSection_module_css_default.reportBox,
1131
1223
  children: [
1132
- recentEntries.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1133
- className: VaultSection_module_css_default.reportBox,
1134
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1135
- className: VaultSection_module_css_default.reportTitle,
1136
- children: t("recentlyAdded")
1137
- }), recentEntries.map((e, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1138
- className: VaultSection_module_css_default.reportLine,
1139
- children: [String(e.title ?? ""), relTime(e.updatedAt) !== "" && ` · ${relTime(e.updatedAt)}`]
1140
- }, i))]
1224
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1225
+ className: VaultSection_module_css_default.reportTitle,
1226
+ children: t("systemSearch")
1141
1227
  }),
1142
- recentEvents.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1143
- className: VaultSection_module_css_default.reportBox,
1144
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1145
- className: VaultSection_module_css_default.reportTitle,
1146
- children: t("recentActivity")
1147
- }), recentEvents.map((ev, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1148
- className: VaultSection_module_css_default.reportLine,
1149
- children: [
1150
- String(ev.action ?? ""),
1151
- " · ",
1152
- String(ev.title ?? ev.id ?? ""),
1153
- relTime(ev.at) !== "" && ` · ${relTime(ev.at)}`
1154
- ]
1155
- }, i))]
1228
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1229
+ className: VaultSection_module_css_default.dupGroup,
1230
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1231
+ className: VaultSection_module_css_default.searchBox,
1232
+ type: "search",
1233
+ placeholder: t("sysSearchPlaceholder"),
1234
+ value: sysQuery,
1235
+ onChange: (event) => setSysQuery(event.target.value),
1236
+ onKeyDown: (event) => {
1237
+ if (event.key === "Enter") searchSystemStores();
1238
+ }
1239
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1240
+ type: "button",
1241
+ className: VaultSection_module_css_default.dupMerge,
1242
+ onClick: () => void searchSystemStores(),
1243
+ disabled: busy,
1244
+ children: t("sysSearchGo")
1245
+ })]
1156
1246
  }),
1157
- report !== null && (report.rotation.length > 0 || report.weak.length > 0 || report.reused.length > 0) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1158
- className: VaultSection_module_css_default.reportBox,
1247
+ sysMatches.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: sysMatches.map((m, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1248
+ className: VaultSection_module_css_default.reportSub,
1159
1249
  children: [
1160
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1161
- className: VaultSection_module_css_default.reportTitle,
1162
- children: t("reportTitle")
1163
- }),
1164
- report.rotation.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1165
- className: VaultSection_module_css_default.reportLine,
1166
- children: [
1167
- t("reportRotation"),
1168
- ": ",
1169
- report.rotation.length
1170
- ]
1171
- }), report.rotation.slice(0, 8).map((item, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1172
- className: VaultSection_module_css_default.reportSub,
1173
- children: [
1174
- "· ",
1175
- String(item.title ?? "?"),
1176
- item.due === "expired" ? ` (${t("dueExpired")})` : item.due === "soon" ? ` (${t("dueExpiring")} ${item.daysLeft ?? 0}d)` : ` (${t("dueNow")})`
1177
- ]
1178
- }, i))] }),
1179
- report.weak.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1180
- className: VaultSection_module_css_default.reportLine,
1181
- children: [
1182
- t("reportWeak"),
1183
- ": ",
1184
- report.weak.length
1185
- ]
1186
- }), report.weak.slice(0, 5).map((item, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1187
- className: VaultSection_module_css_default.reportSub,
1188
- children: ["· ", String(item.title ?? "?")]
1189
- }, i))] }),
1190
- report.reused.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1191
- className: VaultSection_module_css_default.reportLine,
1192
- children: [
1193
- t("reportReused"),
1194
- ": ",
1195
- report.reused.length
1196
- ]
1197
- }), report.reused.slice(0, 3).map((group, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1198
- className: VaultSection_module_css_default.reportSub,
1199
- children: ["· ", (group.entries ?? []).slice(0, 3).map((e) => String(e.title ?? "?")).join(" / ")]
1200
- }, i))] }),
1201
- report.no2fa.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1202
- className: VaultSection_module_css_default.reportLine,
1203
- children: [
1204
- t("no2fa"),
1205
- ": ",
1206
- report.no2fa.length
1207
- ]
1208
- }), report.no2fa.slice(0, 5).map((item, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1209
- className: VaultSection_module_css_default.reportSub,
1210
- children: ["· ", String(item.title ?? "?")]
1211
- }, i))] }),
1212
- report.httpSites.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1213
- className: VaultSection_module_css_default.reportLine,
1214
- children: [
1215
- t("httpSites"),
1216
- ": ",
1217
- report.httpSites.length
1218
- ]
1219
- }), report.httpSites.slice(0, 5).map((item, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1220
- className: VaultSection_module_css_default.reportSub,
1221
- children: ["· ", String(item.title ?? "?")]
1222
- }, i))] })
1250
+ "[",
1251
+ m.source,
1252
+ "] ",
1253
+ m.name,
1254
+ " · ",
1255
+ m.username
1223
1256
  ]
1224
- }),
1225
- audit.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1226
- className: VaultSection_module_css_default.reportBox,
1227
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1228
- className: VaultSection_module_css_default.reportTitle,
1229
- children: [
1230
- t("auditTitle"),
1231
- " (",
1232
- audit.length,
1233
- ")"
1234
- ]
1235
- }), audit.slice(0, 6).map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1236
- className: VaultSection_module_css_default.auditRow,
1237
- children: [
1238
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1239
- className: VaultSection_module_css_default.dupNames,
1240
- children: item.title
1241
- }),
1242
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1243
- className: VaultSection_module_css_default.auditIssues,
1244
- children: item.issues.join("; ")
1245
- }),
1246
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1247
- type: "button",
1248
- className: VaultSection_module_css_default.dupMerge,
1249
- onClick: () => void startEdit(item.id),
1250
- disabled: busy,
1251
- children: t("auditEdit")
1252
- })
1253
- ]
1254
- }, item.id))]
1255
- })
1257
+ }, i)) })
1256
1258
  ]
1257
1259
  }),
1258
- activeTab === "transfer" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1259
- className: VaultSection_module_css_default.tabPane,
1260
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1261
- className: VaultSection_module_css_default.reportBox,
1262
- children: [
1263
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1264
- className: VaultSection_module_css_default.reportTitle,
1265
- children: t("systemSearch")
1266
- }),
1267
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1268
- className: VaultSection_module_css_default.dupGroup,
1269
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1270
- className: VaultSection_module_css_default.searchBox,
1271
- type: "search",
1272
- placeholder: t("sysSearchPlaceholder"),
1273
- value: sysQuery,
1274
- onChange: (event) => setSysQuery(event.target.value),
1275
- onKeyDown: (event) => {
1276
- if (event.key === "Enter") searchSystemStores();
1277
- }
1278
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1279
- type: "button",
1280
- className: VaultSection_module_css_default.dupMerge,
1281
- onClick: () => void searchSystemStores(),
1282
- disabled: busy,
1283
- children: t("sysSearchGo")
1284
- })]
1285
- }),
1286
- sysMatches.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: sysMatches.map((m, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1287
- className: VaultSection_module_css_default.reportSub,
1288
- children: [
1289
- "[",
1290
- m.source,
1291
- "] ",
1292
- m.name,
1293
- " · ",
1294
- m.username
1295
- ]
1296
- }, i)) })
1297
- ]
1298
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1299
- className: VaultSection_module_css_default.reportBox,
1300
- children: [
1301
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1302
- className: VaultSection_module_css_default.reportTitle,
1303
- children: t("systemImport")
1304
- }),
1305
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1306
- className: VaultSection_module_css_default.dupGroup,
1307
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1308
- className: VaultSection_module_css_default.dupNames,
1309
- children: t("importChromeDesc")
1310
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1311
- type: "button",
1312
- className: VaultSection_module_css_default.dupMerge,
1313
- onClick: () => void runSystemImport("chrome", false),
1314
- disabled: busy || readonly || locked,
1315
- children: t("importChrome")
1316
- })]
1317
- }),
1318
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1319
- className: VaultSection_module_css_default.dupGroup,
1320
- children: [
1321
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1322
- className: VaultSection_module_css_default.dupNames,
1323
- children: t("importKeychainDesc")
1324
- }),
1325
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1326
- type: "button",
1327
- className: VaultSection_module_css_default.dupMerge,
1328
- onClick: () => void runSystemImport("keychain", true),
1329
- disabled: busy || readonly || locked,
1330
- children: t("keychainPreview")
1331
- }),
1332
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1333
- type: "button",
1334
- className: VaultSection_module_css_default.dupMerge,
1335
- onClick: () => void runSystemImport("keychain", false),
1336
- disabled: busy || readonly || locked,
1337
- children: t("importKeychain")
1338
- })
1339
- ]
1340
- })
1341
- ]
1342
- })]
1343
- }),
1344
- activeTab === "organize" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1345
- className: VaultSection_module_css_default.tabPane,
1260
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1261
+ className: VaultSection_module_css_default.reportBox,
1346
1262
  children: [
1347
- backupList.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1348
- className: VaultSection_module_css_default.reportBox,
1349
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1350
- className: VaultSection_module_css_default.reportTitle,
1351
- children: t("recentBackups")
1352
- }), backupList.map((b) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1353
- className: VaultSection_module_css_default.reportSub,
1354
- children: ["· ", new Date(b.at).toLocaleString()]
1355
- }, b.path))]
1263
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1264
+ className: VaultSection_module_css_default.reportTitle,
1265
+ children: t("systemImport")
1356
1266
  }),
1357
- tagList.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1358
- className: VaultSection_module_css_default.reportBox,
1359
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1360
- className: VaultSection_module_css_default.reportTitle,
1361
- children: [
1362
- t("tagManage"),
1363
- " (",
1364
- tagList.length,
1365
- ")"
1366
- ]
1367
- }), tagList.slice(0, 8).map((tag) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1368
- className: VaultSection_module_css_default.dupGroup,
1369
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1267
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1268
+ className: VaultSection_module_css_default.dupGroup,
1269
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1270
+ className: VaultSection_module_css_default.dupNames,
1271
+ children: t("importChromeDesc")
1272
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1273
+ type: "button",
1274
+ className: VaultSection_module_css_default.dupMerge,
1275
+ onClick: () => void runSystemImport("chrome", false),
1276
+ disabled: busy || readonly || locked,
1277
+ children: t("importChrome")
1278
+ })]
1279
+ }),
1280
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1281
+ className: VaultSection_module_css_default.dupGroup,
1282
+ children: [
1283
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1370
1284
  className: VaultSection_module_css_default.dupNames,
1371
- children: [
1372
- tag.name,
1373
- " (",
1374
- tag.count,
1375
- ")"
1376
- ]
1377
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1285
+ children: t("importKeychainDesc")
1286
+ }),
1287
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1378
1288
  type: "button",
1379
1289
  className: VaultSection_module_css_default.dupMerge,
1380
- onClick: () => void renameTagAll(tag.name),
1381
- disabled: busy || readonly,
1382
- children: t("tagRename")
1383
- })]
1384
- }, tag.name))]
1385
- }),
1386
- dupList.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1387
- className: VaultSection_module_css_default.reportBox,
1388
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1389
- className: VaultSection_module_css_default.reportTitle,
1390
- children: [
1391
- t("dupTitle"),
1392
- " (",
1393
- dupList.length,
1394
- ")"
1395
- ]
1396
- }), dupList.slice(0, 5).map((group, gi) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1397
- className: VaultSection_module_css_default.dupGroup,
1398
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1399
- className: VaultSection_module_css_default.dupNames,
1400
- children: group.map((g) => g.title).join(" / ")
1401
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1290
+ onClick: () => void runSystemImport("keychain", true),
1291
+ disabled: busy || readonly || locked,
1292
+ children: t("keychainPreview")
1293
+ }),
1294
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1402
1295
  type: "button",
1403
1296
  className: VaultSection_module_css_default.dupMerge,
1404
- onClick: () => void mergeEntries(group),
1405
- disabled: busy || readonly,
1406
- children: t("dupMerge")
1407
- })]
1408
- }, gi))]
1297
+ onClick: () => void runSystemImport("keychain", false),
1298
+ disabled: busy || readonly || locked,
1299
+ children: t("importKeychain")
1300
+ })
1301
+ ]
1409
1302
  })
1410
1303
  ]
1411
1304
  }),
1412
- activeTab === "entries" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1413
- className: VaultSection_module_css_default.tabPane,
1414
- children: [
1415
- state.status === "ready" && filteredCount(state.entries, kindFilter, tagFilter) > visibleCount && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
1416
- type: "button",
1417
- className: VaultSection_module_css_default.trashButton,
1418
- onClick: () => setVisibleCount((count) => count + 50),
1305
+ backupList.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1306
+ className: VaultSection_module_css_default.reportBox,
1307
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1308
+ className: VaultSection_module_css_default.reportTitle,
1309
+ children: t("recentBackups")
1310
+ }), backupList.map((b) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1311
+ className: VaultSection_module_css_default.reportSub,
1312
+ children: ["· ", new Date(b.at).toLocaleString()]
1313
+ }, b.path))]
1314
+ }),
1315
+ tagList.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1316
+ className: VaultSection_module_css_default.reportBox,
1317
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1318
+ className: VaultSection_module_css_default.reportTitle,
1319
+ children: [
1320
+ t("tagManage"),
1321
+ " (",
1322
+ tagList.length,
1323
+ ")"
1324
+ ]
1325
+ }), tagList.slice(0, 8).map((tag) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1326
+ className: VaultSection_module_css_default.dupGroup,
1327
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1328
+ className: VaultSection_module_css_default.dupNames,
1419
1329
  children: [
1420
- t("loadMore"),
1330
+ tag.name,
1421
1331
  " (",
1422
- filteredCount(state.entries, kindFilter, tagFilter) - visibleCount,
1332
+ tag.count,
1423
1333
  ")"
1424
1334
  ]
1425
- }),
1426
- state.status === "ready" && (state.entries.length > 0 || trashEntries.length > 0) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
1427
- type: "button",
1428
- className: VaultSection_module_css_default.trashButton,
1429
- onClick: () => {
1430
- if (!showTrash) trash().then(setTrashEntries);
1431
- setShowTrash(!showTrash);
1432
- },
1433
- children: [showTrash ? t("hideTrash") : t("showTrash"), trashEntries.length > 0 ? ` (${trashEntries.length})` : ""]
1434
- }),
1435
- showTrash && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("ul", {
1436
- className: VaultSection_module_css_default.list,
1437
- children: [trashEntries.map((entry) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
1438
- className: VaultSection_module_css_default.row,
1439
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1440
- className: VaultSection_module_css_default.rowMain,
1441
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1442
- className: VaultSection_module_css_default.title,
1443
- children: entry.title
1444
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1445
- className: VaultSection_module_css_default.identity,
1446
- children: t("trashed")
1447
- })]
1448
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1449
- className: VaultSection_module_css_default.rowActions,
1450
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1451
- type: "button",
1452
- onClick: () => {
1453
- restore(entry.id).then(() => {
1454
- trash().then(setTrashEntries);
1455
- refresh();
1456
- });
1457
- },
1458
- disabled: busy || readonly,
1459
- children: t("restore")
1460
- })
1461
- })]
1462
- }, entry.id)), trashEntries.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1463
- className: VaultSection_module_css_default.empty,
1464
- children: t("trashEmpty")
1465
- })]
1466
- }),
1467
- showTrash && trashEntries.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1335
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1468
1336
  type: "button",
1469
- className: VaultSection_module_css_default.trashButton,
1470
- onClick: () => {
1471
- setBusy(true);
1472
- undeleteAll().then(() => {
1473
- trash().then(setTrashEntries);
1474
- refresh();
1475
- setBusy(false);
1476
- }, () => setBusy(false));
1477
- },
1337
+ className: VaultSection_module_css_default.dupMerge,
1338
+ onClick: () => void renameTagAll(tag.name),
1478
1339
  disabled: busy || readonly,
1479
- children: t("restoreAll")
1340
+ children: t("tagRename")
1341
+ })]
1342
+ }, tag.name))]
1343
+ }),
1344
+ dupList.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1345
+ className: VaultSection_module_css_default.reportBox,
1346
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1347
+ className: VaultSection_module_css_default.reportTitle,
1348
+ children: [
1349
+ t("dupTitle"),
1350
+ " (",
1351
+ dupList.length,
1352
+ ")"
1353
+ ]
1354
+ }), dupList.slice(0, 5).map((group, gi) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1355
+ className: VaultSection_module_css_default.dupGroup,
1356
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1357
+ className: VaultSection_module_css_default.dupNames,
1358
+ children: group.map((g) => g.title).join(" / ")
1480
1359
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1481
1360
  type: "button",
1482
- className: VaultSection_module_css_default.dangerButton,
1483
- onClick: () => {
1484
- if (!window.confirm(t("clearTrashConfirm"))) return;
1485
- setBusy(true);
1486
- Promise.all(trashEntries.map((e) => remove(e.id))).then(() => {
1487
- trash().then(setTrashEntries);
1488
- refresh();
1489
- setBusy(false);
1490
- }, () => setBusy(false));
1491
- },
1361
+ className: VaultSection_module_css_default.dupMerge,
1362
+ onClick: () => void mergeEntries(group),
1492
1363
  disabled: busy || readonly,
1493
- children: t("clearTrash")
1494
- })] }),
1495
- state.status === "ready" && state.entries.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1496
- className: VaultSection_module_css_default.resultCount,
1364
+ children: t("dupMerge")
1365
+ })]
1366
+ }, gi))]
1367
+ }),
1368
+ state.status === "ready" && filteredCount(state.entries, kindFilter, tagFilter) > visibleCount && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
1369
+ type: "button",
1370
+ className: VaultSection_module_css_default.trashButton,
1371
+ onClick: () => setVisibleCount((count) => count + 50),
1372
+ children: [
1373
+ t("loadMore"),
1374
+ " (",
1375
+ filteredCount(state.entries, kindFilter, tagFilter) - visibleCount,
1376
+ ")"
1377
+ ]
1378
+ }),
1379
+ state.status === "ready" && (state.entries.length > 0 || trashEntries.length > 0) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
1380
+ type: "button",
1381
+ className: VaultSection_module_css_default.trashButton,
1382
+ onClick: () => {
1383
+ if (!showTrash) trash().then(setTrashEntries);
1384
+ setShowTrash(!showTrash);
1385
+ },
1386
+ children: [showTrash ? t("hideTrash") : t("showTrash"), trashEntries.length > 0 ? ` (${trashEntries.length})` : ""]
1387
+ }),
1388
+ showTrash && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("ul", {
1389
+ className: VaultSection_module_css_default.list,
1390
+ children: [trashEntries.map((entry) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
1391
+ className: VaultSection_module_css_default.row,
1392
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1393
+ className: VaultSection_module_css_default.rowMain,
1394
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1395
+ className: VaultSection_module_css_default.title,
1396
+ children: entry.title
1397
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1398
+ className: VaultSection_module_css_default.identity,
1399
+ children: t("trashed")
1400
+ })]
1401
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1402
+ className: VaultSection_module_css_default.rowActions,
1403
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1404
+ type: "button",
1405
+ onClick: () => {
1406
+ restore(entry.id).then(() => {
1407
+ trash().then(setTrashEntries);
1408
+ refresh();
1409
+ });
1410
+ },
1411
+ disabled: busy || readonly,
1412
+ children: t("restore")
1413
+ })
1414
+ })]
1415
+ }, entry.id)), trashEntries.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1416
+ className: VaultSection_module_css_default.empty,
1417
+ children: t("trashEmpty")
1418
+ })]
1419
+ }),
1420
+ showTrash && trashEntries.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1421
+ type: "button",
1422
+ className: VaultSection_module_css_default.trashButton,
1423
+ onClick: () => {
1424
+ setBusy(true);
1425
+ undeleteAll().then(() => {
1426
+ trash().then(setTrashEntries);
1427
+ refresh();
1428
+ setBusy(false);
1429
+ }, () => setBusy(false));
1430
+ },
1431
+ disabled: busy || readonly,
1432
+ children: t("restoreAll")
1433
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1434
+ type: "button",
1435
+ className: VaultSection_module_css_default.dangerButton,
1436
+ onClick: () => {
1437
+ if (!window.confirm(t("clearTrashConfirm"))) return;
1438
+ setBusy(true);
1439
+ Promise.all(trashEntries.map((e) => remove(e.id))).then(() => {
1440
+ trash().then(setTrashEntries);
1441
+ refresh();
1442
+ setBusy(false);
1443
+ }, () => setBusy(false));
1444
+ },
1445
+ disabled: busy || readonly,
1446
+ children: t("clearTrash")
1447
+ })] }),
1448
+ state.status === "ready" && state.entries.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1449
+ className: VaultSection_module_css_default.resultCount,
1450
+ children: [
1451
+ t("resultCount"),
1452
+ ": ",
1453
+ filteredCount(state.entries, kindFilter, tagFilter),
1454
+ (() => {
1455
+ const byKind = /* @__PURE__ */ new Map();
1456
+ for (const e of state.entries) if ((kindFilter === "" || e.kind === kindFilter) && (tagFilter === "" || (e.tags ?? []).includes(tagFilter))) {
1457
+ const k = e.kind ?? "login";
1458
+ byKind.set(k, (byKind.get(k) ?? 0) + 1);
1459
+ }
1460
+ return [...byKind.entries()].map(([k, n]) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1461
+ className: VaultSection_module_css_default.kindChip,
1462
+ children: [
1463
+ t(KIND_KEYS[k] ?? "kindCustom"),
1464
+ " ",
1465
+ n
1466
+ ]
1467
+ }, k));
1468
+ })()
1469
+ ]
1470
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
1471
+ className: VaultSection_module_css_default.list,
1472
+ children: state.entries.filter((entry) => (kindFilter === "" || entry.kind === kindFilter) && (tagFilter === "" || (entry.tags ?? []).includes(tagFilter))).sort((a, b) => sortBy === "alpha" ? a.title.localeCompare(b.title) : sortBy === "recent" ? (b.updatedAt ?? 0) - (a.updatedAt ?? 0) : (a.favorite === true ? 0 : 1) - (b.favorite === true ? 0 : 1) || (b.updatedAt ?? 0) - (a.updatedAt ?? 0) || a.title.localeCompare(b.title)).slice(0, visibleCount).map((entry) => {
1473
+ const totpInfo = totpMap[entry.id];
1474
+ const remaining = totpInfo !== void 0 && totpInfo.until > 0 ? Math.max(0, Math.ceil((totpInfo.until - nowTick) / 1e3)) : void 0;
1475
+ const frac = remaining !== void 0 ? remaining / 30 : 0;
1476
+ const code = totpInfo?.code;
1477
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
1478
+ className: `${VaultSection_module_css_default.row}${dueMap[entry.id] !== void 0 ? ` ${dueMap[entry.id].due === "expired" ? VaultSection_module_css_default.rowExpired : VaultSection_module_css_default.rowDue}` : ""}`,
1497
1479
  children: [
1498
- t("resultCount"),
1499
- ": ",
1500
- filteredCount(state.entries, kindFilter, tagFilter),
1501
- (() => {
1502
- const byKind = /* @__PURE__ */ new Map();
1503
- for (const e of state.entries) if ((kindFilter === "" || e.kind === kindFilter) && (tagFilter === "" || (e.tags ?? []).includes(tagFilter))) {
1504
- const k = e.kind ?? "login";
1505
- byKind.set(k, (byKind.get(k) ?? 0) + 1);
1506
- }
1507
- return [...byKind.entries()].map(([k, n]) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1508
- className: VaultSection_module_css_default.kindChip,
1509
- children: [
1510
- t(KIND_KEYS[k] ?? "kindCustom"),
1511
- " ",
1512
- n
1513
- ]
1514
- }, k));
1515
- })()
1516
- ]
1517
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
1518
- className: VaultSection_module_css_default.list,
1519
- children: state.entries.filter((entry) => (kindFilter === "" || entry.kind === kindFilter) && (tagFilter === "" || (entry.tags ?? []).includes(tagFilter))).sort((a, b) => sortBy === "alpha" ? a.title.localeCompare(b.title) : sortBy === "recent" ? (b.updatedAt ?? 0) - (a.updatedAt ?? 0) : (a.favorite === true ? 0 : 1) - (b.favorite === true ? 0 : 1) || (b.updatedAt ?? 0) - (a.updatedAt ?? 0) || a.title.localeCompare(b.title)).slice(0, visibleCount).map((entry) => {
1520
- const totpInfo = totpMap[entry.id];
1521
- const remaining = totpInfo !== void 0 && totpInfo.until > 0 ? Math.max(0, Math.ceil((totpInfo.until - nowTick) / 1e3)) : void 0;
1522
- const frac = remaining !== void 0 ? remaining / 30 : 0;
1523
- const code = totpInfo?.code;
1524
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
1525
- className: `${VaultSection_module_css_default.row}${dueMap[entry.id] !== void 0 ? ` ${dueMap[entry.id].due === "expired" ? VaultSection_module_css_default.rowExpired : VaultSection_module_css_default.rowDue}` : ""}`,
1480
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1481
+ className: VaultSection_module_css_default.rowMain,
1482
+ onClick: () => setExpandedId(expandedId === entry.id ? null : entry.id),
1526
1483
  children: [
1527
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1528
- className: VaultSection_module_css_default.rowMain,
1529
- onClick: () => setExpandedId(expandedId === entry.id ? null : entry.id),
1484
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1485
+ className: VaultSection_module_css_default.title,
1486
+ style: entry.color !== void 0 && entry.color !== "" ? {
1487
+ borderLeft: `3px solid ${entry.color}`,
1488
+ paddingLeft: 6
1489
+ } : void 0,
1530
1490
  children: [
1531
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1532
- className: VaultSection_module_css_default.title,
1533
- style: entry.color !== void 0 && entry.color !== "" ? {
1534
- borderLeft: `3px solid ${entry.color}`,
1535
- paddingLeft: 6
1536
- } : void 0,
1537
- children: [
1538
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1539
- className: VaultSection_module_css_default.kindIcon,
1540
- children: entry.icon ?? kindIcon(entry.kind)
1541
- }),
1542
- entry.favorite && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1543
- className: VaultSection_module_css_default.pinStar,
1544
- title: t("pinned"),
1545
- children: "★"
1546
- }),
1547
- entry.title,
1548
- entry.sensitivity === "high" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1549
- className: VaultSection_module_css_default.highBadge,
1550
- children: t("highSensitivity")
1551
- }),
1552
- dueMap[entry.id] !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1553
- className: `${VaultSection_module_css_default.dueBadge} ${dueMap[entry.id].due === "expired" ? VaultSection_module_css_default.badgeDanger : VaultSection_module_css_default.badgeWarn}`,
1554
- children: dueMap[entry.id].due === "expired" ? t("dueExpired") : dueMap[entry.id].due === "soon" ? `${t("dueExpiring")} ${dueMap[entry.id].daysLeft}d` : t("dueNow")
1555
- }),
1556
- passwordAge(entry) !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1557
- className: VaultSection_module_css_default.dueBadge,
1558
- title: t("ageHint"),
1559
- children: passwordAge(entry)
1560
- })
1561
- ]
1562
- }),
1563
1491
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1564
- className: VaultSection_module_css_default.identity,
1565
- children: identityLine(entry)
1492
+ className: VaultSection_module_css_default.kindIcon,
1493
+ children: entry.icon ?? kindIcon(entry.kind)
1494
+ }),
1495
+ entry.favorite && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1496
+ className: VaultSection_module_css_default.pinStar,
1497
+ title: t("pinned"),
1498
+ children: "★"
1566
1499
  }),
1567
- uriMap[entry.id] !== void 0 && uriMap[entry.id] !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1568
- className: VaultSection_module_css_default.totp,
1569
- title: t("totpUriHint"),
1570
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
1571
- className: VaultSection_module_css_default.uriCode,
1572
- children: uriMap[entry.id]
1573
- })
1500
+ entry.title,
1501
+ entry.sensitivity === "high" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1502
+ className: VaultSection_module_css_default.highBadge,
1503
+ children: t("highSensitivity")
1574
1504
  }),
1575
- code !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1576
- className: VaultSection_module_css_default.totp,
1577
- children: [
1578
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
1579
- className: VaultSection_module_css_default.totpRing,
1580
- width: "16",
1581
- height: "16",
1582
- viewBox: "0 0 16 16",
1583
- "aria-hidden": "true",
1584
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
1585
- cx: "8",
1586
- cy: "8",
1587
- r: "6.5",
1588
- fill: "none",
1589
- stroke: "var(--dsh-color-border, #ddd)",
1590
- strokeWidth: "2"
1591
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
1592
- cx: "8",
1593
- cy: "8",
1594
- r: "6.5",
1595
- fill: "none",
1596
- stroke: remaining !== void 0 && remaining <= 5 ? "#cf3d3d" : "#2e9e5b",
1597
- strokeWidth: "2",
1598
- strokeLinecap: "round",
1599
- strokeDasharray: `${(frac * 2 * Math.PI * 6.5).toFixed(1)} ${(2 * Math.PI * 6.5).toFixed(1)}`,
1600
- transform: "rotate(-90 8 8)"
1601
- })]
1602
- }),
1603
- code,
1604
- remaining !== void 0 ? ` (${remaining}s)` : ""
1605
- ]
1505
+ dueMap[entry.id] !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1506
+ className: `${VaultSection_module_css_default.dueBadge} ${dueMap[entry.id].due === "expired" ? VaultSection_module_css_default.badgeDanger : VaultSection_module_css_default.badgeWarn}`,
1507
+ children: dueMap[entry.id].due === "expired" ? t("dueExpired") : dueMap[entry.id].due === "soon" ? `${t("dueExpiring")} ${dueMap[entry.id].daysLeft}d` : t("dueNow")
1508
+ }),
1509
+ passwordAge(entry) !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1510
+ className: VaultSection_module_css_default.dueBadge,
1511
+ title: t("ageHint"),
1512
+ children: passwordAge(entry)
1606
1513
  })
1607
1514
  ]
1608
1515
  }),
1609
- expandedId === entry.id && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1610
- className: VaultSection_module_css_default.detailBox,
1611
- children: Object.entries(entry).filter(([k]) => ![
1612
- "id",
1613
- "title",
1614
- "favorite"
1615
- ].includes(k) && entry[k] !== void 0).map(([k, v]) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1616
- className: VaultSection_module_css_default.detailItem,
1617
- children: [
1618
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: k }),
1619
- ": ",
1620
- formatDetail(k, v),
1621
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1622
- type: "button",
1623
- className: VaultSection_module_css_default.revealButton,
1624
- title: t("copyFieldHint"),
1625
- onClick: () => void copyValue(entry.id, Array.isArray(v) ? v.join(", ") : String(v)),
1626
- children: "⧉"
1627
- })
1628
- ]
1629
- }, k))
1516
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1517
+ className: VaultSection_module_css_default.identity,
1518
+ children: identityLine(entry)
1519
+ }),
1520
+ uriMap[entry.id] !== void 0 && uriMap[entry.id] !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1521
+ className: VaultSection_module_css_default.totp,
1522
+ title: t("totpUriHint"),
1523
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
1524
+ className: VaultSection_module_css_default.uriCode,
1525
+ children: uriMap[entry.id]
1526
+ })
1630
1527
  }),
1631
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1632
- className: VaultSection_module_css_default.rowActions,
1528
+ code !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1529
+ className: VaultSection_module_css_default.totp,
1633
1530
  children: [
1634
- copiedId === entry.id && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1635
- className: VaultSection_module_css_default.copied,
1636
- children: [
1637
- t("copied"),
1638
- " · ",
1639
- t("clearsIn30s")
1640
- ]
1641
- }),
1642
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1643
- type: "button",
1644
- onClick: () => void copyValue(entry.id, entry.username ?? entry.title),
1645
- disabled: busy,
1646
- children: t("copy")
1647
- }),
1648
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1649
- type: "button",
1650
- onClick: () => {
1651
- setBusy(true);
1652
- get(entry.id).then((r) => {
1653
- if (r.found && r.entry?.password) copyValue(entry.id, r.entry.password);
1654
- setBusy(false);
1655
- }, () => setBusy(false));
1656
- },
1657
- disabled: busy || readonly,
1658
- children: t("copyPassword")
1531
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
1532
+ className: VaultSection_module_css_default.totpRing,
1533
+ width: "16",
1534
+ height: "16",
1535
+ viewBox: "0 0 16 16",
1536
+ "aria-hidden": "true",
1537
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
1538
+ cx: "8",
1539
+ cy: "8",
1540
+ r: "6.5",
1541
+ fill: "none",
1542
+ stroke: "var(--dsh-color-border, #ddd)",
1543
+ strokeWidth: "2"
1544
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
1545
+ cx: "8",
1546
+ cy: "8",
1547
+ r: "6.5",
1548
+ fill: "none",
1549
+ stroke: remaining !== void 0 && remaining <= 5 ? "#cf3d3d" : "#2e9e5b",
1550
+ strokeWidth: "2",
1551
+ strokeLinecap: "round",
1552
+ strokeDasharray: `${(frac * 2 * Math.PI * 6.5).toFixed(1)} ${(2 * Math.PI * 6.5).toFixed(1)}`,
1553
+ transform: "rotate(-90 8 8)"
1554
+ })]
1659
1555
  }),
1660
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1661
- type: "button",
1662
- onClick: () => void showTotp(entry.id),
1663
- disabled: busy,
1664
- children: t("totp")
1665
- }),
1666
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1667
- type: "button",
1668
- onClick: () => void showTotpUri(entry.id),
1669
- disabled: busy,
1670
- title: t("totpUriHint"),
1671
- children: t("totpUri")
1672
- }),
1673
- code !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1674
- type: "button",
1675
- onClick: () => void copyValue(entry.id, code),
1676
- disabled: busy,
1677
- children: t("copyCode")
1678
- }),
1679
- entry.url !== void 0 && entry.url !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1680
- type: "button",
1681
- onClick: () => window.open(entry.url, "_blank", "noopener"),
1682
- title: t("openUrlHint"),
1683
- children: t("openUrl")
1684
- }),
1685
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1686
- type: "button",
1687
- onClick: () => void touch(entry.id).then(() => void refresh()),
1688
- disabled: busy || readonly,
1689
- title: t("touchHint"),
1690
- children: t("touch")
1691
- }),
1692
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1693
- type: "button",
1694
- onClick: () => void startEdit(entry.id),
1695
- disabled: busy || readonly,
1696
- children: t("edit")
1697
- }),
1698
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1699
- type: "button",
1700
- className: VaultSection_module_css_default.deleteButton,
1701
- onClick: () => void removeEntry(entry.id),
1702
- disabled: busy || readonly,
1703
- children: t("delete")
1704
- })
1556
+ code,
1557
+ remaining !== void 0 ? ` (${remaining}s)` : ""
1705
1558
  ]
1706
1559
  })
1707
1560
  ]
1708
- }, entry.id);
1709
- })
1710
- })] })
1711
- ]
1712
- }),
1713
- activeTab === "security" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1714
- className: VaultSection_module_css_default.tabPane,
1715
- children: [
1716
- state.status === "ready" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1717
- className: VaultSection_module_css_default.healthBar,
1718
- children: [
1719
- vaultStats !== null && typeof vaultStats.total === "number" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1720
- className: VaultSection_module_css_default.badge,
1721
- children: [
1722
- t("entryCount"),
1723
- ": ",
1724
- String(vaultStats.total)
1725
- ]
1726
- }),
1727
- vaultStats !== null && typeof vaultStats.withTotp === "number" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1728
- className: VaultSection_module_css_default.badge,
1729
- children: ["TOTP: ", String(vaultStats.withTotp)]
1730
- }),
1731
- vaultStats !== null && typeof vaultStats.highSensitivity === "number" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1732
- className: VaultSection_module_css_default.badge,
1733
- children: [
1734
- t("highSensitivity"),
1735
- ": ",
1736
- String(vaultStats.highSensitivity)
1737
- ]
1738
1561
  }),
1739
- report !== null && report.strength !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1740
- className: `${VaultSection_module_css_default.badge} ${report.strength.weak > 0 ? VaultSection_module_css_default.badgeDanger : VaultSection_module_css_default.badgeOk}`,
1741
- children: [
1742
- t("healthStrength"),
1743
- ": ",
1744
- report.strength.weak,
1745
- "W/",
1746
- report.strength.fair,
1747
- "F/",
1748
- report.strength.strong,
1749
- "S"
1750
- ]
1562
+ expandedId === entry.id && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1563
+ className: VaultSection_module_css_default.detailBox,
1564
+ children: Object.entries(entry).filter(([k]) => ![
1565
+ "id",
1566
+ "title",
1567
+ "favorite"
1568
+ ].includes(k) && entry[k] !== void 0).map(([k, v]) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1569
+ className: VaultSection_module_css_default.detailItem,
1570
+ children: [
1571
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: k }),
1572
+ ": ",
1573
+ formatDetail(k, v),
1574
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1575
+ type: "button",
1576
+ className: VaultSection_module_css_default.revealButton,
1577
+ title: t("copyFieldHint"),
1578
+ onClick: () => void copyValue(entry.id, Array.isArray(v) ? v.join(", ") : String(v)),
1579
+ children: "⧉"
1580
+ })
1581
+ ]
1582
+ }, k))
1751
1583
  }),
1752
- report !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1753
- className: `${VaultSection_module_css_default.badge} ${report.verdict === "good" ? VaultSection_module_css_default.badgeOk : report.verdict === "fair" ? VaultSection_module_css_default.badgeWarn : VaultSection_module_css_default.badgeDanger}`,
1584
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1585
+ className: VaultSection_module_css_default.rowActions,
1754
1586
  children: [
1755
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
1756
- className: VaultSection_module_css_default.scoreRing,
1757
- width: "14",
1758
- height: "14",
1759
- viewBox: "0 0 16 16",
1760
- "aria-hidden": "true",
1761
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
1762
- cx: "8",
1763
- cy: "8",
1764
- r: "6.5",
1765
- fill: "none",
1766
- stroke: "var(--dsh-color-border, #ddd)",
1767
- strokeWidth: "2"
1768
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
1769
- cx: "8",
1770
- cy: "8",
1771
- r: "6.5",
1772
- fill: "none",
1773
- stroke: report.verdict === "good" ? "#2e9e5b" : report.verdict === "fair" ? "#c98a1b" : "#cf3d3d",
1774
- strokeWidth: "2",
1775
- strokeLinecap: "round",
1776
- strokeDasharray: `${(report.score / 100 * 2 * Math.PI * 6.5).toFixed(1)} ${(2 * Math.PI * 6.5).toFixed(1)}`,
1777
- transform: "rotate(-90 8 8)"
1778
- })]
1587
+ copiedId === entry.id && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1588
+ className: VaultSection_module_css_default.copied,
1589
+ children: [
1590
+ t("copied"),
1591
+ " · ",
1592
+ t("clearsIn30s")
1593
+ ]
1779
1594
  }),
1780
- t("healthScore"),
1781
- ": ",
1782
- report.score,
1783
- " (",
1784
- t(VERDICT_KEYS[report.verdict] ?? "verdictGood"),
1785
- ")"
1786
- ]
1787
- }),
1788
- report !== null && report.no2fa.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1789
- className: `${VaultSection_module_css_default.badge} ${VaultSection_module_css_default.badgeWarn}`,
1790
- children: [
1791
- t("no2fa"),
1792
- ": ",
1793
- report.no2fa.length
1794
- ]
1795
- }),
1796
- report !== null && report.httpSites.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1797
- className: `${VaultSection_module_css_default.badge} ${VaultSection_module_css_default.badgeWarn}`,
1798
- children: [
1799
- t("httpSites"),
1800
- ": ",
1801
- report.httpSites.length
1802
- ]
1803
- }),
1804
- report !== null && report.rotation.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1805
- className: `${VaultSection_module_css_default.badge} ${VaultSection_module_css_default.badgeWarn}`,
1806
- children: [
1807
- t("reportRotation"),
1808
- ": ",
1809
- report.rotation.length
1810
- ]
1811
- }),
1812
- vaultStats !== null && typeof vaultStats.expired === "number" && vaultStats.expired > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1813
- className: `${VaultSection_module_css_default.badge} ${VaultSection_module_css_default.badgeDanger}`,
1814
- children: [
1815
- t("dueExpired"),
1816
- ": ",
1817
- String(vaultStats.expired)
1818
- ]
1819
- }),
1820
- report !== null && report.weak.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1821
- className: `${VaultSection_module_css_default.badge} ${VaultSection_module_css_default.badgeDanger}`,
1822
- children: [
1823
- t("reportWeak"),
1824
- ": ",
1825
- report.weak.length
1826
- ]
1827
- }),
1828
- report !== null && report.reused.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1829
- className: `${VaultSection_module_css_default.badge} ${VaultSection_module_css_default.badgeDanger}`,
1830
- children: [
1831
- t("reportReused"),
1832
- ": ",
1833
- report.reused.length
1834
- ]
1835
- }),
1836
- dupGroups > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1837
- className: `${VaultSection_module_css_default.badge} ${VaultSection_module_css_default.badgeWarn}`,
1838
- children: [
1839
- t("dupGroups"),
1840
- ": ",
1841
- dupGroups
1842
- ]
1843
- }),
1844
- report !== null && report.rotation.length === 0 && report.weak.length === 0 && report.reused.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1845
- className: `${VaultSection_module_css_default.badge} ${VaultSection_module_css_default.badgeOk}`,
1846
- children: t("healthOk")
1847
- }),
1848
- backupInfo !== null && backupInfo.daysSinceBackup >= 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1849
- className: `${VaultSection_module_css_default.badge} ${backupInfo.daysSinceBackup > 14 ? VaultSection_module_css_default.badgeDanger : backupInfo.daysSinceBackup > 7 ? VaultSection_module_css_default.badgeWarn : ""}`,
1850
- children: [
1851
- t("healthBackup"),
1852
- ": ",
1853
- backupInfo.daysSinceBackup,
1854
- "d (",
1855
- backupInfo.backups,
1856
- ")"
1595
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1596
+ type: "button",
1597
+ onClick: () => void copyValue(entry.id, entry.username ?? entry.title),
1598
+ disabled: busy,
1599
+ children: t("copy")
1600
+ }),
1601
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1602
+ type: "button",
1603
+ onClick: () => {
1604
+ setBusy(true);
1605
+ get(entry.id).then((r) => {
1606
+ if (r.found && r.entry?.password) copyValue(entry.id, r.entry.password);
1607
+ setBusy(false);
1608
+ }, () => setBusy(false));
1609
+ },
1610
+ disabled: busy || readonly,
1611
+ children: t("copyPassword")
1612
+ }),
1613
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1614
+ type: "button",
1615
+ onClick: () => void showTotp(entry.id),
1616
+ disabled: busy,
1617
+ children: t("totp")
1618
+ }),
1619
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1620
+ type: "button",
1621
+ onClick: () => void showTotpUri(entry.id),
1622
+ disabled: busy,
1623
+ title: t("totpUriHint"),
1624
+ children: t("totpUri")
1625
+ }),
1626
+ code !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1627
+ type: "button",
1628
+ onClick: () => void copyValue(entry.id, code),
1629
+ disabled: busy,
1630
+ children: t("copyCode")
1631
+ }),
1632
+ entry.url !== void 0 && entry.url !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1633
+ type: "button",
1634
+ onClick: () => window.open(entry.url, "_blank", "noopener"),
1635
+ title: t("openUrlHint"),
1636
+ children: t("openUrl")
1637
+ }),
1638
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1639
+ type: "button",
1640
+ onClick: () => void touch(entry.id).then(() => void refresh()),
1641
+ disabled: busy || readonly,
1642
+ title: t("touchHint"),
1643
+ children: t("touch")
1644
+ }),
1645
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1646
+ type: "button",
1647
+ onClick: () => void startEdit(entry.id),
1648
+ disabled: busy || readonly,
1649
+ children: t("edit")
1650
+ }),
1651
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1652
+ type: "button",
1653
+ className: VaultSection_module_css_default.deleteButton,
1654
+ onClick: () => void removeEntry(entry.id),
1655
+ disabled: busy || readonly,
1656
+ children: t("delete")
1657
+ })
1857
1658
  ]
1858
- }),
1859
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1860
- type: "button",
1861
- className: VaultSection_module_css_default.backupButton,
1862
- onClick: () => void backupNow(),
1863
- disabled: busy,
1864
- children: t("backupNow")
1865
- }),
1866
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1867
- type: "button",
1868
- className: VaultSection_module_css_default.backupButton,
1869
- onClick: () => void runBreachCheck(),
1870
- disabled: busy,
1871
- children: t("breachCheck")
1872
- }),
1873
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1874
- type: "button",
1875
- className: VaultSection_module_css_default.backupButton,
1876
- onClick: () => void lockNow(),
1877
- disabled: busy || locked,
1878
- children: t("lock")
1879
1659
  })
1880
1660
  ]
1661
+ }, entry.id);
1662
+ })
1663
+ })] }),
1664
+ state.status === "ready" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1665
+ className: VaultSection_module_css_default.healthBar,
1666
+ children: [
1667
+ vaultStats !== null && typeof vaultStats.total === "number" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1668
+ className: VaultSection_module_css_default.badge,
1669
+ children: [
1670
+ t("entryCount"),
1671
+ ": ",
1672
+ String(vaultStats.total)
1673
+ ]
1881
1674
  }),
1882
- breach !== null && (breach.pwned.length > 0 || breach.weak.length > 0) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1883
- className: VaultSection_module_css_default.reportBox,
1675
+ vaultStats !== null && typeof vaultStats.withTotp === "number" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1676
+ className: VaultSection_module_css_default.badge,
1677
+ children: ["TOTP: ", String(vaultStats.withTotp)]
1678
+ }),
1679
+ vaultStats !== null && typeof vaultStats.highSensitivity === "number" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1680
+ className: VaultSection_module_css_default.badge,
1681
+ children: [
1682
+ t("highSensitivity"),
1683
+ ": ",
1684
+ String(vaultStats.highSensitivity)
1685
+ ]
1686
+ }),
1687
+ report !== null && report.strength !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1688
+ className: `${VaultSection_module_css_default.badge} ${report.strength.weak > 0 ? VaultSection_module_css_default.badgeDanger : VaultSection_module_css_default.badgeOk}`,
1689
+ children: [
1690
+ t("healthStrength"),
1691
+ ": ",
1692
+ report.strength.weak,
1693
+ "W/",
1694
+ report.strength.fair,
1695
+ "F/",
1696
+ report.strength.strong,
1697
+ "S"
1698
+ ]
1699
+ }),
1700
+ report !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1701
+ className: `${VaultSection_module_css_default.badge} ${report.verdict === "good" ? VaultSection_module_css_default.badgeOk : report.verdict === "fair" ? VaultSection_module_css_default.badgeWarn : VaultSection_module_css_default.badgeDanger}`,
1884
1702
  children: [
1885
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1886
- className: VaultSection_module_css_default.reportTitle,
1887
- children: [t("breachTitle"), breach.offline ? ` (${t("breachOffline")})` : ""]
1703
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
1704
+ className: VaultSection_module_css_default.scoreRing,
1705
+ width: "14",
1706
+ height: "14",
1707
+ viewBox: "0 0 16 16",
1708
+ "aria-hidden": "true",
1709
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
1710
+ cx: "8",
1711
+ cy: "8",
1712
+ r: "6.5",
1713
+ fill: "none",
1714
+ stroke: "var(--dsh-color-border, #ddd)",
1715
+ strokeWidth: "2"
1716
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
1717
+ cx: "8",
1718
+ cy: "8",
1719
+ r: "6.5",
1720
+ fill: "none",
1721
+ stroke: report.verdict === "good" ? "#2e9e5b" : report.verdict === "fair" ? "#c98a1b" : "#cf3d3d",
1722
+ strokeWidth: "2",
1723
+ strokeLinecap: "round",
1724
+ strokeDasharray: `${(report.score / 100 * 2 * Math.PI * 6.5).toFixed(1)} ${(2 * Math.PI * 6.5).toFixed(1)}`,
1725
+ transform: "rotate(-90 8 8)"
1726
+ })]
1888
1727
  }),
1889
- breach.pwned.slice(0, 6).map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1890
- className: VaultSection_module_css_default.reportSub,
1891
- children: [
1892
- "· ",
1893
- item.title,
1894
- "",
1895
- t("breachPwned"),
1896
- item.count > 0 ? ` ×${item.count}` : ""
1897
- ]
1898
- }, item.id)),
1899
- breach.weak.slice(0, 6).map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1900
- className: VaultSection_module_css_default.reportSub,
1901
- children: [
1902
- "· ",
1903
- item.title,
1904
- " — ",
1905
- t("breachWeak")
1906
- ]
1907
- }, item.id))
1728
+ t("healthScore"),
1729
+ ": ",
1730
+ report.score,
1731
+ " (",
1732
+ t(VERDICT_KEYS[report.verdict] ?? "verdictGood"),
1733
+ ")"
1908
1734
  ]
1909
1735
  }),
1910
- state.status === "ready" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1911
- className: VaultSection_module_css_default.footer,
1736
+ report !== null && report.no2fa.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1737
+ className: `${VaultSection_module_css_default.badge} ${VaultSection_module_css_default.badgeWarn}`,
1912
1738
  children: [
1913
- t("entryCount"),
1739
+ t("no2fa"),
1914
1740
  ": ",
1915
- state.entries.length,
1916
- vaultStats !== null && typeof vaultStats.withTotp === "number" && ` · TOTP: ${String(vaultStats.withTotp)}`,
1917
- vaultStats !== null && typeof vaultStats.highSensitivity === "number" && ` · ${t("highSensitivity")}: ${String(vaultStats.highSensitivity)}`,
1918
- backupInfo !== null && backupInfo.daysSinceBackup >= 0 && ` · backup: ${backupInfo.daysSinceBackup}d ago`,
1919
- vaultStats !== null && typeof vaultStats.byTag === "object" && vaultStats.byTag !== null && Object.keys(vaultStats.byTag).length > 0 && ` · tags: ${Object.entries(vaultStats.byTag).map(([k, v]) => `${k}(${String(v)})`).join(" ")}`
1741
+ report.no2fa.length
1920
1742
  ]
1743
+ }),
1744
+ report !== null && report.httpSites.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1745
+ className: `${VaultSection_module_css_default.badge} ${VaultSection_module_css_default.badgeWarn}`,
1746
+ children: [
1747
+ t("httpSites"),
1748
+ ": ",
1749
+ report.httpSites.length
1750
+ ]
1751
+ }),
1752
+ report !== null && report.rotation.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1753
+ className: `${VaultSection_module_css_default.badge} ${VaultSection_module_css_default.badgeWarn}`,
1754
+ children: [
1755
+ t("reportRotation"),
1756
+ ": ",
1757
+ report.rotation.length
1758
+ ]
1759
+ }),
1760
+ vaultStats !== null && typeof vaultStats.expired === "number" && vaultStats.expired > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1761
+ className: `${VaultSection_module_css_default.badge} ${VaultSection_module_css_default.badgeDanger}`,
1762
+ children: [
1763
+ t("dueExpired"),
1764
+ ": ",
1765
+ String(vaultStats.expired)
1766
+ ]
1767
+ }),
1768
+ report !== null && report.weak.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1769
+ className: `${VaultSection_module_css_default.badge} ${VaultSection_module_css_default.badgeDanger}`,
1770
+ children: [
1771
+ t("reportWeak"),
1772
+ ": ",
1773
+ report.weak.length
1774
+ ]
1775
+ }),
1776
+ report !== null && report.reused.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1777
+ className: `${VaultSection_module_css_default.badge} ${VaultSection_module_css_default.badgeDanger}`,
1778
+ children: [
1779
+ t("reportReused"),
1780
+ ": ",
1781
+ report.reused.length
1782
+ ]
1783
+ }),
1784
+ dupGroups > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1785
+ className: `${VaultSection_module_css_default.badge} ${VaultSection_module_css_default.badgeWarn}`,
1786
+ children: [
1787
+ t("dupGroups"),
1788
+ ": ",
1789
+ dupGroups
1790
+ ]
1791
+ }),
1792
+ report !== null && report.rotation.length === 0 && report.weak.length === 0 && report.reused.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1793
+ className: `${VaultSection_module_css_default.badge} ${VaultSection_module_css_default.badgeOk}`,
1794
+ children: t("healthOk")
1795
+ }),
1796
+ backupInfo !== null && backupInfo.daysSinceBackup >= 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1797
+ className: `${VaultSection_module_css_default.badge} ${backupInfo.daysSinceBackup > 14 ? VaultSection_module_css_default.badgeDanger : backupInfo.daysSinceBackup > 7 ? VaultSection_module_css_default.badgeWarn : ""}`,
1798
+ children: [
1799
+ t("healthBackup"),
1800
+ ": ",
1801
+ backupInfo.daysSinceBackup,
1802
+ "d (",
1803
+ backupInfo.backups,
1804
+ ")"
1805
+ ]
1806
+ }),
1807
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1808
+ type: "button",
1809
+ className: VaultSection_module_css_default.backupButton,
1810
+ onClick: () => void backupNow(),
1811
+ disabled: busy,
1812
+ children: t("backupNow")
1813
+ }),
1814
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1815
+ type: "button",
1816
+ className: VaultSection_module_css_default.backupButton,
1817
+ onClick: () => void runBreachCheck(),
1818
+ disabled: busy,
1819
+ children: t("breachCheck")
1820
+ }),
1821
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1822
+ type: "button",
1823
+ className: VaultSection_module_css_default.backupButton,
1824
+ onClick: () => void lockNow(),
1825
+ disabled: busy || locked,
1826
+ children: t("lock")
1921
1827
  })
1922
1828
  ]
1923
1829
  }),
1830
+ breach !== null && (breach.pwned.length > 0 || breach.weak.length > 0) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1831
+ className: VaultSection_module_css_default.reportBox,
1832
+ children: [
1833
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1834
+ className: VaultSection_module_css_default.reportTitle,
1835
+ children: [t("breachTitle"), breach.offline ? ` (${t("breachOffline")})` : ""]
1836
+ }),
1837
+ breach.pwned.slice(0, 6).map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1838
+ className: VaultSection_module_css_default.reportSub,
1839
+ children: [
1840
+ "· ",
1841
+ item.title,
1842
+ " — ",
1843
+ t("breachPwned"),
1844
+ item.count > 0 ? ` ×${item.count}` : ""
1845
+ ]
1846
+ }, item.id)),
1847
+ breach.weak.slice(0, 6).map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1848
+ className: VaultSection_module_css_default.reportSub,
1849
+ children: [
1850
+ "· ",
1851
+ item.title,
1852
+ " — ",
1853
+ t("breachWeak")
1854
+ ]
1855
+ }, item.id))
1856
+ ]
1857
+ }),
1858
+ state.status === "ready" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1859
+ className: VaultSection_module_css_default.footer,
1860
+ children: [
1861
+ t("entryCount"),
1862
+ ": ",
1863
+ state.entries.length,
1864
+ vaultStats !== null && typeof vaultStats.withTotp === "number" && ` · TOTP: ${String(vaultStats.withTotp)}`,
1865
+ vaultStats !== null && typeof vaultStats.highSensitivity === "number" && ` · ${t("highSensitivity")}: ${String(vaultStats.highSensitivity)}`,
1866
+ backupInfo !== null && backupInfo.daysSinceBackup >= 0 && ` · backup: ${backupInfo.daysSinceBackup}d ago`,
1867
+ vaultStats !== null && typeof vaultStats.byTag === "object" && vaultStats.byTag !== null && Object.keys(vaultStats.byTag).length > 0 && ` · tags: ${Object.entries(vaultStats.byTag).map(([k, v]) => `${k}(${String(v)})`).join(" ")}`
1868
+ ]
1869
+ }),
1924
1870
  editor.status !== "closed" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1925
1871
  className: VaultSection_module_css_default.editor,
1926
1872
  role: "dialog",
@@ -2302,11 +2248,6 @@ window.__ModuleLoader__.load({
2302
2248
  systemSearch: "Search system stores",
2303
2249
  sysSearchPlaceholder: "Search Chrome / Keychain…",
2304
2250
  sysSearchGo: "Search",
2305
- sectionTabs: "Vault sections",
2306
- tabEntries: "Entries",
2307
- tabSecurity: "Security",
2308
- tabTransfer: "Import / Export",
2309
- tabOrganize: "Organize",
2310
2251
  lockedShort: "🔒 locked",
2311
2252
  httpSites: "HTTP sites",
2312
2253
  healthStrength: "strength",
@@ -2477,11 +2418,6 @@ window.__ModuleLoader__.load({
2477
2418
  systemSearch: "搜索系统凭据库",
2478
2419
  sysSearchPlaceholder: "搜索 Chrome / 钥匙串…",
2479
2420
  sysSearchGo: "搜索",
2480
- sectionTabs: "凭据库分区",
2481
- tabEntries: "条目",
2482
- tabSecurity: "安全",
2483
- tabTransfer: "导入/导出",
2484
- tabOrganize: "整理",
2485
2421
  lockedShort: "🔒 已锁定",
2486
2422
  httpSites: "HTTP站点",
2487
2423
  healthStrength: "强度",