@lynn123411/dsh-a6api 1.1.0 → 1.2.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/README.md +1 -0
- package/lib/client.js +324 -56
- package/lib/client.js.map +2 -2
- package/lib/index.js +29 -6
- package/lib/index.js.map +2 -2
- package/lib/types/server/probe.d.ts +2 -2
- package/lib/types/types.d.ts +4 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,6 +6,7 @@ A6API 多模型聚合站深度接入插件:将 A6API 聚合网关无缝注册
|
|
|
6
6
|
|
|
7
7
|
- **多标签页优雅布局**:重构并优化设置交互,拆分为「可用模型」、「账户资产」、「基础配置」三大专属页面,分类清晰、告别页面拥挤。
|
|
8
8
|
- **全真官方模型卡片复刻**:1:1 像素级复刻 A6API 官网模型卡片视图,包含品牌图标、模型名、商户 ID、渠道说明、输入/输出/缓存读写单价、实时倍率比值胶囊、实时/24h/7d 阶梯成功率点阵、延迟与缓存命中率进度条、智能标签(稳定/低价/高速/高质/保真)以及禁用与固定操作。
|
|
9
|
+
- **路由快照时效标注**:每张模型卡片右下角标注「路由快照」时效(该卡片商户数据来自我最近一次路由请求的时刻,相对时间 + 悬停绝对时间),与全网最近成功时间叠放两行;日志中无路由记录的模型显示灰色「从未路由」。
|
|
9
10
|
- **官方 vs 商户全景价格对比**:展开卡片即可查看详细渠道说明、智能标签、真实数据徽章、近 100 次样本统计,以及官方基准价与商户实时价在「输入价/输出价/缓存读/缓存写 (1M)」各维度的清晰对比表格。
|
|
10
11
|
- **真实账户资产看板与调用明细**:在「账户资产」页面实时呈现真实可用余额(美元及折合人民币)、历史总消耗、累计请求次数,并实时捕获展示近期模型请求的路由明细快照(时间、模型、命中商户渠道、总耗时、Token 消耗及状态)。
|
|
11
12
|
- **原生提供商动态注册与一键加入 DSH**:自动向 DSH LLM 运行时注入 `a6api` 目录,在「可用模型」列表点击「添加到 DSH」即可将模型自动增量同步至 `settings.yaml` 与 DSH 对话选择器。
|
package/lib/client.js
CHANGED
|
@@ -31,6 +31,13 @@ module.exports = __toCommonJS(index_exports);
|
|
|
31
31
|
var import_react4 = require("react");
|
|
32
32
|
|
|
33
33
|
// src/client/store.ts
|
|
34
|
+
function formatRelativeNow(tsSec) {
|
|
35
|
+
const diff = Math.floor(Date.now() / 1e3) - tsSec;
|
|
36
|
+
if (diff < 60) return "\u521A\u521A";
|
|
37
|
+
if (diff < 3600) return `${Math.floor(diff / 60)} \u5206\u949F\u524D`;
|
|
38
|
+
if (diff < 86400) return `${Math.floor(diff / 3600)} \u5C0F\u65F6\u524D`;
|
|
39
|
+
return `${Math.floor(diff / 86400)} \u5929\u524D`;
|
|
40
|
+
}
|
|
34
41
|
var A6ApiStore = class {
|
|
35
42
|
state = {
|
|
36
43
|
loading: true,
|
|
@@ -190,7 +197,10 @@ var A6ApiStore = class {
|
|
|
190
197
|
probeStatus: "success",
|
|
191
198
|
probeLatencyMs: json.result.durationMs,
|
|
192
199
|
probeError: void 0,
|
|
193
|
-
lastProbedAt: Date.now()
|
|
200
|
+
lastProbedAt: Date.now(),
|
|
201
|
+
// 探测请求本身会写路由日志,乐观更新路由快照时效,下次 /state 以日志为准
|
|
202
|
+
lastRoutedAt: Math.floor(Date.now() / 1e3),
|
|
203
|
+
lastRoutedText: formatRelativeNow(Math.floor(Date.now() / 1e3))
|
|
194
204
|
} : m
|
|
195
205
|
);
|
|
196
206
|
} else if (json?.result?.error) {
|
|
@@ -316,6 +326,14 @@ var store = new A6ApiStore();
|
|
|
316
326
|
// src/client/components/MerchantCard.tsx
|
|
317
327
|
var import_react = require("react");
|
|
318
328
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
329
|
+
var formatAbsolute = (tsSec) => {
|
|
330
|
+
const d = new Date(tsSec * 1e3);
|
|
331
|
+
const p = (n) => String(n).padStart(2, "0");
|
|
332
|
+
const nowY = (/* @__PURE__ */ new Date()).getFullYear();
|
|
333
|
+
const y = d.getFullYear();
|
|
334
|
+
const md = `${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}`;
|
|
335
|
+
return y !== nowY ? `${y}-${md}` : md;
|
|
336
|
+
};
|
|
319
337
|
var MerchantCard = ({ model }) => {
|
|
320
338
|
const [expanded, setExpanded] = (0, import_react.useState)(false);
|
|
321
339
|
const isProbing = model.probeStatus === "probing";
|
|
@@ -450,46 +468,64 @@ var MerchantCard = ({ model }) => {
|
|
|
450
468
|
] }) }),
|
|
451
469
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-bar-tags", children: (merchant?.labels || ["\u7A33\u5B9A", "\u4F4E\u4EF7", "\u9AD8\u901F", "\u9AD8\u8D28"]).map((lbl, idx) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: `dsh-a6-smart-pill ${getTagClass(lbl)}`, children: lbl }, idx)) }),
|
|
452
470
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-bar-actions", onClick: (e) => e.stopPropagation(), children: [
|
|
453
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
471
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-time-stack", children: [
|
|
472
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
473
|
+
"span",
|
|
474
|
+
{
|
|
475
|
+
className: "dsh-a6-time-ago",
|
|
476
|
+
"data-tooltip": "\u8BE5\u5546\u6237\u8DEF\u7EBF\u5168\u7F51\u6700\u8FD1\u4E00\u6B21\u6210\u529F\u54CD\u5E94\u65F6\u95F4",
|
|
477
|
+
children: [
|
|
478
|
+
"\u5168\u7F51\u6700\u8FD1\uFF1A",
|
|
479
|
+
merchant?.last_success_text || "\u521A\u521A"
|
|
480
|
+
]
|
|
481
|
+
}
|
|
482
|
+
),
|
|
483
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
484
|
+
"span",
|
|
485
|
+
{
|
|
486
|
+
className: `dsh-a6-time-ago dsh-a6-route-snapshot${model.lastRoutedAt ? "" : " never"}`,
|
|
487
|
+
"data-tooltip": model.lastRoutedAt ? `\u4E2A\u4EBA\u6700\u540E\u4E00\u6B21\u8BF7\u6C42\u8BE5\u6A21\u578B\u7684\u65F6\u95F4\uFF08\u5546\u5BB6\u8DEF\u7531\u60C5\u51B5\u7684\u622A\u6B62\u65F6\u6548\uFF09${formatAbsolute(model.lastRoutedAt)}` : "\u65E5\u5FD7\u4E2D\u6682\u65E0\u8BE5\u6A21\u578B\u7684\u8DEF\u7531\u8BB0\u5F55",
|
|
488
|
+
children: [
|
|
489
|
+
"\u4E2A\u4EBA\u6700\u8FD1\uFF1A",
|
|
490
|
+
model.lastRoutedText || "\u4ECE\u672A\u8DEF\u7531"
|
|
491
|
+
]
|
|
492
|
+
}
|
|
493
|
+
)
|
|
494
|
+
] }),
|
|
495
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-bar-actions-btns", children: [
|
|
496
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
497
|
+
"button",
|
|
498
|
+
{
|
|
499
|
+
type: "button",
|
|
500
|
+
className: "dsh-a6-btn dsh-a6-btn-secondary dsh-a6-btn-sm",
|
|
501
|
+
onClick: handleProbe,
|
|
502
|
+
disabled: isProbing,
|
|
503
|
+
"data-tooltip": "\u5411\u8BE5\u6A21\u578B\u53D1\u9001\u4E00\u6B21\u8BF7\u6C42\u4EE5\u63A2\u6D4B\u5E76\u6355\u83B7\u5176\u5B9E\u9645\u547D\u4E2D\u7684\u5546\u6237 ID\u3001\u4EF7\u683C\u53CA\u5065\u5EB7\u5EA6\u6307\u6807\uFF08\u6D88\u8017\u5C11\u91CFToken\uFF09",
|
|
504
|
+
children: isProbing ? "\u63A2\u6D4B\u4E2D..." : "\u63A2\u6D4B\u5546\u5BB6"
|
|
505
|
+
}
|
|
506
|
+
),
|
|
507
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
508
|
+
"button",
|
|
509
|
+
{
|
|
510
|
+
type: "button",
|
|
511
|
+
className: `dsh-a6-btn dsh-a6-btn-sm ${model.inDsh ? "dsh-a6-btn-in-dsh" : "dsh-a6-btn-primary"}`,
|
|
512
|
+
onClick: handleToggleDsh,
|
|
513
|
+
"data-tooltip": model.inDsh ? "\u5DF2\u52A0\u5165 DSH \u6A21\u578B\u9009\u62E9\u5668 (\u70B9\u51FB\u79FB\u9664)" : "\u6DFB\u52A0\u81F3 DSH \u6A21\u578B\u9009\u62E9\u5668",
|
|
514
|
+
children: model.inDsh ? "\u79FB\u9664\u6A21\u578B" : "\u6DFB\u52A0\u6A21\u578B"
|
|
515
|
+
}
|
|
516
|
+
),
|
|
517
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
518
|
+
"button",
|
|
519
|
+
{
|
|
520
|
+
type: "button",
|
|
521
|
+
className: `dsh-a6-expand-toggle-btn ${expanded ? "open" : ""}`,
|
|
522
|
+
onClick: () => setExpanded(!expanded),
|
|
523
|
+
"data-tooltip": expanded ? "\u6536\u8D77\u4EF7\u683C\u8BE6\u60C5" : "\u5C55\u5F00\u5B98\u65B9\u57FA\u51C6\u4EF7\u4E0E\u5546\u6237\u5B9E\u65F6\u4EF7\u5BF9\u6BD4\u8868",
|
|
524
|
+
"data-tooltip-pos": "left",
|
|
525
|
+
children: expanded ? "\u6536\u8D77" : "\u8BE6\u60C5"
|
|
526
|
+
}
|
|
527
|
+
)
|
|
528
|
+
] })
|
|
493
529
|
] })
|
|
494
530
|
] }),
|
|
495
531
|
expanded && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-detail-container", children: [
|
|
@@ -1794,12 +1830,22 @@ var main_default = `/* A6API Plugin Styles - Clean Professional DSH Native Theme
|
|
|
1794
1830
|
color: #059669;
|
|
1795
1831
|
}
|
|
1796
1832
|
|
|
1797
|
-
/* Right Actions Group */
|
|
1833
|
+
/* Right Actions Group \u2014 \u9ED8\u8BA4\u9760\u53F3\uFF0C\u7A84\u5C4F\u65F6\u5360\u6EE1\u884C\u5BBD\u4E24\u7AEF\u5BF9\u9F50 */
|
|
1798
1834
|
.dsh-a6-bar-actions {
|
|
1799
1835
|
display: flex;
|
|
1800
1836
|
align-items: center;
|
|
1801
|
-
gap:
|
|
1802
|
-
flex
|
|
1837
|
+
gap: 12px;
|
|
1838
|
+
flex: 0 0 auto;
|
|
1839
|
+
margin-left: auto;
|
|
1840
|
+
}
|
|
1841
|
+
|
|
1842
|
+
@media (max-width: 900px) {
|
|
1843
|
+
.dsh-a6-bar-actions {
|
|
1844
|
+
flex: 1 1 100%;
|
|
1845
|
+
width: 100%;
|
|
1846
|
+
margin-left: 0;
|
|
1847
|
+
justify-content: space-between;
|
|
1848
|
+
}
|
|
1803
1849
|
}
|
|
1804
1850
|
|
|
1805
1851
|
.dsh-a6-time-ago {
|
|
@@ -1807,6 +1853,28 @@ var main_default = `/* A6API Plugin Styles - Clean Professional DSH Native Theme
|
|
|
1807
1853
|
color: var(--dsw-alias-label-tertiary, #94a3b8);
|
|
1808
1854
|
}
|
|
1809
1855
|
|
|
1856
|
+
/* \u4E24\u884C\u65F6\u95F4\u6233\u5782\u76F4\u53E0\u653E (\u5168\u7F51\u6700\u8FD1 / \u4E2A\u4EBA\u6700\u8FD1) \u2014 \u5DE6\u5BF9\u9F50 */
|
|
1857
|
+
.dsh-a6-time-stack {
|
|
1858
|
+
display: flex;
|
|
1859
|
+
flex-direction: column;
|
|
1860
|
+
align-items: flex-start;
|
|
1861
|
+
gap: 2px;
|
|
1862
|
+
flex-shrink: 0;
|
|
1863
|
+
text-align: left;
|
|
1864
|
+
}
|
|
1865
|
+
|
|
1866
|
+
/* \u53F3\u4FA7\u4E09\u6309\u94AE\u7EC4 */
|
|
1867
|
+
.dsh-a6-bar-actions-btns {
|
|
1868
|
+
display: flex;
|
|
1869
|
+
align-items: center;
|
|
1870
|
+
gap: 8px;
|
|
1871
|
+
flex-shrink: 0;
|
|
1872
|
+
}
|
|
1873
|
+
|
|
1874
|
+
.dsh-a6-route-snapshot.never {
|
|
1875
|
+
color: var(--dsw-alias-label-quaternary, #cbd5e1);
|
|
1876
|
+
}
|
|
1877
|
+
|
|
1810
1878
|
.dsh-a6-btn-in-dsh {
|
|
1811
1879
|
background: rgba(16, 185, 129, 0.12);
|
|
1812
1880
|
border: 1px solid rgba(16, 185, 129, 0.35);
|
|
@@ -2564,19 +2632,24 @@ var main_default = `/* A6API Plugin Styles - Clean Professional DSH Native Theme
|
|
|
2564
2632
|
bottom: calc(100% + 7px);
|
|
2565
2633
|
left: 50%;
|
|
2566
2634
|
transform: translateX(-50%);
|
|
2567
|
-
padding:
|
|
2568
|
-
background: rgba(15, 23, 42, 0.
|
|
2635
|
+
padding: 6px 10px;
|
|
2636
|
+
background: rgba(15, 23, 42, 0.96);
|
|
2569
2637
|
color: #f8fafc;
|
|
2570
2638
|
font-size: 11px;
|
|
2571
2639
|
font-weight: 400;
|
|
2572
|
-
line-height: 1.
|
|
2573
|
-
white-space:
|
|
2574
|
-
|
|
2575
|
-
|
|
2640
|
+
line-height: 1.4;
|
|
2641
|
+
white-space: normal;
|
|
2642
|
+
max-width: min(320px, 85vw);
|
|
2643
|
+
width: max-content;
|
|
2644
|
+
text-align: left;
|
|
2645
|
+
word-break: break-word;
|
|
2646
|
+
overflow-wrap: anywhere;
|
|
2647
|
+
border-radius: 6px;
|
|
2648
|
+
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.28);
|
|
2576
2649
|
pointer-events: none;
|
|
2577
2650
|
opacity: 0;
|
|
2578
2651
|
visibility: hidden;
|
|
2579
|
-
transition: opacity 0.
|
|
2652
|
+
transition: opacity 0.08s ease-out, visibility 0.08s ease-out;
|
|
2580
2653
|
z-index: 99999;
|
|
2581
2654
|
border: 1px solid rgba(255, 255, 255, 0.12);
|
|
2582
2655
|
}
|
|
@@ -2682,15 +2755,24 @@ var main_default = `/* A6API Plugin Styles - Clean Professional DSH Native Theme
|
|
|
2682
2755
|
border-color: transparent transparent rgba(15, 23, 42, 0.94) transparent;
|
|
2683
2756
|
}
|
|
2684
2757
|
|
|
2685
|
-
/* Card actions tooltip
|
|
2758
|
+
/* Card actions tooltip: keep centered (avoid left:0 right-edge overflow) */
|
|
2686
2759
|
.dsh-a6-bar-actions [data-tooltip]:not([data-tooltip-pos])::after {
|
|
2687
|
-
left:
|
|
2688
|
-
transform:
|
|
2760
|
+
left: 50%;
|
|
2761
|
+
transform: translateX(-50%);
|
|
2762
|
+
right: auto;
|
|
2689
2763
|
}
|
|
2690
2764
|
|
|
2691
2765
|
.dsh-a6-bar-actions [data-tooltip]:not([data-tooltip-pos])::before {
|
|
2692
|
-
left:
|
|
2693
|
-
transform:
|
|
2766
|
+
left: 50%;
|
|
2767
|
+
transform: translateX(-50%);
|
|
2768
|
+
right: auto;
|
|
2769
|
+
}
|
|
2770
|
+
|
|
2771
|
+
/* When JS portal tooltip is active, hide pseudo to avoid double rendering */
|
|
2772
|
+
body.dsh-a6api-tooltip-active [data-tooltip]::after,
|
|
2773
|
+
body.dsh-a6api-tooltip-active [data-tooltip]::before {
|
|
2774
|
+
opacity: 0 !important;
|
|
2775
|
+
visibility: hidden !important;
|
|
2694
2776
|
}
|
|
2695
2777
|
`;
|
|
2696
2778
|
|
|
@@ -2707,8 +2789,194 @@ function injectStyles() {
|
|
|
2707
2789
|
document.head.appendChild(style);
|
|
2708
2790
|
}
|
|
2709
2791
|
}
|
|
2792
|
+
function setupGlobalTooltip() {
|
|
2793
|
+
if (typeof document === "undefined" || typeof window === "undefined") return;
|
|
2794
|
+
if (window.__dsh_a6api_tooltip_setup) return () => {
|
|
2795
|
+
};
|
|
2796
|
+
window.__dsh_a6api_tooltip_setup = true;
|
|
2797
|
+
const portalId = "dsh-a6api-tooltip";
|
|
2798
|
+
const arrowId = "dsh-a6api-tooltip-arrow";
|
|
2799
|
+
let portal = document.getElementById(portalId);
|
|
2800
|
+
let arrow = document.getElementById(arrowId);
|
|
2801
|
+
if (!portal) {
|
|
2802
|
+
portal = document.createElement("div");
|
|
2803
|
+
portal.id = portalId;
|
|
2804
|
+
portal.setAttribute("role", "tooltip");
|
|
2805
|
+
portal.style.cssText = "position:fixed;left:0;top:0;transform:translate(-9999px,-9999px);padding:6px 10px;background:rgba(15,23,42,0.96);color:#f8fafc;font-size:11px;line-height:1.4;border-radius:6px;box-shadow:0 6px 18px rgba(0,0,0,0.28);border:1px solid rgba(255,255,255,0.12);max-width:min(320px,85vw);width:max-content;white-space:normal;word-break:break-word;overflow-wrap:anywhere;text-align:left;pointer-events:none;opacity:0;visibility:hidden;transition:opacity 0.08s;z-index:2147483647;";
|
|
2806
|
+
document.body.appendChild(portal);
|
|
2807
|
+
}
|
|
2808
|
+
if (!arrow) {
|
|
2809
|
+
arrow = document.createElement("div");
|
|
2810
|
+
arrow.id = arrowId;
|
|
2811
|
+
arrow.style.cssText = "position:fixed;left:0;top:0;width:8px;height:8px;background:rgba(15,23,42,0.96);transform:translate(-9999px,-9999px) rotate(45deg);border-left:1px solid rgba(255,255,255,0.12);border-top:1px solid rgba(255,255,255,0.12);pointer-events:none;opacity:0;visibility:hidden;z-index:2147483646;";
|
|
2812
|
+
document.body.appendChild(arrow);
|
|
2813
|
+
}
|
|
2814
|
+
let currentTarget = null;
|
|
2815
|
+
function hide() {
|
|
2816
|
+
if (!portal || !arrow) return;
|
|
2817
|
+
portal.style.opacity = "0";
|
|
2818
|
+
portal.style.visibility = "hidden";
|
|
2819
|
+
arrow.style.opacity = "0";
|
|
2820
|
+
arrow.style.visibility = "hidden";
|
|
2821
|
+
document.body.classList.remove("dsh-a6api-tooltip-active");
|
|
2822
|
+
currentTarget = null;
|
|
2823
|
+
}
|
|
2824
|
+
function position(target) {
|
|
2825
|
+
if (!portal || !arrow || !target) return;
|
|
2826
|
+
const text = target.getAttribute("data-tooltip");
|
|
2827
|
+
if (!text) return;
|
|
2828
|
+
portal.textContent = text;
|
|
2829
|
+
portal.style.visibility = "hidden";
|
|
2830
|
+
portal.style.opacity = "0";
|
|
2831
|
+
portal.style.transform = "translate(-9999px,-9999px)";
|
|
2832
|
+
portal.style.visibility = "visible";
|
|
2833
|
+
const ttRect = portal.getBoundingClientRect();
|
|
2834
|
+
portal.style.visibility = "hidden";
|
|
2835
|
+
const rect = target.getBoundingClientRect();
|
|
2836
|
+
const gap = 8;
|
|
2837
|
+
const vw = window.innerWidth;
|
|
2838
|
+
const vh = window.innerHeight;
|
|
2839
|
+
const margin = 8;
|
|
2840
|
+
let pos = target.getAttribute("data-tooltip-pos") || "";
|
|
2841
|
+
if (!pos) {
|
|
2842
|
+
const spaceAbove = rect.top;
|
|
2843
|
+
const spaceBelow = vh - rect.bottom;
|
|
2844
|
+
if (spaceAbove < ttRect.height + gap + 12 && spaceBelow > spaceAbove) pos = "down";
|
|
2845
|
+
else pos = "top";
|
|
2846
|
+
}
|
|
2847
|
+
let top = 0;
|
|
2848
|
+
let left = 0;
|
|
2849
|
+
let arrowTop = 0;
|
|
2850
|
+
let arrowLeft = 0;
|
|
2851
|
+
const isDown = pos.startsWith("down");
|
|
2852
|
+
if (isDown) {
|
|
2853
|
+
top = rect.bottom + gap;
|
|
2854
|
+
arrowTop = rect.bottom + gap - 4;
|
|
2855
|
+
} else {
|
|
2856
|
+
top = rect.top - ttRect.height - gap;
|
|
2857
|
+
arrowTop = rect.top - gap - 4;
|
|
2858
|
+
}
|
|
2859
|
+
if (pos === "left") {
|
|
2860
|
+
left = rect.right - ttRect.width;
|
|
2861
|
+
arrowLeft = rect.right - 14;
|
|
2862
|
+
} else if (pos === "right") {
|
|
2863
|
+
left = rect.left;
|
|
2864
|
+
arrowLeft = rect.left + 14;
|
|
2865
|
+
} else if (pos === "down-left") {
|
|
2866
|
+
left = rect.right - ttRect.width;
|
|
2867
|
+
arrowLeft = rect.right - 14;
|
|
2868
|
+
} else if (pos === "down-right") {
|
|
2869
|
+
left = rect.left;
|
|
2870
|
+
arrowLeft = rect.left + 14;
|
|
2871
|
+
} else {
|
|
2872
|
+
left = rect.left + rect.width / 2 - ttRect.width / 2;
|
|
2873
|
+
arrowLeft = rect.left + rect.width / 2 - 4;
|
|
2874
|
+
}
|
|
2875
|
+
left = Math.max(margin, Math.min(left, vw - ttRect.width - margin));
|
|
2876
|
+
const minArrow = left + 8;
|
|
2877
|
+
const maxArrow = left + ttRect.width - 12;
|
|
2878
|
+
arrowLeft = Math.max(minArrow, Math.min(arrowLeft, maxArrow));
|
|
2879
|
+
if (top < margin) top = margin;
|
|
2880
|
+
if (top + ttRect.height > vh - margin) top = vh - ttRect.height - margin;
|
|
2881
|
+
portal.style.transform = "translate(" + left + "px," + top + "px)";
|
|
2882
|
+
portal.style.visibility = "visible";
|
|
2883
|
+
portal.style.opacity = "1";
|
|
2884
|
+
arrow.style.transform = "translate(" + arrowLeft + "px," + arrowTop + "px) rotate(45deg)";
|
|
2885
|
+
arrow.style.visibility = "visible";
|
|
2886
|
+
arrow.style.opacity = "1";
|
|
2887
|
+
document.body.classList.add("dsh-a6api-tooltip-active");
|
|
2888
|
+
}
|
|
2889
|
+
let hoverTimer = null;
|
|
2890
|
+
const onMouseOver = (e) => {
|
|
2891
|
+
const target = e.target && e.target.closest ? e.target.closest("[data-tooltip]") : null;
|
|
2892
|
+
if (!target) return;
|
|
2893
|
+
currentTarget = target;
|
|
2894
|
+
if (hoverTimer) clearTimeout(hoverTimer);
|
|
2895
|
+
hoverTimer = setTimeout(() => {
|
|
2896
|
+
if (currentTarget === target) position(target);
|
|
2897
|
+
}, 30);
|
|
2898
|
+
};
|
|
2899
|
+
const onMouseOut = (e) => {
|
|
2900
|
+
const target = e.target && e.target.closest ? e.target.closest("[data-tooltip]") : null;
|
|
2901
|
+
if (!target) return;
|
|
2902
|
+
const related = e.relatedTarget;
|
|
2903
|
+
if (related && target.contains(related)) return;
|
|
2904
|
+
if (currentTarget === target) {
|
|
2905
|
+
if (hoverTimer) clearTimeout(hoverTimer);
|
|
2906
|
+
hide();
|
|
2907
|
+
}
|
|
2908
|
+
};
|
|
2909
|
+
const onFocusIn = (e) => {
|
|
2910
|
+
const target = e.target && e.target.closest ? e.target.closest("[data-tooltip]") : null;
|
|
2911
|
+
if (!target) return;
|
|
2912
|
+
currentTarget = target;
|
|
2913
|
+
position(target);
|
|
2914
|
+
};
|
|
2915
|
+
const onFocusOut = (e) => {
|
|
2916
|
+
const target = e.target && e.target.closest ? e.target.closest("[data-tooltip]") : null;
|
|
2917
|
+
if (!target) return;
|
|
2918
|
+
if (currentTarget === target) hide();
|
|
2919
|
+
};
|
|
2920
|
+
const onScrollOrResize = () => {
|
|
2921
|
+
if (currentTarget) {
|
|
2922
|
+
if (document.body.contains(currentTarget) && currentTarget.matches && currentTarget.matches(":hover")) {
|
|
2923
|
+
position(currentTarget);
|
|
2924
|
+
} else if (document.activeElement === currentTarget) {
|
|
2925
|
+
position(currentTarget);
|
|
2926
|
+
} else {
|
|
2927
|
+
hide();
|
|
2928
|
+
}
|
|
2929
|
+
}
|
|
2930
|
+
};
|
|
2931
|
+
document.addEventListener("mouseover", onMouseOver, true);
|
|
2932
|
+
document.addEventListener("mouseout", onMouseOut, true);
|
|
2933
|
+
document.addEventListener("focusin", onFocusIn, true);
|
|
2934
|
+
document.addEventListener("focusout", onFocusOut, true);
|
|
2935
|
+
window.addEventListener("scroll", onScrollOrResize, true);
|
|
2936
|
+
window.addEventListener("resize", onScrollOrResize);
|
|
2937
|
+
document.addEventListener("scroll", onScrollOrResize, true);
|
|
2938
|
+
return () => {
|
|
2939
|
+
document.removeEventListener("mouseover", onMouseOver, true);
|
|
2940
|
+
document.removeEventListener("mouseout", onMouseOut, true);
|
|
2941
|
+
document.removeEventListener("focusin", onFocusIn, true);
|
|
2942
|
+
document.removeEventListener("focusout", onFocusOut, true);
|
|
2943
|
+
window.removeEventListener("scroll", onScrollOrResize, true);
|
|
2944
|
+
window.removeEventListener("resize", onScrollOrResize);
|
|
2945
|
+
document.removeEventListener("scroll", onScrollOrResize, true);
|
|
2946
|
+
if (hoverTimer) clearTimeout(hoverTimer);
|
|
2947
|
+
try {
|
|
2948
|
+
portal?.remove();
|
|
2949
|
+
} catch {
|
|
2950
|
+
}
|
|
2951
|
+
try {
|
|
2952
|
+
arrow?.remove();
|
|
2953
|
+
} catch {
|
|
2954
|
+
}
|
|
2955
|
+
document.body.classList.remove("dsh-a6api-tooltip-active");
|
|
2956
|
+
try {
|
|
2957
|
+
delete window.__dsh_a6api_tooltip_setup;
|
|
2958
|
+
} catch {
|
|
2959
|
+
window.__dsh_a6api_tooltip_setup = void 0;
|
|
2960
|
+
}
|
|
2961
|
+
currentTarget = null;
|
|
2962
|
+
};
|
|
2963
|
+
}
|
|
2710
2964
|
function apply(ctx) {
|
|
2711
2965
|
injectStyles();
|
|
2966
|
+
if (typeof window !== "undefined") {
|
|
2967
|
+
try {
|
|
2968
|
+
ctx.effect(() => {
|
|
2969
|
+
const dispose = setupGlobalTooltip();
|
|
2970
|
+
return () => {
|
|
2971
|
+
try {
|
|
2972
|
+
if (typeof dispose === "function") dispose();
|
|
2973
|
+
} catch {
|
|
2974
|
+
}
|
|
2975
|
+
};
|
|
2976
|
+
}, "dsh-a6api: tooltip portal");
|
|
2977
|
+
} catch {
|
|
2978
|
+
}
|
|
2979
|
+
}
|
|
2712
2980
|
if (typeof window === "undefined") return;
|
|
2713
2981
|
try {
|
|
2714
2982
|
setTimeout(() => {
|