@flamingo-stack/openframe-frontend-core 0.0.248 → 0.0.249
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/dist/{chunk-AGU44B7B.js → chunk-2FCXJTOV.js} +55 -357
- package/dist/chunk-2FCXJTOV.js.map +1 -0
- package/dist/{chunk-QHYCWQBH.cjs → chunk-3DZ7QYNA.cjs} +166 -15
- package/dist/chunk-3DZ7QYNA.cjs.map +1 -0
- package/dist/{chunk-4VSPLMB6.cjs → chunk-3VTHSACO.cjs} +34 -32
- package/dist/chunk-3VTHSACO.cjs.map +1 -0
- package/dist/{chunk-PMYD4WKR.cjs → chunk-4EED3YEI.cjs} +1550 -5971
- package/dist/chunk-4EED3YEI.cjs.map +1 -0
- package/dist/{chunk-RV2PYHCJ.js → chunk-4HHYUEMD.js} +3 -3
- package/dist/{chunk-UECRKCKH.js → chunk-4RDJZIHW.js} +115 -279
- package/dist/chunk-4RDJZIHW.js.map +1 -0
- package/dist/{chunk-672QV33W.js → chunk-5ZVPKTXM.js} +167 -16
- package/dist/chunk-5ZVPKTXM.js.map +1 -0
- package/dist/chunk-6JINAOI7.cjs +311 -0
- package/dist/chunk-6JINAOI7.cjs.map +1 -0
- package/dist/chunk-6LK4VEXE.cjs +4514 -0
- package/dist/chunk-6LK4VEXE.cjs.map +1 -0
- package/dist/chunk-DAAFVOTL.cjs +172 -0
- package/dist/chunk-DAAFVOTL.cjs.map +1 -0
- package/dist/{chunk-27VVOBDB.cjs → chunk-ELF4OOHC.cjs} +16 -180
- package/dist/chunk-ELF4OOHC.cjs.map +1 -0
- package/dist/{chunk-OZKPUBKX.cjs → chunk-LHZYI23D.cjs} +32 -30
- package/dist/chunk-LHZYI23D.cjs.map +1 -0
- package/dist/chunk-LKI3YCAX.js +4514 -0
- package/dist/chunk-LKI3YCAX.js.map +1 -0
- package/dist/{chunk-2Q5GVNXP.cjs → chunk-LZL6P7SN.cjs} +12 -12
- package/dist/{chunk-2Q5GVNXP.cjs.map → chunk-LZL6P7SN.cjs.map} +1 -1
- package/dist/chunk-M2OCXTNT.js +311 -0
- package/dist/chunk-M2OCXTNT.js.map +1 -0
- package/dist/{chunk-OTFJKBDW.js → chunk-PCXI7ZB2.js} +4928 -9349
- package/dist/chunk-PCXI7ZB2.js.map +1 -0
- package/dist/{chunk-PJT6RRSP.js → chunk-PVAYXHYF.js} +7 -5
- package/dist/{chunk-PJT6RRSP.js.map → chunk-PVAYXHYF.js.map} +1 -1
- package/dist/{chunk-GRTZ23GL.cjs → chunk-TU26IZPO.cjs} +16 -318
- package/dist/chunk-TU26IZPO.cjs.map +1 -0
- package/dist/{chunk-NFUXCXYN.js → chunk-VAKBNCV6.js} +7 -5
- package/dist/{chunk-NFUXCXYN.js.map → chunk-VAKBNCV6.js.map} +1 -1
- package/dist/chunk-ZXZJSTNV.js +172 -0
- package/dist/chunk-ZXZJSTNV.js.map +1 -0
- package/dist/components/chat/index.cjs +11 -7
- package/dist/components/chat/index.cjs.map +1 -1
- package/dist/components/chat/index.js +53 -49
- package/dist/components/contact/index.cjs +11 -8
- package/dist/components/contact/index.cjs.map +1 -1
- package/dist/components/contact/index.js +10 -7
- package/dist/components/features/index.cjs +11 -7
- package/dist/components/features/index.cjs.map +1 -1
- package/dist/components/features/index.js +26 -22
- package/dist/components/index.cjs +112 -109
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.js +134 -131
- package/dist/components/index.js.map +1 -1
- package/dist/components/navigation/index.cjs +10 -7
- package/dist/components/navigation/index.cjs.map +1 -1
- package/dist/components/navigation/index.js +9 -6
- package/dist/components/onboarding-guides/index.cjs +43 -53
- package/dist/components/onboarding-guides/index.cjs.map +1 -1
- package/dist/components/onboarding-guides/index.js +25 -35
- package/dist/components/onboarding-guides/index.js.map +1 -1
- package/dist/components/onboarding-guides/onboarding-guides-catalog-skeleton.d.ts +11 -11
- package/dist/components/onboarding-guides/onboarding-guides-catalog-skeleton.d.ts.map +1 -1
- package/dist/components/related-content/index.cjs +11 -8
- package/dist/components/related-content/index.cjs.map +1 -1
- package/dist/components/related-content/index.js +10 -7
- package/dist/components/tickets/index.cjs +96 -93
- package/dist/components/tickets/index.cjs.map +1 -1
- package/dist/components/tickets/index.js +21 -18
- package/dist/components/tickets/index.js.map +1 -1
- package/dist/components/ui/file-manager/index.cjs +52 -50
- package/dist/components/ui/file-manager/index.cjs.map +1 -1
- package/dist/components/ui/file-manager/index.js +6 -4
- package/dist/components/ui/file-manager/index.js.map +1 -1
- package/dist/components/ui/index.cjs +16 -11
- package/dist/components/ui/index.cjs.map +1 -1
- package/dist/components/ui/index.js +102 -97
- package/dist/contexts/index.cjs +2 -2
- package/dist/contexts/index.js +5 -5
- package/dist/hooks/index.cjs +6 -4
- package/dist/hooks/index.cjs.map +1 -1
- package/dist/hooks/index.js +8 -6
- package/dist/index.cjs +17 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +157 -151
- package/package.json +1 -1
- package/src/components/onboarding-guides/onboarding-guides-catalog-skeleton.tsx +28 -33
- package/dist/chunk-27VVOBDB.cjs.map +0 -1
- package/dist/chunk-4VSPLMB6.cjs.map +0 -1
- package/dist/chunk-672QV33W.js.map +0 -1
- package/dist/chunk-AGU44B7B.js.map +0 -1
- package/dist/chunk-GRTZ23GL.cjs.map +0 -1
- package/dist/chunk-OTFJKBDW.js.map +0 -1
- package/dist/chunk-OZKPUBKX.cjs.map +0 -1
- package/dist/chunk-PMYD4WKR.cjs.map +0 -1
- package/dist/chunk-QHYCWQBH.cjs.map +0 -1
- package/dist/chunk-QWYJETDL.cjs +0 -162
- package/dist/chunk-QWYJETDL.cjs.map +0 -1
- package/dist/chunk-UECRKCKH.js.map +0 -1
- package/dist/chunk-WTTLEGEO.js +0 -162
- package/dist/chunk-WTTLEGEO.js.map +0 -1
- /package/dist/{chunk-RV2PYHCJ.js.map → chunk-4HHYUEMD.js.map} +0 -0
|
@@ -0,0 +1,4514 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }"use client";
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
var _chunkDAAFVOTLcjs = require('./chunk-DAAFVOTL.cjs');
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
var _chunkMEAR2WHScjs = require('./chunk-MEAR2WHS.cjs');
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
var _chunkXL4V2PYGcjs = require('./chunk-XL4V2PYG.cjs');
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
var _chunkTU26IZPOcjs = require('./chunk-TU26IZPO.cjs');
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
var _chunkWBR7H6E3cjs = require('./chunk-WBR7H6E3.cjs');
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
var _chunkZ4IBEIWDcjs = require('./chunk-Z4IBEIWD.cjs');
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
var _chunkFIG2RKZFcjs = require('./chunk-FIG2RKZF.cjs');
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
var _chunkC6ASEPZLcjs = require('./chunk-C6ASEPZL.cjs');
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
var _chunkWZW7C7TFcjs = require('./chunk-WZW7C7TF.cjs');
|
|
55
|
+
|
|
56
|
+
// src/components/ui/hidden-tags-popup.tsx
|
|
57
|
+
var _react = require('react'); var React = _interopRequireWildcard(_react); var React2 = _interopRequireWildcard(_react); var React4 = _interopRequireWildcard(_react); var React6 = _interopRequireWildcard(_react); var React5 = _interopRequireWildcard(_react); var React22 = _interopRequireWildcard(_react); var React12 = _interopRequireWildcard(_react);
|
|
58
|
+
_chunkFIG2RKZFcjs.init_cn.call(void 0, );
|
|
59
|
+
var _jsxruntime = require('react/jsx-runtime');
|
|
60
|
+
var HiddenTagsPopup = _react.forwardRef.call(void 0, function HiddenTagsPopup2({ items, onRemove, disabled, className, style }, ref) {
|
|
61
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
62
|
+
"div",
|
|
63
|
+
{
|
|
64
|
+
ref,
|
|
65
|
+
style,
|
|
66
|
+
className: _chunkFIG2RKZFcjs.cn.call(void 0,
|
|
67
|
+
"absolute top-full left-0 mt-1 z-50 min-w-[200px]",
|
|
68
|
+
"bg-ods-card border border-ods-border rounded-[6px] shadow-lg",
|
|
69
|
+
"animate-in fade-in-0 zoom-in-95 duration-150",
|
|
70
|
+
className
|
|
71
|
+
),
|
|
72
|
+
children: items.map((item) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
73
|
+
"div",
|
|
74
|
+
{
|
|
75
|
+
className: _chunkFIG2RKZFcjs.cn.call(void 0,
|
|
76
|
+
"flex items-center justify-between gap-3 px-3 h-11 md:h-12",
|
|
77
|
+
"border-b border-ods-border last:border-b-0"
|
|
78
|
+
),
|
|
79
|
+
children: [
|
|
80
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-h5 truncate uppercase text-ods-text-primary", title: typeof item.label === "string" ? item.label : void 0, children: item.label }),
|
|
81
|
+
!disabled && onRemove && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
82
|
+
"button",
|
|
83
|
+
{
|
|
84
|
+
type: "button",
|
|
85
|
+
onClick: (e) => {
|
|
86
|
+
e.stopPropagation();
|
|
87
|
+
onRemove(item.value);
|
|
88
|
+
},
|
|
89
|
+
className: "shrink-0 text-ods-text-secondary hover:text-ods-text-primary transition-colors",
|
|
90
|
+
"aria-label": `Remove ${String(item.label)}`,
|
|
91
|
+
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkC6ASEPZLcjs.XmarkCircleIcon, { size: 20 })
|
|
92
|
+
}
|
|
93
|
+
)
|
|
94
|
+
]
|
|
95
|
+
},
|
|
96
|
+
String(item.value)
|
|
97
|
+
))
|
|
98
|
+
}
|
|
99
|
+
);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// src/components/ui/tag.tsx
|
|
103
|
+
var _classvarianceauthority = require('class-variance-authority');
|
|
104
|
+
_chunkFIG2RKZFcjs.init_cn.call(void 0, );
|
|
105
|
+
|
|
106
|
+
var tagVariants = _classvarianceauthority.cva.call(void 0,
|
|
107
|
+
[
|
|
108
|
+
"text-h5 h-8 inline-flex items-center justify-center gap-[var(--spacing-system-xxs)] p-[var(--spacing-system-xsf)] rounded-md",
|
|
109
|
+
"transition-colors duration-150"
|
|
110
|
+
],
|
|
111
|
+
{
|
|
112
|
+
variants: {
|
|
113
|
+
variant: {
|
|
114
|
+
primary: [
|
|
115
|
+
"bg-[var(--ods-open-yellow-base)] text-[var(--ods-system-greys-black)]",
|
|
116
|
+
"hover:bg-[var(--ods-open-yellow-hover)] active:bg-[var(--ods-open-yellow-action)]"
|
|
117
|
+
],
|
|
118
|
+
outline: [
|
|
119
|
+
"bg-[var(--ods-system-greys-black)] text-[var(--ods-system-greys-white)] border border-[var(--ods-system-greys-soft-grey)]",
|
|
120
|
+
"hover:bg-[var(--ods-system-greys-black-hover)] hover:border-[var(--ods-system-greys-soft-grey-hover)]",
|
|
121
|
+
"active:bg-[var(--ods-system-greys-black-action)] active:border-[var(--ods-system-greys-soft-grey-action)]"
|
|
122
|
+
],
|
|
123
|
+
success: [
|
|
124
|
+
"bg-[var(--ods-attention-green-success-secondary)] text-[var(--ods-attention-green-success)]",
|
|
125
|
+
"hover:bg-[#385029] active:bg-[#425a33]"
|
|
126
|
+
],
|
|
127
|
+
warning: [
|
|
128
|
+
"bg-[var(--ods-attention-yellow-warning-secondary)] text-[var(--ods-attention-yellow-warning)]",
|
|
129
|
+
"hover:bg-[#544729] active:bg-[#5e5133]"
|
|
130
|
+
],
|
|
131
|
+
error: [
|
|
132
|
+
"bg-[var(--ods-attention-red-error-secondary)] text-[var(--ods-attention-red-error)]",
|
|
133
|
+
"hover:bg-[#542b2b] active:bg-[#5e3535]"
|
|
134
|
+
],
|
|
135
|
+
critical: [
|
|
136
|
+
"bg-[var(--ods-attention-red-error)] text-[var(--ods-attention-red-error-secondary)]",
|
|
137
|
+
"hover:bg-[var(--ods-attention-red-error-hover)] active:bg-[var(--ods-attention-red-error-action)]"
|
|
138
|
+
],
|
|
139
|
+
grey: [
|
|
140
|
+
"bg-[var(--ods-system-greys-soft-grey)] text-[var(--ods-system-greys-grey)]",
|
|
141
|
+
"hover:bg-[var(--ods-system-greys-soft-grey-hover)] active:bg-[var(--ods-system-greys-soft-grey-action)]"
|
|
142
|
+
],
|
|
143
|
+
// Matches the EntityTagBadges / StatusBadge tag skin (ods-card + ods-border,
|
|
144
|
+
// mono uppercase) so the tag-editor chips render identically to the public
|
|
145
|
+
// tag badges. Used for FilterChipData variant 'tag' (see search-input).
|
|
146
|
+
badge: [
|
|
147
|
+
"bg-ods-card text-ods-text-primary border border-ods-border font-mono uppercase tracking-wide",
|
|
148
|
+
"hover:border-ods-accent transition-colors"
|
|
149
|
+
]
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
defaultVariants: {
|
|
153
|
+
variant: "primary"
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
);
|
|
157
|
+
var disabledTagClasses = [
|
|
158
|
+
"bg-[var(--ods-system-greys-soft-grey)] text-[var(--ods-system-greys-grey)]",
|
|
159
|
+
"border-transparent",
|
|
160
|
+
"cursor-not-allowed",
|
|
161
|
+
"pointer-events-none"
|
|
162
|
+
];
|
|
163
|
+
function Tag({
|
|
164
|
+
label,
|
|
165
|
+
variant,
|
|
166
|
+
icon,
|
|
167
|
+
onClose,
|
|
168
|
+
className,
|
|
169
|
+
labelClassName,
|
|
170
|
+
disabled,
|
|
171
|
+
...props
|
|
172
|
+
}) {
|
|
173
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
174
|
+
"div",
|
|
175
|
+
{
|
|
176
|
+
className: _chunkFIG2RKZFcjs.cn.call(void 0,
|
|
177
|
+
tagVariants({ variant }),
|
|
178
|
+
disabled && disabledTagClasses,
|
|
179
|
+
className
|
|
180
|
+
),
|
|
181
|
+
"aria-disabled": disabled || void 0,
|
|
182
|
+
...props,
|
|
183
|
+
children: [
|
|
184
|
+
icon && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "flex items-center justify-center size-5 shrink-0", children: icon }),
|
|
185
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: _chunkFIG2RKZFcjs.cn.call(void 0, "truncate", labelClassName), title: typeof label === "string" ? label : void 0, children: label }),
|
|
186
|
+
onClose && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
187
|
+
"button",
|
|
188
|
+
{
|
|
189
|
+
type: "button",
|
|
190
|
+
disabled,
|
|
191
|
+
onClick: (e) => {
|
|
192
|
+
e.stopPropagation();
|
|
193
|
+
onClose();
|
|
194
|
+
},
|
|
195
|
+
className: _chunkFIG2RKZFcjs.cn.call(void 0,
|
|
196
|
+
"flex items-center justify-center size-5 shrink-0 rounded-full opacity-70 transition-opacity",
|
|
197
|
+
disabled ? "cursor-not-allowed" : "hover:opacity-100"
|
|
198
|
+
),
|
|
199
|
+
"aria-label": "Remove",
|
|
200
|
+
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkC6ASEPZLcjs.XmarkCircleIcon, { className: "size-4" })
|
|
201
|
+
}
|
|
202
|
+
)
|
|
203
|
+
]
|
|
204
|
+
}
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// src/components/ui/card.tsx
|
|
209
|
+
_chunkFIG2RKZFcjs.init_cn.call(void 0, );
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
var Card = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
213
|
+
"div",
|
|
214
|
+
{
|
|
215
|
+
ref,
|
|
216
|
+
className: _chunkFIG2RKZFcjs.cn.call(void 0,
|
|
217
|
+
"rounded-lg border bg-card text-card-foreground shadow-sm",
|
|
218
|
+
className
|
|
219
|
+
),
|
|
220
|
+
...props
|
|
221
|
+
}
|
|
222
|
+
));
|
|
223
|
+
Card.displayName = "Card";
|
|
224
|
+
var CardHeader = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
225
|
+
"div",
|
|
226
|
+
{
|
|
227
|
+
ref,
|
|
228
|
+
className: _chunkFIG2RKZFcjs.cn.call(void 0, "flex flex-col space-y-1.5 p-6", className),
|
|
229
|
+
...props
|
|
230
|
+
}
|
|
231
|
+
));
|
|
232
|
+
CardHeader.displayName = "CardHeader";
|
|
233
|
+
var CardTitle = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
234
|
+
"div",
|
|
235
|
+
{
|
|
236
|
+
ref,
|
|
237
|
+
className: _chunkFIG2RKZFcjs.cn.call(void 0,
|
|
238
|
+
"text-2xl font-semibold leading-none tracking-tight",
|
|
239
|
+
className
|
|
240
|
+
),
|
|
241
|
+
...props
|
|
242
|
+
}
|
|
243
|
+
));
|
|
244
|
+
CardTitle.displayName = "CardTitle";
|
|
245
|
+
var CardDescription = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
246
|
+
"div",
|
|
247
|
+
{
|
|
248
|
+
ref,
|
|
249
|
+
className: _chunkFIG2RKZFcjs.cn.call(void 0, "text-sm text-muted-foreground", className),
|
|
250
|
+
...props
|
|
251
|
+
}
|
|
252
|
+
));
|
|
253
|
+
CardDescription.displayName = "CardDescription";
|
|
254
|
+
var CardContent = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { ref, className: _chunkFIG2RKZFcjs.cn.call(void 0, "p-6 pt-0", className), ...props }));
|
|
255
|
+
CardContent.displayName = "CardContent";
|
|
256
|
+
var CardFooter = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
257
|
+
"div",
|
|
258
|
+
{
|
|
259
|
+
ref,
|
|
260
|
+
className: _chunkFIG2RKZFcjs.cn.call(void 0, "flex items-center p-6 pt-0", className),
|
|
261
|
+
...props
|
|
262
|
+
}
|
|
263
|
+
));
|
|
264
|
+
CardFooter.displayName = "CardFooter";
|
|
265
|
+
function CardHorizontal({ icon, title, description, className = "", borderLeft = true }) {
|
|
266
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
267
|
+
"div",
|
|
268
|
+
{
|
|
269
|
+
className: _chunkFIG2RKZFcjs.cn.call(void 0,
|
|
270
|
+
"w-full flex flex-row items-center gap-3 md:gap-4 bg-ods-card p-4 md:p-6 min-h-[80px]",
|
|
271
|
+
borderLeft ? "border-l border-ods-border" : "",
|
|
272
|
+
className
|
|
273
|
+
),
|
|
274
|
+
children: [
|
|
275
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-5 h-5 flex-shrink-0", children: icon }),
|
|
276
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col min-w-0", children: [
|
|
277
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "font-medium text-sm md:text-sm text-ods-text-primary leading-tight mb-0.5 text-left", children: title }),
|
|
278
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-xs md:text-sm text-ods-text-secondary leading-tight text-left", children: description })
|
|
279
|
+
] })
|
|
280
|
+
]
|
|
281
|
+
}
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// src/components/ui/tabs.tsx
|
|
286
|
+
_chunkFIG2RKZFcjs.init_cn.call(void 0, );
|
|
287
|
+
|
|
288
|
+
var _reacttabs = require('@radix-ui/react-tabs'); var TabsPrimitive = _interopRequireWildcard(_reacttabs);
|
|
289
|
+
|
|
290
|
+
var Tabs = TabsPrimitive.Root;
|
|
291
|
+
var TabsList = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
292
|
+
TabsPrimitive.List,
|
|
293
|
+
{
|
|
294
|
+
ref,
|
|
295
|
+
className: _chunkFIG2RKZFcjs.cn.call(void 0,
|
|
296
|
+
"inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground",
|
|
297
|
+
className
|
|
298
|
+
),
|
|
299
|
+
...props
|
|
300
|
+
}
|
|
301
|
+
));
|
|
302
|
+
TabsList.displayName = TabsPrimitive.List.displayName;
|
|
303
|
+
var TabsTrigger = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
304
|
+
TabsPrimitive.Trigger,
|
|
305
|
+
{
|
|
306
|
+
ref,
|
|
307
|
+
className: _chunkFIG2RKZFcjs.cn.call(void 0,
|
|
308
|
+
"inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
|
|
309
|
+
className
|
|
310
|
+
),
|
|
311
|
+
...props
|
|
312
|
+
}
|
|
313
|
+
));
|
|
314
|
+
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
|
|
315
|
+
var TabsContent = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
316
|
+
TabsPrimitive.Content,
|
|
317
|
+
{
|
|
318
|
+
ref,
|
|
319
|
+
className: _chunkFIG2RKZFcjs.cn.call(void 0,
|
|
320
|
+
"mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
321
|
+
className
|
|
322
|
+
),
|
|
323
|
+
...props
|
|
324
|
+
}
|
|
325
|
+
));
|
|
326
|
+
TabsContent.displayName = TabsPrimitive.Content.displayName;
|
|
327
|
+
|
|
328
|
+
// src/components/ui/status-badge.tsx
|
|
329
|
+
_chunkFIG2RKZFcjs.init_cn.call(void 0, );
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
var statusBadgeVariants = _classvarianceauthority.cva.call(void 0,
|
|
333
|
+
"inline-flex items-center justify-center rounded font-mono font-medium uppercase tracking-wide",
|
|
334
|
+
{
|
|
335
|
+
variants: {
|
|
336
|
+
variant: {
|
|
337
|
+
card: "px-3 py-1.5 text-sm",
|
|
338
|
+
button: "px-2 py-0.5 text-[10px] leading-none"
|
|
339
|
+
},
|
|
340
|
+
colorScheme: {
|
|
341
|
+
cyan: "bg-[var(--ods-flamingo-cyan-base)] text-ods-text-on-accent",
|
|
342
|
+
pink: "bg-[var(--ods-flamingo-pink-base)] text-ods-text-on-accent",
|
|
343
|
+
yellow: "bg-[var(--ods-flamingo-yellow-base)] text-ods-text-on-accent border border-[var(--ods-system-greys-black)]",
|
|
344
|
+
green: "bg-[var(--ods-flamingo-green-base)] text-ods-text-on-accent",
|
|
345
|
+
purple: "bg-[var(--ods-flamingo-purple-base)] text-ods-text-on-accent",
|
|
346
|
+
success: "bg-[var(--ods-attention-green-success-secondary)] text-[var(--ods-attention-green-success)]",
|
|
347
|
+
error: "bg-[var(--ods-attention-red-error-secondary)] text-[var(--ods-attention-red-error)]",
|
|
348
|
+
warning: "bg-[var(--ods-attention-yellow-warning-secondary)] text-[var(--ods-attention-yellow-warning)]",
|
|
349
|
+
default: "bg-ods-bg-secondary text-ods-text-primary",
|
|
350
|
+
// Border-only variants (no background) - for task type badges
|
|
351
|
+
accentBorder: "bg-transparent border-2 text-ods-accent border-ods-accent",
|
|
352
|
+
errorBorder: "bg-transparent border-2 text-[var(--ods-attention-red-error)] border-[var(--ods-attention-red-error)]",
|
|
353
|
+
whiteBorder: "bg-transparent border-2 text-ods-text-primary border-ods-text-primary"
|
|
354
|
+
}
|
|
355
|
+
},
|
|
356
|
+
defaultVariants: {
|
|
357
|
+
variant: "card",
|
|
358
|
+
colorScheme: "default"
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
);
|
|
362
|
+
function StatusBadge({
|
|
363
|
+
text,
|
|
364
|
+
variant,
|
|
365
|
+
colorScheme,
|
|
366
|
+
className,
|
|
367
|
+
singleLine,
|
|
368
|
+
...props
|
|
369
|
+
}) {
|
|
370
|
+
const renderText = () => {
|
|
371
|
+
if (singleLine) return text;
|
|
372
|
+
if (variant === "button" && text.includes(" ")) {
|
|
373
|
+
const words = text.split(" ");
|
|
374
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "flex flex-col items-center justify-center text-center gap-0", children: words.map((word, index) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "block", children: word }, index)) });
|
|
375
|
+
}
|
|
376
|
+
return text;
|
|
377
|
+
};
|
|
378
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
379
|
+
"span",
|
|
380
|
+
{
|
|
381
|
+
className: _chunkFIG2RKZFcjs.cn.call(void 0, statusBadgeVariants({ variant, colorScheme }), className),
|
|
382
|
+
...props,
|
|
383
|
+
children: renderText()
|
|
384
|
+
}
|
|
385
|
+
);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// src/components/ui/simple-markdown-renderer.tsx
|
|
389
|
+
|
|
390
|
+
var _reactmarkdown = require('react-markdown'); var _reactmarkdown2 = _interopRequireDefault(_reactmarkdown);
|
|
391
|
+
var _remarkgfm = require('remark-gfm'); var _remarkgfm2 = _interopRequireDefault(_remarkgfm);
|
|
392
|
+
var _remarkbreaks = require('remark-breaks'); var _remarkbreaks2 = _interopRequireDefault(_remarkbreaks);
|
|
393
|
+
var _rehypehighlight = require('rehype-highlight'); var _rehypehighlight2 = _interopRequireDefault(_rehypehighlight);
|
|
394
|
+
var _rehyperaw = require('rehype-raw'); var _rehyperaw2 = _interopRequireDefault(_rehyperaw);
|
|
395
|
+
var _unistutilvisit = require('unist-util-visit');
|
|
396
|
+
_chunkFIG2RKZFcjs.init_cn.call(void 0, );
|
|
397
|
+
|
|
398
|
+
var EVENT_HANDLER_ATTR_RE = /^on[a-z]+$/i;
|
|
399
|
+
var JAVASCRIPT_URL_RE = /^[\s\x00-\x1f]*javascript:/i;
|
|
400
|
+
var DATA_URL_RE = /^[\s\x00-\x1f]*data:/i;
|
|
401
|
+
var URL_ATTRS = /* @__PURE__ */ new Set([
|
|
402
|
+
"href",
|
|
403
|
+
"src",
|
|
404
|
+
// `srcset` accepts `javascript:` on legacy browsers — same guard
|
|
405
|
+
// as the canonical hast-util-sanitize default schema's attr set.
|
|
406
|
+
// Multi-candidate scanning lives in `srcsetHasUnsafeCandidate` below;
|
|
407
|
+
// a single-URL check would miss a malicious second candidate like
|
|
408
|
+
// `"https://safe.png 1x, javascript:alert(1) 2x"`.
|
|
409
|
+
"srcset",
|
|
410
|
+
"formaction",
|
|
411
|
+
"xlink:href",
|
|
412
|
+
"poster",
|
|
413
|
+
"data",
|
|
414
|
+
"action",
|
|
415
|
+
"background"
|
|
416
|
+
]);
|
|
417
|
+
function srcsetHasUnsafeCandidate(srcset) {
|
|
418
|
+
for (const candidate of srcset.split(",")) {
|
|
419
|
+
const url = _nullishCoalesce(candidate.trim().split(/\s+/)[0], () => ( ""));
|
|
420
|
+
if (JAVASCRIPT_URL_RE.test(url) || DATA_URL_RE.test(url)) return true;
|
|
421
|
+
}
|
|
422
|
+
return false;
|
|
423
|
+
}
|
|
424
|
+
var STRIP_ELEMENTS = /* @__PURE__ */ new Set([
|
|
425
|
+
"script",
|
|
426
|
+
"style",
|
|
427
|
+
"noscript",
|
|
428
|
+
"noembed",
|
|
429
|
+
"object",
|
|
430
|
+
"embed",
|
|
431
|
+
"applet",
|
|
432
|
+
"base",
|
|
433
|
+
"meta"
|
|
434
|
+
]);
|
|
435
|
+
function rehypeStripUnsafe() {
|
|
436
|
+
return (tree) => {
|
|
437
|
+
_unistutilvisit.visit.call(void 0, tree, "element", (node, index, parent) => {
|
|
438
|
+
const tag = String(_nullishCoalesce(node.tagName, () => ( ""))).toLowerCase();
|
|
439
|
+
if (STRIP_ELEMENTS.has(tag)) {
|
|
440
|
+
if (parent && typeof index === "number") {
|
|
441
|
+
parent.children.splice(index, 1);
|
|
442
|
+
return index;
|
|
443
|
+
}
|
|
444
|
+
node.children = [];
|
|
445
|
+
node.tagName = "span";
|
|
446
|
+
node.properties = {};
|
|
447
|
+
return;
|
|
448
|
+
}
|
|
449
|
+
if (!node.properties || typeof node.properties !== "object") return;
|
|
450
|
+
for (const key of Object.keys(node.properties)) {
|
|
451
|
+
if (EVENT_HANDLER_ATTR_RE.test(key)) {
|
|
452
|
+
delete node.properties[key];
|
|
453
|
+
continue;
|
|
454
|
+
}
|
|
455
|
+
if (URL_ATTRS.has(key.toLowerCase())) {
|
|
456
|
+
const raw = node.properties[key];
|
|
457
|
+
const v = Array.isArray(raw) ? raw[0] : raw;
|
|
458
|
+
if (typeof v === "string") {
|
|
459
|
+
const unsafe = key.toLowerCase() === "srcset" ? srcsetHasUnsafeCandidate(v) : JAVASCRIPT_URL_RE.test(v) || DATA_URL_RE.test(v);
|
|
460
|
+
if (unsafe) {
|
|
461
|
+
delete node.properties[key];
|
|
462
|
+
continue;
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
if (tag === "iframe" && key.toLowerCase() === "srcdoc") {
|
|
467
|
+
delete node.properties[key];
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
});
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
function cardAwareUrlTransform(url, key) {
|
|
474
|
+
if (key === "href" && typeof url === "string" && url.startsWith("card://")) return url;
|
|
475
|
+
return _reactmarkdown.defaultUrlTransform.call(void 0, url);
|
|
476
|
+
}
|
|
477
|
+
var SAFE_HTML_TAGS = /* @__PURE__ */ new Set([
|
|
478
|
+
// Block + inline text
|
|
479
|
+
"a",
|
|
480
|
+
"abbr",
|
|
481
|
+
"address",
|
|
482
|
+
"article",
|
|
483
|
+
"aside",
|
|
484
|
+
"b",
|
|
485
|
+
"bdi",
|
|
486
|
+
"bdo",
|
|
487
|
+
"blockquote",
|
|
488
|
+
"br",
|
|
489
|
+
"caption",
|
|
490
|
+
"cite",
|
|
491
|
+
"code",
|
|
492
|
+
"col",
|
|
493
|
+
"colgroup",
|
|
494
|
+
"data",
|
|
495
|
+
"dd",
|
|
496
|
+
"del",
|
|
497
|
+
"details",
|
|
498
|
+
"dfn",
|
|
499
|
+
"div",
|
|
500
|
+
"dl",
|
|
501
|
+
"dt",
|
|
502
|
+
"em",
|
|
503
|
+
"figcaption",
|
|
504
|
+
"figure",
|
|
505
|
+
"footer",
|
|
506
|
+
"h1",
|
|
507
|
+
"h2",
|
|
508
|
+
"h3",
|
|
509
|
+
"h4",
|
|
510
|
+
"h5",
|
|
511
|
+
"h6",
|
|
512
|
+
"header",
|
|
513
|
+
"hgroup",
|
|
514
|
+
"hr",
|
|
515
|
+
"i",
|
|
516
|
+
"ins",
|
|
517
|
+
"kbd",
|
|
518
|
+
"li",
|
|
519
|
+
"main",
|
|
520
|
+
"mark",
|
|
521
|
+
"nav",
|
|
522
|
+
"ol",
|
|
523
|
+
"p",
|
|
524
|
+
"pre",
|
|
525
|
+
"q",
|
|
526
|
+
"rp",
|
|
527
|
+
"rt",
|
|
528
|
+
"ruby",
|
|
529
|
+
"s",
|
|
530
|
+
"samp",
|
|
531
|
+
"section",
|
|
532
|
+
"small",
|
|
533
|
+
"span",
|
|
534
|
+
"strong",
|
|
535
|
+
"sub",
|
|
536
|
+
"summary",
|
|
537
|
+
"sup",
|
|
538
|
+
"table",
|
|
539
|
+
"tbody",
|
|
540
|
+
"td",
|
|
541
|
+
"tfoot",
|
|
542
|
+
"th",
|
|
543
|
+
"thead",
|
|
544
|
+
"time",
|
|
545
|
+
"tr",
|
|
546
|
+
"u",
|
|
547
|
+
"ul",
|
|
548
|
+
"var",
|
|
549
|
+
"wbr",
|
|
550
|
+
// Media
|
|
551
|
+
"img",
|
|
552
|
+
"picture",
|
|
553
|
+
"source",
|
|
554
|
+
"audio",
|
|
555
|
+
"video",
|
|
556
|
+
"iframe",
|
|
557
|
+
"track",
|
|
558
|
+
// Forms (rehype-raw allows them; mostly harmless for chat output)
|
|
559
|
+
"button",
|
|
560
|
+
"input",
|
|
561
|
+
"label",
|
|
562
|
+
"select",
|
|
563
|
+
"option",
|
|
564
|
+
"optgroup",
|
|
565
|
+
"textarea",
|
|
566
|
+
"form",
|
|
567
|
+
"fieldset",
|
|
568
|
+
"legend"
|
|
569
|
+
]);
|
|
570
|
+
var TAG_LIKE_REGEX = /<(\/?)([a-zA-Z][a-zA-Z0-9-]{0,63})((?:\s[^>]{0,4096}?)?)(\/?)>/g;
|
|
571
|
+
function escapeUnknownHtmlTags(text) {
|
|
572
|
+
if (!text || text.indexOf("<") === -1) return text;
|
|
573
|
+
const parts = [];
|
|
574
|
+
let cursor = 0;
|
|
575
|
+
const PROTECTED_SPAN_RE = /```[\s\S]*?```|`[^`\n]+`/g;
|
|
576
|
+
let span;
|
|
577
|
+
while ((span = PROTECTED_SPAN_RE.exec(text)) !== null) {
|
|
578
|
+
if (span.index > cursor) {
|
|
579
|
+
parts.push(escapeOutsideFences(text.slice(cursor, span.index)));
|
|
580
|
+
}
|
|
581
|
+
parts.push(span[0]);
|
|
582
|
+
cursor = span.index + span[0].length;
|
|
583
|
+
}
|
|
584
|
+
if (cursor < text.length) {
|
|
585
|
+
parts.push(escapeOutsideFences(text.slice(cursor)));
|
|
586
|
+
}
|
|
587
|
+
return parts.join("");
|
|
588
|
+
}
|
|
589
|
+
function escapeOutsideFences(segment) {
|
|
590
|
+
return segment.replace(TAG_LIKE_REGEX, (match, slash, tag, rest, selfClose) => {
|
|
591
|
+
const lower = tag.toLowerCase();
|
|
592
|
+
if (SAFE_HTML_TAGS.has(lower)) return match;
|
|
593
|
+
return `<${slash}${tag}${rest}${selfClose}>`;
|
|
594
|
+
});
|
|
595
|
+
}
|
|
596
|
+
var mermaidStyles = `
|
|
597
|
+
.mermaid-svg-container svg {
|
|
598
|
+
max-width: 100% !important;
|
|
599
|
+
height: auto !important;
|
|
600
|
+
min-height: 200px;
|
|
601
|
+
font-family: 'DM Sans', sans-serif !important;
|
|
602
|
+
font-size: 14px !important;
|
|
603
|
+
}
|
|
604
|
+
@media (min-width: 1520px) {
|
|
605
|
+
.mermaid-svg-container svg {
|
|
606
|
+
max-width: 900px !important;
|
|
607
|
+
max-height: 700px !important;
|
|
608
|
+
min-height: 300px;
|
|
609
|
+
font-size: 16px !important;
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
@media (min-width: 768px) and (max-width: 1519px) {
|
|
613
|
+
.mermaid-svg-container svg {
|
|
614
|
+
max-width: 700px !important;
|
|
615
|
+
max-height: 600px !important;
|
|
616
|
+
min-height: 250px;
|
|
617
|
+
font-size: 15px !important;
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
@media (max-width: 767px) {
|
|
621
|
+
.mermaid-svg-container svg {
|
|
622
|
+
max-width: 90vw !important;
|
|
623
|
+
max-height: 400px !important;
|
|
624
|
+
min-height: 200px;
|
|
625
|
+
font-size: 13px !important;
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
.mermaid-svg-container svg[width] { width: 100% !important; }
|
|
629
|
+
.mermaid-svg-container .node rect,
|
|
630
|
+
.mermaid-svg-container .node circle,
|
|
631
|
+
.mermaid-svg-container .node ellipse,
|
|
632
|
+
.mermaid-svg-container .node polygon { stroke-width: 2px !important; }
|
|
633
|
+
.mermaid-svg-container .edgePath path { stroke-width: 2px !important; }
|
|
634
|
+
@media (min-width: 768px) {
|
|
635
|
+
.mermaid-svg-container .node text,
|
|
636
|
+
.mermaid-svg-container .edgeLabel text { font-size: 14px !important; }
|
|
637
|
+
}
|
|
638
|
+
@media (min-width: 1520px) {
|
|
639
|
+
.mermaid-svg-container .node text,
|
|
640
|
+
.mermaid-svg-container .edgeLabel text { font-size: 16px !important; }
|
|
641
|
+
}
|
|
642
|
+
`;
|
|
643
|
+
var MermaidDiagram = ({ chart }) => {
|
|
644
|
+
const [svg, setSvg] = _react.useState.call(void 0, "");
|
|
645
|
+
const [error, setError] = _react.useState.call(void 0, "");
|
|
646
|
+
const [isLoading, setIsLoading] = _react.useState.call(void 0, true);
|
|
647
|
+
const [mounted, setMounted] = _react.useState.call(void 0, false);
|
|
648
|
+
_react.useEffect.call(void 0, () => {
|
|
649
|
+
setMounted(true);
|
|
650
|
+
}, []);
|
|
651
|
+
_react.useEffect.call(void 0, () => {
|
|
652
|
+
const renderMermaid = async () => {
|
|
653
|
+
try {
|
|
654
|
+
setIsLoading(true);
|
|
655
|
+
const { default: mermaid } = await Promise.resolve().then(() => _interopRequireWildcard(require("mermaid")));
|
|
656
|
+
mermaid.initialize({
|
|
657
|
+
startOnLoad: false,
|
|
658
|
+
theme: "dark",
|
|
659
|
+
themeVariables: {
|
|
660
|
+
primaryColor: "#FFC008",
|
|
661
|
+
primaryTextColor: "#FAFAFA",
|
|
662
|
+
primaryBorderColor: "#3A3A3A",
|
|
663
|
+
lineColor: "#888888",
|
|
664
|
+
secondaryColor: "#212121",
|
|
665
|
+
tertiaryColor: "#2A2A2A",
|
|
666
|
+
background: "transparent",
|
|
667
|
+
mainBkg: "transparent",
|
|
668
|
+
secondBkg: "transparent",
|
|
669
|
+
tertiaryBkg: "transparent",
|
|
670
|
+
cScale0: "#FFC008",
|
|
671
|
+
cScale1: "#4ECDC4",
|
|
672
|
+
cScale2: "#45B7D1",
|
|
673
|
+
cScale3: "#96CEB4",
|
|
674
|
+
cScale4: "#FFEAA7",
|
|
675
|
+
cScale5: "#DDA0DD",
|
|
676
|
+
cScale6: "#98D8C8",
|
|
677
|
+
cScale7: "#F7DC6F",
|
|
678
|
+
cScale8: "#BB8FCE",
|
|
679
|
+
cScale9: "#85C1E9",
|
|
680
|
+
taskTextColor: "#FAFAFA",
|
|
681
|
+
taskTextOutsideColor: "#FAFAFA",
|
|
682
|
+
activeTaskTextColor: "#1A1A1A",
|
|
683
|
+
nodeTextColor: "#FAFAFA"
|
|
684
|
+
},
|
|
685
|
+
flowchart: { useMaxWidth: true, htmlLabels: true, rankSpacing: 50, nodeSpacing: 30, curve: "basis" },
|
|
686
|
+
sequence: { useMaxWidth: true, width: 150 },
|
|
687
|
+
pie: { useMaxWidth: true, useWidth: void 0 },
|
|
688
|
+
fontFamily: "DM Sans, sans-serif",
|
|
689
|
+
fontSize: 14,
|
|
690
|
+
securityLevel: "loose"
|
|
691
|
+
});
|
|
692
|
+
const { svg: renderedSvg } = await mermaid.render(`mermaid-${Date.now()}`, chart);
|
|
693
|
+
setSvg(renderedSvg);
|
|
694
|
+
setIsLoading(false);
|
|
695
|
+
} catch (err) {
|
|
696
|
+
console.error("Mermaid rendering error:", err);
|
|
697
|
+
setError(`Failed to render diagram: ${err instanceof Error ? err.message : "Unknown error"}`);
|
|
698
|
+
setIsLoading(false);
|
|
699
|
+
}
|
|
700
|
+
};
|
|
701
|
+
if (mounted) {
|
|
702
|
+
renderMermaid();
|
|
703
|
+
}
|
|
704
|
+
}, [chart, mounted]);
|
|
705
|
+
if (error) {
|
|
706
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "error-state bg-ods-card border border-ods-border rounded-lg p-6 my-6", children: [
|
|
707
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "error-icon flex justify-center mb-4", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkC6ASEPZLcjs.AlertCircleIcon, { className: "w-12 h-12 text-ods-error" }) }),
|
|
708
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "error-title text-center font-sans font-semibold text-lg text-ods-error mb-2", children: "Diagram Error" }),
|
|
709
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "error-description text-center font-sans text-sm text-ods-text-secondary mb-4 break-words overflow-hidden max-w-full", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "overflow-x-auto", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "pre", { className: "whitespace-pre-wrap break-words text-xs", children: error }) }) })
|
|
710
|
+
] });
|
|
711
|
+
}
|
|
712
|
+
if (isLoading || !svg) {
|
|
713
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "skeleton-code bg-ods-card border border-ods-border rounded-lg p-6 min-h-[120px] flex items-center justify-center", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "animate-pulse text-ods-text-tertiary font-sans", children: isLoading ? "Loading diagram renderer..." : "Rendering diagram..." }) });
|
|
714
|
+
}
|
|
715
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "mermaid-container rounded-lg p-4 md:p-6 lg:p-8 my-6 overflow-x-auto bg-ods-card border border-ods-border", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex justify-center items-center w-full min-h-[200px] md:min-h-[250px] lg:min-h-[300px]", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
716
|
+
"div",
|
|
717
|
+
{
|
|
718
|
+
className: "mermaid-svg-container w-full flex justify-center max-w-full",
|
|
719
|
+
style: { fontSize: "14px" },
|
|
720
|
+
dangerouslySetInnerHTML: {
|
|
721
|
+
__html: svg.replace(
|
|
722
|
+
/<svg[^>]*>/,
|
|
723
|
+
(match) => match.replace(/width="[^"]*"/, 'width="100%"').replace(/height="[^"]*"/, 'height="auto"')
|
|
724
|
+
)
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
) }) });
|
|
728
|
+
};
|
|
729
|
+
function extractText(node) {
|
|
730
|
+
if (typeof node === "string") return node;
|
|
731
|
+
if (Array.isArray(node)) return node.map(extractText).join("");
|
|
732
|
+
if (_optionalChain([node, 'optionalAccess', _ => _.props, 'optionalAccess', _2 => _2.children])) return extractText(node.props.children);
|
|
733
|
+
return "";
|
|
734
|
+
}
|
|
735
|
+
var TEXT_SIZE_PRESETS = {
|
|
736
|
+
default: {
|
|
737
|
+
h1: "text-heading-1",
|
|
738
|
+
h2: "text-heading-2",
|
|
739
|
+
h3: "text-2xl md:text-3xl",
|
|
740
|
+
h4: "text-xl",
|
|
741
|
+
h5: "text-lg md:text-xl",
|
|
742
|
+
h6: "text-base md:text-lg",
|
|
743
|
+
p: "md:text-h4 lg:text-h4",
|
|
744
|
+
li: "text-base md:text-lg",
|
|
745
|
+
blockquote: "text-lg",
|
|
746
|
+
code: "text-[14px]",
|
|
747
|
+
th: "text-xs md:text-sm",
|
|
748
|
+
td: "text-xs md:text-sm"
|
|
749
|
+
},
|
|
750
|
+
compact: {
|
|
751
|
+
h1: "text-heading-2",
|
|
752
|
+
h2: "text-heading-3",
|
|
753
|
+
h3: "text-xl md:text-2xl",
|
|
754
|
+
h4: "text-lg md:text-xl",
|
|
755
|
+
h5: "text-base md:text-lg",
|
|
756
|
+
h6: "text-sm md:text-base",
|
|
757
|
+
p: "text-base md:text-lg",
|
|
758
|
+
li: "text-base md:text-lg",
|
|
759
|
+
blockquote: "text-base md:text-lg",
|
|
760
|
+
code: "text-[13px]",
|
|
761
|
+
th: "text-xs md:text-sm",
|
|
762
|
+
td: "text-xs md:text-sm"
|
|
763
|
+
},
|
|
764
|
+
large: {
|
|
765
|
+
h1: "text-heading-1",
|
|
766
|
+
h2: "text-heading-1",
|
|
767
|
+
h3: "text-heading-2",
|
|
768
|
+
h4: "text-2xl md:text-3xl",
|
|
769
|
+
h5: "text-xl md:text-2xl",
|
|
770
|
+
h6: "text-lg md:text-xl",
|
|
771
|
+
p: "text-h3",
|
|
772
|
+
li: "text-lg md:text-xl",
|
|
773
|
+
blockquote: "text-xl md:text-2xl",
|
|
774
|
+
code: "text-[16px]",
|
|
775
|
+
th: "text-sm md:text-base",
|
|
776
|
+
td: "text-sm md:text-base"
|
|
777
|
+
}
|
|
778
|
+
};
|
|
779
|
+
function resolveTextSizeConfig(config) {
|
|
780
|
+
const defaultSizes = TEXT_SIZE_PRESETS.default;
|
|
781
|
+
if (!config) return defaultSizes;
|
|
782
|
+
if (typeof config === "string") return TEXT_SIZE_PRESETS[config];
|
|
783
|
+
if ("preset" in config) return { ...TEXT_SIZE_PRESETS[config.preset], ...config.overrides };
|
|
784
|
+
return { ...defaultSizes, ...config };
|
|
785
|
+
}
|
|
786
|
+
var SimpleMarkdownRendererImpl = ({
|
|
787
|
+
content,
|
|
788
|
+
className = "",
|
|
789
|
+
sectionIds,
|
|
790
|
+
demoteMarkdownH1ToH2 = false,
|
|
791
|
+
brokenLinks = [],
|
|
792
|
+
onInternalLinkClick,
|
|
793
|
+
currentPath: propCurrentPath,
|
|
794
|
+
onResolveLink,
|
|
795
|
+
preprocessContent,
|
|
796
|
+
componentOverrides,
|
|
797
|
+
textSize,
|
|
798
|
+
additionalRemarkPlugins
|
|
799
|
+
}) => {
|
|
800
|
+
const idCountsRef = _react.useRef.call(void 0, {});
|
|
801
|
+
const textSizes = _react.useMemo.call(void 0, () => resolveTextSizeConfig(textSize), [textSize]);
|
|
802
|
+
const sectionIdMap = _react.useMemo.call(void 0, () => {
|
|
803
|
+
const map = /* @__PURE__ */ new Map();
|
|
804
|
+
if (sectionIds) {
|
|
805
|
+
sectionIds.forEach((section) => {
|
|
806
|
+
const cleanTitle = section.title.replace(/[\u{1F300}-\u{1F9FF}]|[\u{2600}-\u{26FF}]|[\u{2700}-\u{27BF}]/gu, "").trim().toLowerCase();
|
|
807
|
+
map.set(section.title.toLowerCase(), section.id);
|
|
808
|
+
map.set(cleanTitle, section.id);
|
|
809
|
+
map.set(section.title, section.id);
|
|
810
|
+
});
|
|
811
|
+
}
|
|
812
|
+
return map;
|
|
813
|
+
}, [sectionIds]);
|
|
814
|
+
const generateHeadingId = _react.useCallback.call(void 0, (text, level) => {
|
|
815
|
+
if (sectionIds && (level === 1 || level === 2)) {
|
|
816
|
+
const variations = [
|
|
817
|
+
text,
|
|
818
|
+
text.toLowerCase(),
|
|
819
|
+
text.replace(/[\u{1F300}-\u{1F9FF}]|[\u{2600}-\u{26FF}]|[\u{2700}-\u{27BF}]/gu, "").trim(),
|
|
820
|
+
text.replace(/[\u{1F300}-\u{1F9FF}]|[\u{2600}-\u{26FF}]|[\u{2700}-\u{27BF}]/gu, "").trim().toLowerCase()
|
|
821
|
+
];
|
|
822
|
+
for (const v of variations) {
|
|
823
|
+
const id = sectionIdMap.get(v);
|
|
824
|
+
if (id) return id;
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
const baseId = text.replace(/[\u{1F300}-\u{1F9FF}]|[\u{2600}-\u{26FF}]|[\u{2700}-\u{27BF}]/gu, "").trim().toLowerCase().replace(/[^\w\s-]/g, "").replace(/\s+/g, "-").replace(/^-+|-+$/g, "");
|
|
828
|
+
const cleanId = baseId || `section-${Object.keys(idCountsRef.current).length + 1}`;
|
|
829
|
+
if (idCountsRef.current[cleanId]) {
|
|
830
|
+
idCountsRef.current[cleanId]++;
|
|
831
|
+
return `${cleanId}-${idCountsRef.current[cleanId]}`;
|
|
832
|
+
}
|
|
833
|
+
idCountsRef.current[cleanId] = 1;
|
|
834
|
+
return cleanId;
|
|
835
|
+
}, [sectionIds, sectionIdMap]);
|
|
836
|
+
const processedContent = _react.useMemo.call(void 0,
|
|
837
|
+
() => escapeUnknownHtmlTags(preprocessContent ? preprocessContent(content) : content),
|
|
838
|
+
[preprocessContent, content]
|
|
839
|
+
);
|
|
840
|
+
const makeHeading = _react.useCallback.call(void 0,
|
|
841
|
+
(Tag2, level, headingClassName) => ({ children }) => {
|
|
842
|
+
const text = extractText(children);
|
|
843
|
+
const effectiveLevel = Tag2 === "h1" && demoteMarkdownH1ToH2 ? 2 : level;
|
|
844
|
+
const id = generateHeadingId(text, effectiveLevel);
|
|
845
|
+
const EffectiveTag = Tag2 === "h1" && demoteMarkdownH1ToH2 ? "h2" : Tag2;
|
|
846
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, EffectiveTag, { id, className: headingClassName, children });
|
|
847
|
+
},
|
|
848
|
+
[generateHeadingId, demoteMarkdownH1ToH2]
|
|
849
|
+
);
|
|
850
|
+
const components = _react.useMemo.call(void 0, () => ({
|
|
851
|
+
// --- code ---
|
|
852
|
+
code: ({ node, inline, className: codeClassName, children, ...props }) => {
|
|
853
|
+
const match = /language-(\w+)/.exec(codeClassName || "");
|
|
854
|
+
const language = match ? match[1] : "";
|
|
855
|
+
if (!inline && language === "mermaid") {
|
|
856
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, MermaidDiagram, { chart: String(children).replace(/\n$/, "") });
|
|
857
|
+
}
|
|
858
|
+
if (!inline && match) {
|
|
859
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "code-block-container border rounded-lg my-6 overflow-hidden bg-ods-card border-ods-border", children: [
|
|
860
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "code-header border-b px-4 py-2 bg-ods-card border-ods-border", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "font-sans text-xs uppercase tracking-wide text-ods-text-tertiary", children: language || "code" }) }),
|
|
861
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "p-4", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "pre", { className: "overflow-x-auto", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
862
|
+
"code",
|
|
863
|
+
{
|
|
864
|
+
className: _chunkFIG2RKZFcjs.cn.call(void 0, `language-${language} hljs`, textSizes.code),
|
|
865
|
+
style: {
|
|
866
|
+
fontFamily: "JetBrains Mono', 'SF Mono', Consolas, monospace",
|
|
867
|
+
background: "transparent",
|
|
868
|
+
color: "var(--ods-text-primary)"
|
|
869
|
+
},
|
|
870
|
+
...props,
|
|
871
|
+
children
|
|
872
|
+
}
|
|
873
|
+
) }) })
|
|
874
|
+
] });
|
|
875
|
+
}
|
|
876
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "code", { className: "font-mono text-[0.9em] px-1.5 py-0.5 rounded border bg-ods-card text-ods-text-primary border-ods-border", ...props, children });
|
|
877
|
+
},
|
|
878
|
+
// --- div (pass-through, overridable for embeds) ---
|
|
879
|
+
div: ({ node, className: divClassName, children, ...props }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: divClassName, ...props, children }),
|
|
880
|
+
// --- blockquote ---
|
|
881
|
+
blockquote: ({ children }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "blockquote", { className: "border-l-4 border-ods-accent ml-0 pl-6 my-8 py-4 rounded-r-lg bg-ods-bg-secondary", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: _chunkFIG2RKZFcjs.cn.call(void 0, "font-sans leading-relaxed text-ods-text-secondary", textSizes.blockquote), children }) }),
|
|
882
|
+
// --- headings ---
|
|
883
|
+
h1: makeHeading("h1", 1, _chunkFIG2RKZFcjs.cn.call(void 0, "font-sans font-bold mt-8 mb-4 first:mt-0 text-ods-text-primary", textSizes.h1)),
|
|
884
|
+
h2: makeHeading("h2", 2, _chunkFIG2RKZFcjs.cn.call(void 0, "font-sans font-semibold mt-8 mb-4 pb-2 border-b text-ods-text-primary border-ods-border", textSizes.h2)),
|
|
885
|
+
h3: makeHeading("h3", 3, _chunkFIG2RKZFcjs.cn.call(void 0, "font-sans font-semibold mt-6 mb-3 text-ods-text-primary", textSizes.h3)),
|
|
886
|
+
h4: makeHeading("h4", 4, _chunkFIG2RKZFcjs.cn.call(void 0, "font-sans font-semibold mt-4 mb-2 text-ods-text-primary", textSizes.h4)),
|
|
887
|
+
h5: makeHeading("h5", 5, _chunkFIG2RKZFcjs.cn.call(void 0, "font-sans font-semibold mt-3 mb-2 text-ods-text-primary", textSizes.h5)),
|
|
888
|
+
h6: makeHeading("h6", 6, _chunkFIG2RKZFcjs.cn.call(void 0, "font-sans font-semibold mt-3 mb-1 text-ods-text-primary", textSizes.h6)),
|
|
889
|
+
// --- paragraph ---
|
|
890
|
+
p: ({ children }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: _chunkFIG2RKZFcjs.cn.call(void 0, "leading-relaxed mb-4 first:mt-0 last:mb-0 text-ods-text-primary", textSizes.p), children }),
|
|
891
|
+
// --- links ---
|
|
892
|
+
a: ({ href, children, className: linkClassName }) => {
|
|
893
|
+
const isBroken = brokenLinks.includes(href);
|
|
894
|
+
const isInternalDocLink = propCurrentPath !== void 0 && propCurrentPath !== null && href && !href.startsWith("http") && !href.startsWith("#");
|
|
895
|
+
if (isBroken) {
|
|
896
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "text-ods-accent cursor-not-allowed", children: [
|
|
897
|
+
children,
|
|
898
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "sup", { className: "ml-1 text-xs font-bold text-ods-attention-red-error", children: "[BROKEN]" })
|
|
899
|
+
] });
|
|
900
|
+
}
|
|
901
|
+
if (isInternalDocLink && onInternalLinkClick) {
|
|
902
|
+
const currentPath = _nullishCoalesce(propCurrentPath, () => ( ""));
|
|
903
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
904
|
+
"span",
|
|
905
|
+
{
|
|
906
|
+
className: "text-ods-accent no-underline relative transition-colors duration-200 hover:after:w-full after:content-[''] after:absolute after:w-0 after:h-0.5 after:-bottom-0.5 after:left-0 after:bg-ods-accent after:transition-all after:duration-300 cursor-pointer",
|
|
907
|
+
onClick: async (e) => {
|
|
908
|
+
e.preventDefault();
|
|
909
|
+
e.stopPropagation();
|
|
910
|
+
if (onResolveLink) {
|
|
911
|
+
try {
|
|
912
|
+
const result = await onResolveLink(href, currentPath);
|
|
913
|
+
if (result.type === "folder-no-readme" && result.action === "expand_folder") {
|
|
914
|
+
onInternalLinkClick(result.resolvedPath, { expandFolder: true, fromInternalLink: true });
|
|
915
|
+
} else if (result.type === "not-found") {
|
|
916
|
+
return;
|
|
917
|
+
} else if (result.success && result.resolvedPath) {
|
|
918
|
+
onInternalLinkClick(result.resolvedPath, { fromInternalLink: true });
|
|
919
|
+
}
|
|
920
|
+
} catch (error) {
|
|
921
|
+
console.error("Error resolving link:", error);
|
|
922
|
+
}
|
|
923
|
+
} else {
|
|
924
|
+
onInternalLinkClick(href, { fromInternalLink: true });
|
|
925
|
+
}
|
|
926
|
+
},
|
|
927
|
+
role: "link",
|
|
928
|
+
tabIndex: 0,
|
|
929
|
+
onKeyDown: (e) => {
|
|
930
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
931
|
+
e.currentTarget.click();
|
|
932
|
+
}
|
|
933
|
+
},
|
|
934
|
+
children
|
|
935
|
+
}
|
|
936
|
+
);
|
|
937
|
+
}
|
|
938
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
939
|
+
"a",
|
|
940
|
+
{
|
|
941
|
+
href,
|
|
942
|
+
className: `text-ods-accent no-underline relative transition-colors duration-200 hover:after:w-full after:content-[''] after:absolute after:w-0 after:h-0.5 after:-bottom-0.5 after:left-0 after:bg-ods-accent after:transition-all after:duration-300 ${linkClassName || ""}`,
|
|
943
|
+
target: _optionalChain([href, 'optionalAccess', _3 => _3.startsWith, 'call', _4 => _4("http")]) ? "_blank" : void 0,
|
|
944
|
+
rel: _optionalChain([href, 'optionalAccess', _5 => _5.startsWith, 'call', _6 => _6("http")]) ? "noopener noreferrer" : void 0,
|
|
945
|
+
children
|
|
946
|
+
}
|
|
947
|
+
);
|
|
948
|
+
},
|
|
949
|
+
// --- images ---
|
|
950
|
+
// Inline content image renderer. Used by blog posts, docs, AND chat
|
|
951
|
+
// messages (where users may attach screenshots / photos via the +
|
|
952
|
+
// attachment button).
|
|
953
|
+
//
|
|
954
|
+
// Sizing rules (2025-2026 best practice — Claude.ai, ChatGPT,
|
|
955
|
+
// iMessage, Slack, Discord inline image patterns):
|
|
956
|
+
//
|
|
957
|
+
// - CAP max-width at 400px so inline images don't blow out the
|
|
958
|
+
// message column on wide panels. Click-to-expand opens a
|
|
959
|
+
// full-resolution modal for users who need detail.
|
|
960
|
+
// - CAP max-height at 400px so portrait-orientation images
|
|
961
|
+
// don't dominate vertical space (a 1000x3000 phone screenshot
|
|
962
|
+
// would otherwise push the next message off-screen).
|
|
963
|
+
// - Small images render at NATURAL pixel size — a 64x64
|
|
964
|
+
// thumbnail stays 64x64, not stretched to fill the column.
|
|
965
|
+
// - `object-contain` preserves aspect ratio when both dimensions
|
|
966
|
+
// are constrained (long landscape, tall portrait).
|
|
967
|
+
//
|
|
968
|
+
// Implementation: Next.js `<Image>` — the project's canonical
|
|
969
|
+
// image primitive. Gives us:
|
|
970
|
+
// - WebP/AVIF format conversion for modern browsers (smaller
|
|
971
|
+
// bytes for the same visual quality).
|
|
972
|
+
// - Responsive `srcset` via the `sizes` prop (browser picks the
|
|
973
|
+
// right variant for the viewport).
|
|
974
|
+
// - Automatic lazy-loading (`loading="lazy"` by default, mid-
|
|
975
|
+
// page images skipped until they near the viewport).
|
|
976
|
+
// - Automatic `decoding="async"` so image decode doesn't block
|
|
977
|
+
// paint.
|
|
978
|
+
//
|
|
979
|
+
// `width={400} height={400}` props are REQUIRED by Next.js
|
|
980
|
+
// `<Image>` (non-`fill` mode throws without them) but they're
|
|
981
|
+
// effectively a CEILING here, not the display size — the CSS
|
|
982
|
+
// overrides (`w-auto h-auto max-w-full max-h-[400px]`) drive
|
|
983
|
+
// the actual rendered size. The inline `style={{ width: 'auto',
|
|
984
|
+
// height: 'auto' }}` is belt-and-suspenders: Next.js Image sets
|
|
985
|
+
// matching HTML `width`/`height` attributes on the rendered
|
|
986
|
+
// `<img>` and inline style wins over both HTML attributes AND
|
|
987
|
+
// utility classes regardless of CSS-specificity surprises.
|
|
988
|
+
//
|
|
989
|
+
// Layout reservation trade-off: until image bytes arrive, the
|
|
990
|
+
// browser may reserve a placeholder box up to 400x400 (the props'
|
|
991
|
+
// intrinsic-ratio hint). Once loaded, the box collapses to the
|
|
992
|
+
// natural size if smaller. This is the standard Next.js Image
|
|
993
|
+
// behavior across the codebase — accepted for the optimizer +
|
|
994
|
+
// responsive-srcset benefits. Chat attachments hosted in side
|
|
995
|
+
// panels see this only on first render of a fresh attachment
|
|
996
|
+
// (cached re-renders pop in without a perceptible shift).
|
|
997
|
+
img: ({ src, alt }) => {
|
|
998
|
+
if (!src || typeof src !== "string" || src.trim() === "") return null;
|
|
999
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1000
|
+
_chunkXL4V2PYGcjs.next_image_default,
|
|
1001
|
+
{
|
|
1002
|
+
src,
|
|
1003
|
+
alt: _nullishCoalesce(alt, () => ( "No image available")),
|
|
1004
|
+
width: 400,
|
|
1005
|
+
height: 400,
|
|
1006
|
+
sizes: "(max-width: 400px) 100vw, 400px",
|
|
1007
|
+
className: "max-w-full max-h-[400px] w-auto h-auto rounded-lg object-contain",
|
|
1008
|
+
style: { width: "auto", height: "auto" }
|
|
1009
|
+
}
|
|
1010
|
+
);
|
|
1011
|
+
},
|
|
1012
|
+
// --- lists ---
|
|
1013
|
+
ul: ({ children }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "ul", { className: "list-disc list-outside my-4 ml-8 space-y-2 text-ods-text-primary", children }),
|
|
1014
|
+
ol: ({ children }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "ol", { className: "list-decimal list-outside my-4 ml-8 space-y-2 text-ods-text-primary", children }),
|
|
1015
|
+
li: ({ children }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "li", { className: _chunkFIG2RKZFcjs.cn.call(void 0, "leading-relaxed pl-2", textSizes.li), children }),
|
|
1016
|
+
// --- tables ---
|
|
1017
|
+
table: ({ children }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "table-container my-6 overflow-x-auto", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "min-w-full border rounded-lg border-ods-border bg-ods-card", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "table", { className: "w-full table-fixed md:table-auto", children }) }) }),
|
|
1018
|
+
thead: ({ children }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "thead", { className: "bg-ods-bg-secondary", children }),
|
|
1019
|
+
th: ({ children }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { className: _chunkFIG2RKZFcjs.cn.call(void 0, "px-2 md:px-4 py-3 text-left font-semibold text-ods-accent border-r last:border-r-0 break-words border-ods-border", textSizes.th), children }),
|
|
1020
|
+
td: ({ children }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { className: _chunkFIG2RKZFcjs.cn.call(void 0, "px-2 md:px-4 py-3 border-r last:border-r-0 border-b break-words whitespace-normal text-ods-text-primary border-ods-border", textSizes.td), children }),
|
|
1021
|
+
// --- horizontal rule ---
|
|
1022
|
+
hr: () => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "hr", { className: "border-0 border-t my-8 border-ods-border" }),
|
|
1023
|
+
// --- merge overrides ---
|
|
1024
|
+
...componentOverrides
|
|
1025
|
+
}), [makeHeading, brokenLinks, propCurrentPath, onInternalLinkClick, onResolveLink, componentOverrides, textSizes]);
|
|
1026
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: `simple-markdown-renderer ${className}`, children: [
|
|
1027
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "style", { dangerouslySetInnerHTML: { __html: mermaidStyles } }),
|
|
1028
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "content-wrapper max-w-none break-words", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "article", { className: "prose prose-lg max-w-none", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1029
|
+
_reactmarkdown2.default,
|
|
1030
|
+
{
|
|
1031
|
+
remarkPlugins: [_remarkgfm2.default, _remarkbreaks2.default, ..._nullishCoalesce(additionalRemarkPlugins, () => ( []))],
|
|
1032
|
+
rehypePlugins: [
|
|
1033
|
+
// ORDER MATTERS: rehype-raw parses the raw HTML embedded
|
|
1034
|
+
// in the source markdown into HAST nodes; rehypeStripUnsafe
|
|
1035
|
+
// then walks the HAST tree and drops XSS vectors (on*
|
|
1036
|
+
// event handlers, javascript: URLs, script/style/iframe-srcdoc,
|
|
1037
|
+
// data: URIs). Reversing the order would have nothing to
|
|
1038
|
+
// sanitize (raw HTML would still be strings).
|
|
1039
|
+
_rehyperaw2.default,
|
|
1040
|
+
rehypeStripUnsafe,
|
|
1041
|
+
[_rehypehighlight2.default, { detect: true, ignoreMissing: true }]
|
|
1042
|
+
],
|
|
1043
|
+
urlTransform: cardAwareUrlTransform,
|
|
1044
|
+
components,
|
|
1045
|
+
children: processedContent
|
|
1046
|
+
}
|
|
1047
|
+
) }) })
|
|
1048
|
+
] });
|
|
1049
|
+
};
|
|
1050
|
+
var SimpleMarkdownRenderer = _react.memo.call(void 0, SimpleMarkdownRendererImpl);
|
|
1051
|
+
|
|
1052
|
+
// src/utils/format.ts
|
|
1053
|
+
function formatDate(date, options = {
|
|
1054
|
+
year: "numeric",
|
|
1055
|
+
month: "long",
|
|
1056
|
+
day: "numeric"
|
|
1057
|
+
}) {
|
|
1058
|
+
const dateObj = typeof date === "string" ? new Date(date) : date;
|
|
1059
|
+
if (isNaN(dateObj.getTime())) {
|
|
1060
|
+
console.warn("Invalid date provided to formatDate:", date);
|
|
1061
|
+
return "Invalid Date";
|
|
1062
|
+
}
|
|
1063
|
+
return dateObj.toLocaleDateString("en-US", options);
|
|
1064
|
+
}
|
|
1065
|
+
function formatNumber(num) {
|
|
1066
|
+
return num.toLocaleString();
|
|
1067
|
+
}
|
|
1068
|
+
function formatPrice(price, currency = "USD") {
|
|
1069
|
+
return new Intl.NumberFormat("en-US", {
|
|
1070
|
+
style: "currency",
|
|
1071
|
+
currency
|
|
1072
|
+
}).format(price);
|
|
1073
|
+
}
|
|
1074
|
+
function formatBytes(bytes, decimals = 2) {
|
|
1075
|
+
if (bytes === 0) return "0 Bytes";
|
|
1076
|
+
const k = 1024;
|
|
1077
|
+
const dm = decimals < 0 ? 0 : decimals;
|
|
1078
|
+
const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
|
1079
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
1080
|
+
return Number.parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i];
|
|
1081
|
+
}
|
|
1082
|
+
function formatBytesShort(bytes) {
|
|
1083
|
+
if (bytes === 0) return "0 B";
|
|
1084
|
+
const k = 1024;
|
|
1085
|
+
const sizes = ["B", "KB", "MB", "GB", "TB"];
|
|
1086
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
1087
|
+
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
|
|
1088
|
+
}
|
|
1089
|
+
function formatLargeNumber(num) {
|
|
1090
|
+
if (num === 0) return "0";
|
|
1091
|
+
const isNegative = num < 0;
|
|
1092
|
+
const absNum = Math.abs(num);
|
|
1093
|
+
let result;
|
|
1094
|
+
if (absNum >= 1e9) {
|
|
1095
|
+
result = `${Math.floor(absNum / 1e9)}B`;
|
|
1096
|
+
} else if (absNum >= 1e6) {
|
|
1097
|
+
result = `${Math.floor(absNum / 1e6)}M`;
|
|
1098
|
+
} else if (absNum >= 1e3) {
|
|
1099
|
+
result = `${Math.floor(absNum / 1e3)}K`;
|
|
1100
|
+
} else {
|
|
1101
|
+
result = Math.floor(absNum).toString();
|
|
1102
|
+
}
|
|
1103
|
+
return isNegative ? `-${result}` : result;
|
|
1104
|
+
}
|
|
1105
|
+
function formatAbbreviatedNumber(n) {
|
|
1106
|
+
if (n >= 1e9) {
|
|
1107
|
+
const value = n / 1e9;
|
|
1108
|
+
return `${Number.isInteger(value) ? value.toFixed(0) : value.toFixed(1)}B`;
|
|
1109
|
+
}
|
|
1110
|
+
if (n >= 1e6) {
|
|
1111
|
+
const value = n / 1e6;
|
|
1112
|
+
return `${Number.isInteger(value) ? value.toFixed(0) : value.toFixed(1)}M`;
|
|
1113
|
+
}
|
|
1114
|
+
if (n >= 1e3) {
|
|
1115
|
+
const value = n / 1e3;
|
|
1116
|
+
return `${Number.isInteger(value) ? value.toFixed(0) : value.toFixed(1)}K`;
|
|
1117
|
+
}
|
|
1118
|
+
return n.toLocaleString();
|
|
1119
|
+
}
|
|
1120
|
+
function getFirstLastInitials(name) {
|
|
1121
|
+
if (!name) return "";
|
|
1122
|
+
const words = name.trim().split(/\s+/);
|
|
1123
|
+
if (words.length === 0 || !words[0]) return "";
|
|
1124
|
+
if (words.length === 1) return words[0].charAt(0).toUpperCase();
|
|
1125
|
+
return (words[0].charAt(0) + words[words.length - 1].charAt(0)).toUpperCase();
|
|
1126
|
+
}
|
|
1127
|
+
function nameInitials(name, fallback = "E") {
|
|
1128
|
+
const source = typeof name === "string" ? name.trim() : "";
|
|
1129
|
+
const words = source.length > 0 ? source.split(/\s+/) : [];
|
|
1130
|
+
const letters = words.map((w) => w[0]).filter(Boolean).slice(0, 2).join("");
|
|
1131
|
+
return (letters || fallback).toUpperCase();
|
|
1132
|
+
}
|
|
1133
|
+
function formatDurationMMSS(seconds) {
|
|
1134
|
+
if (!seconds) return "";
|
|
1135
|
+
const hours = Math.floor(seconds / 3600);
|
|
1136
|
+
const minutes = Math.floor(seconds % 3600 / 60);
|
|
1137
|
+
const secs = Math.floor(seconds % 60);
|
|
1138
|
+
if (hours > 0) {
|
|
1139
|
+
return `${hours}:${minutes.toString().padStart(2, "0")}:${secs.toString().padStart(2, "0")}`;
|
|
1140
|
+
}
|
|
1141
|
+
return `${minutes}:${secs.toString().padStart(2, "0")}`;
|
|
1142
|
+
}
|
|
1143
|
+
function formatDurationCompact(seconds) {
|
|
1144
|
+
if (!seconds) return "";
|
|
1145
|
+
const hours = Math.floor(seconds / 3600);
|
|
1146
|
+
const minutes = Math.floor(seconds % 3600 / 60);
|
|
1147
|
+
if (hours > 0) {
|
|
1148
|
+
return `${hours}h ${minutes}m`;
|
|
1149
|
+
}
|
|
1150
|
+
return `${minutes} min`;
|
|
1151
|
+
}
|
|
1152
|
+
function formatTimeWithTimezone(date, timezone) {
|
|
1153
|
+
if (!date) return "";
|
|
1154
|
+
const dateObj = typeof date === "string" ? new Date(date) : date;
|
|
1155
|
+
const timeStr = dateObj.toLocaleTimeString("en-US", {
|
|
1156
|
+
hour: "numeric",
|
|
1157
|
+
minute: "2-digit",
|
|
1158
|
+
hour12: true
|
|
1159
|
+
});
|
|
1160
|
+
return timezone ? `${timeStr} ${timezone}` : timeStr;
|
|
1161
|
+
}
|
|
1162
|
+
function formatDurationFromRange(startAt, endAt) {
|
|
1163
|
+
if (!startAt || !endAt) return "";
|
|
1164
|
+
const start = typeof startAt === "string" ? new Date(startAt) : startAt;
|
|
1165
|
+
const end = typeof endAt === "string" ? new Date(endAt) : endAt;
|
|
1166
|
+
const durationMs = end.getTime() - start.getTime();
|
|
1167
|
+
const minutes = Math.round(durationMs / 6e4);
|
|
1168
|
+
if (minutes >= 60) {
|
|
1169
|
+
const hours = Math.floor(minutes / 60);
|
|
1170
|
+
const mins = minutes % 60;
|
|
1171
|
+
return mins > 0 ? `${hours}h ${mins}m` : `${hours}h`;
|
|
1172
|
+
}
|
|
1173
|
+
return `${minutes}m`;
|
|
1174
|
+
}
|
|
1175
|
+
function formatDateUTC(value, options = {}) {
|
|
1176
|
+
const { fallback = "N/A", timezone = "UTC" } = options;
|
|
1177
|
+
if (value === null || value === void 0 || value === "") return fallback;
|
|
1178
|
+
let ms;
|
|
1179
|
+
if (typeof value === "number") {
|
|
1180
|
+
ms = value;
|
|
1181
|
+
} else {
|
|
1182
|
+
const n = Number(value);
|
|
1183
|
+
if (Number.isFinite(n) && n > 0 && /^-?\d+(\.\d+)?$/.test(value.trim())) {
|
|
1184
|
+
ms = n;
|
|
1185
|
+
} else {
|
|
1186
|
+
ms = Date.parse(value.includes("T") ? value : value + "T00:00:00Z");
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
if (!Number.isFinite(ms)) return fallback;
|
|
1190
|
+
return new Date(ms).toLocaleDateString("en-US", {
|
|
1191
|
+
year: "numeric",
|
|
1192
|
+
month: "short",
|
|
1193
|
+
day: "numeric",
|
|
1194
|
+
timeZone: timezone === "local" ? void 0 : "UTC"
|
|
1195
|
+
});
|
|
1196
|
+
}
|
|
1197
|
+
function formatLegalDate(dateInput) {
|
|
1198
|
+
return new Intl.DateTimeFormat("en-US", {
|
|
1199
|
+
year: "numeric",
|
|
1200
|
+
month: "2-digit",
|
|
1201
|
+
day: "2-digit"
|
|
1202
|
+
}).format(new Date(dateInput));
|
|
1203
|
+
}
|
|
1204
|
+
function formatCurrency(value) {
|
|
1205
|
+
if (value == null) return "N/A";
|
|
1206
|
+
return new Intl.NumberFormat("en-US", {
|
|
1207
|
+
style: "currency",
|
|
1208
|
+
currency: "USD",
|
|
1209
|
+
maximumFractionDigits: 0
|
|
1210
|
+
}).format(value);
|
|
1211
|
+
}
|
|
1212
|
+
function formatPercent(value) {
|
|
1213
|
+
if (value == null) return "N/A";
|
|
1214
|
+
return `${value.toFixed(2)}%`;
|
|
1215
|
+
}
|
|
1216
|
+
function formatWholeDollars(price, currency = "USD") {
|
|
1217
|
+
return new Intl.NumberFormat("en-US", {
|
|
1218
|
+
style: "currency",
|
|
1219
|
+
currency,
|
|
1220
|
+
maximumFractionDigits: 0
|
|
1221
|
+
}).format(price);
|
|
1222
|
+
}
|
|
1223
|
+
function formatCompactMetric(value, format = "number", options) {
|
|
1224
|
+
if (value === 0 || value === null || value === void 0) {
|
|
1225
|
+
if (format === "currency") return `${_optionalChain([options, 'optionalAccess', _7 => _7.prefix]) || "$"}0`;
|
|
1226
|
+
if (format === "percentage") return "0%";
|
|
1227
|
+
if (format === "months") return `0 ${_optionalChain([options, 'optionalAccess', _8 => _8.suffix]) || "months"}`;
|
|
1228
|
+
return "0";
|
|
1229
|
+
}
|
|
1230
|
+
const absValue = Math.abs(value);
|
|
1231
|
+
const sign = value < 0 ? "-" : "";
|
|
1232
|
+
if (format === "currency") {
|
|
1233
|
+
const prefix = _optionalChain([options, 'optionalAccess', _9 => _9.prefix]) || "$";
|
|
1234
|
+
const compact = (val, divisor, suffix) => {
|
|
1235
|
+
const divided = val / divisor;
|
|
1236
|
+
const formatted = divided % 1 === 0 ? divided.toFixed(0) : divided.toFixed(1);
|
|
1237
|
+
return `${sign}${prefix}${formatted}${suffix}`;
|
|
1238
|
+
};
|
|
1239
|
+
if (absValue >= 1e9) return compact(absValue, 1e9, "B");
|
|
1240
|
+
if (absValue >= 1e6) return compact(absValue, 1e6, "M");
|
|
1241
|
+
if (absValue >= 1e3) return `${sign}${prefix}${(absValue / 1e3).toFixed(0)}K`;
|
|
1242
|
+
return `${sign}${prefix}${absValue.toLocaleString()}`;
|
|
1243
|
+
}
|
|
1244
|
+
if (format === "percentage") {
|
|
1245
|
+
return `${sign}${absValue}%`;
|
|
1246
|
+
}
|
|
1247
|
+
if (format === "months") {
|
|
1248
|
+
const rounded = Math.round(value * 10) / 10;
|
|
1249
|
+
return `${rounded} ${_optionalChain([options, 'optionalAccess', _10 => _10.suffix]) || "months"}`;
|
|
1250
|
+
}
|
|
1251
|
+
if (absValue >= 1e6) return `${sign}${(absValue / 1e6).toFixed(1)}M`;
|
|
1252
|
+
if (absValue >= 1e3) return `${sign}${(absValue / 1e3).toFixed(1)}K`;
|
|
1253
|
+
return value.toLocaleString();
|
|
1254
|
+
}
|
|
1255
|
+
function getTrendColors(direction, polarity = "positive") {
|
|
1256
|
+
if (direction === "neutral" || polarity === "neutral") {
|
|
1257
|
+
return {
|
|
1258
|
+
textClass: "text-ods-text-secondary",
|
|
1259
|
+
badgeClass: "bg-ods-border text-ods-text-secondary"
|
|
1260
|
+
};
|
|
1261
|
+
}
|
|
1262
|
+
const isPositiveOutcome = direction === "up" && polarity === "positive" || direction === "down" && polarity === "negative";
|
|
1263
|
+
if (isPositiveOutcome) {
|
|
1264
|
+
return {
|
|
1265
|
+
textClass: "text-ods-success",
|
|
1266
|
+
badgeClass: "bg-ods-success-secondary text-ods-success"
|
|
1267
|
+
};
|
|
1268
|
+
}
|
|
1269
|
+
return {
|
|
1270
|
+
textClass: "text-ods-error",
|
|
1271
|
+
badgeClass: "bg-ods-error-secondary text-ods-error"
|
|
1272
|
+
};
|
|
1273
|
+
}
|
|
1274
|
+
function formatDateRange(start, end) {
|
|
1275
|
+
if (!start || !end) return "";
|
|
1276
|
+
const fmt = (s) => {
|
|
1277
|
+
const bareMatch = /^(\d{4})-(\d{2})-(\d{2})$/.exec(s);
|
|
1278
|
+
const d = bareMatch ? new Date(Number(bareMatch[1]), Number(bareMatch[2]) - 1, Number(bareMatch[3])) : new Date(s);
|
|
1279
|
+
if (Number.isNaN(d.getTime())) return s;
|
|
1280
|
+
return d.toLocaleDateString(void 0, {
|
|
1281
|
+
month: "short",
|
|
1282
|
+
day: "numeric",
|
|
1283
|
+
year: "numeric"
|
|
1284
|
+
});
|
|
1285
|
+
};
|
|
1286
|
+
return `${fmt(start)} \u2014 ${fmt(end)}`;
|
|
1287
|
+
}
|
|
1288
|
+
function formatDateTimeAt(dateString) {
|
|
1289
|
+
const date = new Date(dateString);
|
|
1290
|
+
const dateStr = date.toLocaleDateString("en-US", {
|
|
1291
|
+
month: "short",
|
|
1292
|
+
day: "numeric",
|
|
1293
|
+
year: "numeric"
|
|
1294
|
+
});
|
|
1295
|
+
const timeStr = date.toLocaleTimeString("en-US", {
|
|
1296
|
+
hour: "numeric",
|
|
1297
|
+
minute: "2-digit",
|
|
1298
|
+
hour12: true
|
|
1299
|
+
});
|
|
1300
|
+
return `${dateStr} at ${timeStr}`;
|
|
1301
|
+
}
|
|
1302
|
+
function formatDurationFromMs(ms) {
|
|
1303
|
+
if (!ms || isNaN(ms) || ms < 0) return "0ms";
|
|
1304
|
+
if (ms < 1e3) return `${ms}ms`;
|
|
1305
|
+
if (ms < 6e4) return `${(ms / 1e3).toFixed(1)}s`;
|
|
1306
|
+
return `${(ms / 6e4).toFixed(1)}m`;
|
|
1307
|
+
}
|
|
1308
|
+
function formatDuration(seconds) {
|
|
1309
|
+
if (seconds < 60) return `${seconds} seconds`;
|
|
1310
|
+
if (seconds < 3600) return `${Math.floor(seconds / 60)} minutes`;
|
|
1311
|
+
const hours = Math.floor(seconds / 3600);
|
|
1312
|
+
const minutes = Math.floor(seconds % 3600 / 60);
|
|
1313
|
+
if (minutes === 0) return `${hours} hour${hours > 1 ? "s" : ""}`;
|
|
1314
|
+
return `${hours} hour${hours > 1 ? "s" : ""} ${minutes} minute${minutes > 1 ? "s" : ""}`;
|
|
1315
|
+
}
|
|
1316
|
+
function formatUnderscoreText(text) {
|
|
1317
|
+
return text.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
|
|
1318
|
+
}
|
|
1319
|
+
function stripHtml(html) {
|
|
1320
|
+
let noTags = html;
|
|
1321
|
+
let prev;
|
|
1322
|
+
do {
|
|
1323
|
+
prev = noTags;
|
|
1324
|
+
noTags = noTags.replace(/<[^<>]*>/g, "");
|
|
1325
|
+
} while (noTags !== prev);
|
|
1326
|
+
return noTags.replace(/ /g, " ").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/'/g, "'").replace(/'/g, "'").replace(/'/g, "'").replace(/&/g, "&").replace(/\s+/g, " ").trim();
|
|
1327
|
+
}
|
|
1328
|
+
function formatClassification(classification) {
|
|
1329
|
+
const customMappings = {
|
|
1330
|
+
openframe_selected: "OpenFrame Selected"
|
|
1331
|
+
};
|
|
1332
|
+
return customMappings[classification] || formatUnderscoreText(classification);
|
|
1333
|
+
}
|
|
1334
|
+
function formatPricingModel(pricingModel) {
|
|
1335
|
+
const customMappings = {
|
|
1336
|
+
one_time: "One-time Purchase",
|
|
1337
|
+
self_hosted: "Self-hosted"
|
|
1338
|
+
};
|
|
1339
|
+
return customMappings[pricingModel] || formatUnderscoreText(pricingModel);
|
|
1340
|
+
}
|
|
1341
|
+
function formatBioText(aboutHtml, fallback = "") {
|
|
1342
|
+
if (!aboutHtml || !aboutHtml.trim()) return fallback;
|
|
1343
|
+
if (aboutHtml.includes("<p")) {
|
|
1344
|
+
const paragraphs = aboutHtml.split(/<p[^<>]*>/).slice(1).map((part) => part.split("</p>")[0]).map((text) => stripHtml(text).trim()).filter((text) => text.length > 0);
|
|
1345
|
+
if (paragraphs.length > 0) return paragraphs.join(" ");
|
|
1346
|
+
}
|
|
1347
|
+
return stripHtml(aboutHtml).trim() || fallback;
|
|
1348
|
+
}
|
|
1349
|
+
|
|
1350
|
+
// src/components/ui/square-avatar.tsx
|
|
1351
|
+
|
|
1352
|
+
_chunkFIG2RKZFcjs.init_cn.call(void 0, );
|
|
1353
|
+
|
|
1354
|
+
var SquareAvatar = React4.memo(React4.forwardRef(
|
|
1355
|
+
({ className, src, alt, size = "md", fallback, variant = "square", initialsClassName, ...props }, ref) => {
|
|
1356
|
+
const sizeClasses = {
|
|
1357
|
+
sm: "h-8 w-8",
|
|
1358
|
+
md: "h-10 w-10",
|
|
1359
|
+
lg: "h-12 w-12",
|
|
1360
|
+
xl: "h-16 w-16"
|
|
1361
|
+
};
|
|
1362
|
+
const sizePx = {
|
|
1363
|
+
sm: 32,
|
|
1364
|
+
md: 40,
|
|
1365
|
+
lg: 48,
|
|
1366
|
+
xl: 64
|
|
1367
|
+
};
|
|
1368
|
+
const variantClasses = {
|
|
1369
|
+
square: "rounded-md",
|
|
1370
|
+
round: "rounded-full"
|
|
1371
|
+
};
|
|
1372
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
1373
|
+
"div",
|
|
1374
|
+
{
|
|
1375
|
+
className: _chunkFIG2RKZFcjs.cn.call(void 0,
|
|
1376
|
+
"relative flex items-center justify-center shrink-0 overflow-hidden border border-ods-border bg-ods-bg",
|
|
1377
|
+
sizeClasses[size],
|
|
1378
|
+
variantClasses[variant],
|
|
1379
|
+
className
|
|
1380
|
+
),
|
|
1381
|
+
ref,
|
|
1382
|
+
...props,
|
|
1383
|
+
children: [
|
|
1384
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: _chunkFIG2RKZFcjs.cn.call(void 0,
|
|
1385
|
+
// Initials use `text-ods-text-primary` so they stay readable
|
|
1386
|
+
// both on the default `bg-ods-bg` AND on accent-fill backgrounds
|
|
1387
|
+
// (`bg-ods-flamingo-pink` for the current user, `bg-ods-flamingo-cyan`
|
|
1388
|
+
// for Mingo). With `text-ods-text-secondary` (#888) on a pink fill
|
|
1389
|
+
// (#F357BB) the initials clocked ~2.0:1 contrast — failing WCAG AA
|
|
1390
|
+
// and visually rendering as a blank colored dot. Primary text
|
|
1391
|
+
// (#fafafa) on the same pink yields ~3.5:1 (AA Large) and on the
|
|
1392
|
+
// dark default bg yields ~15:1.
|
|
1393
|
+
"flex items-center justify-center text-xs font-medium text-ods-text-primary",
|
|
1394
|
+
initialsClassName,
|
|
1395
|
+
src && "hidden"
|
|
1396
|
+
), children: getFirstLastInitials(fallback || alt) || "?" }),
|
|
1397
|
+
src && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1398
|
+
_chunkXL4V2PYGcjs.next_image_default,
|
|
1399
|
+
{
|
|
1400
|
+
className: "absolute inset-0 h-full w-full object-cover",
|
|
1401
|
+
src,
|
|
1402
|
+
alt: alt || "",
|
|
1403
|
+
width: sizePx[size],
|
|
1404
|
+
height: sizePx[size],
|
|
1405
|
+
onError: (e) => {
|
|
1406
|
+
e.currentTarget.style.display = "none";
|
|
1407
|
+
const el = e.currentTarget.previousElementSibling;
|
|
1408
|
+
if (el) el.classList.remove("hidden");
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
)
|
|
1412
|
+
]
|
|
1413
|
+
}
|
|
1414
|
+
);
|
|
1415
|
+
}
|
|
1416
|
+
));
|
|
1417
|
+
SquareAvatar.displayName = "SquareAvatar";
|
|
1418
|
+
|
|
1419
|
+
// src/components/ui/actions-menu.tsx
|
|
1420
|
+
var _reactdropdownmenu = require('@radix-ui/react-dropdown-menu'); var DropdownMenuPrimitive = _interopRequireWildcard(_reactdropdownmenu);
|
|
1421
|
+
|
|
1422
|
+
// node_modules/@radix-ui/react-use-controllable-state/dist/index.mjs
|
|
1423
|
+
|
|
1424
|
+
|
|
1425
|
+
// node_modules/@radix-ui/react-use-layout-effect/dist/index.mjs
|
|
1426
|
+
|
|
1427
|
+
var useLayoutEffect2 = _optionalChain([globalThis, 'optionalAccess', _11 => _11.document]) ? React5.useLayoutEffect : () => {
|
|
1428
|
+
};
|
|
1429
|
+
|
|
1430
|
+
// node_modules/@radix-ui/react-use-controllable-state/dist/index.mjs
|
|
1431
|
+
|
|
1432
|
+
var useInsertionEffect = React6[" useInsertionEffect ".trim().toString()] || useLayoutEffect2;
|
|
1433
|
+
function useControllableState({
|
|
1434
|
+
prop,
|
|
1435
|
+
defaultProp,
|
|
1436
|
+
onChange = () => {
|
|
1437
|
+
},
|
|
1438
|
+
caller
|
|
1439
|
+
}) {
|
|
1440
|
+
const [uncontrolledProp, setUncontrolledProp, onChangeRef] = useUncontrolledState({
|
|
1441
|
+
defaultProp,
|
|
1442
|
+
onChange
|
|
1443
|
+
});
|
|
1444
|
+
const isControlled = prop !== void 0;
|
|
1445
|
+
const value = isControlled ? prop : uncontrolledProp;
|
|
1446
|
+
if (true) {
|
|
1447
|
+
const isControlledRef = React6.useRef(prop !== void 0);
|
|
1448
|
+
React6.useEffect(() => {
|
|
1449
|
+
const wasControlled = isControlledRef.current;
|
|
1450
|
+
if (wasControlled !== isControlled) {
|
|
1451
|
+
const from = wasControlled ? "controlled" : "uncontrolled";
|
|
1452
|
+
const to = isControlled ? "controlled" : "uncontrolled";
|
|
1453
|
+
console.warn(
|
|
1454
|
+
`${caller} is changing from ${from} to ${to}. Components should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled value for the lifetime of the component.`
|
|
1455
|
+
);
|
|
1456
|
+
}
|
|
1457
|
+
isControlledRef.current = isControlled;
|
|
1458
|
+
}, [isControlled, caller]);
|
|
1459
|
+
}
|
|
1460
|
+
const setValue = React6.useCallback(
|
|
1461
|
+
(nextValue) => {
|
|
1462
|
+
if (isControlled) {
|
|
1463
|
+
const value2 = isFunction(nextValue) ? nextValue(prop) : nextValue;
|
|
1464
|
+
if (value2 !== prop) {
|
|
1465
|
+
_optionalChain([onChangeRef, 'access', _12 => _12.current, 'optionalCall', _13 => _13(value2)]);
|
|
1466
|
+
}
|
|
1467
|
+
} else {
|
|
1468
|
+
setUncontrolledProp(nextValue);
|
|
1469
|
+
}
|
|
1470
|
+
},
|
|
1471
|
+
[isControlled, prop, setUncontrolledProp, onChangeRef]
|
|
1472
|
+
);
|
|
1473
|
+
return [value, setValue];
|
|
1474
|
+
}
|
|
1475
|
+
function useUncontrolledState({
|
|
1476
|
+
defaultProp,
|
|
1477
|
+
onChange
|
|
1478
|
+
}) {
|
|
1479
|
+
const [value, setValue] = React6.useState(defaultProp);
|
|
1480
|
+
const prevValueRef = React6.useRef(value);
|
|
1481
|
+
const onChangeRef = React6.useRef(onChange);
|
|
1482
|
+
useInsertionEffect(() => {
|
|
1483
|
+
onChangeRef.current = onChange;
|
|
1484
|
+
}, [onChange]);
|
|
1485
|
+
React6.useEffect(() => {
|
|
1486
|
+
if (prevValueRef.current !== value) {
|
|
1487
|
+
_optionalChain([onChangeRef, 'access', _14 => _14.current, 'optionalCall', _15 => _15(value)]);
|
|
1488
|
+
prevValueRef.current = value;
|
|
1489
|
+
}
|
|
1490
|
+
}, [value, prevValueRef]);
|
|
1491
|
+
return [value, setValue, onChangeRef];
|
|
1492
|
+
}
|
|
1493
|
+
function isFunction(value) {
|
|
1494
|
+
return typeof value === "function";
|
|
1495
|
+
}
|
|
1496
|
+
|
|
1497
|
+
// src/components/ui/actions-menu.tsx
|
|
1498
|
+
_chunkWBR7H6E3cjs.init_next_link.call(void 0, );
|
|
1499
|
+
var _lucidereact = require('lucide-react');
|
|
1500
|
+
|
|
1501
|
+
_chunkFIG2RKZFcjs.init_cn.call(void 0, );
|
|
1502
|
+
_chunkTU26IZPOcjs.init_button2.call(void 0, );
|
|
1503
|
+
|
|
1504
|
+
var ROW_CLASSES = "flex flex-1 min-w-0 items-center gap-[var(--spacing-system-xsf)] p-[var(--spacing-system-s)] cursor-pointer transition-colors bg-ods-bg outline-none";
|
|
1505
|
+
var WRAPPER_CLASSES = "relative flex items-stretch border-b border-ods-border last:border-b-0";
|
|
1506
|
+
var SECONDARY_ACTION_CLASSES = "flex p-[var(--spacing-system-s)] shrink-0 items-center justify-center self-stretch border-l border-ods-border transition-colors hover:bg-ods-bg-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ods-focus [&_svg]:w-4 [&_svg]:h-4 md:[&_svg]:w-6 md:[&_svg]:h-6";
|
|
1507
|
+
var SecondaryAction = ({ action }) => {
|
|
1508
|
+
const handleClick = _react.useCallback.call(void 0,
|
|
1509
|
+
(e) => {
|
|
1510
|
+
e.stopPropagation();
|
|
1511
|
+
if (action.disabled) {
|
|
1512
|
+
e.preventDefault();
|
|
1513
|
+
return;
|
|
1514
|
+
}
|
|
1515
|
+
_optionalChain([action, 'access', _16 => _16.onClick, 'optionalCall', _17 => _17()]);
|
|
1516
|
+
},
|
|
1517
|
+
[action]
|
|
1518
|
+
);
|
|
1519
|
+
const classes = _chunkFIG2RKZFcjs.cn.call(void 0,
|
|
1520
|
+
SECONDARY_ACTION_CLASSES,
|
|
1521
|
+
action.disabled && "cursor-not-allowed opacity-60 pointer-events-none"
|
|
1522
|
+
);
|
|
1523
|
+
if (action.href) {
|
|
1524
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1525
|
+
_chunkWBR7H6E3cjs.next_link_default,
|
|
1526
|
+
{
|
|
1527
|
+
href: action.href,
|
|
1528
|
+
prefetch: false,
|
|
1529
|
+
target: action.openInNewTab ? "_blank" : void 0,
|
|
1530
|
+
rel: action.openInNewTab ? "noopener noreferrer" : void 0,
|
|
1531
|
+
"aria-label": action["aria-label"],
|
|
1532
|
+
"aria-disabled": action.disabled || void 0,
|
|
1533
|
+
tabIndex: action.disabled ? -1 : void 0,
|
|
1534
|
+
className: classes,
|
|
1535
|
+
onClick: handleClick,
|
|
1536
|
+
children: action.icon
|
|
1537
|
+
}
|
|
1538
|
+
);
|
|
1539
|
+
}
|
|
1540
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1541
|
+
"button",
|
|
1542
|
+
{
|
|
1543
|
+
type: "button",
|
|
1544
|
+
"aria-label": action["aria-label"],
|
|
1545
|
+
disabled: action.disabled,
|
|
1546
|
+
className: classes,
|
|
1547
|
+
onClick: handleClick,
|
|
1548
|
+
children: action.icon
|
|
1549
|
+
}
|
|
1550
|
+
);
|
|
1551
|
+
};
|
|
1552
|
+
var MenuItem = ({ item, onItemClick }) => {
|
|
1553
|
+
const activate = _react.useCallback.call(void 0, () => {
|
|
1554
|
+
if (item.disabled) return;
|
|
1555
|
+
if (item.type === "checkbox") {
|
|
1556
|
+
_optionalChain([item, 'access', _18 => _18.onClick, 'optionalCall', _19 => _19()]);
|
|
1557
|
+
_optionalChain([onItemClick, 'optionalCall', _20 => _20(item)]);
|
|
1558
|
+
return;
|
|
1559
|
+
}
|
|
1560
|
+
if (item.type === "submenu") return;
|
|
1561
|
+
_optionalChain([item, 'access', _21 => _21.onClick, 'optionalCall', _22 => _22()]);
|
|
1562
|
+
_optionalChain([onItemClick, 'optionalCall', _23 => _23(item)]);
|
|
1563
|
+
}, [item, onItemClick]);
|
|
1564
|
+
const handleClick = _react.useCallback.call(void 0,
|
|
1565
|
+
(e) => {
|
|
1566
|
+
e.stopPropagation();
|
|
1567
|
+
e.preventDefault();
|
|
1568
|
+
activate();
|
|
1569
|
+
},
|
|
1570
|
+
[activate]
|
|
1571
|
+
);
|
|
1572
|
+
const handleKeyDown = _react.useCallback.call(void 0,
|
|
1573
|
+
(e) => {
|
|
1574
|
+
if (e.key !== "Enter" && e.key !== " ") return;
|
|
1575
|
+
e.preventDefault();
|
|
1576
|
+
e.stopPropagation();
|
|
1577
|
+
activate();
|
|
1578
|
+
},
|
|
1579
|
+
[activate]
|
|
1580
|
+
);
|
|
1581
|
+
const handleLinkClick = _react.useCallback.call(void 0,
|
|
1582
|
+
(e) => {
|
|
1583
|
+
if (item.disabled) {
|
|
1584
|
+
e.preventDefault();
|
|
1585
|
+
e.stopPropagation();
|
|
1586
|
+
return;
|
|
1587
|
+
}
|
|
1588
|
+
_optionalChain([item, 'access', _24 => _24.onClick, 'optionalCall', _25 => _25()]);
|
|
1589
|
+
_optionalChain([onItemClick, 'optionalCall', _26 => _26(item)]);
|
|
1590
|
+
},
|
|
1591
|
+
[item, onItemClick]
|
|
1592
|
+
);
|
|
1593
|
+
if (item.type === "separator") {
|
|
1594
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "bg-ods-system-greys-soft-grey h-1 w-full" });
|
|
1595
|
+
}
|
|
1596
|
+
const itemClasses = _chunkFIG2RKZFcjs.cn.call(void 0,
|
|
1597
|
+
ROW_CLASSES,
|
|
1598
|
+
item.disabled ? "text-ods-text-secondary cursor-not-allowed pointer-events-none opacity-60" : "text-ods-text-primary hover:bg-ods-bg-hover"
|
|
1599
|
+
);
|
|
1600
|
+
const subTriggerClasses = _chunkFIG2RKZFcjs.cn.call(void 0,
|
|
1601
|
+
itemClasses,
|
|
1602
|
+
"data-[state=open]:bg-ods-bg-active focus:bg-ods-bg-hover"
|
|
1603
|
+
);
|
|
1604
|
+
const renderAsLink = !!item.href && item.type !== "submenu" && item.type !== "checkbox";
|
|
1605
|
+
const rowContent = /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
1606
|
+
item.icon && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1607
|
+
"div",
|
|
1608
|
+
{
|
|
1609
|
+
className: _chunkFIG2RKZFcjs.cn.call(void 0,
|
|
1610
|
+
"w-4 h-4 md:w-6 md:h-6 flex-shrink-0 flex items-center justify-center",
|
|
1611
|
+
item.danger && "text-ods-error",
|
|
1612
|
+
item.disabled && "opacity-50"
|
|
1613
|
+
),
|
|
1614
|
+
children: item.icon
|
|
1615
|
+
}
|
|
1616
|
+
),
|
|
1617
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1618
|
+
"span",
|
|
1619
|
+
{
|
|
1620
|
+
className: _chunkFIG2RKZFcjs.cn.call(void 0,
|
|
1621
|
+
"flex-1 text-h4 font-medium leading-6",
|
|
1622
|
+
item.disabled ? "text-ods-text-secondary" : item.danger ? "text-ods-error" : "text-ods-text-primary"
|
|
1623
|
+
),
|
|
1624
|
+
children: item.label
|
|
1625
|
+
}
|
|
1626
|
+
),
|
|
1627
|
+
item.type === "checkbox" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1628
|
+
"div",
|
|
1629
|
+
{
|
|
1630
|
+
className: _chunkFIG2RKZFcjs.cn.call(void 0,
|
|
1631
|
+
"w-4 h-4 md:w-6 md:h-6 flex items-center justify-center rounded-md transition-colors",
|
|
1632
|
+
item.checked ? "bg-ods-accent" : "border-2 border-ods-border bg-transparent"
|
|
1633
|
+
),
|
|
1634
|
+
children: item.checked && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Check, { className: "w-3 h-3 md:w-4 md:h-4 text-ods-text-on-accent", strokeWidth: 3 })
|
|
1635
|
+
}
|
|
1636
|
+
),
|
|
1637
|
+
item.type === "submenu" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkC6ASEPZLcjs.Chevron02RightIcon, { className: "w-4 h-4 md:w-6 md:h-6 text-ods-text-secondary" })
|
|
1638
|
+
] });
|
|
1639
|
+
if (renderAsLink && item.href) {
|
|
1640
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: WRAPPER_CLASSES, children: [
|
|
1641
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1642
|
+
_chunkWBR7H6E3cjs.next_link_default,
|
|
1643
|
+
{
|
|
1644
|
+
href: item.href,
|
|
1645
|
+
prefetch: false,
|
|
1646
|
+
className: itemClasses,
|
|
1647
|
+
onClick: handleLinkClick,
|
|
1648
|
+
"aria-disabled": item.disabled,
|
|
1649
|
+
tabIndex: item.disabled ? -1 : void 0,
|
|
1650
|
+
children: rowContent
|
|
1651
|
+
}
|
|
1652
|
+
),
|
|
1653
|
+
item.iconAction && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SecondaryAction, { action: item.iconAction })
|
|
1654
|
+
] });
|
|
1655
|
+
}
|
|
1656
|
+
if (item.type === "submenu" && item.submenu) {
|
|
1657
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: WRAPPER_CLASSES, children: [
|
|
1658
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, DropdownMenuPrimitive.Sub, { children: [
|
|
1659
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1660
|
+
DropdownMenuPrimitive.SubTrigger,
|
|
1661
|
+
{
|
|
1662
|
+
disabled: item.disabled,
|
|
1663
|
+
className: subTriggerClasses,
|
|
1664
|
+
children: rowContent
|
|
1665
|
+
}
|
|
1666
|
+
),
|
|
1667
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1668
|
+
DropdownMenuPrimitive.SubContent,
|
|
1669
|
+
{
|
|
1670
|
+
sideOffset: 4,
|
|
1671
|
+
className: "z-[1500] min-w-[256px] max-h-[var(--radix-popper-available-height)] bg-ods-bg border border-ods-border rounded-md shadow-xl overflow-y-auto p-0",
|
|
1672
|
+
children: item.submenu.map((subItem, index) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1673
|
+
MenuItem,
|
|
1674
|
+
{
|
|
1675
|
+
item: subItem,
|
|
1676
|
+
onItemClick
|
|
1677
|
+
},
|
|
1678
|
+
subItem.id || index
|
|
1679
|
+
))
|
|
1680
|
+
}
|
|
1681
|
+
) })
|
|
1682
|
+
] }),
|
|
1683
|
+
item.iconAction && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SecondaryAction, { action: item.iconAction })
|
|
1684
|
+
] });
|
|
1685
|
+
}
|
|
1686
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: WRAPPER_CLASSES, children: [
|
|
1687
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1688
|
+
"div",
|
|
1689
|
+
{
|
|
1690
|
+
role: "menuitem",
|
|
1691
|
+
tabIndex: item.disabled ? -1 : 0,
|
|
1692
|
+
"aria-disabled": item.disabled,
|
|
1693
|
+
className: itemClasses,
|
|
1694
|
+
onClick: handleClick,
|
|
1695
|
+
onKeyDown: handleKeyDown,
|
|
1696
|
+
children: rowContent
|
|
1697
|
+
}
|
|
1698
|
+
),
|
|
1699
|
+
item.iconAction && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SecondaryAction, { action: item.iconAction })
|
|
1700
|
+
] });
|
|
1701
|
+
};
|
|
1702
|
+
var GroupSeparator = () => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "bg-ods-bg-surface h-[3px] w-full" });
|
|
1703
|
+
var ActionsMenu = ({
|
|
1704
|
+
groups,
|
|
1705
|
+
className = "",
|
|
1706
|
+
onItemClick
|
|
1707
|
+
}) => {
|
|
1708
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1709
|
+
"div",
|
|
1710
|
+
{
|
|
1711
|
+
className: `relative min-w-[256px] max-h-[var(--radix-popper-available-height)] bg-ods-bg border border-ods-border rounded-md shadow-lg overflow-y-auto ${className}`,
|
|
1712
|
+
children: groups.map((group, groupIndex) => {
|
|
1713
|
+
const groupKey = group.id || group.items.map((i) => i.id).join("|");
|
|
1714
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, React.default.Fragment, { children: [
|
|
1715
|
+
group.items.map((item, itemIndex) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1716
|
+
MenuItem,
|
|
1717
|
+
{
|
|
1718
|
+
item,
|
|
1719
|
+
onItemClick
|
|
1720
|
+
},
|
|
1721
|
+
item.id || `${groupKey}-${itemIndex}`
|
|
1722
|
+
)),
|
|
1723
|
+
group.separator && groupIndex < groups.length - 1 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, GroupSeparator, {})
|
|
1724
|
+
] }, groupKey);
|
|
1725
|
+
})
|
|
1726
|
+
}
|
|
1727
|
+
);
|
|
1728
|
+
};
|
|
1729
|
+
var ActionsMenuDropdown = ({
|
|
1730
|
+
groups,
|
|
1731
|
+
onItemClick,
|
|
1732
|
+
className,
|
|
1733
|
+
trigger,
|
|
1734
|
+
customTrigger,
|
|
1735
|
+
triggerAriaLabel = "More actions",
|
|
1736
|
+
triggerClassName,
|
|
1737
|
+
contentClassName,
|
|
1738
|
+
align = "end",
|
|
1739
|
+
side = "bottom",
|
|
1740
|
+
sideOffset = 6,
|
|
1741
|
+
open: openProp,
|
|
1742
|
+
onOpenChange,
|
|
1743
|
+
onCloseAutoFocus
|
|
1744
|
+
}) => {
|
|
1745
|
+
const [open = false, setOpen] = useControllableState({
|
|
1746
|
+
prop: openProp,
|
|
1747
|
+
defaultProp: false,
|
|
1748
|
+
onChange: onOpenChange
|
|
1749
|
+
});
|
|
1750
|
+
const handleItemClick = _react.useCallback.call(void 0,
|
|
1751
|
+
(item) => {
|
|
1752
|
+
_optionalChain([onItemClick, 'optionalCall', _27 => _27(item)]);
|
|
1753
|
+
if (item.type !== "checkbox" && item.type !== "submenu") {
|
|
1754
|
+
setOpen(false);
|
|
1755
|
+
}
|
|
1756
|
+
},
|
|
1757
|
+
[onItemClick, setOpen]
|
|
1758
|
+
);
|
|
1759
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkTU26IZPOcjs.DropdownMenu, { open, onOpenChange: setOpen, modal: false, children: [
|
|
1760
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkTU26IZPOcjs.DropdownMenuTrigger, { asChild: true, children: _nullishCoalesce(customTrigger, () => ( /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1761
|
+
_chunkTU26IZPOcjs.Button,
|
|
1762
|
+
{
|
|
1763
|
+
variant: "outline",
|
|
1764
|
+
size: "icon",
|
|
1765
|
+
"aria-label": triggerAriaLabel,
|
|
1766
|
+
className: triggerClassName || "bg-ods-card border-ods-border hover:bg-ods-bg-hover flex items-center justify-center focus-visible:ring-0",
|
|
1767
|
+
leftIcon: _nullishCoalesce(trigger, () => ( /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkC6ASEPZLcjs.Ellipsis01Icon, { size: 24, className: "text-ods-text-primary" })))
|
|
1768
|
+
}
|
|
1769
|
+
))) }),
|
|
1770
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1771
|
+
_chunkTU26IZPOcjs.DropdownMenuContent,
|
|
1772
|
+
{
|
|
1773
|
+
align,
|
|
1774
|
+
side,
|
|
1775
|
+
sideOffset,
|
|
1776
|
+
onCloseAutoFocus,
|
|
1777
|
+
className: _chunkFIG2RKZFcjs.cn.call(void 0,
|
|
1778
|
+
"p-0 border-0 bg-transparent shadow-none overflow-visible",
|
|
1779
|
+
contentClassName
|
|
1780
|
+
),
|
|
1781
|
+
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1782
|
+
ActionsMenu,
|
|
1783
|
+
{
|
|
1784
|
+
groups,
|
|
1785
|
+
onItemClick: handleItemClick,
|
|
1786
|
+
className
|
|
1787
|
+
}
|
|
1788
|
+
)
|
|
1789
|
+
}
|
|
1790
|
+
)
|
|
1791
|
+
] });
|
|
1792
|
+
};
|
|
1793
|
+
|
|
1794
|
+
// src/components/chat/utils/is-cross-origin-url.ts
|
|
1795
|
+
function isCrossOriginUrl(url) {
|
|
1796
|
+
if (!url) return false;
|
|
1797
|
+
if (url.startsWith("/") && !url.startsWith("//")) return false;
|
|
1798
|
+
return true;
|
|
1799
|
+
}
|
|
1800
|
+
|
|
1801
|
+
// src/components/chat/utils/decide-new-tab.ts
|
|
1802
|
+
function decideNewTab(input) {
|
|
1803
|
+
const { href, targetPlatform, openIn, alwaysNewTab, runtimeMode, currentSource } = input;
|
|
1804
|
+
if (runtimeMode === "embed") return true;
|
|
1805
|
+
if (openIn === "new-tab") return true;
|
|
1806
|
+
if (alwaysNewTab === true) return true;
|
|
1807
|
+
if (openIn === "same-tab") return false;
|
|
1808
|
+
if (targetPlatform !== void 0 && targetPlatform !== null && currentSource) {
|
|
1809
|
+
return targetPlatform !== currentSource;
|
|
1810
|
+
}
|
|
1811
|
+
if (!href) return false;
|
|
1812
|
+
return isCrossOriginUrl(href);
|
|
1813
|
+
}
|
|
1814
|
+
|
|
1815
|
+
// src/components/chat/utils/nav-anchor-props.ts
|
|
1816
|
+
function computeIsNewTab(runtime, href, targetPlatform) {
|
|
1817
|
+
if (!href) return false;
|
|
1818
|
+
if (runtime.navigation.mode === "embed") return true;
|
|
1819
|
+
return _nullishCoalesce(_optionalChain([runtime, 'access', _28 => _28.navigation, 'access', _29 => _29.decideNewTab, 'optionalCall', _30 => _30({ href, targetPlatform })]), () => ( decideNewTab({
|
|
1820
|
+
href,
|
|
1821
|
+
targetPlatform,
|
|
1822
|
+
currentSource: _nullishCoalesce(runtime.source, () => ( ""))
|
|
1823
|
+
})));
|
|
1824
|
+
}
|
|
1825
|
+
function newTabAnchorAttrs(isNewTab) {
|
|
1826
|
+
return isNewTab ? { target: "_blank", rel: "noopener noreferrer" } : {};
|
|
1827
|
+
}
|
|
1828
|
+
function buildAnchorProps(href, isNewTab) {
|
|
1829
|
+
return href ? { href, ...newTabAnchorAttrs(isNewTab) } : void 0;
|
|
1830
|
+
}
|
|
1831
|
+
|
|
1832
|
+
// src/components/chat/utils/chat-nav-resolution.ts
|
|
1833
|
+
var NEW_TAB_FEATURES = "noopener,noreferrer";
|
|
1834
|
+
function isModifierClick(e) {
|
|
1835
|
+
return e.button !== 0 || !!e.metaKey || !!e.ctrlKey || !!e.shiftKey || !!e.altKey;
|
|
1836
|
+
}
|
|
1837
|
+
function stripSameOriginToPath(href) {
|
|
1838
|
+
if (!href.startsWith("http")) return href;
|
|
1839
|
+
try {
|
|
1840
|
+
const u = new URL(href);
|
|
1841
|
+
return u.pathname + u.search + u.hash;
|
|
1842
|
+
} catch (e2) {
|
|
1843
|
+
return href;
|
|
1844
|
+
}
|
|
1845
|
+
}
|
|
1846
|
+
function resolveHrefForRuntime(href, runtime) {
|
|
1847
|
+
if (runtime.navigation.mode !== "embed") return href;
|
|
1848
|
+
if (href.startsWith("http")) return href;
|
|
1849
|
+
if (href.startsWith("//")) return href;
|
|
1850
|
+
const origin = runtime.navigation.defaultContentOrigin;
|
|
1851
|
+
if (!origin) return href;
|
|
1852
|
+
return origin.replace(/\/+$/, "") + (href.startsWith("/") ? href : "/" + href);
|
|
1853
|
+
}
|
|
1854
|
+
function resolveExternalNavigation(args) {
|
|
1855
|
+
let abs = args.href;
|
|
1856
|
+
if (abs.startsWith("//")) abs = window.location.protocol + abs;
|
|
1857
|
+
if (!abs.startsWith("http")) {
|
|
1858
|
+
if (args.runtime.navigation.defaultContentOrigin) {
|
|
1859
|
+
let origin = args.runtime.navigation.defaultContentOrigin;
|
|
1860
|
+
while (origin.endsWith("/")) origin = origin.slice(0, -1);
|
|
1861
|
+
abs = origin + (abs.startsWith("/") ? abs : "/" + abs);
|
|
1862
|
+
} else if (args.runtime.navigation.mode === "embed" && process.env.NODE_ENV !== "production") {
|
|
1863
|
+
console.warn(
|
|
1864
|
+
"[chat-nav-resolution] relative href in embed mode with no defaultContentOrigin set on runtime.navigation \u2014 link will resolve against the embedder origin.",
|
|
1865
|
+
{ href: abs, targetPlatform: args.targetPlatform }
|
|
1866
|
+
);
|
|
1867
|
+
}
|
|
1868
|
+
}
|
|
1869
|
+
const open = () => {
|
|
1870
|
+
if (args.runtime.navigation.openExternal) {
|
|
1871
|
+
args.runtime.navigation.openExternal(abs);
|
|
1872
|
+
} else {
|
|
1873
|
+
window.open(abs, "_blank", NEW_TAB_FEATURES);
|
|
1874
|
+
}
|
|
1875
|
+
};
|
|
1876
|
+
return { href: abs, open };
|
|
1877
|
+
}
|
|
1878
|
+
|
|
1879
|
+
// src/components/chat/entity-cards/entity-author-card.tsx
|
|
1880
|
+
|
|
1881
|
+
var EMPTY_AUTHOR_PLACEHOLDER = {
|
|
1882
|
+
full_name: "\u2014",
|
|
1883
|
+
avatar_url: null,
|
|
1884
|
+
job_title: "Unknown"
|
|
1885
|
+
};
|
|
1886
|
+
function EntityMetadataValueCell({
|
|
1887
|
+
value,
|
|
1888
|
+
label,
|
|
1889
|
+
className,
|
|
1890
|
+
uppercase = true
|
|
1891
|
+
}) {
|
|
1892
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: `bg-ods-card p-4 flex flex-col gap-3 ${_nullishCoalesce(className, () => ( ""))}`, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-0", children: [
|
|
1893
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-h4 text-ods-text-primary", children: uppercase ? value.toLocaleUpperCase() : value }),
|
|
1894
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "font-['DM_Sans'] font-medium text-[14px] leading-[20px] text-ods-text-secondary", children: label })
|
|
1895
|
+
] }) });
|
|
1896
|
+
}
|
|
1897
|
+
function EntityMetadataAuthorCell({
|
|
1898
|
+
author,
|
|
1899
|
+
roleLabel = "Author",
|
|
1900
|
+
className
|
|
1901
|
+
}) {
|
|
1902
|
+
const fullName = author.full_name || "Unknown Author";
|
|
1903
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: `bg-ods-card p-4 flex items-center gap-3 ${_nullishCoalesce(className, () => ( ""))}`, children: [
|
|
1904
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1905
|
+
SquareAvatar,
|
|
1906
|
+
{
|
|
1907
|
+
src: author.avatar_url || "",
|
|
1908
|
+
alt: fullName,
|
|
1909
|
+
fallback: nameInitials(fullName, ""),
|
|
1910
|
+
size: "md",
|
|
1911
|
+
variant: "round"
|
|
1912
|
+
}
|
|
1913
|
+
),
|
|
1914
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-0 flex-1 min-w-0", children: [
|
|
1915
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-h3 tracking-[-0.36px] text-ods-text-primary truncate", children: fullName }),
|
|
1916
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "font-['DM_Sans'] font-medium text-[14px] leading-[20px] text-ods-text-secondary", children: author.job_title || roleLabel })
|
|
1917
|
+
] })
|
|
1918
|
+
] });
|
|
1919
|
+
}
|
|
1920
|
+
function EntityAuthorCard({
|
|
1921
|
+
author,
|
|
1922
|
+
roleLabel = "Author",
|
|
1923
|
+
publishedAt,
|
|
1924
|
+
publishedLabel = "Published",
|
|
1925
|
+
extraCells,
|
|
1926
|
+
renderEmptyAuthor = false,
|
|
1927
|
+
className
|
|
1928
|
+
}) {
|
|
1929
|
+
const hasAuthor = !!_optionalChain([author, 'optionalAccess', _31 => _31.full_name]);
|
|
1930
|
+
if (!hasAuthor && !renderEmptyAuthor) return null;
|
|
1931
|
+
const effectiveAuthor = hasAuthor ? author : EMPTY_AUTHOR_PLACEHOLDER;
|
|
1932
|
+
const formatted = publishedAt ? formatDate(publishedAt) : "";
|
|
1933
|
+
const dateLabel = formatted === "Invalid Date" ? "" : formatted;
|
|
1934
|
+
const showDateCell = !!dateLabel;
|
|
1935
|
+
const extras = _nullishCoalesce(extraCells, () => ( []));
|
|
1936
|
+
const totalCells = extras.length + (showDateCell ? 1 : 0) + 1;
|
|
1937
|
+
const gridColsClass = totalCells >= 4 ? "md:grid-cols-4" : totalCells === 3 ? "md:grid-cols-3" : totalCells === 2 ? "md:grid-cols-2" : "md:grid-cols-1";
|
|
1938
|
+
const dividerClass = "border-b md:border-b-0 md:border-r border-ods-border";
|
|
1939
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
1940
|
+
"div",
|
|
1941
|
+
{
|
|
1942
|
+
className: `grid grid-cols-1 ${gridColsClass} border border-ods-border rounded-md overflow-hidden w-full ${_nullishCoalesce(className, () => ( ""))}`,
|
|
1943
|
+
children: [
|
|
1944
|
+
extras.map((cell, i) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1945
|
+
EntityMetadataValueCell,
|
|
1946
|
+
{
|
|
1947
|
+
value: cell.value,
|
|
1948
|
+
label: cell.label,
|
|
1949
|
+
uppercase: _nullishCoalesce(cell.uppercase, () => ( true)),
|
|
1950
|
+
className: dividerClass
|
|
1951
|
+
},
|
|
1952
|
+
`${cell.label}-${i}`
|
|
1953
|
+
)),
|
|
1954
|
+
showDateCell && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1955
|
+
EntityMetadataValueCell,
|
|
1956
|
+
{
|
|
1957
|
+
value: dateLabel,
|
|
1958
|
+
label: publishedLabel,
|
|
1959
|
+
uppercase: false,
|
|
1960
|
+
className: dividerClass
|
|
1961
|
+
}
|
|
1962
|
+
),
|
|
1963
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, EntityMetadataAuthorCell, { author: effectiveAuthor, roleLabel })
|
|
1964
|
+
]
|
|
1965
|
+
}
|
|
1966
|
+
);
|
|
1967
|
+
}
|
|
1968
|
+
|
|
1969
|
+
// src/components/chat/entity-cards/blog-image-placeholder.tsx
|
|
1970
|
+
|
|
1971
|
+
function BlogImagePlaceholder({
|
|
1972
|
+
imageUrl,
|
|
1973
|
+
title,
|
|
1974
|
+
className = ""
|
|
1975
|
+
}) {
|
|
1976
|
+
if (!imageUrl) return null;
|
|
1977
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: `relative block w-full h-full overflow-hidden bg-ods-bg ${className}`, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1978
|
+
"img",
|
|
1979
|
+
{
|
|
1980
|
+
src: imageUrl,
|
|
1981
|
+
alt: `Cover image for ${title}`,
|
|
1982
|
+
className: "block w-full h-full object-contain",
|
|
1983
|
+
loading: "lazy",
|
|
1984
|
+
onError: (e) => {
|
|
1985
|
+
e.currentTarget.style.display = "none";
|
|
1986
|
+
}
|
|
1987
|
+
}
|
|
1988
|
+
) });
|
|
1989
|
+
}
|
|
1990
|
+
|
|
1991
|
+
// src/utils/fetch-priority.ts
|
|
1992
|
+
|
|
1993
|
+
var REACT_MAJOR = parseInt((React.default.version || "0").split(".")[0], 10);
|
|
1994
|
+
var USE_CAMEL_CASE_FETCH_PRIORITY = REACT_MAJOR >= 19;
|
|
1995
|
+
function fetchPriorityProp(priority) {
|
|
1996
|
+
const value = priority === void 0 ? "auto" : typeof priority === "boolean" ? priority ? "high" : "low" : priority;
|
|
1997
|
+
return USE_CAMEL_CASE_FETCH_PRIORITY ? { fetchPriority: value } : { fetchpriority: value };
|
|
1998
|
+
}
|
|
1999
|
+
|
|
2000
|
+
// src/components/features/video.tsx
|
|
2001
|
+
|
|
2002
|
+
var _muxplayerreact = require('@mux/mux-player-react'); var _muxplayerreact2 = _interopRequireDefault(_muxplayerreact);
|
|
2003
|
+
|
|
2004
|
+
if (typeof window !== "undefined") {
|
|
2005
|
+
const w = window;
|
|
2006
|
+
if (!_optionalChain([w, 'access', _32 => _32.chrome, 'optionalAccess', _33 => _33.cast])) {
|
|
2007
|
+
w.chrome = { ..._nullishCoalesce(w.chrome, () => ( {})), cast: { isAvailable: false } };
|
|
2008
|
+
}
|
|
2009
|
+
}
|
|
2010
|
+
if (typeof window !== "undefined" && typeof console !== "undefined") {
|
|
2011
|
+
const w = window;
|
|
2012
|
+
if (!w.__MEDIA_CHROME_WARN_PATCHED__) {
|
|
2013
|
+
w.__MEDIA_CHROME_WARN_PATCHED__ = true;
|
|
2014
|
+
const MEDIA_CHROME_NO_STYLESHEET_PREFIX = "Media Chrome: No style sheet found on style tag of";
|
|
2015
|
+
const originalWarn = console.warn.bind(console);
|
|
2016
|
+
console.warn = (...args) => {
|
|
2017
|
+
if (typeof args[0] === "string" && args[0].startsWith(MEDIA_CHROME_NO_STYLESHEET_PREFIX)) {
|
|
2018
|
+
return;
|
|
2019
|
+
}
|
|
2020
|
+
originalWarn(...args);
|
|
2021
|
+
};
|
|
2022
|
+
}
|
|
2023
|
+
}
|
|
2024
|
+
var YT_HOSTS = /* @__PURE__ */ new Set([
|
|
2025
|
+
"youtube.com",
|
|
2026
|
+
"www.youtube.com",
|
|
2027
|
+
"m.youtube.com",
|
|
2028
|
+
"youtu.be",
|
|
2029
|
+
"youtube-nocookie.com",
|
|
2030
|
+
"www.youtube-nocookie.com"
|
|
2031
|
+
]);
|
|
2032
|
+
function isYouTubeUrl(url) {
|
|
2033
|
+
try {
|
|
2034
|
+
return YT_HOSTS.has(new URL(url, "http://placeholder.local").hostname.toLowerCase());
|
|
2035
|
+
} catch (e3) {
|
|
2036
|
+
return false;
|
|
2037
|
+
}
|
|
2038
|
+
}
|
|
2039
|
+
var YT_PATH_RE = /^\/(?:embed|v|shorts)\/([^/]+)\/?$/;
|
|
2040
|
+
var BARE_YT_ID_RE = /^[A-Za-z0-9_-]{11}$/;
|
|
2041
|
+
function extractYouTubeId(url) {
|
|
2042
|
+
if (!url) return null;
|
|
2043
|
+
if (BARE_YT_ID_RE.test(url)) return url;
|
|
2044
|
+
let u;
|
|
2045
|
+
try {
|
|
2046
|
+
u = new URL(url, "http://placeholder.local");
|
|
2047
|
+
} catch (e4) {
|
|
2048
|
+
return null;
|
|
2049
|
+
}
|
|
2050
|
+
if (!YT_HOSTS.has(u.hostname.toLowerCase())) return null;
|
|
2051
|
+
if (u.hostname.toLowerCase().endsWith("youtu.be")) {
|
|
2052
|
+
return _nullishCoalesce(u.pathname.split("/").filter(Boolean)[0], () => ( null));
|
|
2053
|
+
}
|
|
2054
|
+
const v = u.searchParams.get("v");
|
|
2055
|
+
if (v) return v;
|
|
2056
|
+
const m = u.pathname.match(YT_PATH_RE);
|
|
2057
|
+
return m ? m[1] : null;
|
|
2058
|
+
}
|
|
2059
|
+
function Video(props) {
|
|
2060
|
+
const url = props.url;
|
|
2061
|
+
if (!url) return null;
|
|
2062
|
+
const effectiveKind = resolveKind(props, url);
|
|
2063
|
+
const layout = _nullishCoalesce(props.layout, () => ( "native"));
|
|
2064
|
+
const inner = effectiveKind === "youtube" ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2065
|
+
YouTubeFacade,
|
|
2066
|
+
{
|
|
2067
|
+
url,
|
|
2068
|
+
title: props.title,
|
|
2069
|
+
priority: props.priority,
|
|
2070
|
+
className: props.className,
|
|
2071
|
+
minimalControls: props.minimalControls
|
|
2072
|
+
}
|
|
2073
|
+
) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2074
|
+
FilePlayer,
|
|
2075
|
+
{
|
|
2076
|
+
url,
|
|
2077
|
+
poster: props.poster,
|
|
2078
|
+
muted: props.muted,
|
|
2079
|
+
srtContent: "srtContent" in props ? props.srtContent : null,
|
|
2080
|
+
captionsUrl: "captionsUrl" in props ? props.captionsUrl : null,
|
|
2081
|
+
className: props.className
|
|
2082
|
+
}
|
|
2083
|
+
);
|
|
2084
|
+
return wrapWithLayout(inner, layout);
|
|
2085
|
+
}
|
|
2086
|
+
function resolveKind(props, url) {
|
|
2087
|
+
if ("kind" in props) {
|
|
2088
|
+
if (props.kind === "youtube") return "youtube";
|
|
2089
|
+
if (props.kind === "file") return "file";
|
|
2090
|
+
}
|
|
2091
|
+
if (BARE_YT_ID_RE.test(url)) return "youtube";
|
|
2092
|
+
return isYouTubeUrl(url) ? "youtube" : "file";
|
|
2093
|
+
}
|
|
2094
|
+
function wrapWithLayout(inner, layout) {
|
|
2095
|
+
switch (layout) {
|
|
2096
|
+
case "centered":
|
|
2097
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex justify-center w-full", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-full max-w-3xl aspect-video rounded-lg overflow-hidden border border-ods-border", children: inner }) });
|
|
2098
|
+
case "fill":
|
|
2099
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "absolute inset-0 w-full h-full", children: inner });
|
|
2100
|
+
case "native":
|
|
2101
|
+
default:
|
|
2102
|
+
return inner;
|
|
2103
|
+
}
|
|
2104
|
+
}
|
|
2105
|
+
function FilePlayer({
|
|
2106
|
+
url,
|
|
2107
|
+
poster,
|
|
2108
|
+
muted,
|
|
2109
|
+
srtContent,
|
|
2110
|
+
captionsUrl,
|
|
2111
|
+
className
|
|
2112
|
+
}) {
|
|
2113
|
+
if (process.env.NODE_ENV !== "production" && srtContent && !captionsUrl) {
|
|
2114
|
+
console.warn(
|
|
2115
|
+
"[Video] srtContent supplied without captionsUrl \u2014 captions will not render. Pass captionsUrl (the VTT URL) instead; raw SRT text overlays are no longer supported."
|
|
2116
|
+
);
|
|
2117
|
+
}
|
|
2118
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2119
|
+
_muxplayerreact2.default,
|
|
2120
|
+
{
|
|
2121
|
+
src: url,
|
|
2122
|
+
poster: poster || void 0,
|
|
2123
|
+
streamType: "on-demand",
|
|
2124
|
+
playsInline: true,
|
|
2125
|
+
muted,
|
|
2126
|
+
preferCmcd: "header",
|
|
2127
|
+
accentColor: "var(--ods-accent, var(--color-accent-primary))",
|
|
2128
|
+
className,
|
|
2129
|
+
style: { width: "100%", height: "100%" },
|
|
2130
|
+
children: captionsUrl ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2131
|
+
"track",
|
|
2132
|
+
{
|
|
2133
|
+
kind: "captions",
|
|
2134
|
+
src: captionsUrl,
|
|
2135
|
+
srcLang: "en",
|
|
2136
|
+
label: "English",
|
|
2137
|
+
default: true
|
|
2138
|
+
}
|
|
2139
|
+
) : null
|
|
2140
|
+
}
|
|
2141
|
+
);
|
|
2142
|
+
}
|
|
2143
|
+
function YouTubeFacade({
|
|
2144
|
+
url,
|
|
2145
|
+
title = "YouTube Video",
|
|
2146
|
+
priority,
|
|
2147
|
+
className,
|
|
2148
|
+
minimalControls
|
|
2149
|
+
}) {
|
|
2150
|
+
const videoId = extractYouTubeId(url);
|
|
2151
|
+
if (!videoId) return null;
|
|
2152
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, YouTubeFacadeInner, { videoId, title, priority, className, minimalControls });
|
|
2153
|
+
}
|
|
2154
|
+
var YT_NOCOOKIE_ORIGIN = "https://www.youtube-nocookie.com";
|
|
2155
|
+
var YT_STATE_ENDED = 0;
|
|
2156
|
+
var YT_STATE_PLAYING = 1;
|
|
2157
|
+
var YT_PLAYING_BLUR_DELAY_MS = 1e3;
|
|
2158
|
+
function YouTubeFacadeInner({
|
|
2159
|
+
videoId,
|
|
2160
|
+
title,
|
|
2161
|
+
priority,
|
|
2162
|
+
className,
|
|
2163
|
+
minimalControls
|
|
2164
|
+
}) {
|
|
2165
|
+
const [activated, setActivated] = _react.useState.call(void 0, false);
|
|
2166
|
+
const iframeRef = _react.useRef.call(void 0, null);
|
|
2167
|
+
const { embedUrl, posterJpg, posterWebp } = _react.useMemo.call(void 0, () => {
|
|
2168
|
+
const params = new URLSearchParams({
|
|
2169
|
+
autoplay: "1",
|
|
2170
|
+
rel: "0",
|
|
2171
|
+
modestbranding: "1",
|
|
2172
|
+
playsinline: "1",
|
|
2173
|
+
enablejsapi: "1"
|
|
2174
|
+
});
|
|
2175
|
+
if (typeof window !== "undefined") {
|
|
2176
|
+
params.set("origin", window.location.origin);
|
|
2177
|
+
}
|
|
2178
|
+
if (minimalControls) {
|
|
2179
|
+
params.set("controls", "0");
|
|
2180
|
+
params.set("fs", "0");
|
|
2181
|
+
params.set("iv_load_policy", "3");
|
|
2182
|
+
params.set("cc_load_policy", "0");
|
|
2183
|
+
params.set("disablekb", "1");
|
|
2184
|
+
}
|
|
2185
|
+
return {
|
|
2186
|
+
embedUrl: `${YT_NOCOOKIE_ORIGIN}/embed/${videoId}?${params.toString()}`,
|
|
2187
|
+
posterJpg: `https://i.ytimg.com/vi/${videoId}/mqdefault.jpg`,
|
|
2188
|
+
posterWebp: `https://i.ytimg.com/vi_webp/${videoId}/mqdefault.webp`
|
|
2189
|
+
};
|
|
2190
|
+
}, [videoId, minimalControls]);
|
|
2191
|
+
_react.useEffect.call(void 0, () => {
|
|
2192
|
+
if (!activated) return;
|
|
2193
|
+
const iframe = iframeRef.current;
|
|
2194
|
+
if (!iframe) return;
|
|
2195
|
+
function subscribe() {
|
|
2196
|
+
_optionalChain([iframe, 'optionalAccess', _34 => _34.contentWindow, 'optionalAccess', _35 => _35.postMessage, 'call', _36 => _36(
|
|
2197
|
+
'{"event":"listening"}',
|
|
2198
|
+
YT_NOCOOKIE_ORIGIN
|
|
2199
|
+
)]);
|
|
2200
|
+
}
|
|
2201
|
+
iframe.addEventListener("load", subscribe);
|
|
2202
|
+
subscribe();
|
|
2203
|
+
let blurTimer = null;
|
|
2204
|
+
function handleMessage(event) {
|
|
2205
|
+
if (event.origin !== YT_NOCOOKIE_ORIGIN) return;
|
|
2206
|
+
if (typeof event.data !== "string") return;
|
|
2207
|
+
let payload = null;
|
|
2208
|
+
try {
|
|
2209
|
+
payload = JSON.parse(event.data);
|
|
2210
|
+
} catch (e5) {
|
|
2211
|
+
return;
|
|
2212
|
+
}
|
|
2213
|
+
if (!payload || payload.event !== "infoDelivery") return;
|
|
2214
|
+
const state = _optionalChain([payload, 'access', _37 => _37.info, 'optionalAccess', _38 => _38.playerState]);
|
|
2215
|
+
if (typeof state !== "number") return;
|
|
2216
|
+
if (state === YT_STATE_PLAYING) {
|
|
2217
|
+
if (blurTimer !== null) return;
|
|
2218
|
+
blurTimer = setTimeout(() => {
|
|
2219
|
+
blurTimer = null;
|
|
2220
|
+
_optionalChain([iframeRef, 'access', _39 => _39.current, 'optionalAccess', _40 => _40.blur, 'call', _41 => _41()]);
|
|
2221
|
+
}, YT_PLAYING_BLUR_DELAY_MS);
|
|
2222
|
+
return;
|
|
2223
|
+
}
|
|
2224
|
+
if (state === YT_STATE_ENDED) {
|
|
2225
|
+
setActivated(false);
|
|
2226
|
+
}
|
|
2227
|
+
}
|
|
2228
|
+
window.addEventListener("message", handleMessage);
|
|
2229
|
+
return () => {
|
|
2230
|
+
iframe.removeEventListener("load", subscribe);
|
|
2231
|
+
window.removeEventListener("message", handleMessage);
|
|
2232
|
+
if (blurTimer !== null) clearTimeout(blurTimer);
|
|
2233
|
+
};
|
|
2234
|
+
}, [activated]);
|
|
2235
|
+
const wrapperClass = `relative w-full ${_nullishCoalesce(className, () => ( ""))}`;
|
|
2236
|
+
const wrapperStyle = { paddingBottom: "56.25%" };
|
|
2237
|
+
if (activated) {
|
|
2238
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: wrapperClass, style: wrapperStyle, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2239
|
+
"iframe",
|
|
2240
|
+
{
|
|
2241
|
+
ref: iframeRef,
|
|
2242
|
+
src: embedUrl,
|
|
2243
|
+
allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",
|
|
2244
|
+
allowFullScreen: true,
|
|
2245
|
+
title,
|
|
2246
|
+
className: "absolute inset-0 w-full h-full border-0 rounded-lg"
|
|
2247
|
+
}
|
|
2248
|
+
) });
|
|
2249
|
+
}
|
|
2250
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: wrapperClass, style: wrapperStyle, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
2251
|
+
"button",
|
|
2252
|
+
{
|
|
2253
|
+
type: "button",
|
|
2254
|
+
"aria-label": `Play: ${title}`,
|
|
2255
|
+
onClick: () => setActivated(true),
|
|
2256
|
+
className: "group absolute inset-0 p-0 m-0 border border-ods-border rounded-lg overflow-hidden bg-ods-card cursor-pointer",
|
|
2257
|
+
children: [
|
|
2258
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "picture", { children: [
|
|
2259
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "source", { type: "image/webp", srcSet: posterWebp }),
|
|
2260
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2261
|
+
"img",
|
|
2262
|
+
{
|
|
2263
|
+
src: posterJpg,
|
|
2264
|
+
alt: title,
|
|
2265
|
+
loading: "lazy",
|
|
2266
|
+
...fetchPriorityProp(priority),
|
|
2267
|
+
decoding: priority ? "sync" : "async",
|
|
2268
|
+
className: "absolute inset-0 w-full h-full object-cover"
|
|
2269
|
+
}
|
|
2270
|
+
)
|
|
2271
|
+
] }),
|
|
2272
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "absolute inset-0 flex items-center justify-center bg-ods-bg-inverse bg-opacity-20 transition-opacity duration-200 group-hover:bg-opacity-30", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "flex items-center justify-center w-16 h-16 rounded-full bg-ods-accent text-ods-text-on-accent shadow-lg transition-transform duration-200 group-hover:scale-110", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkC6ASEPZLcjs.PlayIcon, { size: 24, color: "currentColor", className: "ml-1" }) }) })
|
|
2273
|
+
]
|
|
2274
|
+
}
|
|
2275
|
+
) });
|
|
2276
|
+
}
|
|
2277
|
+
|
|
2278
|
+
// src/components/features/video-ratio-tabs.tsx
|
|
2279
|
+
|
|
2280
|
+
var TAB_TRIGGER_CLASS = "rounded-none border-b-2 border-transparent data-[state=active]:border-ods-accent data-[state=active]:bg-transparent data-[state=active]:shadow-none px-4 py-2 text-sm text-ods-text-secondary data-[state=active]:text-ods-text-primary";
|
|
2281
|
+
var RATIO_GRID_CLASS = {
|
|
2282
|
+
portrait: "grid grid-cols-2 md:grid-cols-3 gap-4",
|
|
2283
|
+
square: "grid grid-cols-2 md:grid-cols-3 gap-4",
|
|
2284
|
+
landscape: "grid grid-cols-1 md:grid-cols-2 gap-4"
|
|
2285
|
+
};
|
|
2286
|
+
var RATIO_DISPLAY_GRID_CLASS = {
|
|
2287
|
+
portrait: "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4",
|
|
2288
|
+
square: "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4",
|
|
2289
|
+
landscape: "grid grid-cols-1 md:grid-cols-2 gap-6"
|
|
2290
|
+
};
|
|
2291
|
+
var RATIO_TAB_CONFIG = [
|
|
2292
|
+
{ key: "portrait", label: "Portrait 9:16" },
|
|
2293
|
+
{ key: "square", label: "Square 1:1" },
|
|
2294
|
+
{ key: "landscape", label: "Landscape 16:9" }
|
|
2295
|
+
];
|
|
2296
|
+
function RatioTabs({
|
|
2297
|
+
groups,
|
|
2298
|
+
defaultTab,
|
|
2299
|
+
className = ""
|
|
2300
|
+
}) {
|
|
2301
|
+
const activeTabs = RATIO_TAB_CONFIG.filter((t) => groups[t.key].count > 0);
|
|
2302
|
+
if (activeTabs.length <= 1) {
|
|
2303
|
+
const active = activeTabs[0];
|
|
2304
|
+
return active ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment, { children: groups[active.key].render() }) : null;
|
|
2305
|
+
}
|
|
2306
|
+
const firstTab = defaultTab && groups[defaultTab].count > 0 ? defaultTab : activeTabs[0].key;
|
|
2307
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Tabs, { defaultValue: firstTab, className: `w-full ${className}`, children: [
|
|
2308
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, TabsList, { className: "inline-flex justify-start rounded-none bg-transparent h-auto p-0 gap-0 mb-2", children: activeTabs.map((t) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, TabsTrigger, { value: t.key, className: TAB_TRIGGER_CLASS, children: [
|
|
2309
|
+
t.label,
|
|
2310
|
+
" (",
|
|
2311
|
+
groups[t.key].count,
|
|
2312
|
+
")"
|
|
2313
|
+
] }, t.key)) }),
|
|
2314
|
+
activeTabs.map((t) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2315
|
+
TabsContent,
|
|
2316
|
+
{
|
|
2317
|
+
value: t.key,
|
|
2318
|
+
forceMount: true,
|
|
2319
|
+
className: "data-[state=inactive]:hidden",
|
|
2320
|
+
children: groups[t.key].render()
|
|
2321
|
+
},
|
|
2322
|
+
t.key
|
|
2323
|
+
))
|
|
2324
|
+
] });
|
|
2325
|
+
}
|
|
2326
|
+
function detectAspectRatio(ratioString, width, height) {
|
|
2327
|
+
if (ratioString === "16:9") return "16:9";
|
|
2328
|
+
if (ratioString === "1:1") return "1:1";
|
|
2329
|
+
if (ratioString === "9:16") return "9:16";
|
|
2330
|
+
if (width && height) {
|
|
2331
|
+
if (Math.abs(width - height) < Math.min(width, height) * 0.1) return "1:1";
|
|
2332
|
+
if (width > height) return "16:9";
|
|
2333
|
+
}
|
|
2334
|
+
return "9:16";
|
|
2335
|
+
}
|
|
2336
|
+
function ratioToCategory(ratio) {
|
|
2337
|
+
if (ratio === "16:9") return "landscape";
|
|
2338
|
+
if (ratio === "1:1") return "square";
|
|
2339
|
+
return "portrait";
|
|
2340
|
+
}
|
|
2341
|
+
function groupByAspectRatio(items, getAspectRatio) {
|
|
2342
|
+
const portrait = [];
|
|
2343
|
+
const square = [];
|
|
2344
|
+
const landscape = [];
|
|
2345
|
+
for (const item of items) {
|
|
2346
|
+
const cat = ratioToCategory(getAspectRatio(item));
|
|
2347
|
+
if (cat === "landscape") landscape.push(item);
|
|
2348
|
+
else if (cat === "square") square.push(item);
|
|
2349
|
+
else portrait.push(item);
|
|
2350
|
+
}
|
|
2351
|
+
const filled = [portrait, square, landscape].filter((a) => a.length > 0).length;
|
|
2352
|
+
return { portrait, square, landscape, hasMultiple: filled > 1 };
|
|
2353
|
+
}
|
|
2354
|
+
|
|
2355
|
+
// src/components/features/video-bites-display.tsx
|
|
2356
|
+
|
|
2357
|
+
|
|
2358
|
+
var RATIO_TO_CSS_ASPECT = {
|
|
2359
|
+
portrait: "9 / 16",
|
|
2360
|
+
square: "1 / 1",
|
|
2361
|
+
landscape: "16 / 9"
|
|
2362
|
+
};
|
|
2363
|
+
function LazyBite({ ratio, children }) {
|
|
2364
|
+
const { ref, isNear } = _chunkDAAFVOTLcjs.useNearViewport.call(void 0, "500px");
|
|
2365
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { ref, style: { aspectRatio: RATIO_TO_CSS_ASPECT[ratio] }, children: isNear ? children : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-full h-full bg-ods-card rounded-md" }) });
|
|
2366
|
+
}
|
|
2367
|
+
function VideoBitesDisplay({
|
|
2368
|
+
bites,
|
|
2369
|
+
title = "Video Highlights",
|
|
2370
|
+
filterPublished = true,
|
|
2371
|
+
showTitle = true
|
|
2372
|
+
}) {
|
|
2373
|
+
const grouped = _react.useMemo.call(void 0, () => {
|
|
2374
|
+
const filtered = filterPublished ? bites.filter((b) => b.published) : bites;
|
|
2375
|
+
const sorted = [...filtered].sort((a, b) => {
|
|
2376
|
+
if (!a.created_at && !b.created_at) return 0;
|
|
2377
|
+
if (!a.created_at) return 1;
|
|
2378
|
+
if (!b.created_at) return -1;
|
|
2379
|
+
return new Date(b.created_at).getTime() - new Date(a.created_at).getTime();
|
|
2380
|
+
});
|
|
2381
|
+
return groupByAspectRatio(
|
|
2382
|
+
sorted,
|
|
2383
|
+
(b) => detectAspectRatio(b.aspect_ratio)
|
|
2384
|
+
);
|
|
2385
|
+
}, [bites, filterPublished]);
|
|
2386
|
+
const totalCount = grouped.portrait.length + grouped.square.length + grouped.landscape.length;
|
|
2387
|
+
if (totalCount === 0) return null;
|
|
2388
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-6 w-full min-w-0", children: [
|
|
2389
|
+
showTitle && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { className: "text-h1 tracking-[-1.12px] text-ods-text-primary break-words", children: title }),
|
|
2390
|
+
grouped.hasMultiple ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2391
|
+
RatioTabs,
|
|
2392
|
+
{
|
|
2393
|
+
groups: {
|
|
2394
|
+
portrait: {
|
|
2395
|
+
count: grouped.portrait.length,
|
|
2396
|
+
render: () => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, BiteGrid, { bites: grouped.portrait, ratio: "portrait" })
|
|
2397
|
+
},
|
|
2398
|
+
square: {
|
|
2399
|
+
count: grouped.square.length,
|
|
2400
|
+
render: () => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, BiteGrid, { bites: grouped.square, ratio: "square" })
|
|
2401
|
+
},
|
|
2402
|
+
landscape: {
|
|
2403
|
+
count: grouped.landscape.length,
|
|
2404
|
+
render: () => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, BiteGrid, { bites: grouped.landscape, ratio: "landscape" })
|
|
2405
|
+
}
|
|
2406
|
+
}
|
|
2407
|
+
}
|
|
2408
|
+
) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2409
|
+
BiteGrid,
|
|
2410
|
+
{
|
|
2411
|
+
bites: grouped.portrait.length > 0 ? grouped.portrait : grouped.square.length > 0 ? grouped.square : grouped.landscape,
|
|
2412
|
+
ratio: grouped.portrait.length > 0 ? "portrait" : grouped.square.length > 0 ? "square" : "landscape"
|
|
2413
|
+
}
|
|
2414
|
+
)
|
|
2415
|
+
] });
|
|
2416
|
+
}
|
|
2417
|
+
function BiteGrid({ bites, ratio }) {
|
|
2418
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: RATIO_DISPLAY_GRID_CLASS[ratio], children: bites.map((bite, index) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, LazyBite, { ratio, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, VideoBiteCard, { url: bite.url, title: bite.title, thumbnailUrl: bite.thumbnail_url }) }, bite.url || index)) });
|
|
2419
|
+
}
|
|
2420
|
+
function VideoBiteCard({ url, title, thumbnailUrl }) {
|
|
2421
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Card, { className: "overflow-hidden border border-ods-border bg-ods-card hover:border-ods-accent transition-colors flex flex-col h-full", children: [
|
|
2422
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "relative flex-1 min-h-0", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Video, { url, poster: thumbnailUrl || void 0, layout: "fill" }) }),
|
|
2423
|
+
title && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "p-4", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-h4 text-ods-text-primary line-clamp-2", title, children: title }) })
|
|
2424
|
+
] });
|
|
2425
|
+
}
|
|
2426
|
+
|
|
2427
|
+
// src/components/features/entity-video-section.tsx
|
|
2428
|
+
|
|
2429
|
+
function EntityVideoSection({
|
|
2430
|
+
mainVideoUrl,
|
|
2431
|
+
youtubeUrl,
|
|
2432
|
+
highlightVideoUrl,
|
|
2433
|
+
highlightVideoThumbnail,
|
|
2434
|
+
mainVideoPoster,
|
|
2435
|
+
title = "Video",
|
|
2436
|
+
videoSummary,
|
|
2437
|
+
videoBites,
|
|
2438
|
+
bitesTitle = "Video Highlights",
|
|
2439
|
+
filterPublishedBites = true,
|
|
2440
|
+
MarkdownRenderer,
|
|
2441
|
+
srtContent,
|
|
2442
|
+
captionsUrl,
|
|
2443
|
+
priority = false
|
|
2444
|
+
}) {
|
|
2445
|
+
const hasFullVideo = !!(youtubeUrl || mainVideoUrl);
|
|
2446
|
+
const hasHighlight = !!highlightVideoUrl;
|
|
2447
|
+
const hasVideo = hasFullVideo || hasHighlight;
|
|
2448
|
+
if (!hasVideo && !videoSummary && (!videoBites || videoBites.length === 0)) {
|
|
2449
|
+
return null;
|
|
2450
|
+
}
|
|
2451
|
+
const fullVideoUrl = youtubeUrl || mainVideoUrl || null;
|
|
2452
|
+
const fullVideoKind = youtubeUrl ? "youtube" : "auto";
|
|
2453
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
2454
|
+
hasVideo && (hasFullVideo && hasHighlight ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Tabs, { defaultValue: "full-video", className: "w-full", children: [
|
|
2455
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, TabsList, { className: "inline-flex justify-start rounded-none bg-transparent h-auto p-0 gap-0", children: [
|
|
2456
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2457
|
+
TabsTrigger,
|
|
2458
|
+
{
|
|
2459
|
+
value: "full-video",
|
|
2460
|
+
className: "rounded-none border-b-2 border-transparent data-[state=active]:border-ods-accent data-[state=active]:bg-transparent data-[state=active]:shadow-none px-4 md:px-6 py-3 text-ods-text-secondary data-[state=active]:text-ods-text-primary",
|
|
2461
|
+
children: "Full Video"
|
|
2462
|
+
}
|
|
2463
|
+
),
|
|
2464
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2465
|
+
TabsTrigger,
|
|
2466
|
+
{
|
|
2467
|
+
value: "highlights",
|
|
2468
|
+
className: "rounded-none border-b-2 border-transparent data-[state=active]:border-ods-accent data-[state=active]:bg-transparent data-[state=active]:shadow-none px-4 md:px-6 py-3 text-ods-text-secondary data-[state=active]:text-ods-text-primary",
|
|
2469
|
+
children: "Highlights"
|
|
2470
|
+
}
|
|
2471
|
+
)
|
|
2472
|
+
] }),
|
|
2473
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, TabsContent, { value: "full-video", className: "mt-4", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2474
|
+
Video,
|
|
2475
|
+
{
|
|
2476
|
+
kind: fullVideoKind,
|
|
2477
|
+
url: fullVideoUrl,
|
|
2478
|
+
poster: mainVideoPoster,
|
|
2479
|
+
title,
|
|
2480
|
+
srtContent,
|
|
2481
|
+
captionsUrl,
|
|
2482
|
+
layout: "centered",
|
|
2483
|
+
priority
|
|
2484
|
+
}
|
|
2485
|
+
) }),
|
|
2486
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, TabsContent, { value: "highlights", className: "mt-4", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2487
|
+
Video,
|
|
2488
|
+
{
|
|
2489
|
+
url: highlightVideoUrl,
|
|
2490
|
+
poster: highlightVideoThumbnail,
|
|
2491
|
+
layout: "centered"
|
|
2492
|
+
}
|
|
2493
|
+
) })
|
|
2494
|
+
] }) : hasFullVideo ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2495
|
+
Video,
|
|
2496
|
+
{
|
|
2497
|
+
kind: fullVideoKind,
|
|
2498
|
+
url: fullVideoUrl,
|
|
2499
|
+
poster: mainVideoPoster,
|
|
2500
|
+
title,
|
|
2501
|
+
srtContent,
|
|
2502
|
+
captionsUrl,
|
|
2503
|
+
layout: "centered",
|
|
2504
|
+
priority
|
|
2505
|
+
}
|
|
2506
|
+
) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2507
|
+
Video,
|
|
2508
|
+
{
|
|
2509
|
+
url: highlightVideoUrl,
|
|
2510
|
+
poster: highlightVideoThumbnail,
|
|
2511
|
+
layout: "centered",
|
|
2512
|
+
priority
|
|
2513
|
+
}
|
|
2514
|
+
)),
|
|
2515
|
+
videoSummary && MarkdownRenderer && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-6 w-full min-w-0", children: [
|
|
2516
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { className: "text-h1 tracking-[-1.12px] text-ods-text-primary break-words", children: "Summary" }),
|
|
2517
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "text-h4 text-ods-text-primary break-words overflow-hidden", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, MarkdownRenderer, { content: videoSummary }) })
|
|
2518
|
+
] }),
|
|
2519
|
+
videoBites && videoBites.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2520
|
+
VideoBitesDisplay,
|
|
2521
|
+
{
|
|
2522
|
+
bites: videoBites,
|
|
2523
|
+
title: bitesTitle,
|
|
2524
|
+
filterPublished: filterPublishedBites
|
|
2525
|
+
}
|
|
2526
|
+
)
|
|
2527
|
+
] });
|
|
2528
|
+
}
|
|
2529
|
+
|
|
2530
|
+
// src/components/chat/utils/compact-card-classes.ts
|
|
2531
|
+
var COMPACT_CARD_OUTER = "my-1.5 flex items-start gap-3 w-full p-2 rounded-lg border border-ods-border bg-ods-card no-underline transition-colors hover:border-ods-text-secondary/40";
|
|
2532
|
+
var COMPACT_CARD_OUTER_STATIC = "my-1.5 flex items-start gap-3 w-full p-2 rounded-lg border border-ods-border bg-ods-card no-underline cursor-default";
|
|
2533
|
+
var COMPACT_CARD_SKELETON_OUTER = "my-1.5 flex w-full animate-pulse items-start gap-3 rounded-lg border border-ods-border bg-ods-card p-2";
|
|
2534
|
+
var COMPACT_CARD_IMAGE_SLOT = "relative block shrink-0 self-start w-14 h-14 aspect-square overflow-hidden rounded-md bg-ods-bg";
|
|
2535
|
+
var COMPACT_CARD_SKELETON_IMAGE_SLOT = "block h-14 w-14 aspect-square shrink-0 self-start rounded-md bg-ods-bg";
|
|
2536
|
+
var COMPACT_CARD_ICON_SLOT = "flex h-14 w-14 aspect-square shrink-0 self-start items-center justify-center rounded-md bg-ods-bg text-ods-accent";
|
|
2537
|
+
var COMPACT_CARD_TEXT_COL = "flex min-w-0 flex-1 flex-col gap-0.5 min-h-14";
|
|
2538
|
+
var COMPACT_CARD_TITLE_ROW = "flex items-center min-w-0 h-5";
|
|
2539
|
+
var COMPACT_CARD_META_ROW_BOX = "flex items-center min-w-0 h-4";
|
|
2540
|
+
var COMPACT_CARD_TITLE = "truncate text-sm font-semibold leading-5 text-ods-text-primary";
|
|
2541
|
+
var COMPACT_CARD_SUBTITLE = "truncate text-[11px] leading-4 text-ods-text-secondary";
|
|
2542
|
+
var COMPACT_CARD_SUMMARY = "truncate text-[11px] leading-4 text-ods-text-secondary/80";
|
|
2543
|
+
var COMPACT_CARD_META_ROW = "flex items-center gap-1.5 min-w-0 text-[11px] leading-4 text-ods-text-secondary";
|
|
2544
|
+
var COMPACT_CARD_ROW_FILLER = "\xA0";
|
|
2545
|
+
var SAFE_URL_SCHEMES = ["http:", "https:", "mailto:"];
|
|
2546
|
+
function safeHref(url) {
|
|
2547
|
+
if (!url) return null;
|
|
2548
|
+
if (/[\u0000-\u001f\u007f\u200b-\u200d\u2028\u2029\ufeff]/.test(url)) return null;
|
|
2549
|
+
const trimmed = url.trim();
|
|
2550
|
+
if (!trimmed) return null;
|
|
2551
|
+
if (trimmed.startsWith("/") && !trimmed.startsWith("//")) return trimmed;
|
|
2552
|
+
if (trimmed.startsWith("#")) return trimmed;
|
|
2553
|
+
if (/^[a-z][a-z0-9+.-]*:$/i.test(trimmed)) return null;
|
|
2554
|
+
try {
|
|
2555
|
+
const parsed = new URL(trimmed, "https://_safehref_base.invalid");
|
|
2556
|
+
if (!SAFE_URL_SCHEMES.includes(parsed.protocol)) return null;
|
|
2557
|
+
if ((parsed.protocol === "https:" || parsed.protocol === "http:") && !parsed.hostname) return null;
|
|
2558
|
+
return trimmed;
|
|
2559
|
+
} catch (e6) {
|
|
2560
|
+
return null;
|
|
2561
|
+
}
|
|
2562
|
+
}
|
|
2563
|
+
|
|
2564
|
+
// src/components/chat/entity-cards/onboarding-guide-card.tsx
|
|
2565
|
+
_chunkWBR7H6E3cjs.init_next_link.call(void 0, );
|
|
2566
|
+
_chunkFIG2RKZFcjs.init_cn.call(void 0, );
|
|
2567
|
+
|
|
2568
|
+
|
|
2569
|
+
// src/components/chat/entity-cards/use-entity-card-link.ts
|
|
2570
|
+
|
|
2571
|
+
function useEntityCardLink({
|
|
2572
|
+
href,
|
|
2573
|
+
targetPlatform,
|
|
2574
|
+
target,
|
|
2575
|
+
rel
|
|
2576
|
+
}) {
|
|
2577
|
+
const runtime = _chunkMEAR2WHScjs.useChatRuntime.call(void 0, );
|
|
2578
|
+
return _react.useMemo.call(void 0, () => {
|
|
2579
|
+
if (target !== void 0 || rel !== void 0) {
|
|
2580
|
+
const safeRel = _nullishCoalesce(rel, () => ( (target === "_blank" ? "noopener noreferrer" : void 0)));
|
|
2581
|
+
return { target, rel: safeRel };
|
|
2582
|
+
}
|
|
2583
|
+
const newTab = runtime ? computeIsNewTab(runtime, href, _nullishCoalesce(targetPlatform, () => ( null))) : false;
|
|
2584
|
+
return newTab ? { target: "_blank", rel: "noopener noreferrer" } : { target: void 0, rel: void 0 };
|
|
2585
|
+
}, [target, rel, href, targetPlatform, runtime]);
|
|
2586
|
+
}
|
|
2587
|
+
|
|
2588
|
+
// src/components/chat/entity-cards/use-entity-card-placeholder.ts
|
|
2589
|
+
var NO_OP_BUILDER = () => "";
|
|
2590
|
+
function useEntityCardPlaceholder({
|
|
2591
|
+
title,
|
|
2592
|
+
placeholderUrl,
|
|
2593
|
+
siteName = "",
|
|
2594
|
+
aspect = "wide"
|
|
2595
|
+
}) {
|
|
2596
|
+
const runtime = _chunkMEAR2WHScjs.useChatRuntime.call(void 0, );
|
|
2597
|
+
const builder = _nullishCoalesce(_optionalChain([runtime, 'optionalAccess', _42 => _42.resolvePlaceholderUrl]), () => ( NO_OP_BUILDER));
|
|
2598
|
+
const enabled = placeholderUrl === void 0 && !!_optionalChain([runtime, 'optionalAccess', _43 => _43.resolvePlaceholderUrl]);
|
|
2599
|
+
const derived = _chunkDAAFVOTLcjs.useOgPlaceholder.call(void 0, builder, title, siteName, enabled, aspect);
|
|
2600
|
+
return placeholderUrl !== void 0 ? placeholderUrl : derived;
|
|
2601
|
+
}
|
|
2602
|
+
|
|
2603
|
+
// src/components/chat/entity-cards/onboarding-guide-card.tsx
|
|
2604
|
+
|
|
2605
|
+
function stripMarkdownPreview(text) {
|
|
2606
|
+
return text.replace(/```[\s\S]*?```/g, " ").replace(/^#{1,6}\s+/gm, "").replace(/!?\[([^\]]*)\]\([^)]*\)/g, "$1").replace(/[*_~`>]/g, "").replace(/^\s*[-+]\s+/gm, "").replace(/-{3,}/g, " ").replace(/\s+/g, " ").trim().replace(/^([\s\S]{240})[\s\S]+$/, "$1\u2026");
|
|
2607
|
+
}
|
|
2608
|
+
var HORIZONTAL_SIZE_TOKENS = {
|
|
2609
|
+
default: {
|
|
2610
|
+
padding: "p-4",
|
|
2611
|
+
step: "w-8 h-8 text-sm",
|
|
2612
|
+
title: "text-h5",
|
|
2613
|
+
summaryClamp: "line-clamp-2"
|
|
2614
|
+
}
|
|
2615
|
+
};
|
|
2616
|
+
function OnboardingGuideCardSkeleton({ size = "default" }) {
|
|
2617
|
+
if (size === "catalog") {
|
|
2618
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "bg-ods-system-greys-black border border-ods-border rounded-lg overflow-hidden flex flex-col p-6 gap-4 animate-pulse", children: [
|
|
2619
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col md:flex-row gap-4 md:gap-6", children: [
|
|
2620
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-full md:w-[256px] aspect-[1200/630] bg-ods-border rounded-lg flex-shrink-0" }),
|
|
2621
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex-1 min-w-0 flex flex-col", children: [
|
|
2622
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "min-h-[60px] md:min-h-[72px] flex flex-col gap-1.5 justify-start mb-3", children: [
|
|
2623
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-[25px] md:h-[30px] w-3/4 bg-ods-border rounded" }),
|
|
2624
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-[25px] md:h-[30px] w-1/2 bg-ods-border rounded" })
|
|
2625
|
+
] }),
|
|
2626
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "min-h-[46px] md:min-h-[52px] flex flex-col gap-2 justify-start", children: [
|
|
2627
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-3 w-full bg-ods-border/70 rounded" }),
|
|
2628
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-3 w-5/6 bg-ods-border/70 rounded" })
|
|
2629
|
+
] })
|
|
2630
|
+
] })
|
|
2631
|
+
] }),
|
|
2632
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "grid grid-cols-1 md:grid-cols-3 border border-ods-border rounded-md overflow-hidden w-full", children: [
|
|
2633
|
+
[0, 1].map((i) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2634
|
+
"div",
|
|
2635
|
+
{
|
|
2636
|
+
className: "bg-ods-card p-4 flex flex-col gap-3 border-b md:border-b-0 md:border-r border-ods-border",
|
|
2637
|
+
children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-2", children: [
|
|
2638
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-6 w-32 bg-ods-bg rounded" }),
|
|
2639
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-3 w-20 bg-ods-bg/60 rounded" })
|
|
2640
|
+
] })
|
|
2641
|
+
},
|
|
2642
|
+
`cell-${i}`
|
|
2643
|
+
)),
|
|
2644
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "bg-ods-card p-4 flex items-center gap-3", children: [
|
|
2645
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-10 w-10 rounded-full bg-ods-bg shrink-0" }),
|
|
2646
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-2 flex-1 min-w-0", children: [
|
|
2647
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-4 w-3/4 bg-ods-bg rounded" }),
|
|
2648
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-3 w-1/2 bg-ods-bg/60 rounded" })
|
|
2649
|
+
] })
|
|
2650
|
+
] })
|
|
2651
|
+
] })
|
|
2652
|
+
] });
|
|
2653
|
+
}
|
|
2654
|
+
if (size === "sm") {
|
|
2655
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: COMPACT_CARD_SKELETON_OUTER, children: [
|
|
2656
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: COMPACT_CARD_SKELETON_IMAGE_SLOT }),
|
|
2657
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: COMPACT_CARD_TEXT_COL, children: [
|
|
2658
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: COMPACT_CARD_TITLE_ROW, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "h-3.5 w-3/5 rounded bg-ods-bg" }) }),
|
|
2659
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: COMPACT_CARD_META_ROW_BOX, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "h-3 w-2/5 rounded bg-ods-bg/70" }) }),
|
|
2660
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: COMPACT_CARD_META_ROW_BOX, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "h-3 w-11/12 rounded bg-ods-bg/40" }) })
|
|
2661
|
+
] }),
|
|
2662
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "flex shrink-0 items-center self-start h-5", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "h-3.5 w-3.5 rounded bg-ods-bg" }) })
|
|
2663
|
+
] });
|
|
2664
|
+
}
|
|
2665
|
+
const t = HORIZONTAL_SIZE_TOKENS.default;
|
|
2666
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
2667
|
+
"span",
|
|
2668
|
+
{
|
|
2669
|
+
className: `flex items-start gap-3 rounded-md border border-ods-border bg-ods-card ${t.padding} animate-pulse`,
|
|
2670
|
+
children: [
|
|
2671
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: `shrink-0 inline-flex items-center justify-center rounded-full bg-ods-bg ${t.step}` }),
|
|
2672
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "flex flex-col gap-2 flex-1 min-w-0", children: [
|
|
2673
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "block h-4 w-2/3 rounded bg-ods-bg" }),
|
|
2674
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "block h-3 w-1/3 rounded bg-ods-bg/70" }),
|
|
2675
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "block h-3 w-full rounded bg-ods-bg/40" })
|
|
2676
|
+
] })
|
|
2677
|
+
]
|
|
2678
|
+
}
|
|
2679
|
+
);
|
|
2680
|
+
}
|
|
2681
|
+
function OnboardingGuideCard({
|
|
2682
|
+
guide,
|
|
2683
|
+
href,
|
|
2684
|
+
target: targetProp,
|
|
2685
|
+
rel: relProp,
|
|
2686
|
+
targetPlatform,
|
|
2687
|
+
placeholderUrl: placeholderUrlProp,
|
|
2688
|
+
size = "default",
|
|
2689
|
+
className
|
|
2690
|
+
}) {
|
|
2691
|
+
const { target, rel } = useEntityCardLink({
|
|
2692
|
+
href,
|
|
2693
|
+
targetPlatform,
|
|
2694
|
+
target: targetProp,
|
|
2695
|
+
rel: relProp
|
|
2696
|
+
});
|
|
2697
|
+
const placeholderUrl = useEntityCardPlaceholder({
|
|
2698
|
+
title: guide.title,
|
|
2699
|
+
placeholderUrl: placeholderUrlProp,
|
|
2700
|
+
aspect: size === "sm" ? "square" : "wide"
|
|
2701
|
+
});
|
|
2702
|
+
if (size === "catalog") {
|
|
2703
|
+
const coverImage = guide.featured_image || guide.main_video_thumbnail || guide.og_image_url || null;
|
|
2704
|
+
const hasVideoCover = !!(guide.main_video_thumbnail || guide.highlight_video_thumbnail);
|
|
2705
|
+
const stepLabel = typeof guide.step_order === "number" ? String(guide.step_order).padStart(2, "0") : "\u2014";
|
|
2706
|
+
const durationLabel = typeof guide.highlight_video_duration_ms === "number" && guide.highlight_video_duration_ms > 0 ? formatDurationMMSS(Math.floor(guide.highlight_video_duration_ms / 1e3)) : "";
|
|
2707
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2708
|
+
_chunkWBR7H6E3cjs.next_link_default,
|
|
2709
|
+
{
|
|
2710
|
+
href,
|
|
2711
|
+
target,
|
|
2712
|
+
rel,
|
|
2713
|
+
prefetch: false,
|
|
2714
|
+
className: _chunkFIG2RKZFcjs.cn.call(void 0,
|
|
2715
|
+
"group block no-underline bg-ods-system-greys-black",
|
|
2716
|
+
"border border-ods-border rounded-lg overflow-hidden",
|
|
2717
|
+
"transition-all duration-300 ease-out",
|
|
2718
|
+
"transform hover:translate-y-[-2px]",
|
|
2719
|
+
"hover:border-ods-accent hover:shadow-lg hover:shadow-ods-accent/[0.08]",
|
|
2720
|
+
className
|
|
2721
|
+
),
|
|
2722
|
+
"aria-label": `Open ${guide.title}`,
|
|
2723
|
+
children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col p-6 gap-4", children: [
|
|
2724
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col md:flex-row gap-4 md:gap-6", children: [
|
|
2725
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-full md:w-[256px] flex-shrink-0", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "relative rounded-lg overflow-hidden w-full aspect-[1200/630] bg-ods-bg", children: [
|
|
2726
|
+
coverImage ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2727
|
+
_chunkXL4V2PYGcjs.next_image_default,
|
|
2728
|
+
{
|
|
2729
|
+
src: coverImage,
|
|
2730
|
+
alt: guide.title,
|
|
2731
|
+
fill: true,
|
|
2732
|
+
sizes: "(max-width: 768px) 100vw, 256px",
|
|
2733
|
+
className: "object-cover",
|
|
2734
|
+
unoptimized: true
|
|
2735
|
+
}
|
|
2736
|
+
) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2737
|
+
BlogImagePlaceholder,
|
|
2738
|
+
{
|
|
2739
|
+
title: guide.title,
|
|
2740
|
+
imageUrl: _nullishCoalesce(placeholderUrl, () => ( null)),
|
|
2741
|
+
className: "absolute inset-0"
|
|
2742
|
+
}
|
|
2743
|
+
),
|
|
2744
|
+
hasVideoCover && coverImage && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "absolute inset-0 flex items-center justify-center bg-black/30", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Play, { className: "w-10 h-10 text-white", fill: "white" }) }),
|
|
2745
|
+
durationLabel && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "absolute bottom-2 right-2 inline-flex items-center gap-1 px-2 py-1 rounded bg-black/60 text-white text-xs font-medium font-mono", children: [
|
|
2746
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Clock, { className: "w-3 h-3" }),
|
|
2747
|
+
durationLabel
|
|
2748
|
+
] })
|
|
2749
|
+
] }) }),
|
|
2750
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex-1 min-w-0 flex flex-col", children: [
|
|
2751
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "min-h-[60px] md:min-h-[72px] flex items-start mb-3", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "font-['Azeret_Mono'] font-semibold text-xl md:text-2xl text-ods-text-primary leading-tight line-clamp-2", children: guide.title }) }),
|
|
2752
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "min-h-[46px] md:min-h-[52px]", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "font-['DM_Sans'] text-sm md:text-base text-ods-text-secondary leading-relaxed line-clamp-2", children: stripMarkdownPreview(guide.video_summary || guide.content || "") }) })
|
|
2753
|
+
] })
|
|
2754
|
+
] }),
|
|
2755
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2756
|
+
EntityAuthorCard,
|
|
2757
|
+
{
|
|
2758
|
+
author: guide.author,
|
|
2759
|
+
publishedAt: guide.published_at,
|
|
2760
|
+
renderEmptyAuthor: true,
|
|
2761
|
+
extraCells: [
|
|
2762
|
+
{
|
|
2763
|
+
value: `${guide.section} \xB7 Step ${stepLabel}`,
|
|
2764
|
+
label: "Section",
|
|
2765
|
+
uppercase: false
|
|
2766
|
+
}
|
|
2767
|
+
]
|
|
2768
|
+
}
|
|
2769
|
+
)
|
|
2770
|
+
] })
|
|
2771
|
+
}
|
|
2772
|
+
);
|
|
2773
|
+
}
|
|
2774
|
+
if (size === "sm") {
|
|
2775
|
+
const coverImage = guide.featured_image || guide.main_video_thumbnail || guide.og_image_url || null;
|
|
2776
|
+
const compactCover = coverImage || placeholderUrl || null;
|
|
2777
|
+
const hasVideoCover = !guide.featured_image && !!guide.main_video_thumbnail;
|
|
2778
|
+
const summary2 = stripMarkdownPreview(guide.video_summary || guide.content || "");
|
|
2779
|
+
const author = _optionalChain([guide, 'access', _44 => _44.author, 'optionalAccess', _45 => _45.full_name, 'optionalAccess', _46 => _46.trim, 'call', _47 => _47()]) || "";
|
|
2780
|
+
const subtitleParts = [
|
|
2781
|
+
`Step ${guide.step_order}`,
|
|
2782
|
+
guide.section,
|
|
2783
|
+
author
|
|
2784
|
+
].filter((s) => typeof s === "string" && s.length > 0);
|
|
2785
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkWBR7H6E3cjs.next_link_default, { href, target, rel, prefetch: false, className: _chunkFIG2RKZFcjs.cn.call(void 0, COMPACT_CARD_OUTER, className), children: [
|
|
2786
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: COMPACT_CARD_IMAGE_SLOT, children: [
|
|
2787
|
+
compactCover ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2788
|
+
_chunkXL4V2PYGcjs.next_image_default,
|
|
2789
|
+
{
|
|
2790
|
+
src: compactCover,
|
|
2791
|
+
alt: guide.title,
|
|
2792
|
+
fill: true,
|
|
2793
|
+
sizes: "56px",
|
|
2794
|
+
className: "object-contain",
|
|
2795
|
+
unoptimized: true
|
|
2796
|
+
}
|
|
2797
|
+
) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "flex h-full w-full items-center justify-center text-ods-accent", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.GraduationCap, { className: "w-4 h-4" }) }),
|
|
2798
|
+
hasVideoCover && compactCover && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "absolute inset-0 flex items-center justify-center bg-black/30", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Play, { className: "h-4 w-4 text-white", fill: "white" }) })
|
|
2799
|
+
] }),
|
|
2800
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: COMPACT_CARD_TEXT_COL, children: [
|
|
2801
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: COMPACT_CARD_TITLE_ROW, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: _chunkFIG2RKZFcjs.cn.call(void 0, COMPACT_CARD_TITLE, "font-['Azeret_Mono']"), children: guide.title }) }),
|
|
2802
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: COMPACT_CARD_META_ROW_BOX, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "truncate text-[11px] leading-4 text-[var(--color-accent-primary)]", children: subtitleParts.join(" \xB7 ") }) }),
|
|
2803
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: COMPACT_CARD_META_ROW_BOX, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: COMPACT_CARD_SUMMARY, children: summary2 || COMPACT_CARD_ROW_FILLER }) })
|
|
2804
|
+
] }),
|
|
2805
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "flex shrink-0 items-center self-start h-5 text-ods-text-secondary", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.ExternalLink, { className: "w-3.5 h-3.5" }) })
|
|
2806
|
+
] });
|
|
2807
|
+
}
|
|
2808
|
+
const t = HORIZONTAL_SIZE_TOKENS.default;
|
|
2809
|
+
const summary = stripMarkdownPreview(guide.video_summary || guide.content || "");
|
|
2810
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
2811
|
+
_chunkWBR7H6E3cjs.next_link_default,
|
|
2812
|
+
{
|
|
2813
|
+
href,
|
|
2814
|
+
target,
|
|
2815
|
+
rel,
|
|
2816
|
+
prefetch: false,
|
|
2817
|
+
className: _chunkFIG2RKZFcjs.cn.call(void 0,
|
|
2818
|
+
`flex items-start gap-3 rounded-md border border-ods-border bg-ods-card hover:border-ods-accent transition-colors ${t.padding}`,
|
|
2819
|
+
className
|
|
2820
|
+
),
|
|
2821
|
+
children: [
|
|
2822
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2823
|
+
"span",
|
|
2824
|
+
{
|
|
2825
|
+
className: `shrink-0 inline-flex items-center justify-center rounded-full bg-ods-accent/10 text-ods-accent font-semibold ${t.step}`,
|
|
2826
|
+
"aria-hidden": "true",
|
|
2827
|
+
children: guide.step_order
|
|
2828
|
+
}
|
|
2829
|
+
),
|
|
2830
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "flex flex-col gap-0.5 flex-1 min-w-0", children: [
|
|
2831
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: `block ${t.title} text-ods-text-primary truncate`, children: guide.title }),
|
|
2832
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "inline-flex items-center gap-1 font-['DM_Sans'] text-[12px] leading-[16px] text-ods-text-secondary", children: [
|
|
2833
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.GraduationCap, { className: "h-3 w-3 shrink-0" }),
|
|
2834
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "truncate", children: guide.section })
|
|
2835
|
+
] }),
|
|
2836
|
+
summary && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: `font-['DM_Sans'] text-[14px] leading-[20px] text-ods-text-secondary ${t.summaryClamp}`, children: summary })
|
|
2837
|
+
] })
|
|
2838
|
+
]
|
|
2839
|
+
}
|
|
2840
|
+
);
|
|
2841
|
+
}
|
|
2842
|
+
|
|
2843
|
+
// src/utils/source-icons.ts
|
|
2844
|
+
var SOURCE_ICON_NAMES = {
|
|
2845
|
+
// Doc tables
|
|
2846
|
+
"openframe-docs": "openframe",
|
|
2847
|
+
"data-room-docs": "shield",
|
|
2848
|
+
// CMS / programs
|
|
2849
|
+
"blog-posts": "newspaper",
|
|
2850
|
+
"product-releases": "rocket",
|
|
2851
|
+
"case-studies": "briefcase",
|
|
2852
|
+
"onboarding-guides": "graduation-cap",
|
|
2853
|
+
webinars: "video",
|
|
2854
|
+
events: "calendar",
|
|
2855
|
+
podcasts: "headphones",
|
|
2856
|
+
"customer-interviews": "users",
|
|
2857
|
+
// Financials
|
|
2858
|
+
"investor-updates": "mail",
|
|
2859
|
+
"financial-kpis": "activity",
|
|
2860
|
+
"financial-cap-table": "table",
|
|
2861
|
+
"financial-pnl": "trending-up",
|
|
2862
|
+
"financial-balance-sheet": "dollar-sign",
|
|
2863
|
+
"financial-cash-flow": "banknote",
|
|
2864
|
+
// ClickUp
|
|
2865
|
+
"clickup-roadmap": "clickup",
|
|
2866
|
+
"clickup-delivery": "clickup",
|
|
2867
|
+
"clickup-tasks-internal": "clickup",
|
|
2868
|
+
// GitHub
|
|
2869
|
+
"github-commits": "github",
|
|
2870
|
+
"github-pull-requests": "github",
|
|
2871
|
+
"github-pr-reviews": "github",
|
|
2872
|
+
"github-commits-public": "github",
|
|
2873
|
+
"github-pull-requests-public": "github",
|
|
2874
|
+
"github-pr-reviews-public": "github",
|
|
2875
|
+
// HubSpot
|
|
2876
|
+
"hubspot-tickets": "hubspot",
|
|
2877
|
+
"hubspot-tickets-anon": "hubspot",
|
|
2878
|
+
"hubspot-tickets-self": "hubspot",
|
|
2879
|
+
// Communications
|
|
2880
|
+
"slack-messages": "slack"
|
|
2881
|
+
};
|
|
2882
|
+
function getSourceIconName(tableId) {
|
|
2883
|
+
if (!tableId) return void 0;
|
|
2884
|
+
return SOURCE_ICON_NAMES[tableId];
|
|
2885
|
+
}
|
|
2886
|
+
var SOURCE_LABELS_BY_TABLE = {
|
|
2887
|
+
// Doc tables
|
|
2888
|
+
"openframe-docs": "OpenFrame Docs",
|
|
2889
|
+
"data-room-docs": "Data Room",
|
|
2890
|
+
// CMS / programs
|
|
2891
|
+
"blog-posts": "Blog Posts",
|
|
2892
|
+
"product-releases": "Product Releases",
|
|
2893
|
+
"case-studies": "Case Studies",
|
|
2894
|
+
"onboarding-guides": "Onboarding Guides",
|
|
2895
|
+
webinars: "Webinars",
|
|
2896
|
+
events: "Events",
|
|
2897
|
+
podcasts: "Podcasts",
|
|
2898
|
+
"customer-interviews": "Customer Interviews",
|
|
2899
|
+
// Financials
|
|
2900
|
+
"investor-updates": "Investor Updates",
|
|
2901
|
+
"financial-kpis": "Financial KPIs",
|
|
2902
|
+
"financial-cap-table": "Cap Table",
|
|
2903
|
+
"financial-pnl": "Profit & Loss",
|
|
2904
|
+
"financial-balance-sheet": "Balance Sheet",
|
|
2905
|
+
"financial-cash-flow": "Cash Flow",
|
|
2906
|
+
// ClickUp
|
|
2907
|
+
"clickup-roadmap": "ClickUp Roadmap",
|
|
2908
|
+
"clickup-delivery": "ClickUp Delivery",
|
|
2909
|
+
"clickup-tasks-internal": "ClickUp Tasks",
|
|
2910
|
+
// GitHub
|
|
2911
|
+
"github-commits": "GitHub Commits",
|
|
2912
|
+
"github-pull-requests": "GitHub Pull Requests",
|
|
2913
|
+
"github-pr-reviews": "GitHub PR Reviews",
|
|
2914
|
+
"github-commits-public": "OpenFrame Commits",
|
|
2915
|
+
"github-pull-requests-public": "OpenFrame Pull Requests",
|
|
2916
|
+
"github-pr-reviews-public": "OpenFrame PR Reviews",
|
|
2917
|
+
// HubSpot
|
|
2918
|
+
"hubspot-tickets": "HubSpot Tickets",
|
|
2919
|
+
"hubspot-tickets-anon": "Known Issues",
|
|
2920
|
+
"hubspot-tickets-self": "My Tickets",
|
|
2921
|
+
// Communications
|
|
2922
|
+
"slack-messages": "OpenMSP Community"
|
|
2923
|
+
};
|
|
2924
|
+
function getSourceLabel(tableId) {
|
|
2925
|
+
return _nullishCoalesce(SOURCE_LABELS_BY_TABLE[tableId], () => ( tableId));
|
|
2926
|
+
}
|
|
2927
|
+
var DEFAULT_DOCUMENT_TYPE_TO_TABLE_ID = {
|
|
2928
|
+
// Doc tables
|
|
2929
|
+
markdown: "openframe-docs",
|
|
2930
|
+
data_room_doc: "data-room-docs",
|
|
2931
|
+
// CMS / programs
|
|
2932
|
+
blog_post: "blog-posts",
|
|
2933
|
+
product_release: "product-releases",
|
|
2934
|
+
case_study: "case-studies",
|
|
2935
|
+
onboarding_guide: "onboarding-guides",
|
|
2936
|
+
webinar: "webinars",
|
|
2937
|
+
event: "events",
|
|
2938
|
+
podcast: "podcasts",
|
|
2939
|
+
customer_interview: "customer-interviews",
|
|
2940
|
+
// Financials
|
|
2941
|
+
investor_update: "investor-updates",
|
|
2942
|
+
financial_kpi: "financial-kpis",
|
|
2943
|
+
cap_table: "financial-cap-table",
|
|
2944
|
+
profit_loss: "financial-pnl",
|
|
2945
|
+
balance_sheet: "financial-balance-sheet",
|
|
2946
|
+
cash_flow: "financial-cash-flow",
|
|
2947
|
+
// ClickUp
|
|
2948
|
+
roadmap_item: "clickup-roadmap",
|
|
2949
|
+
delivery_item: "clickup-delivery",
|
|
2950
|
+
internal_task: "clickup-tasks-internal",
|
|
2951
|
+
// GitHub
|
|
2952
|
+
github_commit: "github-commits",
|
|
2953
|
+
github_pull_request: "github-pull-requests",
|
|
2954
|
+
github_pr_review: "github-pr-reviews",
|
|
2955
|
+
github_commit_public: "github-commits-public",
|
|
2956
|
+
github_pull_request_public: "github-pull-requests-public",
|
|
2957
|
+
github_pr_review_public: "github-pr-reviews-public",
|
|
2958
|
+
// HubSpot
|
|
2959
|
+
hubspot_ticket: "hubspot-tickets",
|
|
2960
|
+
hubspot_ticket_anon: "hubspot-tickets-anon",
|
|
2961
|
+
hubspot_ticket_self: "hubspot-tickets-self",
|
|
2962
|
+
// Communications
|
|
2963
|
+
slack_message: "slack-messages"
|
|
2964
|
+
};
|
|
2965
|
+
function defaultTableIdForDocumentType(documentType) {
|
|
2966
|
+
return _nullishCoalesce(DEFAULT_DOCUMENT_TYPE_TO_TABLE_ID[documentType], () => ( null));
|
|
2967
|
+
}
|
|
2968
|
+
|
|
2969
|
+
// src/components/chat/utils/icon-registry.ts
|
|
2970
|
+
|
|
2971
|
+
|
|
2972
|
+
|
|
2973
|
+
|
|
2974
|
+
|
|
2975
|
+
|
|
2976
|
+
|
|
2977
|
+
|
|
2978
|
+
|
|
2979
|
+
|
|
2980
|
+
|
|
2981
|
+
|
|
2982
|
+
|
|
2983
|
+
|
|
2984
|
+
|
|
2985
|
+
|
|
2986
|
+
|
|
2987
|
+
|
|
2988
|
+
|
|
2989
|
+
|
|
2990
|
+
|
|
2991
|
+
|
|
2992
|
+
|
|
2993
|
+
|
|
2994
|
+
|
|
2995
|
+
|
|
2996
|
+
|
|
2997
|
+
|
|
2998
|
+
|
|
2999
|
+
|
|
3000
|
+
|
|
3001
|
+
|
|
3002
|
+
|
|
3003
|
+
|
|
3004
|
+
|
|
3005
|
+
|
|
3006
|
+
|
|
3007
|
+
|
|
3008
|
+
var OpenFrameLogoIcon = ({ className }) => _react.createElement.call(void 0, _chunkZ4IBEIWDcjs.OpenFrameLogo, { className, upperPathColor: "currentColor" });
|
|
3009
|
+
var ICON_REGISTRY = {
|
|
3010
|
+
// lucide-react (kebab-case)
|
|
3011
|
+
activity: _lucidereact.Activity,
|
|
3012
|
+
banknote: _lucidereact.Banknote,
|
|
3013
|
+
bell: _lucidereact.Bell,
|
|
3014
|
+
"book-open": _lucidereact.BookOpen,
|
|
3015
|
+
box: _lucidereact.Box,
|
|
3016
|
+
briefcase: _lucidereact.Briefcase,
|
|
3017
|
+
calendar: _lucidereact.Calendar,
|
|
3018
|
+
"check-square": _lucidereact.CheckSquare,
|
|
3019
|
+
"dollar-sign": _lucidereact.DollarSign,
|
|
3020
|
+
// For brand-vs-lucide variants the kebab key is the BRAND (most-common
|
|
3021
|
+
// social-platform intent); `'<name>-lucide'` carries the lucide outline.
|
|
3022
|
+
facebook: _chunkZ4IBEIWDcjs.FacebookIcon,
|
|
3023
|
+
"facebook-lucide": _lucidereact.Facebook,
|
|
3024
|
+
"file-text": _lucidereact.FileText,
|
|
3025
|
+
// `'github-lucide'` is the lucide outline glyph (used by
|
|
3026
|
+
// `social_platforms.icon_name='Github'`); `'github'` is the brand icon
|
|
3027
|
+
// (used by `chat_admin_slash_commands.icon_name='github'`). The PascalCase
|
|
3028
|
+
// alias `'Github' → 'github-lucide'` routes the lucide glyph for
|
|
3029
|
+
// social-platform DB rows; `'GitHubIcon' → 'github'` keeps brand routing
|
|
3030
|
+
// consistent for callers that store the PascalCase component name.
|
|
3031
|
+
github: _chunkZ4IBEIWDcjs.GitHubIcon,
|
|
3032
|
+
"github-lucide": _lucidereact.Github,
|
|
3033
|
+
globe: _lucidereact.Globe,
|
|
3034
|
+
"graduation-cap": _lucidereact.GraduationCap,
|
|
3035
|
+
headphones: _lucidereact.Headphones,
|
|
3036
|
+
info: _lucidereact.Info,
|
|
3037
|
+
instagram: _chunkZ4IBEIWDcjs.InstagramIcon,
|
|
3038
|
+
"instagram-lucide": _lucidereact.Instagram,
|
|
3039
|
+
mail: _lucidereact.Mail,
|
|
3040
|
+
megaphone: _lucidereact.Megaphone,
|
|
3041
|
+
"message-circle": _lucidereact.MessageCircle,
|
|
3042
|
+
"message-square": _lucidereact.MessageSquare,
|
|
3043
|
+
newspaper: _lucidereact.Newspaper,
|
|
3044
|
+
package: _lucidereact.Package,
|
|
3045
|
+
"pen-square": _lucidereact.PenSquare,
|
|
3046
|
+
rocket: _lucidereact.Rocket,
|
|
3047
|
+
search: _lucidereact.Search,
|
|
3048
|
+
send: _lucidereact.Send,
|
|
3049
|
+
shield: _lucidereact.Shield,
|
|
3050
|
+
star: _lucidereact.Star,
|
|
3051
|
+
table: _lucidereact.TableProperties,
|
|
3052
|
+
"trending-up": _lucidereact.TrendingUp,
|
|
3053
|
+
twitter: _lucidereact.Twitter,
|
|
3054
|
+
users: _lucidereact.Users,
|
|
3055
|
+
video: _lucidereact.Video,
|
|
3056
|
+
youtube: _chunkZ4IBEIWDcjs.YouTubeIcon,
|
|
3057
|
+
"youtube-lucide": _lucidereact.Youtube,
|
|
3058
|
+
// brand-only icons (no lucide variant in current use)
|
|
3059
|
+
slack: _chunkZ4IBEIWDcjs.SlackIcon,
|
|
3060
|
+
clickup: _chunkZ4IBEIWDcjs.ClickUpIcon,
|
|
3061
|
+
hubspot: _chunkZ4IBEIWDcjs.HubspotIcon,
|
|
3062
|
+
linkedin: _chunkZ4IBEIWDcjs.LinkedInIcon,
|
|
3063
|
+
x: _chunkZ4IBEIWDcjs.XLogo,
|
|
3064
|
+
openframe: OpenFrameLogoIcon
|
|
3065
|
+
};
|
|
3066
|
+
var PASCAL_TO_KEBAB_ALIASES = {
|
|
3067
|
+
// Lucide PascalCase names → kebab equivalents
|
|
3068
|
+
Activity: "activity",
|
|
3069
|
+
Banknote: "banknote",
|
|
3070
|
+
Bell: "bell",
|
|
3071
|
+
BookOpen: "book-open",
|
|
3072
|
+
Box: "box",
|
|
3073
|
+
Briefcase: "briefcase",
|
|
3074
|
+
Calendar: "calendar",
|
|
3075
|
+
CheckSquare: "check-square",
|
|
3076
|
+
DollarSign: "dollar-sign",
|
|
3077
|
+
// Lucide PascalCase → the `-lucide` kebab variant (kebab default is the
|
|
3078
|
+
// brand icon for the social-platform names below).
|
|
3079
|
+
Facebook: "facebook-lucide",
|
|
3080
|
+
FileText: "file-text",
|
|
3081
|
+
Github: "github-lucide",
|
|
3082
|
+
Globe: "globe",
|
|
3083
|
+
GraduationCap: "graduation-cap",
|
|
3084
|
+
Headphones: "headphones",
|
|
3085
|
+
Info: "info",
|
|
3086
|
+
Instagram: "instagram-lucide",
|
|
3087
|
+
Mail: "mail",
|
|
3088
|
+
Megaphone: "megaphone",
|
|
3089
|
+
MessageCircle: "message-circle",
|
|
3090
|
+
MessageSquare: "message-square",
|
|
3091
|
+
Newspaper: "newspaper",
|
|
3092
|
+
Package: "package",
|
|
3093
|
+
PenSquare: "pen-square",
|
|
3094
|
+
Rocket: "rocket",
|
|
3095
|
+
Search: "search",
|
|
3096
|
+
Send: "send",
|
|
3097
|
+
Shield: "shield",
|
|
3098
|
+
Star: "star",
|
|
3099
|
+
TableProperties: "table",
|
|
3100
|
+
TrendingUp: "trending-up",
|
|
3101
|
+
Twitter: "twitter",
|
|
3102
|
+
Users: "users",
|
|
3103
|
+
Video: "video",
|
|
3104
|
+
Youtube: "youtube-lucide",
|
|
3105
|
+
// Brand-icon PascalCase exports → kebab (kebab default is the brand)
|
|
3106
|
+
SlackIcon: "slack",
|
|
3107
|
+
GitHubIcon: "github",
|
|
3108
|
+
ClickUpIcon: "clickup",
|
|
3109
|
+
HubspotIcon: "hubspot",
|
|
3110
|
+
LinkedInIcon: "linkedin",
|
|
3111
|
+
FacebookIcon: "facebook",
|
|
3112
|
+
InstagramIcon: "instagram",
|
|
3113
|
+
YouTubeIcon: "youtube",
|
|
3114
|
+
XLogo: "x",
|
|
3115
|
+
OpenFrameLogo: "openframe"
|
|
3116
|
+
};
|
|
3117
|
+
function normalizeIconKey(key) {
|
|
3118
|
+
return _nullishCoalesce(PASCAL_TO_KEBAB_ALIASES[key], () => ( key));
|
|
3119
|
+
}
|
|
3120
|
+
function getIconComponent(iconName) {
|
|
3121
|
+
if (!iconName) return _lucidereact.FileText;
|
|
3122
|
+
return _nullishCoalesce(ICON_REGISTRY[normalizeIconKey(iconName)], () => ( _lucidereact.FileText));
|
|
3123
|
+
}
|
|
3124
|
+
var SIZE_CLASSES = {
|
|
3125
|
+
xs: "w-3 h-3",
|
|
3126
|
+
// 12px
|
|
3127
|
+
sm: "w-4 h-4",
|
|
3128
|
+
// 16px
|
|
3129
|
+
md: "w-6 h-6",
|
|
3130
|
+
// 24px
|
|
3131
|
+
lg: "w-8 h-8",
|
|
3132
|
+
// 32px
|
|
3133
|
+
xl: "w-12 h-12"
|
|
3134
|
+
// 48px
|
|
3135
|
+
};
|
|
3136
|
+
var ICON_COLORS = {
|
|
3137
|
+
linkedin: { color: "#0A66C2" },
|
|
3138
|
+
facebook: { color: "#1877F2" },
|
|
3139
|
+
youtube: { color: "#FF0000" }
|
|
3140
|
+
};
|
|
3141
|
+
function getDynamicIcon(iconName, size = "md", className) {
|
|
3142
|
+
if (!iconName) {
|
|
3143
|
+
console.warn("[getDynamicIcon] No iconName provided, using Globe fallback");
|
|
3144
|
+
return _react.createElement.call(void 0, _lucidereact.Globe, { className: SIZE_CLASSES[size] });
|
|
3145
|
+
}
|
|
3146
|
+
const sizeClass = SIZE_CLASSES[size];
|
|
3147
|
+
const finalClassName = className ? `${sizeClass} ${className}` : sizeClass;
|
|
3148
|
+
const canonicalKey = normalizeIconKey(iconName);
|
|
3149
|
+
const IconComponent = ICON_REGISTRY[canonicalKey];
|
|
3150
|
+
if (IconComponent) {
|
|
3151
|
+
const colorConfig = ICON_COLORS[canonicalKey] || {};
|
|
3152
|
+
return _react.createElement.call(void 0, IconComponent, { className: finalClassName, ...colorConfig });
|
|
3153
|
+
}
|
|
3154
|
+
console.error(
|
|
3155
|
+
`[getDynamicIcon] Icon NOT found in registry: "${iconName}" (normalized to "${canonicalKey}"). Available icons:`,
|
|
3156
|
+
Object.keys(ICON_REGISTRY)
|
|
3157
|
+
);
|
|
3158
|
+
return _react.createElement.call(void 0, _lucidereact.Globe, { className: finalClassName });
|
|
3159
|
+
}
|
|
3160
|
+
|
|
3161
|
+
// src/components/chat/utils/source-row-cta.ts
|
|
3162
|
+
|
|
3163
|
+
_chunkFIG2RKZFcjs.init_cn.call(void 0, );
|
|
3164
|
+
function sanitizePath(path) {
|
|
3165
|
+
return (path || "").replace(/[^a-zA-Z0-9/_\-.]/g, "");
|
|
3166
|
+
}
|
|
3167
|
+
function sourceRowCtxFromRuntime(runtime, surface = {}) {
|
|
3168
|
+
return {
|
|
3169
|
+
currentPlatform: _nullishCoalesce(runtime.source, () => ( null)),
|
|
3170
|
+
composeContentUrl: runtime.composeContentUrl,
|
|
3171
|
+
docPlatformTargets: runtime.docPlatformTargets,
|
|
3172
|
+
baseRoute: surface.baseRoute,
|
|
3173
|
+
chipBasePlatform: surface.chipBasePlatform
|
|
3174
|
+
};
|
|
3175
|
+
}
|
|
3176
|
+
function pickSourceIcon(sourceRepo, documentType) {
|
|
3177
|
+
const iconName = sourceRepo ? getSourceIconName(sourceRepo) : void 0;
|
|
3178
|
+
const icon = iconName ? getIconComponent(iconName) : _lucidereact.FileText;
|
|
3179
|
+
const iconLabel = _nullishCoalesce(documentType, () => ( "Source"));
|
|
3180
|
+
return { icon, iconLabel };
|
|
3181
|
+
}
|
|
3182
|
+
var DOC_TABLE_TYPES = ["markdown", "data_room_doc"];
|
|
3183
|
+
function shouldFallbackToPathNav(row) {
|
|
3184
|
+
return !!row.documentType && DOC_TABLE_TYPES.includes(row.documentType);
|
|
3185
|
+
}
|
|
3186
|
+
function resolveSourceRowCTA(row, ctx = {}) {
|
|
3187
|
+
const sourceRepo = _nullishCoalesce(_nullishCoalesce(row.sourceRepo, () => ( (row.documentType && ctx.tableIdForDocumentType ? ctx.tableIdForDocumentType(row.documentType) : null))), () => ( null));
|
|
3188
|
+
const { icon, iconLabel } = pickSourceIcon(sourceRepo, row.documentType);
|
|
3189
|
+
let href = null;
|
|
3190
|
+
let targetPlatform = null;
|
|
3191
|
+
const idValue = (_nullishCoalesce(row.id, () => ( ""))).trim();
|
|
3192
|
+
if (row.path && shouldFallbackToPathNav(row) && !row.externalUrl) {
|
|
3193
|
+
const safePath = sanitizePath(row.path);
|
|
3194
|
+
if (safePath) {
|
|
3195
|
+
const docTarget = row.documentType ? _optionalChain([ctx, 'access', _48 => _48.docPlatformTargets, 'optionalAccess', _49 => _49[row.documentType]]) : void 0;
|
|
3196
|
+
if (docTarget) {
|
|
3197
|
+
const seg = docTarget.basePath.split("/").filter(Boolean).join("/");
|
|
3198
|
+
const base = `${_chunkFIG2RKZFcjs.getBaseUrl.call(void 0, docTarget.platform)}${seg ? `/${seg}` : ""}/`;
|
|
3199
|
+
href = _nullishCoalesce(safeHref(new URL(safePath, base).toString()), () => ( null));
|
|
3200
|
+
targetPlatform = docTarget.platform;
|
|
3201
|
+
} else if (ctx.chipBasePlatform) {
|
|
3202
|
+
const base = `${_chunkFIG2RKZFcjs.getBaseUrl.call(void 0, ctx.chipBasePlatform)}/knowledge-base/`;
|
|
3203
|
+
href = _nullishCoalesce(safeHref(new URL(safePath, base).toString()), () => ( null));
|
|
3204
|
+
targetPlatform = ctx.chipBasePlatform;
|
|
3205
|
+
} else if (ctx.baseRoute) {
|
|
3206
|
+
const synthetic = `https://_internal_.local${ctx.baseRoute.startsWith("/") ? ctx.baseRoute : "/" + ctx.baseRoute}/`;
|
|
3207
|
+
const absolute = new URL(safePath, synthetic).toString();
|
|
3208
|
+
href = _nullishCoalesce(safeHref(absolute.replace("https://_internal_.local", "")), () => ( null));
|
|
3209
|
+
targetPlatform = _nullishCoalesce(ctx.currentPlatform, () => ( null));
|
|
3210
|
+
}
|
|
3211
|
+
}
|
|
3212
|
+
} else if (ctx.composeContentUrl && row.documentType && row.externalUrl) {
|
|
3213
|
+
const composed = ctx.composeContentUrl({
|
|
3214
|
+
type: row.documentType,
|
|
3215
|
+
identifier: idValue,
|
|
3216
|
+
externalUrl: row.externalUrl,
|
|
3217
|
+
targetPlatform: _nullishCoalesce(row.targetPlatform, () => ( null))
|
|
3218
|
+
});
|
|
3219
|
+
href = composed.href ? _nullishCoalesce(safeHref(composed.href), () => ( null)) : null;
|
|
3220
|
+
targetPlatform = composed.targetPlatform;
|
|
3221
|
+
} else if (row.externalUrl) {
|
|
3222
|
+
href = _nullishCoalesce(safeHref(row.externalUrl), () => ( null));
|
|
3223
|
+
targetPlatform = _nullishCoalesce(row.targetPlatform, () => ( null));
|
|
3224
|
+
}
|
|
3225
|
+
const askable = !!(idValue && row.documentType);
|
|
3226
|
+
const chatRef = askable ? {
|
|
3227
|
+
type: row.documentType,
|
|
3228
|
+
...sourceRepo ? { sourceRepo } : {},
|
|
3229
|
+
id: idValue,
|
|
3230
|
+
title: row.title,
|
|
3231
|
+
url: href,
|
|
3232
|
+
targetPlatform,
|
|
3233
|
+
// Carry `path` so a downstream inline card (rendered from this
|
|
3234
|
+
// chatRef on a subsequent turn) gets the same doc-tree-swap
|
|
3235
|
+
// routing the chip already used. Without it, the Ask drill-in
|
|
3236
|
+
// would resolve to a same-tab full-page nav even when an in-app
|
|
3237
|
+
// path is available.
|
|
3238
|
+
...row.path ? { metadata: { path: row.path } } : {}
|
|
3239
|
+
} : null;
|
|
3240
|
+
return { icon, iconLabel, href, targetPlatform, askable, chatRef };
|
|
3241
|
+
}
|
|
3242
|
+
function resolveSourceIcon(input, ctx = {}) {
|
|
3243
|
+
if (!input) return { Icon: _lucidereact.FileText, label: "Source" };
|
|
3244
|
+
const { sourceRepo, documentType } = typeof input === "string" ? { sourceRepo: null, documentType: input } : input;
|
|
3245
|
+
if (!sourceRepo && !documentType) return { Icon: _lucidereact.FileText, label: "Source" };
|
|
3246
|
+
const resolvedRepo = _nullishCoalesce(_nullishCoalesce(sourceRepo, () => ( (documentType && ctx.tableIdForDocumentType ? ctx.tableIdForDocumentType(documentType) : null))), () => ( null));
|
|
3247
|
+
const { icon, iconLabel } = pickSourceIcon(resolvedRepo, documentType);
|
|
3248
|
+
return { Icon: icon, label: iconLabel };
|
|
3249
|
+
}
|
|
3250
|
+
|
|
3251
|
+
// src/components/ui/page-actions.tsx
|
|
3252
|
+
_chunkFIG2RKZFcjs.init_cn.call(void 0, );
|
|
3253
|
+
|
|
3254
|
+
_chunkTU26IZPOcjs.init_button2.call(void 0, );
|
|
3255
|
+
|
|
3256
|
+
function actionKey(action, idx) {
|
|
3257
|
+
return `${_nullishCoalesce(_nullishCoalesce(action.label, () => ( action.ariaLabel)), () => ( "action"))}-${idx}`;
|
|
3258
|
+
}
|
|
3259
|
+
function actionToMenuItems(action, idx) {
|
|
3260
|
+
if (action.submenu && action.submenu.length > 0) {
|
|
3261
|
+
if (!action.label) return action.submenu;
|
|
3262
|
+
return action.submenu.map((item) => ({
|
|
3263
|
+
...item,
|
|
3264
|
+
label: `${action.label} (${item.label})`
|
|
3265
|
+
}));
|
|
3266
|
+
}
|
|
3267
|
+
if (!action.label) return [];
|
|
3268
|
+
return [{
|
|
3269
|
+
id: `action-${idx}`,
|
|
3270
|
+
label: action.label,
|
|
3271
|
+
icon: action.icon,
|
|
3272
|
+
onClick: action.onClick,
|
|
3273
|
+
disabled: action.disabled,
|
|
3274
|
+
href: action.href,
|
|
3275
|
+
iconAction: action.iconAction ? {
|
|
3276
|
+
icon: action.iconAction.icon,
|
|
3277
|
+
"aria-label": action.iconAction["aria-label"],
|
|
3278
|
+
onClick: action.iconAction.onClick,
|
|
3279
|
+
href: action.iconAction.href,
|
|
3280
|
+
openInNewTab: action.iconAction.openInNewTab,
|
|
3281
|
+
disabled: action.iconAction.disabled
|
|
3282
|
+
} : void 0
|
|
3283
|
+
}];
|
|
3284
|
+
}
|
|
3285
|
+
function renderActionButton(action, opts = {}) {
|
|
3286
|
+
if (action.iconAction) {
|
|
3287
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3288
|
+
_chunkTU26IZPOcjs.SplitButton,
|
|
3289
|
+
{
|
|
3290
|
+
variant: _nullishCoalesce(action.variant, () => ( void 0)),
|
|
3291
|
+
href: action.href,
|
|
3292
|
+
prefetch: action.prefetch,
|
|
3293
|
+
openInNewTab: action.openInNewTab,
|
|
3294
|
+
onClick: action.onClick,
|
|
3295
|
+
disabled: action.disabled,
|
|
3296
|
+
mainDisabled: action.mainDisabled,
|
|
3297
|
+
leftIcon: action.icon,
|
|
3298
|
+
fullWidth: opts.fullWidth,
|
|
3299
|
+
iconAction: action.iconAction,
|
|
3300
|
+
children: action.label
|
|
3301
|
+
}
|
|
3302
|
+
);
|
|
3303
|
+
}
|
|
3304
|
+
if (action.submenu && action.submenu.length > 0) {
|
|
3305
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3306
|
+
ActionsMenuDropdown,
|
|
3307
|
+
{
|
|
3308
|
+
groups: [{ items: action.submenu }],
|
|
3309
|
+
customTrigger: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3310
|
+
_chunkTU26IZPOcjs.Button,
|
|
3311
|
+
{
|
|
3312
|
+
variant: "outline",
|
|
3313
|
+
disabled: action.disabled,
|
|
3314
|
+
loading: action.loading,
|
|
3315
|
+
leftIcon: action.icon,
|
|
3316
|
+
splitIcon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkC6ASEPZLcjs.Chevron02DownIcon, { className: "h-4 w-4" }),
|
|
3317
|
+
className: opts.fullWidth ? "flex-1" : void 0,
|
|
3318
|
+
children: action.label
|
|
3319
|
+
}
|
|
3320
|
+
)
|
|
3321
|
+
}
|
|
3322
|
+
);
|
|
3323
|
+
}
|
|
3324
|
+
const isIconOnly = opts.iconOnly || !action.label || action.iconOnlyOnDesktop;
|
|
3325
|
+
if (isIconOnly) {
|
|
3326
|
+
const iconNode = action.iconOnlyOnDesktop ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "inline-flex [&_svg]:!text-ods-text-primary", children: action.icon }) : action.icon;
|
|
3327
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3328
|
+
_chunkTU26IZPOcjs.Button,
|
|
3329
|
+
{
|
|
3330
|
+
variant: action.variant,
|
|
3331
|
+
size: "icon",
|
|
3332
|
+
href: action.href,
|
|
3333
|
+
prefetch: action.prefetch,
|
|
3334
|
+
openInNewTab: action.openInNewTab,
|
|
3335
|
+
onClick: action.onClick,
|
|
3336
|
+
disabled: action.disabled,
|
|
3337
|
+
loading: action.loading,
|
|
3338
|
+
leftIcon: iconNode,
|
|
3339
|
+
"aria-label": _nullishCoalesce(action.label, () => ( action.ariaLabel))
|
|
3340
|
+
}
|
|
3341
|
+
);
|
|
3342
|
+
}
|
|
3343
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3344
|
+
_chunkTU26IZPOcjs.Button,
|
|
3345
|
+
{
|
|
3346
|
+
variant: action.variant,
|
|
3347
|
+
href: action.href,
|
|
3348
|
+
prefetch: action.prefetch,
|
|
3349
|
+
openInNewTab: action.openInNewTab,
|
|
3350
|
+
onClick: action.onClick,
|
|
3351
|
+
disabled: action.disabled,
|
|
3352
|
+
loading: action.loading,
|
|
3353
|
+
leftIcon: action.icon,
|
|
3354
|
+
className: opts.fullWidth ? "flex-1" : void 0,
|
|
3355
|
+
children: action.label
|
|
3356
|
+
}
|
|
3357
|
+
);
|
|
3358
|
+
}
|
|
3359
|
+
var ACTIONS_GAP = "gap-[var(--spacing-system-xs)]";
|
|
3360
|
+
function PageActions({
|
|
3361
|
+
variant = "icon-buttons",
|
|
3362
|
+
actions,
|
|
3363
|
+
menuActions,
|
|
3364
|
+
selector,
|
|
3365
|
+
className
|
|
3366
|
+
}) {
|
|
3367
|
+
if (variant === "icon-buttons") {
|
|
3368
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, IconButtonsVariant, { actions, menuActions, selector, className });
|
|
3369
|
+
}
|
|
3370
|
+
if (variant === "menu-primary") {
|
|
3371
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, MenuPrimaryVariant, { actions, menuActions: menuActions || [], selector, className });
|
|
3372
|
+
}
|
|
3373
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, PrimaryButtonsVariant, { actions, className });
|
|
3374
|
+
}
|
|
3375
|
+
function IconButtonsVariant({
|
|
3376
|
+
actions,
|
|
3377
|
+
menuActions,
|
|
3378
|
+
selector,
|
|
3379
|
+
className
|
|
3380
|
+
}) {
|
|
3381
|
+
const desktopActions = actions.filter((a) => !a.showOnlyMobile);
|
|
3382
|
+
const hasMenuActions = !!menuActions && menuActions.some((g) => g.items.length > 0);
|
|
3383
|
+
const isSingleAction = actions.length === 1 && !_optionalChain([actions, 'access', _50 => _50[0], 'access', _51 => _51.submenu, 'optionalAccess', _52 => _52.length]);
|
|
3384
|
+
const singleAction = isSingleAction ? actions[0] : null;
|
|
3385
|
+
const useSingleActionMobile = isSingleAction && !hasMenuActions;
|
|
3386
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
3387
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: _chunkFIG2RKZFcjs.cn.call(void 0, "hidden md:flex items-center", ACTIONS_GAP, className), children: [
|
|
3388
|
+
selector,
|
|
3389
|
+
desktopActions.map((action, idx) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, React.default.Fragment, { children: renderActionButton(action) }, actionKey(action, idx))),
|
|
3390
|
+
hasMenuActions && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ActionsMenuDropdown, { groups: menuActions })
|
|
3391
|
+
] }),
|
|
3392
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: _chunkFIG2RKZFcjs.cn.call(void 0, "flex md:hidden", className), children: useSingleActionMobile && singleAction ? renderActionButton(singleAction, { iconOnly: true }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3393
|
+
ActionsMenuDropdown,
|
|
3394
|
+
{
|
|
3395
|
+
groups: [
|
|
3396
|
+
{ items: actions.flatMap(actionToMenuItems) },
|
|
3397
|
+
..._nullishCoalesce(menuActions, () => ( []))
|
|
3398
|
+
]
|
|
3399
|
+
}
|
|
3400
|
+
) })
|
|
3401
|
+
] });
|
|
3402
|
+
}
|
|
3403
|
+
function PrimaryButtonsVariant({
|
|
3404
|
+
actions,
|
|
3405
|
+
className
|
|
3406
|
+
}) {
|
|
3407
|
+
const sortedActions = [...actions].sort((a, b) => {
|
|
3408
|
+
if (a.variant === "accent" && b.variant !== "accent") return 1;
|
|
3409
|
+
if (a.variant !== "accent" && b.variant === "accent") return -1;
|
|
3410
|
+
return 0;
|
|
3411
|
+
});
|
|
3412
|
+
const desktopActions = sortedActions.filter((a) => !a.showOnlyMobile);
|
|
3413
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
3414
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: _chunkFIG2RKZFcjs.cn.call(void 0, "hidden md:flex items-center", ACTIONS_GAP, className), children: desktopActions.map((action, idx) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, React.default.Fragment, { children: renderActionButton(action) }, `desktop-${actionKey(action, idx)}`)) }),
|
|
3415
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, MobileBottomActions, { actions: sortedActions })
|
|
3416
|
+
] });
|
|
3417
|
+
}
|
|
3418
|
+
function MenuPrimaryVariant({
|
|
3419
|
+
actions,
|
|
3420
|
+
menuActions,
|
|
3421
|
+
selector,
|
|
3422
|
+
className
|
|
3423
|
+
}) {
|
|
3424
|
+
const desktopActions = actions.filter((a) => !a.showOnlyMobile);
|
|
3425
|
+
const hasMenuActions = menuActions.some((g) => g.items.length > 0);
|
|
3426
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
3427
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: _chunkFIG2RKZFcjs.cn.call(void 0, "hidden md:flex items-center", ACTIONS_GAP, className), children: [
|
|
3428
|
+
selector,
|
|
3429
|
+
hasMenuActions && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ActionsMenuDropdown, { groups: menuActions }),
|
|
3430
|
+
desktopActions.map((action, idx) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, React.default.Fragment, { children: renderActionButton({ ...action, variant: action.variant || "accent" }) }, `desktop-${actionKey(action, idx)}`))
|
|
3431
|
+
] }),
|
|
3432
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: _chunkFIG2RKZFcjs.cn.call(void 0, "flex md:hidden", className), children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3433
|
+
ActionsMenuDropdown,
|
|
3434
|
+
{
|
|
3435
|
+
groups: [
|
|
3436
|
+
{ items: actions.flatMap(actionToMenuItems) },
|
|
3437
|
+
...menuActions
|
|
3438
|
+
]
|
|
3439
|
+
}
|
|
3440
|
+
) })
|
|
3441
|
+
] });
|
|
3442
|
+
}
|
|
3443
|
+
function MobileBottomActions({ actions }) {
|
|
3444
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: _chunkFIG2RKZFcjs.cn.call(void 0,
|
|
3445
|
+
"fixed md:hidden bottom-0 left-0 right-0 z-50",
|
|
3446
|
+
"bg-ods-card border-t border-ods-border",
|
|
3447
|
+
"flex items-start pt-6 pb-6 px-6",
|
|
3448
|
+
ACTIONS_GAP
|
|
3449
|
+
), children: actions.map((action, idx) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, React.default.Fragment, { children: renderActionButton(action, { fullWidth: !!action.label }) }, `mobile-${actionKey(action, idx)}`)) });
|
|
3450
|
+
}
|
|
3451
|
+
function usePageActionsBottomPadding(variant) {
|
|
3452
|
+
return variant === "primary-buttons" || variant === "menu-primary" ? "pb-40 md:pb-0" : "";
|
|
3453
|
+
}
|
|
3454
|
+
|
|
3455
|
+
// src/components/layout/page-container.tsx
|
|
3456
|
+
_chunkFIG2RKZFcjs.init_cn.call(void 0, );
|
|
3457
|
+
|
|
3458
|
+
// src/components/layout/back-button.tsx
|
|
3459
|
+
_chunkFIG2RKZFcjs.init_cn.call(void 0, );
|
|
3460
|
+
|
|
3461
|
+
function BackButton({ label = "Back", className, type = "button", ...props }) {
|
|
3462
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
3463
|
+
"button",
|
|
3464
|
+
{
|
|
3465
|
+
type,
|
|
3466
|
+
className: _chunkFIG2RKZFcjs.cn.call(void 0,
|
|
3467
|
+
"group inline-flex items-center justify-center self-start rounded-md",
|
|
3468
|
+
"gap-[var(--spacing-system-xsf)] py-[var(--spacing-system-sf)]",
|
|
3469
|
+
"text-ods-text-secondary hover:text-ods-text-primary",
|
|
3470
|
+
"transition-colors duration-200",
|
|
3471
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ods-focus",
|
|
3472
|
+
className
|
|
3473
|
+
),
|
|
3474
|
+
...props,
|
|
3475
|
+
children: [
|
|
3476
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkC6ASEPZLcjs.Chevron02LeftIcon, { className: "size-6 shrink-0" }),
|
|
3477
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-h4", children: label })
|
|
3478
|
+
]
|
|
3479
|
+
}
|
|
3480
|
+
);
|
|
3481
|
+
}
|
|
3482
|
+
|
|
3483
|
+
// src/components/layout/page-container.tsx
|
|
3484
|
+
|
|
3485
|
+
function isAdvancedProps(props) {
|
|
3486
|
+
return "variant" in props || "title" in props || "subtitle" in props || "backButton" in props || "headerActions" in props || "headerContent" in props || "showHeader" in props || "contentClassName" in props || "actions" in props || "actionsVariant" in props;
|
|
3487
|
+
}
|
|
3488
|
+
function PageContainer(props) {
|
|
3489
|
+
if (isAdvancedProps(props)) {
|
|
3490
|
+
return renderAdvancedPageContainer(props);
|
|
3491
|
+
} else {
|
|
3492
|
+
return renderLegacyPageContainer(props);
|
|
3493
|
+
}
|
|
3494
|
+
}
|
|
3495
|
+
function renderLegacyPageContainer({
|
|
3496
|
+
children,
|
|
3497
|
+
className = "",
|
|
3498
|
+
fullWidthBackground = true,
|
|
3499
|
+
backgroundClassName = "bg-ods-bg",
|
|
3500
|
+
backgroundStyle,
|
|
3501
|
+
contentPadding,
|
|
3502
|
+
maxWidth = "max-w-[1920px]",
|
|
3503
|
+
as: Component = "section",
|
|
3504
|
+
id
|
|
3505
|
+
}) {
|
|
3506
|
+
const content = /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: _chunkFIG2RKZFcjs.cn.call(void 0, maxWidth, contentPadding, "mx-auto", className), children });
|
|
3507
|
+
if (fullWidthBackground) {
|
|
3508
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3509
|
+
Component,
|
|
3510
|
+
{
|
|
3511
|
+
className: _chunkFIG2RKZFcjs.cn.call(void 0, "w-full", backgroundClassName),
|
|
3512
|
+
style: backgroundStyle,
|
|
3513
|
+
id,
|
|
3514
|
+
children: content
|
|
3515
|
+
}
|
|
3516
|
+
);
|
|
3517
|
+
}
|
|
3518
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Component, { className: "w-full", id, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: _chunkFIG2RKZFcjs.cn.call(void 0, maxWidth, contentPadding, "mx-auto", backgroundClassName, className), style: backgroundStyle, children }) });
|
|
3519
|
+
}
|
|
3520
|
+
function renderAdvancedPageContainer({
|
|
3521
|
+
children,
|
|
3522
|
+
variant = "content",
|
|
3523
|
+
title,
|
|
3524
|
+
subtitle,
|
|
3525
|
+
backButton,
|
|
3526
|
+
headerActions,
|
|
3527
|
+
headerContent,
|
|
3528
|
+
actions,
|
|
3529
|
+
actionsVariant,
|
|
3530
|
+
menuActions,
|
|
3531
|
+
padding = "none",
|
|
3532
|
+
background = "transparent",
|
|
3533
|
+
className,
|
|
3534
|
+
contentClassName,
|
|
3535
|
+
showHeader = true
|
|
3536
|
+
}) {
|
|
3537
|
+
const getActionsVariant = () => {
|
|
3538
|
+
if (actionsVariant) return actionsVariant;
|
|
3539
|
+
if (variant === "list") return "icon-buttons";
|
|
3540
|
+
return "primary-buttons";
|
|
3541
|
+
};
|
|
3542
|
+
const renderActions = () => {
|
|
3543
|
+
if (!actions || actions.length === 0) return null;
|
|
3544
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, PageActions, { variant: getActionsVariant(), actions, menuActions });
|
|
3545
|
+
};
|
|
3546
|
+
const needsBottomPadding = actions && actions.length > 0 && getActionsVariant() === "primary-buttons";
|
|
3547
|
+
const paddingClasses = {
|
|
3548
|
+
none: "",
|
|
3549
|
+
sm: "p-4",
|
|
3550
|
+
md: "p-6",
|
|
3551
|
+
lg: "p-8"
|
|
3552
|
+
};
|
|
3553
|
+
const backgroundClasses = {
|
|
3554
|
+
default: "bg-ods-bg",
|
|
3555
|
+
card: "bg-ods-card",
|
|
3556
|
+
transparent: ""
|
|
3557
|
+
};
|
|
3558
|
+
const renderHeader = () => {
|
|
3559
|
+
if (!showHeader) return null;
|
|
3560
|
+
if (headerContent) {
|
|
3561
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: _chunkFIG2RKZFcjs.cn.call(void 0,
|
|
3562
|
+
"flex items-end justify-between gap-4"
|
|
3563
|
+
), children: headerContent });
|
|
3564
|
+
}
|
|
3565
|
+
if (variant === "detail") {
|
|
3566
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-end justify-between md:flex-col md:items-start md:justify-start lg:flex-row lg:items-end lg:justify-between gap-4", children: [
|
|
3567
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-2 flex-1 min-w-0", children: [
|
|
3568
|
+
backButton && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3569
|
+
BackButton,
|
|
3570
|
+
{
|
|
3571
|
+
onClick: backButton.onClick,
|
|
3572
|
+
label: backButton.label,
|
|
3573
|
+
className: "hidden md:inline-flex"
|
|
3574
|
+
}
|
|
3575
|
+
),
|
|
3576
|
+
title && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h1", { className: "text-h2 tracking-[-0.64px] text-ods-text-primary", children: title }),
|
|
3577
|
+
subtitle && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "text-ods-text-secondary font-['DM_Sans'] font-medium text-[16px]", children: subtitle })
|
|
3578
|
+
] }),
|
|
3579
|
+
(headerActions || actions) && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex gap-2 items-center shrink-0", children: [
|
|
3580
|
+
headerActions,
|
|
3581
|
+
renderActions()
|
|
3582
|
+
] })
|
|
3583
|
+
] });
|
|
3584
|
+
}
|
|
3585
|
+
if (variant === "list") {
|
|
3586
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center justify-between md:flex-col md:items-start md:justify-start lg:flex-row lg:items-center lg:justify-between gap-4", children: [
|
|
3587
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-1 flex-1 min-w-0", children: [
|
|
3588
|
+
backButton && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3589
|
+
BackButton,
|
|
3590
|
+
{
|
|
3591
|
+
onClick: backButton.onClick,
|
|
3592
|
+
label: backButton.label,
|
|
3593
|
+
className: "hidden md:inline-flex"
|
|
3594
|
+
}
|
|
3595
|
+
),
|
|
3596
|
+
title && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h1", { className: "text-h2 tracking-[-0.48px] text-ods-text-primary", children: title }),
|
|
3597
|
+
subtitle && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "text-ods-text-secondary font-['DM_Sans'] font-medium text-[16px]", children: subtitle })
|
|
3598
|
+
] }),
|
|
3599
|
+
(headerActions || actions) && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex gap-3 items-center shrink-0", children: [
|
|
3600
|
+
headerActions,
|
|
3601
|
+
renderActions()
|
|
3602
|
+
] })
|
|
3603
|
+
] });
|
|
3604
|
+
}
|
|
3605
|
+
if (variant === "form") {
|
|
3606
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-end justify-between md:flex-col md:items-start md:justify-start lg:flex-row lg:items-end lg:justify-between gap-4", children: [
|
|
3607
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-2 flex-1 min-w-0", children: [
|
|
3608
|
+
backButton && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3609
|
+
BackButton,
|
|
3610
|
+
{
|
|
3611
|
+
onClick: backButton.onClick,
|
|
3612
|
+
label: backButton.label,
|
|
3613
|
+
className: "hidden md:inline-flex"
|
|
3614
|
+
}
|
|
3615
|
+
),
|
|
3616
|
+
title && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h1", { className: "text-[32px] font-['Azeret_Mono:SemiBold',_sans-serif] font-semibold text-ods-text-primary tracking-[-0.64px]", children: title })
|
|
3617
|
+
] }),
|
|
3618
|
+
(headerActions || actions) && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex gap-4 items-center shrink-0", children: [
|
|
3619
|
+
headerActions,
|
|
3620
|
+
renderActions()
|
|
3621
|
+
] })
|
|
3622
|
+
] });
|
|
3623
|
+
}
|
|
3624
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center justify-between md:flex-col md:items-start md:justify-start lg:flex-row lg:items-center lg:justify-between gap-4", children: [
|
|
3625
|
+
(title || subtitle) && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-1 flex-1 min-w-0", children: [
|
|
3626
|
+
title && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h1", { className: "text-h2 text-ods-text-primary", children: title }),
|
|
3627
|
+
subtitle && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "text-ods-text-secondary font-['DM_Sans'] font-medium text-[16px]", children: subtitle })
|
|
3628
|
+
] }),
|
|
3629
|
+
(headerActions || actions) && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex gap-3 items-center shrink-0", children: [
|
|
3630
|
+
headerActions,
|
|
3631
|
+
renderActions()
|
|
3632
|
+
] })
|
|
3633
|
+
] });
|
|
3634
|
+
};
|
|
3635
|
+
const getContainerClasses = () => {
|
|
3636
|
+
const baseClasses = [
|
|
3637
|
+
"flex flex-col w-full",
|
|
3638
|
+
backgroundClasses[background],
|
|
3639
|
+
paddingClasses[padding]
|
|
3640
|
+
];
|
|
3641
|
+
switch (variant) {
|
|
3642
|
+
case "list":
|
|
3643
|
+
return _chunkFIG2RKZFcjs.cn.call(void 0, baseClasses, "gap-4 md:gap-6", className);
|
|
3644
|
+
case "detail":
|
|
3645
|
+
return _chunkFIG2RKZFcjs.cn.call(void 0, baseClasses, "gap-4 md:gap-6", className);
|
|
3646
|
+
case "form":
|
|
3647
|
+
return _chunkFIG2RKZFcjs.cn.call(void 0, baseClasses, "gap-6 md:gap-10", className);
|
|
3648
|
+
case "content":
|
|
3649
|
+
default:
|
|
3650
|
+
return _chunkFIG2RKZFcjs.cn.call(void 0, baseClasses, "gap-4 md:gap-6", className);
|
|
3651
|
+
}
|
|
3652
|
+
};
|
|
3653
|
+
const getContentClasses = () => {
|
|
3654
|
+
const mobilePadding = needsBottomPadding ? "pb-28 md:pb-0" : "";
|
|
3655
|
+
switch (variant) {
|
|
3656
|
+
case "detail":
|
|
3657
|
+
return _chunkFIG2RKZFcjs.cn.call(void 0, "flex-1 overflow-auto", mobilePadding, contentClassName);
|
|
3658
|
+
case "list":
|
|
3659
|
+
return _chunkFIG2RKZFcjs.cn.call(void 0, "flex flex-col gap-4 md:gap-6", mobilePadding, contentClassName);
|
|
3660
|
+
case "form":
|
|
3661
|
+
return _chunkFIG2RKZFcjs.cn.call(void 0, "flex flex-col gap-4 md:gap-10", mobilePadding, contentClassName);
|
|
3662
|
+
case "content":
|
|
3663
|
+
default:
|
|
3664
|
+
return _chunkFIG2RKZFcjs.cn.call(void 0, "flex-1", mobilePadding, contentClassName);
|
|
3665
|
+
}
|
|
3666
|
+
};
|
|
3667
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: getContainerClasses(), children: [
|
|
3668
|
+
renderHeader(),
|
|
3669
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: getContentClasses(), children })
|
|
3670
|
+
] });
|
|
3671
|
+
}
|
|
3672
|
+
var ListPageContainer = (props) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, PageContainer, { ...props, variant: "list" });
|
|
3673
|
+
var DetailPageContainer = (props) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, PageContainer, { ...props, variant: "detail" });
|
|
3674
|
+
var FormPageContainer = (props) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, PageContainer, { ...props, variant: "form" });
|
|
3675
|
+
var ContentPageContainer = (props) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, PageContainer, { ...props, variant: "content" });
|
|
3676
|
+
|
|
3677
|
+
// src/components/layout/article-detail-layout.tsx
|
|
3678
|
+
|
|
3679
|
+
function PageShell({ children, schemas }) {
|
|
3680
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "main", { className: "bg-ods-bg min-h-screen", children: [
|
|
3681
|
+
schemas,
|
|
3682
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "max-w-[1920px] mx-auto px-6 md:px-20 py-6 md:py-10", children })
|
|
3683
|
+
] });
|
|
3684
|
+
}
|
|
3685
|
+
function ArticleDetailLayout({ children, schemas }) {
|
|
3686
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "main", { className: "bg-ods-bg min-h-screen", children: [
|
|
3687
|
+
schemas,
|
|
3688
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "max-w-[1280px] mx-auto px-6 md:px-20 py-6 md:py-10", children })
|
|
3689
|
+
] });
|
|
3690
|
+
}
|
|
3691
|
+
|
|
3692
|
+
// src/utils/content-href.ts
|
|
3693
|
+
var DEFAULT_CONTENT_SUFFIXES = {
|
|
3694
|
+
onboarding_guide: "onboarding-guides",
|
|
3695
|
+
product_release: "releases",
|
|
3696
|
+
blog_post: "blog",
|
|
3697
|
+
case_study: "case-studies",
|
|
3698
|
+
customer_interview: "interviews",
|
|
3699
|
+
investor_update: "investor-updates",
|
|
3700
|
+
webinar: "webinars",
|
|
3701
|
+
podcast: "podcasts",
|
|
3702
|
+
event: "events"
|
|
3703
|
+
};
|
|
3704
|
+
function lastPathSegment(url) {
|
|
3705
|
+
try {
|
|
3706
|
+
const pathname = new URL(url, "https://_.local").pathname;
|
|
3707
|
+
const segs = pathname.split("/").filter(Boolean);
|
|
3708
|
+
return segs.length > 0 ? segs[segs.length - 1] : null;
|
|
3709
|
+
} catch (e7) {
|
|
3710
|
+
return null;
|
|
3711
|
+
}
|
|
3712
|
+
}
|
|
3713
|
+
function makeComposeContentUrl(opts) {
|
|
3714
|
+
const suffixes = _nullishCoalesce(opts.suffixes, () => ( DEFAULT_CONTENT_SUFFIXES));
|
|
3715
|
+
return ({ type, identifier, externalUrl, targetPlatform }) => {
|
|
3716
|
+
const override = opts.overrides && Object.prototype.hasOwnProperty.call(opts.overrides, type) ? opts.overrides[type] : void 0;
|
|
3717
|
+
if (override) return override(identifier);
|
|
3718
|
+
const seg = _nullishCoalesce((Object.prototype.hasOwnProperty.call(suffixes, type) ? suffixes[type] : void 0), () => ( type));
|
|
3719
|
+
if (opts.hostedTypes.has(type)) {
|
|
3720
|
+
const recovered = externalUrl ? lastPathSegment(externalUrl) : null;
|
|
3721
|
+
const slug = recovered && recovered !== seg ? recovered : identifier;
|
|
3722
|
+
return { href: `/${seg}/${slug}`, targetPlatform: null };
|
|
3723
|
+
}
|
|
3724
|
+
return externalUrl ? { href: externalUrl, targetPlatform: _nullishCoalesce(targetPlatform, () => ( null)) } : { href: `${opts.contentOrigin}/${seg}/${identifier}`, targetPlatform: null };
|
|
3725
|
+
};
|
|
3726
|
+
}
|
|
3727
|
+
function buildDefaultHref(basePath, slug) {
|
|
3728
|
+
return { href: `${basePath}/${slug}`, targetPlatform: null };
|
|
3729
|
+
}
|
|
3730
|
+
function resolveContentHref(composeContentUrl, args) {
|
|
3731
|
+
return composeContentUrl ? composeContentUrl({ type: args.type, identifier: args.slug, platforms: args.platforms }) : buildDefaultHref(args.basePath, args.slug);
|
|
3732
|
+
}
|
|
3733
|
+
|
|
3734
|
+
// src/components/ui/error-state.tsx
|
|
3735
|
+
_chunkTU26IZPOcjs.init_button2.call(void 0, );
|
|
3736
|
+
_chunkFIG2RKZFcjs.init_cn.call(void 0, );
|
|
3737
|
+
|
|
3738
|
+
|
|
3739
|
+
function ErrorState({
|
|
3740
|
+
title = "Error",
|
|
3741
|
+
message,
|
|
3742
|
+
variant = "error",
|
|
3743
|
+
showIcon = true,
|
|
3744
|
+
showRetry = false,
|
|
3745
|
+
showHome = false,
|
|
3746
|
+
onRetry,
|
|
3747
|
+
onHome,
|
|
3748
|
+
className,
|
|
3749
|
+
containerClassName
|
|
3750
|
+
}) {
|
|
3751
|
+
const getVariantStyles = () => {
|
|
3752
|
+
switch (variant) {
|
|
3753
|
+
case "error":
|
|
3754
|
+
return {
|
|
3755
|
+
bg: "bg-ods-attention-red-error/20",
|
|
3756
|
+
border: "border-ods-attention-red-error",
|
|
3757
|
+
text: "text-ods-attention-red-error",
|
|
3758
|
+
icon: "text-ods-attention-red-error"
|
|
3759
|
+
};
|
|
3760
|
+
case "warning":
|
|
3761
|
+
return {
|
|
3762
|
+
bg: "bg-ods-attention-yellow-warning/20",
|
|
3763
|
+
border: "border-ods-attention-yellow-warning",
|
|
3764
|
+
text: "text-ods-attention-yellow-warning",
|
|
3765
|
+
icon: "text-ods-attention-yellow-warning"
|
|
3766
|
+
};
|
|
3767
|
+
case "info":
|
|
3768
|
+
return {
|
|
3769
|
+
bg: "bg-ods-bg-surface",
|
|
3770
|
+
border: "border-ods-border",
|
|
3771
|
+
text: "text-ods-text-secondary",
|
|
3772
|
+
icon: "text-ods-text-secondary"
|
|
3773
|
+
};
|
|
3774
|
+
}
|
|
3775
|
+
};
|
|
3776
|
+
const styles = getVariantStyles();
|
|
3777
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: _chunkFIG2RKZFcjs.cn.call(void 0, "p-6", containerClassName), children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: _chunkFIG2RKZFcjs.cn.call(void 0,
|
|
3778
|
+
"rounded-lg p-4 border",
|
|
3779
|
+
styles.bg,
|
|
3780
|
+
styles.border,
|
|
3781
|
+
className
|
|
3782
|
+
), children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-start gap-3", children: [
|
|
3783
|
+
showIcon && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.AlertTriangle, { className: _chunkFIG2RKZFcjs.cn.call(void 0, "h-5 w-5 mt-0.5 flex-shrink-0", styles.icon) }),
|
|
3784
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex-1", children: [
|
|
3785
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: _chunkFIG2RKZFcjs.cn.call(void 0, "font-semibold mb-1", styles.text), children: title }),
|
|
3786
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: _chunkFIG2RKZFcjs.cn.call(void 0, "text-sm", styles.text), children: message }),
|
|
3787
|
+
(showRetry || showHome) && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex gap-2 mt-3", children: [
|
|
3788
|
+
showRetry && onRetry && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3789
|
+
_chunkTU26IZPOcjs.Button,
|
|
3790
|
+
{
|
|
3791
|
+
onClick: onRetry,
|
|
3792
|
+
variant: "outline",
|
|
3793
|
+
size: "small-legacy",
|
|
3794
|
+
className: "h-8",
|
|
3795
|
+
leftIcon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.RefreshCw, { className: "h-4 w-4" }),
|
|
3796
|
+
children: "Try Again"
|
|
3797
|
+
}
|
|
3798
|
+
),
|
|
3799
|
+
showHome && onHome && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3800
|
+
_chunkTU26IZPOcjs.Button,
|
|
3801
|
+
{
|
|
3802
|
+
onClick: onHome,
|
|
3803
|
+
variant: "outline",
|
|
3804
|
+
size: "small-legacy",
|
|
3805
|
+
className: "h-8",
|
|
3806
|
+
leftIcon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Home, { className: "h-4 w-4" }),
|
|
3807
|
+
children: "Go Home"
|
|
3808
|
+
}
|
|
3809
|
+
)
|
|
3810
|
+
] })
|
|
3811
|
+
] })
|
|
3812
|
+
] }) }) });
|
|
3813
|
+
}
|
|
3814
|
+
function PageError({ message, onRetry, onHome }) {
|
|
3815
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3816
|
+
ErrorState,
|
|
3817
|
+
{
|
|
3818
|
+
title: "Page Error",
|
|
3819
|
+
message,
|
|
3820
|
+
variant: "error",
|
|
3821
|
+
showRetry: !!onRetry,
|
|
3822
|
+
showHome: !!onHome,
|
|
3823
|
+
onRetry,
|
|
3824
|
+
onHome
|
|
3825
|
+
}
|
|
3826
|
+
);
|
|
3827
|
+
}
|
|
3828
|
+
function LoadError({ message, onRetry }) {
|
|
3829
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3830
|
+
ErrorState,
|
|
3831
|
+
{
|
|
3832
|
+
title: "Loading Error",
|
|
3833
|
+
message,
|
|
3834
|
+
variant: "error",
|
|
3835
|
+
showRetry: !!onRetry,
|
|
3836
|
+
onRetry
|
|
3837
|
+
}
|
|
3838
|
+
);
|
|
3839
|
+
}
|
|
3840
|
+
function NotFoundError({ message = "The requested item was not found", onHome }) {
|
|
3841
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3842
|
+
ErrorState,
|
|
3843
|
+
{
|
|
3844
|
+
title: "Not Found",
|
|
3845
|
+
message,
|
|
3846
|
+
variant: "warning",
|
|
3847
|
+
showHome: !!onHome,
|
|
3848
|
+
onHome
|
|
3849
|
+
}
|
|
3850
|
+
);
|
|
3851
|
+
}
|
|
3852
|
+
|
|
3853
|
+
// src/components/features/entity-tag-badges.tsx
|
|
3854
|
+
var _link = require('next/link'); var _link2 = _interopRequireDefault(_link);
|
|
3855
|
+
|
|
3856
|
+
var BADGE_CLASS = "bg-ods-card border border-ods-border";
|
|
3857
|
+
function EntityTagBadges({ tags, basePath, max, className }) {
|
|
3858
|
+
const items = (tags || []).filter((t) => !!t && !!t.name);
|
|
3859
|
+
if (items.length === 0) return null;
|
|
3860
|
+
const visibleLimit = max == null ? items.length : Math.max(0, max);
|
|
3861
|
+
const shown = items.slice(0, visibleLimit);
|
|
3862
|
+
const overflow = items.length - shown.length;
|
|
3863
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: `flex flex-wrap items-center gap-2 w-full ${className || ""}`, children: [
|
|
3864
|
+
shown.map((tag) => {
|
|
3865
|
+
const key = _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(tag.tag_id, () => ( tag.id)), () => ( tag.slug)), () => ( tag.name));
|
|
3866
|
+
const label = (tag.name || "").toUpperCase();
|
|
3867
|
+
if (basePath && tag.slug) {
|
|
3868
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _link2.default, { href: `${basePath}?tags=${tag.slug}`, className: "inline-flex", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3869
|
+
StatusBadge,
|
|
3870
|
+
{
|
|
3871
|
+
text: label,
|
|
3872
|
+
variant: "card",
|
|
3873
|
+
className: `${BADGE_CLASS} cursor-pointer transition-colors hover:border-ods-accent`
|
|
3874
|
+
}
|
|
3875
|
+
) }, key);
|
|
3876
|
+
}
|
|
3877
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StatusBadge, { text: label, variant: "card", className: BADGE_CLASS }, key);
|
|
3878
|
+
}),
|
|
3879
|
+
overflow > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StatusBadge, { text: `+${overflow}`, variant: "card", className: `${BADGE_CLASS} text-ods-text-secondary` })
|
|
3880
|
+
] });
|
|
3881
|
+
}
|
|
3882
|
+
|
|
3883
|
+
// src/components/features/mux-origins.ts
|
|
3884
|
+
var MUX_STREAM_ORIGIN = "https://stream.mux.com";
|
|
3885
|
+
var MUX_IMAGE_ORIGIN = "https://image.mux.com";
|
|
3886
|
+
|
|
3887
|
+
// src/components/features/use-video-warmup.ts
|
|
3888
|
+
|
|
3889
|
+
var _reactdom = require('react-dom'); var _reactdom2 = _interopRequireDefault(_reactdom);
|
|
3890
|
+
function useVideoOriginPreconnect({
|
|
3891
|
+
supabaseStorageOrigin
|
|
3892
|
+
} = {}) {
|
|
3893
|
+
const runtime = _chunkMEAR2WHScjs.useChatRuntime.call(void 0, );
|
|
3894
|
+
const resolvedOrigin = _nullishCoalesce(supabaseStorageOrigin, () => ( _optionalChain([runtime, 'optionalAccess', _53 => _53.endpoints, 'access', _54 => _54.supabaseStorageOrigin])));
|
|
3895
|
+
try {
|
|
3896
|
+
_reactdom2.default.preconnect(MUX_STREAM_ORIGIN, { crossOrigin: "anonymous" });
|
|
3897
|
+
_reactdom2.default.preconnect(MUX_IMAGE_ORIGIN, { crossOrigin: "anonymous" });
|
|
3898
|
+
if (resolvedOrigin) {
|
|
3899
|
+
_reactdom2.default.preconnect(resolvedOrigin, { crossOrigin: "anonymous" });
|
|
3900
|
+
}
|
|
3901
|
+
} catch (err) {
|
|
3902
|
+
if (process.env.NODE_ENV !== "production") {
|
|
3903
|
+
console.warn("[useVideoOriginPreconnect] preconnect failed:", err);
|
|
3904
|
+
}
|
|
3905
|
+
}
|
|
3906
|
+
}
|
|
3907
|
+
function useVideoWarmup({
|
|
3908
|
+
videoUrl,
|
|
3909
|
+
supabaseStorageOrigin,
|
|
3910
|
+
nearMargin = "1000px"
|
|
3911
|
+
} = {}) {
|
|
3912
|
+
const runtime = _chunkMEAR2WHScjs.useChatRuntime.call(void 0, );
|
|
3913
|
+
const resolvedOrigin = _nullishCoalesce(supabaseStorageOrigin, () => ( _optionalChain([runtime, 'optionalAccess', _55 => _55.endpoints, 'access', _56 => _56.supabaseStorageOrigin])));
|
|
3914
|
+
useVideoOriginPreconnect({ supabaseStorageOrigin: resolvedOrigin });
|
|
3915
|
+
const { ref, isNear } = _chunkDAAFVOTLcjs.useNearViewport.call(void 0, nearMargin);
|
|
3916
|
+
_react.useEffect.call(void 0, () => {
|
|
3917
|
+
if (!isNear || !videoUrl || !resolvedOrigin) return;
|
|
3918
|
+
const conn = navigator.connection;
|
|
3919
|
+
if (_optionalChain([conn, 'optionalAccess', _57 => _57.saveData]) === true) return;
|
|
3920
|
+
let videoOrigin;
|
|
3921
|
+
try {
|
|
3922
|
+
videoOrigin = new URL(videoUrl, "http://placeholder.local").origin;
|
|
3923
|
+
} catch (e8) {
|
|
3924
|
+
return;
|
|
3925
|
+
}
|
|
3926
|
+
if (videoOrigin !== resolvedOrigin) return;
|
|
3927
|
+
const link = document.createElement("link");
|
|
3928
|
+
link.rel = "preload";
|
|
3929
|
+
link.as = "video";
|
|
3930
|
+
link.href = videoUrl;
|
|
3931
|
+
link.crossOrigin = "anonymous";
|
|
3932
|
+
if ("fetchPriority" in link) {
|
|
3933
|
+
;
|
|
3934
|
+
link.fetchPriority = "low";
|
|
3935
|
+
}
|
|
3936
|
+
document.head.appendChild(link);
|
|
3937
|
+
return () => {
|
|
3938
|
+
link.remove();
|
|
3939
|
+
};
|
|
3940
|
+
}, [isNear, videoUrl, resolvedOrigin]);
|
|
3941
|
+
return { ref, isNear };
|
|
3942
|
+
}
|
|
3943
|
+
|
|
3944
|
+
// src/components/features/captions-url.ts
|
|
3945
|
+
function getCaptionsUrl(entityType, entityId, srtContent) {
|
|
3946
|
+
if (!srtContent) return void 0;
|
|
3947
|
+
const hash = `${srtContent.length}-${srtContent.slice(0, 8).replace(/\s/g, "")}`;
|
|
3948
|
+
return `/api/captions/${entityType}/${entityId}?v=${hash}`;
|
|
3949
|
+
}
|
|
3950
|
+
|
|
3951
|
+
// src/components/ui/search-input.tsx
|
|
3952
|
+
_chunkFIG2RKZFcjs.init_cn.call(void 0, );
|
|
3953
|
+
var _reactpopover = require('@radix-ui/react-popover'); var PopoverPrimitive = _interopRequireWildcard(_reactpopover);
|
|
3954
|
+
var _reactscrollarea = require('@radix-ui/react-scroll-area'); var ScrollAreaPrimitive = _interopRequireWildcard(_reactscrollarea);
|
|
3955
|
+
|
|
3956
|
+
|
|
3957
|
+
var containerStyles = _chunkFIG2RKZFcjs.cn.call(void 0,
|
|
3958
|
+
// Layout & spacing — matches lib Input component
|
|
3959
|
+
"flex items-center gap-2 rounded-[6px] border px-3 h-11 md:h-12 cursor-text",
|
|
3960
|
+
"has-[:focus-visible]:outline-none",
|
|
3961
|
+
"group",
|
|
3962
|
+
"transition-colors duration-200",
|
|
3963
|
+
// Theme palette — matches lib Input component
|
|
3964
|
+
"bg-ods-card border-ods-border has-[:focus]:border-ods-accent"
|
|
3965
|
+
);
|
|
3966
|
+
var innerInputStyles = _chunkFIG2RKZFcjs.cn.call(void 0,
|
|
3967
|
+
"flex-1 min-w-[60px] bg-transparent border-none outline-none",
|
|
3968
|
+
"text-h4",
|
|
3969
|
+
"text-ods-text-primary placeholder:text-ods-text-secondary",
|
|
3970
|
+
"disabled:cursor-not-allowed",
|
|
3971
|
+
"touch-manipulation"
|
|
3972
|
+
);
|
|
3973
|
+
function chipVariantToTagVariant(variant) {
|
|
3974
|
+
switch (variant) {
|
|
3975
|
+
case "selected":
|
|
3976
|
+
return "primary";
|
|
3977
|
+
// Content tags render with the unified badge skin (ods-card + ods-border,
|
|
3978
|
+
// mono uppercase) — identical to the public EntityTagBadges display.
|
|
3979
|
+
case "tag":
|
|
3980
|
+
return "badge";
|
|
3981
|
+
case "category":
|
|
3982
|
+
case "subcategory":
|
|
3983
|
+
default:
|
|
3984
|
+
return "outline";
|
|
3985
|
+
}
|
|
3986
|
+
}
|
|
3987
|
+
function SearchInput({
|
|
3988
|
+
placeholder = "Search...",
|
|
3989
|
+
value,
|
|
3990
|
+
defaultValue = "",
|
|
3991
|
+
onChange,
|
|
3992
|
+
onSubmit,
|
|
3993
|
+
results = [],
|
|
3994
|
+
isLoading = false,
|
|
3995
|
+
onResultSelect,
|
|
3996
|
+
debounceMs = 300,
|
|
3997
|
+
renderResult,
|
|
3998
|
+
groupBy,
|
|
3999
|
+
emptyResultsText = "No results found",
|
|
4000
|
+
showDropdown: showDropdownProp,
|
|
4001
|
+
filterChips = [],
|
|
4002
|
+
onFilterRemove,
|
|
4003
|
+
startAdornment,
|
|
4004
|
+
endAdornment,
|
|
4005
|
+
className,
|
|
4006
|
+
dropdownClassName,
|
|
4007
|
+
minQueryLength = 2,
|
|
4008
|
+
limitTags = "auto",
|
|
4009
|
+
getLimitTagsText = (more) => `+${more}`
|
|
4010
|
+
}) {
|
|
4011
|
+
const [internalValue, setInternalValue] = React12.useState(defaultValue);
|
|
4012
|
+
const currentValue = onChange ? _nullishCoalesce(value, () => ( "")) : internalValue;
|
|
4013
|
+
const debouncedValue = _chunkDAAFVOTLcjs.useDebounce.call(void 0, currentValue, debounceMs);
|
|
4014
|
+
const [isOpen, setIsOpen] = React12.useState(false);
|
|
4015
|
+
const [highlightedIndex, setHighlightedIndex] = React12.useState(-1);
|
|
4016
|
+
const containerRef = React12.useRef(null);
|
|
4017
|
+
const currentPlaceholder = filterChips.length > 0 ? "Add filter..." : placeholder;
|
|
4018
|
+
const {
|
|
4019
|
+
visibleCount: rawVisibleCount,
|
|
4020
|
+
middleRef,
|
|
4021
|
+
measureRef,
|
|
4022
|
+
textMeasureRef,
|
|
4023
|
+
badgeRef,
|
|
4024
|
+
inputRef
|
|
4025
|
+
} = _chunkDAAFVOTLcjs.useAutoLimitTags.call(void 0, {
|
|
4026
|
+
count: filterChips.length,
|
|
4027
|
+
limitTags,
|
|
4028
|
+
// When chips exist, pass empty placeholder so the hook only reserves input minWidth,
|
|
4029
|
+
// not the full placeholder text width — gives more room for chips on narrow screens
|
|
4030
|
+
placeholder: filterChips.length > 0 ? "" : placeholder
|
|
4031
|
+
});
|
|
4032
|
+
const visibleCount = filterChips.length > 0 ? Math.max(1, rawVisibleCount) : rawVisibleCount;
|
|
4033
|
+
const hiddenTagsRef = React12.useRef(null);
|
|
4034
|
+
const hiddenTagsPopupRef = React12.useRef(null);
|
|
4035
|
+
const [showHiddenTags, setShowHiddenTags] = React12.useState(false);
|
|
4036
|
+
React12.useEffect(() => {
|
|
4037
|
+
if (!showHiddenTags) return;
|
|
4038
|
+
const handleClick = (e) => {
|
|
4039
|
+
const target = e.target;
|
|
4040
|
+
if (!_optionalChain([hiddenTagsRef, 'access', _58 => _58.current, 'optionalAccess', _59 => _59.contains, 'call', _60 => _60(target)]) && !_optionalChain([hiddenTagsPopupRef, 'access', _61 => _61.current, 'optionalAccess', _62 => _62.contains, 'call', _63 => _63(target)])) {
|
|
4041
|
+
setShowHiddenTags(false);
|
|
4042
|
+
}
|
|
4043
|
+
};
|
|
4044
|
+
document.addEventListener("mousedown", handleClick);
|
|
4045
|
+
return () => document.removeEventListener("mousedown", handleClick);
|
|
4046
|
+
}, [showHiddenTags]);
|
|
4047
|
+
const hiddenCount = filterChips.length - visibleCount;
|
|
4048
|
+
const visibleChips = filterChips.slice(0, visibleCount);
|
|
4049
|
+
const hiddenChips = filterChips.slice(visibleCount);
|
|
4050
|
+
const { flatResults, groups } = React12.useMemo(() => {
|
|
4051
|
+
if (!groupBy) return { flatResults: results, groups: null };
|
|
4052
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
4053
|
+
for (const r of results) {
|
|
4054
|
+
const key = groupBy(r);
|
|
4055
|
+
const arr = grouped.get(key);
|
|
4056
|
+
if (arr) {
|
|
4057
|
+
arr.push(r);
|
|
4058
|
+
} else {
|
|
4059
|
+
grouped.set(key, [r]);
|
|
4060
|
+
}
|
|
4061
|
+
}
|
|
4062
|
+
return { flatResults: results, groups: grouped };
|
|
4063
|
+
}, [results, groupBy]);
|
|
4064
|
+
const meetsMinQuery = debouncedValue.length >= minQueryLength;
|
|
4065
|
+
const autoShow = meetsMinQuery;
|
|
4066
|
+
const dropdownVisible = _nullishCoalesce(showDropdownProp, () => ( (isOpen && autoShow)));
|
|
4067
|
+
React12.useEffect(() => {
|
|
4068
|
+
setHighlightedIndex(-1);
|
|
4069
|
+
}, [flatResults.length]);
|
|
4070
|
+
const handleChange = (e) => {
|
|
4071
|
+
const newVal = e.target.value;
|
|
4072
|
+
if (onChange) {
|
|
4073
|
+
onChange(newVal);
|
|
4074
|
+
} else {
|
|
4075
|
+
setInternalValue(newVal);
|
|
4076
|
+
}
|
|
4077
|
+
if (!isOpen) setIsOpen(true);
|
|
4078
|
+
setHighlightedIndex(-1);
|
|
4079
|
+
};
|
|
4080
|
+
const handleClear = (e) => {
|
|
4081
|
+
e.stopPropagation();
|
|
4082
|
+
e.preventDefault();
|
|
4083
|
+
if (onChange) {
|
|
4084
|
+
onChange("");
|
|
4085
|
+
} else {
|
|
4086
|
+
setInternalValue("");
|
|
4087
|
+
}
|
|
4088
|
+
_optionalChain([inputRef, 'access', _64 => _64.current, 'optionalAccess', _65 => _65.focus, 'call', _66 => _66()]);
|
|
4089
|
+
};
|
|
4090
|
+
const handleResultClick = (result, e) => {
|
|
4091
|
+
_optionalChain([onResultSelect, 'optionalCall', _67 => _67(
|
|
4092
|
+
result,
|
|
4093
|
+
e ? {
|
|
4094
|
+
metaKey: e.metaKey,
|
|
4095
|
+
ctrlKey: e.ctrlKey,
|
|
4096
|
+
shiftKey: e.shiftKey,
|
|
4097
|
+
altKey: e.altKey,
|
|
4098
|
+
button: e.button
|
|
4099
|
+
} : void 0
|
|
4100
|
+
)]);
|
|
4101
|
+
setIsOpen(false);
|
|
4102
|
+
};
|
|
4103
|
+
const handleKeyDown = (e) => {
|
|
4104
|
+
switch (e.key) {
|
|
4105
|
+
case "ArrowDown":
|
|
4106
|
+
e.preventDefault();
|
|
4107
|
+
if (!isOpen) setIsOpen(true);
|
|
4108
|
+
setHighlightedIndex(
|
|
4109
|
+
(prev) => prev < flatResults.length - 1 ? prev + 1 : 0
|
|
4110
|
+
);
|
|
4111
|
+
break;
|
|
4112
|
+
case "ArrowUp":
|
|
4113
|
+
e.preventDefault();
|
|
4114
|
+
setHighlightedIndex(
|
|
4115
|
+
(prev) => prev > 0 ? prev - 1 : flatResults.length - 1
|
|
4116
|
+
);
|
|
4117
|
+
break;
|
|
4118
|
+
case "Enter":
|
|
4119
|
+
e.preventDefault();
|
|
4120
|
+
if (highlightedIndex >= 0 && flatResults[highlightedIndex]) {
|
|
4121
|
+
handleResultClick(flatResults[highlightedIndex]);
|
|
4122
|
+
} else {
|
|
4123
|
+
_optionalChain([onSubmit, 'optionalCall', _68 => _68(currentValue)]);
|
|
4124
|
+
}
|
|
4125
|
+
break;
|
|
4126
|
+
case "Escape":
|
|
4127
|
+
setIsOpen(false);
|
|
4128
|
+
setHighlightedIndex(-1);
|
|
4129
|
+
break;
|
|
4130
|
+
case "Backspace":
|
|
4131
|
+
if (!currentValue && filterChips.length > 0 && onFilterRemove) {
|
|
4132
|
+
onFilterRemove(filterChips[filterChips.length - 1].id);
|
|
4133
|
+
}
|
|
4134
|
+
break;
|
|
4135
|
+
}
|
|
4136
|
+
};
|
|
4137
|
+
const handleOpenChange = (open) => {
|
|
4138
|
+
setIsOpen(open);
|
|
4139
|
+
};
|
|
4140
|
+
const defaultRenderResult = (result, isHighlighted) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-3 w-full min-w-0", children: [
|
|
4141
|
+
result.icon && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "flex-shrink-0 text-ods-text-secondary [&_svg]:size-4", children: result.icon }),
|
|
4142
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "min-w-0 flex-1", children: [
|
|
4143
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: _chunkFIG2RKZFcjs.cn.call(void 0,
|
|
4144
|
+
"text-sm font-medium leading-5 truncate",
|
|
4145
|
+
isHighlighted ? "text-ods-accent" : "text-ods-text-primary"
|
|
4146
|
+
), title: result.title, children: result.title }),
|
|
4147
|
+
result.description && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "text-xs leading-4 text-ods-text-secondary truncate mt-0.5", title: result.description, children: result.description })
|
|
4148
|
+
] }),
|
|
4149
|
+
result.type && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "flex-shrink-0 text-[11px] font-medium text-ods-text-muted uppercase tracking-wider", children: result.type })
|
|
4150
|
+
] });
|
|
4151
|
+
const renderRow = (result, index) => {
|
|
4152
|
+
const isHighlighted = index === highlightedIndex;
|
|
4153
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
4154
|
+
"div",
|
|
4155
|
+
{
|
|
4156
|
+
role: "option",
|
|
4157
|
+
"aria-selected": isHighlighted,
|
|
4158
|
+
className: _chunkFIG2RKZFcjs.cn.call(void 0,
|
|
4159
|
+
"flex items-center min-h-10 px-3 cursor-pointer transition-colors border-b border-ods-border last:border-b-0",
|
|
4160
|
+
isHighlighted && "bg-ods-bg-hover",
|
|
4161
|
+
!isHighlighted && "hover:bg-ods-bg-hover"
|
|
4162
|
+
),
|
|
4163
|
+
onClick: (e) => handleResultClick(result, e),
|
|
4164
|
+
onMouseEnter: () => setHighlightedIndex(index),
|
|
4165
|
+
children: renderResult ? renderResult(result, isHighlighted) : defaultRenderResult(result, isHighlighted)
|
|
4166
|
+
},
|
|
4167
|
+
result.id
|
|
4168
|
+
);
|
|
4169
|
+
};
|
|
4170
|
+
const renderDropdownContent = () => {
|
|
4171
|
+
if (isLoading) {
|
|
4172
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "px-4 py-3 text-ods-text-secondary text-[14px]", children: "Loading..." });
|
|
4173
|
+
}
|
|
4174
|
+
if (flatResults.length === 0) {
|
|
4175
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "px-4 py-3 text-ods-text-secondary text-[14px]", children: emptyResultsText });
|
|
4176
|
+
}
|
|
4177
|
+
if (groups) {
|
|
4178
|
+
let globalIndex = 0;
|
|
4179
|
+
return Array.from(groups.entries()).map(([groupLabel, groupResults]) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
|
|
4180
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "px-4 py-2 text-[12px] font-semibold text-ods-text-secondary uppercase tracking-wide bg-ods-bg", children: groupLabel }),
|
|
4181
|
+
groupResults.map((result) => {
|
|
4182
|
+
const idx = globalIndex++;
|
|
4183
|
+
return renderRow(result, idx);
|
|
4184
|
+
})
|
|
4185
|
+
] }, groupLabel));
|
|
4186
|
+
}
|
|
4187
|
+
return flatResults.map((result, index) => renderRow(result, index));
|
|
4188
|
+
};
|
|
4189
|
+
const hasValue = currentValue.length > 0;
|
|
4190
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: _chunkFIG2RKZFcjs.cn.call(void 0, "relative", className), ref: containerRef, children: [
|
|
4191
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, PopoverPrimitive.Root, { open: dropdownVisible, onOpenChange: handleOpenChange, modal: false, children: [
|
|
4192
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, PopoverPrimitive.Anchor, { asChild: true, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
4193
|
+
"div",
|
|
4194
|
+
{
|
|
4195
|
+
className: _chunkFIG2RKZFcjs.cn.call(void 0,
|
|
4196
|
+
containerStyles,
|
|
4197
|
+
"hover:bg-ods-bg-hover hover:border-ods-border-hover active:bg-ods-bg-active active:border-ods-border-active",
|
|
4198
|
+
dropdownVisible && "!border-ods-accent"
|
|
4199
|
+
),
|
|
4200
|
+
onClick: () => {
|
|
4201
|
+
_optionalChain([inputRef, 'access', _69 => _69.current, 'optionalAccess', _70 => _70.focus, 'call', _71 => _71()]);
|
|
4202
|
+
setIsOpen(true);
|
|
4203
|
+
},
|
|
4204
|
+
children: [
|
|
4205
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "flex-shrink-0 text-ods-text-secondary transition-colors duration-200 group-has-[:focus]:text-ods-accent [&_svg]:size-4 md:[&_svg]:size-6", children: startAdornment !== void 0 ? startAdornment : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkWZW7C7TFcjs.SearchIcon, {}) }),
|
|
4206
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { ref: middleRef, className: "flex-1 flex items-center gap-2 min-w-0 overflow-hidden", children: [
|
|
4207
|
+
visibleChips.map((chip) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
4208
|
+
Tag,
|
|
4209
|
+
{
|
|
4210
|
+
variant: chipVariantToTagVariant(chip.variant),
|
|
4211
|
+
label: chip.label,
|
|
4212
|
+
labelClassName: "truncate max-w-[120px]",
|
|
4213
|
+
onClose: onFilterRemove ? () => onFilterRemove(chip.id) : void 0
|
|
4214
|
+
},
|
|
4215
|
+
chip.id
|
|
4216
|
+
)),
|
|
4217
|
+
hiddenCount > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { ref: hiddenTagsRef, className: "shrink-0", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
4218
|
+
"button",
|
|
4219
|
+
{
|
|
4220
|
+
ref: badgeRef,
|
|
4221
|
+
type: "button",
|
|
4222
|
+
onClick: (e) => {
|
|
4223
|
+
e.stopPropagation();
|
|
4224
|
+
setShowHiddenTags((prev) => !prev);
|
|
4225
|
+
},
|
|
4226
|
+
className: _chunkFIG2RKZFcjs.cn.call(void 0,
|
|
4227
|
+
"flex items-center h-8 px-2",
|
|
4228
|
+
"bg-ods-card border border-ods-border rounded-[6px]",
|
|
4229
|
+
"font-mono text-[14px] font-medium leading-5 text-ods-text-secondary uppercase tracking-[-0.28px]",
|
|
4230
|
+
"hover:bg-ods-bg-hover transition-colors cursor-pointer"
|
|
4231
|
+
),
|
|
4232
|
+
"aria-label": `${hiddenCount} more selected filters`,
|
|
4233
|
+
children: getLimitTagsText(hiddenCount)
|
|
4234
|
+
}
|
|
4235
|
+
) }),
|
|
4236
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
4237
|
+
"input",
|
|
4238
|
+
{
|
|
4239
|
+
ref: inputRef,
|
|
4240
|
+
type: "text",
|
|
4241
|
+
value: currentValue,
|
|
4242
|
+
onChange: handleChange,
|
|
4243
|
+
onKeyDown: handleKeyDown,
|
|
4244
|
+
onFocus: () => {
|
|
4245
|
+
setIsOpen(true);
|
|
4246
|
+
setShowHiddenTags(false);
|
|
4247
|
+
},
|
|
4248
|
+
placeholder: currentPlaceholder,
|
|
4249
|
+
className: innerInputStyles
|
|
4250
|
+
}
|
|
4251
|
+
)
|
|
4252
|
+
] }),
|
|
4253
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-1 shrink-0 ml-auto", children: [
|
|
4254
|
+
hasValue && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
4255
|
+
"button",
|
|
4256
|
+
{
|
|
4257
|
+
type: "button",
|
|
4258
|
+
onClick: handleClear,
|
|
4259
|
+
className: "flex items-center justify-center hover:opacity-70 transition-opacity",
|
|
4260
|
+
"aria-label": "Clear search",
|
|
4261
|
+
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkC6ASEPZLcjs.XmarkCircleIcon, { className: "text-ods-text-secondary", size: 24 })
|
|
4262
|
+
}
|
|
4263
|
+
),
|
|
4264
|
+
endAdornment
|
|
4265
|
+
] })
|
|
4266
|
+
]
|
|
4267
|
+
}
|
|
4268
|
+
) }),
|
|
4269
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
4270
|
+
PopoverPrimitive.Content,
|
|
4271
|
+
{
|
|
4272
|
+
className: _chunkFIG2RKZFcjs.cn.call(void 0,
|
|
4273
|
+
"z-50 w-[var(--radix-popover-trigger-width)] mt-1",
|
|
4274
|
+
"bg-ods-card border border-ods-border rounded-[6px] overflow-hidden shadow-lg",
|
|
4275
|
+
"data-[state=open]:animate-in data-[state=closed]:animate-out",
|
|
4276
|
+
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
4277
|
+
"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
|
|
4278
|
+
"data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2",
|
|
4279
|
+
dropdownClassName
|
|
4280
|
+
),
|
|
4281
|
+
sideOffset: 4,
|
|
4282
|
+
align: "start",
|
|
4283
|
+
onOpenAutoFocus: (e) => {
|
|
4284
|
+
e.preventDefault();
|
|
4285
|
+
_optionalChain([inputRef, 'access', _72 => _72.current, 'optionalAccess', _73 => _73.focus, 'call', _74 => _74()]);
|
|
4286
|
+
},
|
|
4287
|
+
onInteractOutside: (e) => {
|
|
4288
|
+
if (_optionalChain([containerRef, 'access', _75 => _75.current, 'optionalAccess', _76 => _76.contains, 'call', _77 => _77(e.target)])) {
|
|
4289
|
+
e.preventDefault();
|
|
4290
|
+
}
|
|
4291
|
+
},
|
|
4292
|
+
children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, ScrollAreaPrimitive.Root, { className: "overflow-hidden", children: [
|
|
4293
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, ScrollAreaPrimitive.Viewport, { className: "max-h-[320px] w-full", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { role: "listbox", children: renderDropdownContent() }) }),
|
|
4294
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, ScrollAreaPrimitive.Scrollbar, { className: "hidden", orientation: "vertical", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ScrollAreaPrimitive.Thumb, {}) })
|
|
4295
|
+
] })
|
|
4296
|
+
}
|
|
4297
|
+
)
|
|
4298
|
+
] }),
|
|
4299
|
+
showHiddenTags && hiddenCount > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
4300
|
+
HiddenTagsPopup,
|
|
4301
|
+
{
|
|
4302
|
+
ref: hiddenTagsPopupRef,
|
|
4303
|
+
items: hiddenChips.map((chip) => ({ label: chip.label, value: chip.id })),
|
|
4304
|
+
style: {
|
|
4305
|
+
left: badgeRef.current ? badgeRef.current.getBoundingClientRect().left - (_nullishCoalesce(_optionalChain([containerRef, 'access', _78 => _78.current, 'optionalAccess', _79 => _79.getBoundingClientRect, 'call', _80 => _80(), 'access', _81 => _81.left]), () => ( 0))) : 0
|
|
4306
|
+
},
|
|
4307
|
+
onRemove: (value2) => {
|
|
4308
|
+
_optionalChain([onFilterRemove, 'optionalCall', _82 => _82(value2)]);
|
|
4309
|
+
if (hiddenCount <= 1) setShowHiddenTags(false);
|
|
4310
|
+
}
|
|
4311
|
+
}
|
|
4312
|
+
),
|
|
4313
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
4314
|
+
"span",
|
|
4315
|
+
{
|
|
4316
|
+
ref: textMeasureRef,
|
|
4317
|
+
"aria-hidden": "true",
|
|
4318
|
+
className: "fixed -left-[9999px] top-0 pointer-events-none whitespace-nowrap text-ods-text-primary",
|
|
4319
|
+
children: currentPlaceholder
|
|
4320
|
+
}
|
|
4321
|
+
),
|
|
4322
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
4323
|
+
"div",
|
|
4324
|
+
{
|
|
4325
|
+
ref: measureRef,
|
|
4326
|
+
"aria-hidden": "true",
|
|
4327
|
+
className: "fixed -left-[9999px] top-0 flex gap-2 pointer-events-none",
|
|
4328
|
+
children: filterChips.map((chip) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
4329
|
+
Tag,
|
|
4330
|
+
{
|
|
4331
|
+
variant: chipVariantToTagVariant(chip.variant),
|
|
4332
|
+
label: chip.label,
|
|
4333
|
+
labelClassName: "truncate max-w-[120px]",
|
|
4334
|
+
onClose: () => {
|
|
4335
|
+
}
|
|
4336
|
+
},
|
|
4337
|
+
`m-${chip.id}`
|
|
4338
|
+
))
|
|
4339
|
+
}
|
|
4340
|
+
)
|
|
4341
|
+
] });
|
|
4342
|
+
}
|
|
4343
|
+
|
|
4344
|
+
// src/components/ui/filter-pill-row.tsx
|
|
4345
|
+
_chunkTU26IZPOcjs.init_button2.call(void 0, );
|
|
4346
|
+
|
|
4347
|
+
|
|
4348
|
+
function FilterPillRow({
|
|
4349
|
+
label,
|
|
4350
|
+
selectedValue,
|
|
4351
|
+
onValueChange,
|
|
4352
|
+
options,
|
|
4353
|
+
countLabel,
|
|
4354
|
+
children
|
|
4355
|
+
}) {
|
|
4356
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-wrap items-center gap-3 p-4 bg-ods-card border border-ods-border rounded-lg", children: [
|
|
4357
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-2", children: [
|
|
4358
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Filter, { className: "h-4 w-4 text-ods-accent" }),
|
|
4359
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-h5 text-ods-text-secondary", children: label })
|
|
4360
|
+
] }),
|
|
4361
|
+
children || options.map((opt) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
4362
|
+
_chunkTU26IZPOcjs.Button,
|
|
4363
|
+
{
|
|
4364
|
+
type: "button",
|
|
4365
|
+
variant: selectedValue === opt.value ? "accent" : "outline",
|
|
4366
|
+
size: "small-legacy",
|
|
4367
|
+
onClick: () => onValueChange(opt.value),
|
|
4368
|
+
className: "text-h3",
|
|
4369
|
+
children: opt.label
|
|
4370
|
+
},
|
|
4371
|
+
opt.value
|
|
4372
|
+
)),
|
|
4373
|
+
countLabel && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "ml-auto text-[12px] font-['DM_Sans'] text-ods-text-secondary shrink-0", children: countLabel })
|
|
4374
|
+
] });
|
|
4375
|
+
}
|
|
4376
|
+
|
|
4377
|
+
|
|
4378
|
+
|
|
4379
|
+
|
|
4380
|
+
|
|
4381
|
+
|
|
4382
|
+
|
|
4383
|
+
|
|
4384
|
+
|
|
4385
|
+
|
|
4386
|
+
|
|
4387
|
+
|
|
4388
|
+
|
|
4389
|
+
|
|
4390
|
+
|
|
4391
|
+
|
|
4392
|
+
|
|
4393
|
+
|
|
4394
|
+
|
|
4395
|
+
|
|
4396
|
+
|
|
4397
|
+
|
|
4398
|
+
|
|
4399
|
+
|
|
4400
|
+
|
|
4401
|
+
|
|
4402
|
+
|
|
4403
|
+
|
|
4404
|
+
|
|
4405
|
+
|
|
4406
|
+
|
|
4407
|
+
|
|
4408
|
+
|
|
4409
|
+
|
|
4410
|
+
|
|
4411
|
+
|
|
4412
|
+
|
|
4413
|
+
|
|
4414
|
+
|
|
4415
|
+
|
|
4416
|
+
|
|
4417
|
+
|
|
4418
|
+
|
|
4419
|
+
|
|
4420
|
+
|
|
4421
|
+
|
|
4422
|
+
|
|
4423
|
+
|
|
4424
|
+
|
|
4425
|
+
|
|
4426
|
+
|
|
4427
|
+
|
|
4428
|
+
|
|
4429
|
+
|
|
4430
|
+
|
|
4431
|
+
|
|
4432
|
+
|
|
4433
|
+
|
|
4434
|
+
|
|
4435
|
+
|
|
4436
|
+
|
|
4437
|
+
|
|
4438
|
+
|
|
4439
|
+
|
|
4440
|
+
|
|
4441
|
+
|
|
4442
|
+
|
|
4443
|
+
|
|
4444
|
+
|
|
4445
|
+
|
|
4446
|
+
|
|
4447
|
+
|
|
4448
|
+
|
|
4449
|
+
|
|
4450
|
+
|
|
4451
|
+
|
|
4452
|
+
|
|
4453
|
+
|
|
4454
|
+
|
|
4455
|
+
|
|
4456
|
+
|
|
4457
|
+
|
|
4458
|
+
|
|
4459
|
+
|
|
4460
|
+
|
|
4461
|
+
|
|
4462
|
+
|
|
4463
|
+
|
|
4464
|
+
|
|
4465
|
+
|
|
4466
|
+
|
|
4467
|
+
|
|
4468
|
+
|
|
4469
|
+
|
|
4470
|
+
|
|
4471
|
+
|
|
4472
|
+
|
|
4473
|
+
|
|
4474
|
+
|
|
4475
|
+
|
|
4476
|
+
|
|
4477
|
+
|
|
4478
|
+
|
|
4479
|
+
|
|
4480
|
+
|
|
4481
|
+
|
|
4482
|
+
|
|
4483
|
+
|
|
4484
|
+
|
|
4485
|
+
|
|
4486
|
+
|
|
4487
|
+
|
|
4488
|
+
|
|
4489
|
+
|
|
4490
|
+
|
|
4491
|
+
|
|
4492
|
+
|
|
4493
|
+
|
|
4494
|
+
|
|
4495
|
+
|
|
4496
|
+
|
|
4497
|
+
|
|
4498
|
+
|
|
4499
|
+
|
|
4500
|
+
|
|
4501
|
+
|
|
4502
|
+
|
|
4503
|
+
|
|
4504
|
+
|
|
4505
|
+
|
|
4506
|
+
|
|
4507
|
+
|
|
4508
|
+
|
|
4509
|
+
|
|
4510
|
+
|
|
4511
|
+
|
|
4512
|
+
|
|
4513
|
+
exports.HiddenTagsPopup = HiddenTagsPopup; exports.tagVariants = tagVariants; exports.Tag = Tag; exports.Card = Card; exports.CardHeader = CardHeader; exports.CardTitle = CardTitle; exports.CardDescription = CardDescription; exports.CardContent = CardContent; exports.CardFooter = CardFooter; exports.CardHorizontal = CardHorizontal; exports.Tabs = Tabs; exports.TabsList = TabsList; exports.TabsTrigger = TabsTrigger; exports.TabsContent = TabsContent; exports.statusBadgeVariants = statusBadgeVariants; exports.StatusBadge = StatusBadge; exports.SimpleMarkdownRenderer = SimpleMarkdownRenderer; exports.formatDate = formatDate; exports.formatNumber = formatNumber; exports.formatPrice = formatPrice; exports.formatBytes = formatBytes; exports.formatBytesShort = formatBytesShort; exports.formatLargeNumber = formatLargeNumber; exports.formatAbbreviatedNumber = formatAbbreviatedNumber; exports.getFirstLastInitials = getFirstLastInitials; exports.nameInitials = nameInitials; exports.formatDurationMMSS = formatDurationMMSS; exports.formatDurationCompact = formatDurationCompact; exports.formatTimeWithTimezone = formatTimeWithTimezone; exports.formatDurationFromRange = formatDurationFromRange; exports.formatDateUTC = formatDateUTC; exports.formatLegalDate = formatLegalDate; exports.formatCurrency = formatCurrency; exports.formatPercent = formatPercent; exports.formatWholeDollars = formatWholeDollars; exports.formatCompactMetric = formatCompactMetric; exports.getTrendColors = getTrendColors; exports.formatDateRange = formatDateRange; exports.formatDateTimeAt = formatDateTimeAt; exports.formatDurationFromMs = formatDurationFromMs; exports.formatDuration = formatDuration; exports.formatUnderscoreText = formatUnderscoreText; exports.stripHtml = stripHtml; exports.formatClassification = formatClassification; exports.formatPricingModel = formatPricingModel; exports.formatBioText = formatBioText; exports.SquareAvatar = SquareAvatar; exports.useControllableState = useControllableState; exports.ActionsMenu = ActionsMenu; exports.ActionsMenuDropdown = ActionsMenuDropdown; exports.isCrossOriginUrl = isCrossOriginUrl; exports.decideNewTab = decideNewTab; exports.computeIsNewTab = computeIsNewTab; exports.newTabAnchorAttrs = newTabAnchorAttrs; exports.buildAnchorProps = buildAnchorProps; exports.NEW_TAB_FEATURES = NEW_TAB_FEATURES; exports.isModifierClick = isModifierClick; exports.stripSameOriginToPath = stripSameOriginToPath; exports.resolveHrefForRuntime = resolveHrefForRuntime; exports.resolveExternalNavigation = resolveExternalNavigation; exports.EMPTY_AUTHOR_PLACEHOLDER = EMPTY_AUTHOR_PLACEHOLDER; exports.EntityMetadataValueCell = EntityMetadataValueCell; exports.EntityMetadataAuthorCell = EntityMetadataAuthorCell; exports.EntityAuthorCard = EntityAuthorCard; exports.BlogImagePlaceholder = BlogImagePlaceholder; exports.fetchPriorityProp = fetchPriorityProp; exports.extractYouTubeId = extractYouTubeId; exports.Video = Video; exports.RATIO_GRID_CLASS = RATIO_GRID_CLASS; exports.RATIO_DISPLAY_GRID_CLASS = RATIO_DISPLAY_GRID_CLASS; exports.RatioTabs = RatioTabs; exports.detectAspectRatio = detectAspectRatio; exports.ratioToCategory = ratioToCategory; exports.groupByAspectRatio = groupByAspectRatio; exports.VideoBitesDisplay = VideoBitesDisplay; exports.VideoBiteCard = VideoBiteCard; exports.EntityVideoSection = EntityVideoSection; exports.useEntityCardLink = useEntityCardLink; exports.useEntityCardPlaceholder = useEntityCardPlaceholder; exports.COMPACT_CARD_OUTER = COMPACT_CARD_OUTER; exports.COMPACT_CARD_OUTER_STATIC = COMPACT_CARD_OUTER_STATIC; exports.COMPACT_CARD_SKELETON_OUTER = COMPACT_CARD_SKELETON_OUTER; exports.COMPACT_CARD_IMAGE_SLOT = COMPACT_CARD_IMAGE_SLOT; exports.COMPACT_CARD_SKELETON_IMAGE_SLOT = COMPACT_CARD_SKELETON_IMAGE_SLOT; exports.COMPACT_CARD_ICON_SLOT = COMPACT_CARD_ICON_SLOT; exports.COMPACT_CARD_TEXT_COL = COMPACT_CARD_TEXT_COL; exports.COMPACT_CARD_TITLE_ROW = COMPACT_CARD_TITLE_ROW; exports.COMPACT_CARD_META_ROW_BOX = COMPACT_CARD_META_ROW_BOX; exports.COMPACT_CARD_TITLE = COMPACT_CARD_TITLE; exports.COMPACT_CARD_SUBTITLE = COMPACT_CARD_SUBTITLE; exports.COMPACT_CARD_SUMMARY = COMPACT_CARD_SUMMARY; exports.COMPACT_CARD_META_ROW = COMPACT_CARD_META_ROW; exports.COMPACT_CARD_ROW_FILLER = COMPACT_CARD_ROW_FILLER; exports.safeHref = safeHref; exports.OnboardingGuideCardSkeleton = OnboardingGuideCardSkeleton; exports.OnboardingGuideCard = OnboardingGuideCard; exports.SOURCE_ICON_NAMES = SOURCE_ICON_NAMES; exports.getSourceIconName = getSourceIconName; exports.SOURCE_LABELS_BY_TABLE = SOURCE_LABELS_BY_TABLE; exports.getSourceLabel = getSourceLabel; exports.DEFAULT_DOCUMENT_TYPE_TO_TABLE_ID = DEFAULT_DOCUMENT_TYPE_TO_TABLE_ID; exports.defaultTableIdForDocumentType = defaultTableIdForDocumentType; exports.ICON_REGISTRY = ICON_REGISTRY; exports.normalizeIconKey = normalizeIconKey; exports.getIconComponent = getIconComponent; exports.getDynamicIcon = getDynamicIcon; exports.sourceRowCtxFromRuntime = sourceRowCtxFromRuntime; exports.resolveSourceRowCTA = resolveSourceRowCTA; exports.resolveSourceIcon = resolveSourceIcon; exports.PageActions = PageActions; exports.usePageActionsBottomPadding = usePageActionsBottomPadding; exports.BackButton = BackButton; exports.PageContainer = PageContainer; exports.ListPageContainer = ListPageContainer; exports.DetailPageContainer = DetailPageContainer; exports.FormPageContainer = FormPageContainer; exports.ContentPageContainer = ContentPageContainer; exports.PageShell = PageShell; exports.ArticleDetailLayout = ArticleDetailLayout; exports.DEFAULT_CONTENT_SUFFIXES = DEFAULT_CONTENT_SUFFIXES; exports.makeComposeContentUrl = makeComposeContentUrl; exports.buildDefaultHref = buildDefaultHref; exports.resolveContentHref = resolveContentHref; exports.ErrorState = ErrorState; exports.PageError = PageError; exports.LoadError = LoadError; exports.NotFoundError = NotFoundError; exports.EntityTagBadges = EntityTagBadges; exports.MUX_STREAM_ORIGIN = MUX_STREAM_ORIGIN; exports.MUX_IMAGE_ORIGIN = MUX_IMAGE_ORIGIN; exports.useVideoOriginPreconnect = useVideoOriginPreconnect; exports.useVideoWarmup = useVideoWarmup; exports.getCaptionsUrl = getCaptionsUrl; exports.SearchInput = SearchInput; exports.FilterPillRow = FilterPillRow;
|
|
4514
|
+
//# sourceMappingURL=chunk-6LK4VEXE.cjs.map
|