@burdenoff/microfe-bigconsole 2026.803.2 → 2026.803.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. package/dist/bigconsole/components/dashboard/ShareDialog/EmbedTab.js +268 -168
  2. package/dist/bigconsole/components/dashboard/ShareDialog/EmbedTab.js.map +1 -1
  3. package/dist/bigconsole/components/embed/ReadOnlyDashboardRenderer.js +63 -24
  4. package/dist/bigconsole/components/embed/ReadOnlyDashboardRenderer.js.map +1 -1
  5. package/dist/bigconsole/components/embed/types.js.map +1 -1
  6. package/dist/bigconsole/components/widgets/WidgetRegistry.js +1 -1
  7. package/dist/bigconsole/components/widgets/WidgetRegistry.js.map +1 -1
  8. package/dist/bigconsole/components/widgets/WidgetWrapper.js +127 -130
  9. package/dist/bigconsole/components/widgets/WidgetWrapper.js.map +1 -1
  10. package/dist/bigconsole/components/widgets/iframe-widget/IframeWidget.js +32 -18
  11. package/dist/bigconsole/components/widgets/iframe-widget/IframeWidget.js.map +1 -1
  12. package/dist/bigconsole/components/widgets/iframe-widget/index.js +2 -2
  13. package/dist/bigconsole/components/widgets/text-widget/TextWidget.js +25 -19
  14. package/dist/bigconsole/components/widgets/text-widget/TextWidget.js.map +1 -1
  15. package/dist/bigconsole/components/widgets/text-widget/index.js +3 -2
  16. package/dist/bigconsole/components/widgets/text-widget/textData.js +71 -0
  17. package/dist/bigconsole/components/widgets/text-widget/textData.js.map +1 -0
  18. package/dist/bigconsole/hooks/useDashboardEmbedPolicy.js +87 -50
  19. package/dist/bigconsole/hooks/useDashboardEmbedPolicy.js.map +1 -1
  20. package/dist/generated/wspace-operations.js +3 -0
  21. package/dist/generated/wspace-operations.js.map +1 -1
  22. package/dist/generated/wspace-types.js +8 -0
  23. package/dist/generated/wspace-types.js.map +1 -0
  24. package/package.json +1 -1
@@ -0,0 +1,71 @@
1
+ //#region src/bigconsole/components/widgets/text-widget/textData.ts
2
+ var e = new Set([
3
+ "markdown",
4
+ "html",
5
+ "plain"
6
+ ]), t = new Set([
7
+ "left",
8
+ "center",
9
+ "right",
10
+ "justify"
11
+ ]);
12
+ function n(t) {
13
+ return typeof t == "string" && e.has(t);
14
+ }
15
+ function r(e) {
16
+ return typeof e == "string" && t.has(e);
17
+ }
18
+ function i(e) {
19
+ return e == null ? "" : typeof e == "string" ? e : String(e);
20
+ }
21
+ function a(e) {
22
+ let t = [];
23
+ for (let [n, r] of Object.entries(e)) if (r && typeof r == "object" && !Array.isArray(r)) {
24
+ t.push(`### ${n}`);
25
+ for (let [e, n] of Object.entries(r)) t.push(`- **${e}:** ${n}`);
26
+ } else Array.isArray(r) ? (t.push(`### ${n}`), r.slice(0, 10).forEach((e) => {
27
+ if (e && typeof e == "object") {
28
+ let n = Object.entries(e);
29
+ t.push(`- ${n.map(([e, t]) => `**${e}:** ${t}`).join(" | ")}`);
30
+ } else t.push(`- ${e}`);
31
+ })) : t.push(`- **${n}:** ${r}`);
32
+ return t.join("\n");
33
+ }
34
+ function o(e, t) {
35
+ let o = e ?? {}, s = i(o.content), c = n(o.format) ? o.format : "markdown", l = r(o.alignment) ? o.alignment : "left";
36
+ if (typeof t == "string") return {
37
+ content: t,
38
+ format: c,
39
+ alignment: l,
40
+ hasContent: t.length > 0
41
+ };
42
+ if (t && typeof t == "object" && !Array.isArray(t)) {
43
+ let e = t;
44
+ if ("content" in e) {
45
+ let t = i(e.content);
46
+ return {
47
+ content: t,
48
+ format: n(e.format) ? e.format : c,
49
+ alignment: r(e.alignment) ? e.alignment : l,
50
+ hasContent: t.length > 0
51
+ };
52
+ }
53
+ let o = a(e);
54
+ return {
55
+ content: o,
56
+ format: "markdown",
57
+ alignment: l,
58
+ hasContent: o.length > 0
59
+ };
60
+ }
61
+ return {
62
+ content: s,
63
+ format: c,
64
+ alignment: l,
65
+ hasContent: s.length > 0
66
+ };
67
+ }
68
+ //#endregion
69
+ export { o as resolveTextData };
70
+
71
+ //# sourceMappingURL=textData.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"textData.js","names":[],"sources":["../../../../../src/bigconsole/components/widgets/text-widget/textData.ts"],"sourcesContent":["/**\n * Text widget data contract (BOFF-5555).\n *\n * Centralises how raw parser / DataSink output and static widget configuration\n * are merged into the shape the TextWidget renderer expects. Keeping this logic\n * pure makes the DataSink → Parser → Widget contract testable and keeps the\n * React component thin.\n */\n\nexport type TextFormat = 'markdown' | 'html' | 'plain';\nexport type TextAlignment = 'left' | 'center' | 'right' | 'justify';\n\nexport interface TextData {\n content?: string;\n format?: TextFormat;\n alignment?: TextAlignment;\n}\n\nconst VALID_FORMATS = new Set<TextFormat>(['markdown', 'html', 'plain']);\nconst VALID_ALIGNMENTS = new Set<TextAlignment>(['left', 'center', 'right', 'justify']);\n\nfunction isValidFormat(value: unknown): value is TextFormat {\n return typeof value === 'string' && VALID_FORMATS.has(value as TextFormat);\n}\n\nfunction isValidAlignment(value: unknown): value is TextAlignment {\n return typeof value === 'string' && VALID_ALIGNMENTS.has(value as TextAlignment);\n}\n\nfunction asString(value: unknown): string {\n if (value === null || value === undefined) return '';\n if (typeof value === 'string') return value;\n return String(value);\n}\n\n/**\n * Convert an arbitrary object (e.g. parser output that forgot to wrap text in\n * a `content` field) into a reasonable markdown representation.\n */\nfunction objectToMarkdown(obj: Record<string, unknown>): string {\n const lines: string[] = [];\n\n for (const [key, val] of Object.entries(obj)) {\n if (val && typeof val === 'object' && !Array.isArray(val)) {\n lines.push(`### ${key}`);\n for (const [k2, v2] of Object.entries(val as Record<string, unknown>)) {\n lines.push(`- **${k2}:** ${v2}`);\n }\n } else if (Array.isArray(val)) {\n lines.push(`### ${key}`);\n val.slice(0, 10).forEach((item: unknown) => {\n if (item && typeof item === 'object') {\n const entries = Object.entries(item as Record<string, unknown>);\n lines.push(`- ${entries.map(([k, v]) => `**${k}:** ${v}`).join(' | ')}`);\n } else {\n lines.push(`- ${item}`);\n }\n });\n } else {\n lines.push(`- **${key}:** ${val}`);\n }\n }\n\n return lines.join('\\n');\n}\n\nexport interface ResolvedTextData extends TextData {\n /** Whether any renderable text content is available. */\n hasContent: boolean;\n}\n\n/**\n * Resolve the effective text widget data.\n *\n * Priority (highest first):\n * 1. Parser-provided `data` fields (`content`, `format`, `alignment`).\n * - If `data` is a plain string it becomes `content`.\n * - If `data` is an object without a `content` key it is auto-formatted as\n * markdown so arbitrary parser output still renders.\n * 2. Static `widgetConfig` fields (`content`, `format`, `alignment`).\n * 3. Safe defaults (`content: ''`, `format: 'markdown'`, `alignment: 'left'`).\n */\nexport function resolveTextData(widgetConfig: Record<string, unknown> | undefined, rawData: unknown): ResolvedTextData {\n const cfg = widgetConfig ?? {};\n const cfgContent = asString(cfg.content);\n const cfgFormat: TextFormat = isValidFormat(cfg.format) ? cfg.format : 'markdown';\n const cfgAlignment: TextAlignment = isValidAlignment(cfg.alignment) ? cfg.alignment : 'left';\n\n // Parser provided a plain string — common for simple text sinks.\n if (typeof rawData === 'string') {\n return {\n content: rawData,\n format: cfgFormat,\n alignment: cfgAlignment,\n hasContent: rawData.length > 0,\n };\n }\n\n // Parser provided a structured object.\n if (rawData && typeof rawData === 'object' && !Array.isArray(rawData)) {\n const obj = rawData as Record<string, unknown>;\n\n if ('content' in obj) {\n const content = asString(obj.content);\n return {\n content,\n format: isValidFormat(obj.format) ? obj.format : cfgFormat,\n alignment: isValidAlignment(obj.alignment) ? obj.alignment : cfgAlignment,\n hasContent: content.length > 0,\n };\n }\n\n // Object without an explicit content key — render it as markdown.\n const content = objectToMarkdown(obj);\n return {\n content,\n format: 'markdown' as TextFormat,\n alignment: cfgAlignment,\n hasContent: content.length > 0,\n };\n }\n\n // No parser data — fall back to static configuration.\n return {\n content: cfgContent,\n format: cfgFormat,\n alignment: cfgAlignment,\n hasContent: cfgContent.length > 0,\n };\n}\n"],"mappings":";AAkBA,IAAM,IAAgB,IAAI,IAAgB;CAAC;CAAY;CAAQ;CAAQ,CAAC,EAClE,IAAmB,IAAI,IAAmB;CAAC;CAAQ;CAAU;CAAS;CAAU,CAAC;AAEvF,SAAS,EAAc,GAAqC;AAC1D,QAAO,OAAO,KAAU,YAAY,EAAc,IAAI,EAAoB;;AAG5E,SAAS,EAAiB,GAAwC;AAChE,QAAO,OAAO,KAAU,YAAY,EAAiB,IAAI,EAAuB;;AAGlF,SAAS,EAAS,GAAwB;AAGxC,QAFI,KAAU,OAAoC,KAC9C,OAAO,KAAU,WAAiB,IAC/B,OAAO,EAAM;;AAOtB,SAAS,EAAiB,GAAsC;CAC9D,IAAM,IAAkB,EAAE;AAE1B,MAAK,IAAM,CAAC,GAAK,MAAQ,OAAO,QAAQ,EAAI,CAC1C,KAAI,KAAO,OAAO,KAAQ,YAAY,CAAC,MAAM,QAAQ,EAAI,EAAE;AACzD,IAAM,KAAK,OAAO,IAAM;AACxB,OAAK,IAAM,CAAC,GAAI,MAAO,OAAO,QAAQ,EAA+B,CACnE,GAAM,KAAK,OAAO,EAAG,MAAM,IAAK;QAEzB,MAAM,QAAQ,EAAI,IAC3B,EAAM,KAAK,OAAO,IAAM,EACxB,EAAI,MAAM,GAAG,GAAG,CAAC,SAAS,MAAkB;AAC1C,MAAI,KAAQ,OAAO,KAAS,UAAU;GACpC,IAAM,IAAU,OAAO,QAAQ,EAAgC;AAC/D,KAAM,KAAK,KAAK,EAAQ,KAAK,CAAC,GAAG,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC,KAAK,MAAM,GAAG;QAExE,GAAM,KAAK,KAAK,IAAO;GAEzB,IAEF,EAAM,KAAK,OAAO,EAAI,MAAM,IAAM;AAItC,QAAO,EAAM,KAAK,KAAK;;AAmBzB,SAAgB,EAAgB,GAAmD,GAAoC;CACrH,IAAM,IAAM,KAAgB,EAAE,EACxB,IAAa,EAAS,EAAI,QAAQ,EAClC,IAAwB,EAAc,EAAI,OAAO,GAAG,EAAI,SAAS,YACjE,IAA8B,EAAiB,EAAI,UAAU,GAAG,EAAI,YAAY;AAGtF,KAAI,OAAO,KAAY,SACrB,QAAO;EACL,SAAS;EACT,QAAQ;EACR,WAAW;EACX,YAAY,EAAQ,SAAS;EAC9B;AAIH,KAAI,KAAW,OAAO,KAAY,YAAY,CAAC,MAAM,QAAQ,EAAQ,EAAE;EACrE,IAAM,IAAM;AAEZ,MAAI,aAAa,GAAK;GACpB,IAAM,IAAU,EAAS,EAAI,QAAQ;AACrC,UAAO;IACL;IACA,QAAQ,EAAc,EAAI,OAAO,GAAG,EAAI,SAAS;IACjD,WAAW,EAAiB,EAAI,UAAU,GAAG,EAAI,YAAY;IAC7D,YAAY,EAAQ,SAAS;IAC9B;;EAIH,IAAM,IAAU,EAAiB,EAAI;AACrC,SAAO;GACL;GACA,QAAQ;GACR,WAAW;GACX,YAAY,EAAQ,SAAS;GAC9B;;AAIH,QAAO;EACL,SAAS;EACT,QAAQ;EACR,WAAW;EACX,YAAY,EAAW,SAAS;EACjC"}
@@ -1,64 +1,101 @@
1
1
  import { CreateDashboardEmbedPolicyDocument as e, ListDashboardEmbedPoliciesDocument as t, PublishDashboardEmbedPolicyDocument as n, RevokeDashboardEmbedPolicyDocument as r, RotateDashboardEmbedPolicyDocument as i, UpdateDashboardEmbedPolicyDocument as a } from "../../generated/wspace-operations.js";
2
- import { useCallback as o, useState as s } from "react";
3
- import { useApolloClient as c } from "@apollo/client/react";
2
+ import { DashboardEmbedTheme as o } from "../../generated/wspace-types.js";
3
+ import { useCallback as s, useState as c } from "react";
4
+ import { useApolloClient as l } from "@apollo/client/react";
4
5
  //#region src/bigconsole/hooks/useDashboardEmbedPolicy.ts
5
- function l(e) {
6
+ var u = {
7
+ light: o.Light,
8
+ dark: o.Dark,
9
+ auto: o.Auto
10
+ };
11
+ function d(e) {
12
+ switch (e) {
13
+ case o.Dark: return "dark";
14
+ case o.Auto: return "auto";
15
+ default: return "light";
16
+ }
17
+ }
18
+ function f(e) {
6
19
  return e.length === 0 ? null : e.find((e) => e.status === "ACTIVE") || ([...e].sort((e, t) => Date.parse(t.updatedAt) - Date.parse(e.updatedAt))[0] ?? null);
7
20
  }
8
- function u() {
9
- let [u, d] = s(null), [f, p] = s(null), [m, h] = s(!1), [g, _] = s(null), v = c();
21
+ function p() {
22
+ let [o, d] = c(null), [p, m] = c(null), [h, g] = c(!1), [_, v] = c(null), y = l();
10
23
  return {
11
- policy: u,
12
- secret: f,
13
- loading: m,
14
- error: g,
15
- fetchPolicy: o(async (e) => {
24
+ policy: o,
25
+ secret: p,
26
+ loading: h,
27
+ error: _,
28
+ fetchPolicy: s(async (e) => {
16
29
  try {
17
- h(!0), _(null);
18
- let n = l((await v.query({
30
+ g(!0), v(null);
31
+ let n = f((await y.query({
19
32
  query: t,
20
33
  variables: { dashboardId: e },
21
34
  fetchPolicy: "network-only"
22
35
  })).data?.listDashboardEmbedPolicies?.nodes ?? []);
23
36
  return d(n), n;
24
37
  } catch (e) {
25
- return _(e instanceof Error ? e : /* @__PURE__ */ Error("Failed to load embed policy")), null;
38
+ return v(e instanceof Error ? e : /* @__PURE__ */ Error("Failed to load embed policy")), null;
26
39
  } finally {
27
- h(!1);
40
+ g(!1);
28
41
  }
29
- }, [v]),
30
- publishToWeb: o(async (t, r, i) => {
42
+ }, [y]),
43
+ publishToWeb: s(async (t, r, i, a) => {
31
44
  try {
32
- h(!0), _(null);
33
- let a = (await v.mutate({
45
+ g(!0), v(null);
46
+ let o = (await y.mutate({
34
47
  mutation: e,
35
48
  variables: { input: {
36
49
  dashboardId: t,
37
- allowedParentOrigins: r
50
+ allowedParentOrigins: r,
51
+ ...a ? {
52
+ presentationTheme: u[a.theme],
53
+ showDashboardTitle: a.showTitle,
54
+ showBrandingFooter: a.showBranding
55
+ } : {}
38
56
  } }
39
57
  })).data?.createDashboardEmbedPolicy;
40
- if (!a) return null;
41
- let o = (await v.mutate({
58
+ if (!o) return null;
59
+ let s = (await y.mutate({
42
60
  mutation: n,
43
61
  variables: {
44
- policyId: a.policy.id,
62
+ policyId: o.policy.id,
45
63
  contentSafetyAttested: i
46
64
  }
47
- })).data?.publishDashboardEmbedPolicy ?? a.policy, s = {
48
- ...a,
49
- policy: o
65
+ })).data?.publishDashboardEmbedPolicy ?? o.policy, c = {
66
+ ...o,
67
+ policy: s
50
68
  };
51
- return p(s), d(o), s;
69
+ return m(c), d(s), c;
70
+ } catch (e) {
71
+ return v(e instanceof Error ? e : /* @__PURE__ */ Error("Failed to publish to web")), null;
72
+ } finally {
73
+ g(!1);
74
+ }
75
+ }, [y]),
76
+ applyPresentation: s(async (e, t) => {
77
+ try {
78
+ g(!0), v(null);
79
+ let n = (await y.mutate({
80
+ mutation: a,
81
+ variables: { input: {
82
+ policyId: e,
83
+ presentationTheme: u[t.theme],
84
+ showDashboardTitle: t.showTitle,
85
+ showBrandingFooter: t.showBranding
86
+ } }
87
+ })).data?.updateDashboardEmbedPolicy ?? null;
88
+ return n && d(n), n;
52
89
  } catch (e) {
53
- return _(e instanceof Error ? e : /* @__PURE__ */ Error("Failed to publish to web")), null;
90
+ return v(e instanceof Error ? e : /* @__PURE__ */ Error("Failed to update presentation")), null;
54
91
  } finally {
55
- h(!1);
92
+ g(!1);
56
93
  }
57
- }, [v]),
58
- setAllowedOrigins: o(async (e, t) => {
94
+ }, [y]),
95
+ setAllowedOrigins: s(async (e, t) => {
59
96
  try {
60
- h(!0), _(null);
61
- let n = (await v.mutate({
97
+ g(!0), v(null);
98
+ let n = (await y.mutate({
62
99
  mutation: a,
63
100
  variables: { input: {
64
101
  policyId: e,
@@ -67,42 +104,42 @@ function u() {
67
104
  })).data?.updateDashboardEmbedPolicy ?? null;
68
105
  return n && d(n), n;
69
106
  } catch (e) {
70
- return _(e instanceof Error ? e : /* @__PURE__ */ Error("Failed to update allowed domains")), null;
107
+ return v(e instanceof Error ? e : /* @__PURE__ */ Error("Failed to update allowed domains")), null;
71
108
  } finally {
72
- h(!1);
109
+ g(!1);
73
110
  }
74
- }, [v]),
75
- rotateKey: o(async (e) => {
111
+ }, [y]),
112
+ rotateKey: s(async (e) => {
76
113
  try {
77
- h(!0), _(null);
78
- let t = (await v.mutate({
114
+ g(!0), v(null);
115
+ let t = (await y.mutate({
79
116
  mutation: i,
80
117
  variables: { policyId: e }
81
118
  })).data?.rotateDashboardEmbedPolicy ?? null;
82
- return t && (p(t), d(t.policy)), t;
119
+ return t && (m(t), d(t.policy)), t;
83
120
  } catch (e) {
84
- return _(e instanceof Error ? e : /* @__PURE__ */ Error("Failed to rotate embed link")), null;
121
+ return v(e instanceof Error ? e : /* @__PURE__ */ Error("Failed to rotate embed link")), null;
85
122
  } finally {
86
- h(!1);
123
+ g(!1);
87
124
  }
88
- }, [v]),
89
- unpublish: o(async (e) => {
125
+ }, [y]),
126
+ unpublish: s(async (e) => {
90
127
  try {
91
- h(!0), _(null);
92
- let t = (await v.mutate({
128
+ g(!0), v(null);
129
+ let t = (await y.mutate({
93
130
  mutation: r,
94
131
  variables: { policyId: e }
95
132
  })).data?.revokeDashboardEmbedPolicy ?? null;
96
- return t ? (d(t), p(null), !0) : !1;
133
+ return t ? (d(t), m(null), !0) : !1;
97
134
  } catch (e) {
98
- return _(e instanceof Error ? e : /* @__PURE__ */ Error("Failed to unpublish")), !1;
135
+ return v(e instanceof Error ? e : /* @__PURE__ */ Error("Failed to unpublish")), !1;
99
136
  } finally {
100
- h(!1);
137
+ g(!1);
101
138
  }
102
- }, [v])
139
+ }, [y])
103
140
  };
104
141
  }
105
142
  //#endregion
106
- export { u as default };
143
+ export { p as default, d as themeChoiceFromPolicy };
107
144
 
108
145
  //# sourceMappingURL=useDashboardEmbedPolicy.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useDashboardEmbedPolicy.js","names":[],"sources":["../../../src/bigconsole/hooks/useDashboardEmbedPolicy.ts"],"sourcesContent":["/**\n * useDashboardEmbedPolicy Hook\n *\n * Owner-facing operations for publishing a dashboard to the web (anonymous-link\n * embed). Mirrors {@link useDashboardSharing}. All mutations are gateway-enforced\n * by `@rbac(manage_embed)` (owner-only). Publishing serves the dashboard's LIVE\n * data anonymously — the caller confirms content-safety before enabling.\n */\n\nimport { useCallback, useState } from 'react';\nimport { useApolloClient } from '@apollo/client/react';\nimport {\n ListDashboardEmbedPoliciesDocument,\n CreateDashboardEmbedPolicyDocument,\n PublishDashboardEmbedPolicyDocument,\n UpdateDashboardEmbedPolicyDocument,\n RotateDashboardEmbedPolicyDocument,\n RevokeDashboardEmbedPolicyDocument,\n} from '../../generated/wspace-operations';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type EmbedPolicyStatus = 'DRAFT' | 'ACTIVE' | 'NEEDS_REVIEW' | 'BROKEN' | 'REVOKED' | 'EXPIRED';\n\nexport interface DashboardEmbedPolicy {\n id: string;\n dashboardId: string;\n status: EmbedPolicyStatus;\n accessMode: string;\n version: number;\n allowedParentOrigins: string[];\n expiresAt?: string | null;\n sessionTtlSeconds: number;\n contentReviewState: string;\n activePublicationId?: string | null;\n locatorPublicId?: string | null;\n fingerprint?: string | null;\n createdAt: string;\n updatedAt: string;\n activatedAt?: string | null;\n revokedAt?: string | null;\n}\n\n/** Returned once on create / rotate — carries the secret embed URL + snippet. */\nexport interface EmbedPolicySecret {\n embedUrl: string;\n iframeSnippet: string;\n fingerprint: string;\n policy: DashboardEmbedPolicy;\n}\n\nexport interface UseDashboardEmbedPolicyResult {\n /** The dashboard's active (or most recent) embed policy, if any. */\n policy: DashboardEmbedPolicy | null;\n /** The one-time secret from the last create/rotate (embed URL + iframe snippet). */\n secret: EmbedPolicySecret | null;\n loading: boolean;\n error: Error | null;\n\n fetchPolicy: (dashboardId: string) => Promise<DashboardEmbedPolicy | null>;\n /** Create (if needed) + publish → returns the live embed secret. */\n publishToWeb: (\n dashboardId: string,\n allowedParentOrigins: string[],\n contentSafetyAttested: boolean\n ) => Promise<EmbedPolicySecret | null>;\n setAllowedOrigins: (policyId: string, allowedParentOrigins: string[]) => Promise<DashboardEmbedPolicy | null>;\n rotateKey: (policyId: string) => Promise<EmbedPolicySecret | null>;\n /** Unpublish: revoke the policy (embed stops serving immediately). */\n unpublish: (policyId: string) => Promise<boolean>;\n}\n\n// ============================================================================\n// Hook\n// ============================================================================\n\n/** Pick the live-serving policy (ACTIVE) else the most recently updated one. */\nfunction pickCurrent(policies: DashboardEmbedPolicy[]): DashboardEmbedPolicy | null {\n if (policies.length === 0) return null;\n const active = policies.find((p) => p.status === 'ACTIVE');\n if (active) return active;\n return [...policies].sort((a, b) => Date.parse(b.updatedAt) - Date.parse(a.updatedAt))[0] ?? null;\n}\n\nexport function useDashboardEmbedPolicy(): UseDashboardEmbedPolicyResult {\n const [policy, setPolicy] = useState<DashboardEmbedPolicy | null>(null);\n const [secret, setSecret] = useState<EmbedPolicySecret | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const apolloClient = useApolloClient();\n\n const fetchPolicy = useCallback(\n async (dashboardId: string): Promise<DashboardEmbedPolicy | null> => {\n try {\n setLoading(true);\n setError(null);\n const result = await apolloClient.query<{\n listDashboardEmbedPolicies?: { nodes?: DashboardEmbedPolicy[] };\n }>({\n query: ListDashboardEmbedPoliciesDocument,\n variables: { dashboardId },\n fetchPolicy: 'network-only',\n });\n const current = pickCurrent(result.data?.listDashboardEmbedPolicies?.nodes ?? []);\n setPolicy(current);\n return current;\n } catch (err) {\n setError(err instanceof Error ? err : new Error('Failed to load embed policy'));\n return null;\n } finally {\n setLoading(false);\n }\n },\n [apolloClient]\n );\n\n const publishToWeb = useCallback(\n async (\n dashboardId: string,\n allowedParentOrigins: string[],\n contentSafetyAttested: boolean\n ): Promise<EmbedPolicySecret | null> => {\n try {\n setLoading(true);\n setError(null);\n\n // Create a DRAFT policy + anonymous-link locator (returns the secret once).\n const created = await apolloClient.mutate<{ createDashboardEmbedPolicy?: EmbedPolicySecret }>({\n mutation: CreateDashboardEmbedPolicyDocument,\n variables: { input: { dashboardId, allowedParentOrigins } },\n });\n const createdSecret = created.data?.createDashboardEmbedPolicy;\n if (!createdSecret) return null;\n\n // Activate it for live embedding (owner attests content-safety).\n const published = await apolloClient.mutate<{ publishDashboardEmbedPolicy?: DashboardEmbedPolicy }>({\n mutation: PublishDashboardEmbedPolicyDocument,\n variables: { policyId: createdSecret.policy.id, contentSafetyAttested },\n });\n const activePolicy = published.data?.publishDashboardEmbedPolicy ?? createdSecret.policy;\n\n const result: EmbedPolicySecret = { ...createdSecret, policy: activePolicy };\n setSecret(result);\n setPolicy(activePolicy);\n return result;\n } catch (err) {\n setError(err instanceof Error ? err : new Error('Failed to publish to web'));\n return null;\n } finally {\n setLoading(false);\n }\n },\n [apolloClient]\n );\n\n const setAllowedOrigins = useCallback(\n async (policyId: string, allowedParentOrigins: string[]): Promise<DashboardEmbedPolicy | null> => {\n try {\n setLoading(true);\n setError(null);\n const result = await apolloClient.mutate<{ updateDashboardEmbedPolicy?: DashboardEmbedPolicy }>({\n mutation: UpdateDashboardEmbedPolicyDocument,\n variables: { input: { policyId, allowedParentOrigins } },\n });\n const updated = result.data?.updateDashboardEmbedPolicy ?? null;\n if (updated) setPolicy(updated);\n return updated;\n } catch (err) {\n setError(err instanceof Error ? err : new Error('Failed to update allowed domains'));\n return null;\n } finally {\n setLoading(false);\n }\n },\n [apolloClient]\n );\n\n const rotateKey = useCallback(\n async (policyId: string): Promise<EmbedPolicySecret | null> => {\n try {\n setLoading(true);\n setError(null);\n const result = await apolloClient.mutate<{ rotateDashboardEmbedPolicy?: EmbedPolicySecret }>({\n mutation: RotateDashboardEmbedPolicyDocument,\n variables: { policyId },\n });\n const rotated = result.data?.rotateDashboardEmbedPolicy ?? null;\n if (rotated) {\n setSecret(rotated);\n setPolicy(rotated.policy);\n }\n return rotated;\n } catch (err) {\n setError(err instanceof Error ? err : new Error('Failed to rotate embed link'));\n return null;\n } finally {\n setLoading(false);\n }\n },\n [apolloClient]\n );\n\n const unpublish = useCallback(\n async (policyId: string): Promise<boolean> => {\n try {\n setLoading(true);\n setError(null);\n const result = await apolloClient.mutate<{ revokeDashboardEmbedPolicy?: DashboardEmbedPolicy }>({\n mutation: RevokeDashboardEmbedPolicyDocument,\n variables: { policyId },\n });\n const revoked = result.data?.revokeDashboardEmbedPolicy ?? null;\n if (revoked) {\n setPolicy(revoked);\n setSecret(null);\n return true;\n }\n return false;\n } catch (err) {\n setError(err instanceof Error ? err : new Error('Failed to unpublish'));\n return false;\n } finally {\n setLoading(false);\n }\n },\n [apolloClient]\n );\n\n return { policy, secret, loading, error, fetchPolicy, publishToWeb, setAllowedOrigins, rotateKey, unpublish };\n}\n\nexport default useDashboardEmbedPolicy;\n"],"mappings":"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"}
1
+ {"version":3,"file":"useDashboardEmbedPolicy.js","names":[],"sources":["../../../src/bigconsole/hooks/useDashboardEmbedPolicy.ts"],"sourcesContent":["/**\n * useDashboardEmbedPolicy Hook\n *\n * Owner-facing operations for publishing a dashboard to the web (anonymous-link\n * embed). Mirrors {@link useDashboardSharing}. All mutations are gateway-enforced\n * by `@rbac(manage_embed)` (owner-only). Publishing serves the dashboard's LIVE\n * data anonymously — the caller confirms content-safety before enabling.\n */\n\nimport { useCallback, useState } from 'react';\nimport { useApolloClient } from '@apollo/client/react';\nimport {\n ListDashboardEmbedPoliciesDocument,\n CreateDashboardEmbedPolicyDocument,\n PublishDashboardEmbedPolicyDocument,\n UpdateDashboardEmbedPolicyDocument,\n RotateDashboardEmbedPolicyDocument,\n RevokeDashboardEmbedPolicyDocument,\n} from '../../generated/wspace-operations';\nimport { DashboardEmbedTheme } from '../../generated/wspace-types';\nimport type { EmbedThemeMode } from '../components/embed/types';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type EmbedPolicyStatus = 'DRAFT' | 'ACTIVE' | 'NEEDS_REVIEW' | 'BROKEN' | 'REVOKED' | 'EXPIRED';\n\n/**\n * Owner-facing color mode (BOFF-5735); maps to the backend {@link DashboardEmbedTheme}\n * enum. Same shape as the render-model's {@link EmbedThemeMode} — aliased to avoid a\n * duplicate union.\n */\nexport type EmbedThemeChoice = EmbedThemeMode;\n\n/** Publish-time presentation options the owner controls in the Share dialog. */\nexport interface EmbedPresentationChoice {\n theme: EmbedThemeChoice;\n showTitle: boolean;\n showBranding: boolean;\n}\n\nconst THEME_TO_ENUM: Record<EmbedThemeChoice, DashboardEmbedTheme> = {\n light: DashboardEmbedTheme.Light,\n dark: DashboardEmbedTheme.Dark,\n auto: DashboardEmbedTheme.Auto,\n};\n\n/** Map the backend enum back to the lowercase owner-facing choice (defaults to light). */\nexport function themeChoiceFromPolicy(value: string | null | undefined): EmbedThemeChoice {\n switch (value) {\n case DashboardEmbedTheme.Dark:\n return 'dark';\n case DashboardEmbedTheme.Auto:\n return 'auto';\n default:\n return 'light';\n }\n}\n\nexport interface DashboardEmbedPolicy {\n id: string;\n dashboardId: string;\n status: EmbedPolicyStatus;\n accessMode: string;\n version: number;\n allowedParentOrigins: string[];\n expiresAt?: string | null;\n sessionTtlSeconds: number;\n contentReviewState: string;\n presentationTheme: DashboardEmbedTheme;\n showDashboardTitle: boolean;\n showBrandingFooter: boolean;\n activePublicationId?: string | null;\n locatorPublicId?: string | null;\n fingerprint?: string | null;\n createdAt: string;\n updatedAt: string;\n activatedAt?: string | null;\n revokedAt?: string | null;\n}\n\n/** Returned once on create / rotate — carries the secret embed URL + snippet. */\nexport interface EmbedPolicySecret {\n embedUrl: string;\n iframeSnippet: string;\n fingerprint: string;\n policy: DashboardEmbedPolicy;\n}\n\nexport interface UseDashboardEmbedPolicyResult {\n /** The dashboard's active (or most recent) embed policy, if any. */\n policy: DashboardEmbedPolicy | null;\n /** The one-time secret from the last create/rotate (embed URL + iframe snippet). */\n secret: EmbedPolicySecret | null;\n loading: boolean;\n error: Error | null;\n\n fetchPolicy: (dashboardId: string) => Promise<DashboardEmbedPolicy | null>;\n /** Create (if needed) + publish → returns the live embed secret. */\n publishToWeb: (\n dashboardId: string,\n allowedParentOrigins: string[],\n contentSafetyAttested: boolean,\n presentation?: EmbedPresentationChoice\n ) => Promise<EmbedPolicySecret | null>;\n /**\n * Persist the presentation options of an already-published policy. They are\n * read live by the embed renderer, so the change applies on the next render\n * with no re-publish — the embed link/key are untouched.\n */\n applyPresentation: (policyId: string, presentation: EmbedPresentationChoice) => Promise<DashboardEmbedPolicy | null>;\n setAllowedOrigins: (policyId: string, allowedParentOrigins: string[]) => Promise<DashboardEmbedPolicy | null>;\n rotateKey: (policyId: string) => Promise<EmbedPolicySecret | null>;\n /** Unpublish: revoke the policy (embed stops serving immediately). */\n unpublish: (policyId: string) => Promise<boolean>;\n}\n\n// ============================================================================\n// Hook\n// ============================================================================\n\n/** Pick the live-serving policy (ACTIVE) else the most recently updated one. */\nfunction pickCurrent(policies: DashboardEmbedPolicy[]): DashboardEmbedPolicy | null {\n if (policies.length === 0) return null;\n const active = policies.find((p) => p.status === 'ACTIVE');\n if (active) return active;\n return [...policies].sort((a, b) => Date.parse(b.updatedAt) - Date.parse(a.updatedAt))[0] ?? null;\n}\n\nexport function useDashboardEmbedPolicy(): UseDashboardEmbedPolicyResult {\n const [policy, setPolicy] = useState<DashboardEmbedPolicy | null>(null);\n const [secret, setSecret] = useState<EmbedPolicySecret | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const apolloClient = useApolloClient();\n\n const fetchPolicy = useCallback(\n async (dashboardId: string): Promise<DashboardEmbedPolicy | null> => {\n try {\n setLoading(true);\n setError(null);\n const result = await apolloClient.query<{\n listDashboardEmbedPolicies?: { nodes?: DashboardEmbedPolicy[] };\n }>({\n query: ListDashboardEmbedPoliciesDocument,\n variables: { dashboardId },\n fetchPolicy: 'network-only',\n });\n const current = pickCurrent(result.data?.listDashboardEmbedPolicies?.nodes ?? []);\n setPolicy(current);\n return current;\n } catch (err) {\n setError(err instanceof Error ? err : new Error('Failed to load embed policy'));\n return null;\n } finally {\n setLoading(false);\n }\n },\n [apolloClient]\n );\n\n const publishToWeb = useCallback(\n async (\n dashboardId: string,\n allowedParentOrigins: string[],\n contentSafetyAttested: boolean,\n presentation?: EmbedPresentationChoice\n ): Promise<EmbedPolicySecret | null> => {\n try {\n setLoading(true);\n setError(null);\n\n // Create a DRAFT policy + anonymous-link locator (returns the secret once).\n // Presentation options (BOFF-5735) are captured here so the very first\n // render reflects them; they're read live thereafter.\n const created = await apolloClient.mutate<{ createDashboardEmbedPolicy?: EmbedPolicySecret }>({\n mutation: CreateDashboardEmbedPolicyDocument,\n variables: {\n input: {\n dashboardId,\n allowedParentOrigins,\n ...(presentation\n ? {\n presentationTheme: THEME_TO_ENUM[presentation.theme],\n showDashboardTitle: presentation.showTitle,\n showBrandingFooter: presentation.showBranding,\n }\n : {}),\n },\n },\n });\n const createdSecret = created.data?.createDashboardEmbedPolicy;\n if (!createdSecret) return null;\n\n // Activate it for live embedding (owner attests content-safety).\n const published = await apolloClient.mutate<{ publishDashboardEmbedPolicy?: DashboardEmbedPolicy }>({\n mutation: PublishDashboardEmbedPolicyDocument,\n variables: { policyId: createdSecret.policy.id, contentSafetyAttested },\n });\n const activePolicy = published.data?.publishDashboardEmbedPolicy ?? createdSecret.policy;\n\n const result: EmbedPolicySecret = { ...createdSecret, policy: activePolicy };\n setSecret(result);\n setPolicy(activePolicy);\n return result;\n } catch (err) {\n setError(err instanceof Error ? err : new Error('Failed to publish to web'));\n return null;\n } finally {\n setLoading(false);\n }\n },\n [apolloClient]\n );\n\n const applyPresentation = useCallback(\n async (policyId: string, presentation: EmbedPresentationChoice): Promise<DashboardEmbedPolicy | null> => {\n try {\n setLoading(true);\n setError(null);\n // Presentation is read LIVE at view time by the embed renderer, so simply\n // persisting the choices on the policy is enough — no re-publish, and the\n // embed link/key are untouched. Live embeds pick up the change on their\n // next render (bounded by the service's short render-cache window).\n const result = await apolloClient.mutate<{ updateDashboardEmbedPolicy?: DashboardEmbedPolicy }>({\n mutation: UpdateDashboardEmbedPolicyDocument,\n variables: {\n input: {\n policyId,\n presentationTheme: THEME_TO_ENUM[presentation.theme],\n showDashboardTitle: presentation.showTitle,\n showBrandingFooter: presentation.showBranding,\n },\n },\n });\n const updated = result.data?.updateDashboardEmbedPolicy ?? null;\n if (updated) setPolicy(updated);\n return updated;\n } catch (err) {\n setError(err instanceof Error ? err : new Error('Failed to update presentation'));\n return null;\n } finally {\n setLoading(false);\n }\n },\n [apolloClient]\n );\n\n const setAllowedOrigins = useCallback(\n async (policyId: string, allowedParentOrigins: string[]): Promise<DashboardEmbedPolicy | null> => {\n try {\n setLoading(true);\n setError(null);\n const result = await apolloClient.mutate<{ updateDashboardEmbedPolicy?: DashboardEmbedPolicy }>({\n mutation: UpdateDashboardEmbedPolicyDocument,\n variables: { input: { policyId, allowedParentOrigins } },\n });\n const updated = result.data?.updateDashboardEmbedPolicy ?? null;\n if (updated) setPolicy(updated);\n return updated;\n } catch (err) {\n setError(err instanceof Error ? err : new Error('Failed to update allowed domains'));\n return null;\n } finally {\n setLoading(false);\n }\n },\n [apolloClient]\n );\n\n const rotateKey = useCallback(\n async (policyId: string): Promise<EmbedPolicySecret | null> => {\n try {\n setLoading(true);\n setError(null);\n const result = await apolloClient.mutate<{ rotateDashboardEmbedPolicy?: EmbedPolicySecret }>({\n mutation: RotateDashboardEmbedPolicyDocument,\n variables: { policyId },\n });\n const rotated = result.data?.rotateDashboardEmbedPolicy ?? null;\n if (rotated) {\n setSecret(rotated);\n setPolicy(rotated.policy);\n }\n return rotated;\n } catch (err) {\n setError(err instanceof Error ? err : new Error('Failed to rotate embed link'));\n return null;\n } finally {\n setLoading(false);\n }\n },\n [apolloClient]\n );\n\n const unpublish = useCallback(\n async (policyId: string): Promise<boolean> => {\n try {\n setLoading(true);\n setError(null);\n const result = await apolloClient.mutate<{ revokeDashboardEmbedPolicy?: DashboardEmbedPolicy }>({\n mutation: RevokeDashboardEmbedPolicyDocument,\n variables: { policyId },\n });\n const revoked = result.data?.revokeDashboardEmbedPolicy ?? null;\n if (revoked) {\n setPolicy(revoked);\n setSecret(null);\n return true;\n }\n return false;\n } catch (err) {\n setError(err instanceof Error ? err : new Error('Failed to unpublish'));\n return false;\n } finally {\n setLoading(false);\n }\n },\n [apolloClient]\n );\n\n return {\n policy,\n secret,\n loading,\n error,\n fetchPolicy,\n publishToWeb,\n applyPresentation,\n setAllowedOrigins,\n rotateKey,\n unpublish,\n };\n}\n\nexport default useDashboardEmbedPolicy;\n"],"mappings":";;;;;AA0CA,IAAM,IAA+D;CACnE,OAAO,EAAoB;CAC3B,MAAM,EAAoB;CAC1B,MAAM,EAAoB;CAC3B;AAGD,SAAgB,EAAsB,GAAoD;AACxF,SAAQ,GAAR;EACE,KAAK,EAAoB,KACvB,QAAO;EACT,KAAK,EAAoB,KACvB,QAAO;EACT,QACE,QAAO;;;AAmEb,SAAS,EAAY,GAA+D;AAIlF,QAHI,EAAS,WAAW,IAAU,OACnB,EAAS,MAAM,MAAM,EAAE,WAAW,SAAS,KAEnD,CAAC,GAAG,EAAS,CAAC,MAAM,GAAG,MAAM,KAAK,MAAM,EAAE,UAAU,GAAG,KAAK,MAAM,EAAE,UAAU,CAAC,CAAC,MAAM;;AAG/F,SAAgB,IAAyD;CACvE,IAAM,CAAC,GAAQ,KAAa,EAAsC,KAAK,EACjE,CAAC,GAAQ,KAAa,EAAmC,KAAK,EAC9D,CAAC,GAAS,KAAc,EAAS,GAAM,EACvC,CAAC,GAAO,KAAY,EAAuB,KAAK,EAEhD,IAAe,GAAiB;AA2LtC,QAAO;EACL;EACA;EACA;EACA;EACA,aA9LkB,EAClB,OAAO,MAA8D;AACnE,OAAI;AAEF,IADA,EAAW,GAAK,EAChB,EAAS,KAAK;IAQd,IAAM,IAAU,GAPD,MAAM,EAAa,MAE/B;KACD,OAAO;KACP,WAAW,EAAE,gBAAa;KAC1B,aAAa;KACd,CAAC,EACiC,MAAM,4BAA4B,SAAS,EAAE,CAAC;AAEjF,WADA,EAAU,EAAQ,EACX;YACA,GAAK;AAEZ,WADA,EAAS,aAAe,QAAQ,IAAM,gBAAI,MAAM,8BAA8B,CAAC,EACxE;aACC;AACR,MAAW,GAAM;;KAGrB,CAAC,EAAa,CACf;EAwKC,cAtKmB,EACnB,OACE,GACA,GACA,GACA,MACsC;AACtC,OAAI;AAEF,IADA,EAAW,GAAK,EAChB,EAAS,KAAK;IAqBd,IAAM,KAhBU,MAAM,EAAa,OAA2D;KAC5F,UAAU;KACV,WAAW,EACT,OAAO;MACL;MACA;MACA,GAAI,IACA;OACE,mBAAmB,EAAc,EAAa;OAC9C,oBAAoB,EAAa;OACjC,oBAAoB,EAAa;OAClC,GACD,EAAE;MACP,EACF;KACF,CAAC,EAC4B,MAAM;AACpC,QAAI,CAAC,EAAe,QAAO;IAO3B,IAAM,KAJY,MAAM,EAAa,OAA+D;KAClG,UAAU;KACV,WAAW;MAAE,UAAU,EAAc,OAAO;MAAI;MAAuB;KACxE,CAAC,EAC6B,MAAM,+BAA+B,EAAc,QAE5E,IAA4B;KAAE,GAAG;KAAe,QAAQ;KAAc;AAG5E,WAFA,EAAU,EAAO,EACjB,EAAU,EAAa,EAChB;YACA,GAAK;AAEZ,WADA,EAAS,aAAe,QAAQ,IAAM,gBAAI,MAAM,2BAA2B,CAAC,EACrE;aACC;AACR,MAAW,GAAM;;KAGrB,CAAC,EAAa,CACf;EAmHC,mBAjHwB,EACxB,OAAO,GAAkB,MAAgF;AACvG,OAAI;AAEF,IADA,EAAW,GAAK,EAChB,EAAS,KAAK;IAgBd,IAAM,KAXS,MAAM,EAAa,OAA8D;KAC9F,UAAU;KACV,WAAW,EACT,OAAO;MACL;MACA,mBAAmB,EAAc,EAAa;MAC9C,oBAAoB,EAAa;MACjC,oBAAoB,EAAa;MAClC,EACF;KACF,CAAC,EACqB,MAAM,8BAA8B;AAE3D,WADI,KAAS,EAAU,EAAQ,EACxB;YACA,GAAK;AAEZ,WADA,EAAS,aAAe,QAAQ,IAAM,gBAAI,MAAM,gCAAgC,CAAC,EAC1E;aACC;AACR,MAAW,GAAM;;KAGrB,CAAC,EAAa,CACf;EAmFC,mBAjFwB,EACxB,OAAO,GAAkB,MAAyE;AAChG,OAAI;AAEF,IADA,EAAW,GAAK,EAChB,EAAS,KAAK;IAKd,IAAM,KAJS,MAAM,EAAa,OAA8D;KAC9F,UAAU;KACV,WAAW,EAAE,OAAO;MAAE;MAAU;MAAsB,EAAE;KACzD,CAAC,EACqB,MAAM,8BAA8B;AAE3D,WADI,KAAS,EAAU,EAAQ,EACxB;YACA,GAAK;AAEZ,WADA,EAAS,aAAe,QAAQ,IAAM,gBAAI,MAAM,mCAAmC,CAAC,EAC7E;aACC;AACR,MAAW,GAAM;;KAGrB,CAAC,EAAa,CACf;EA8DC,WA5DgB,EAChB,OAAO,MAAwD;AAC7D,OAAI;AAEF,IADA,EAAW,GAAK,EAChB,EAAS,KAAK;IAKd,IAAM,KAJS,MAAM,EAAa,OAA2D;KAC3F,UAAU;KACV,WAAW,EAAE,aAAU;KACxB,CAAC,EACqB,MAAM,8BAA8B;AAK3D,WAJI,MACF,EAAU,EAAQ,EAClB,EAAU,EAAQ,OAAO,GAEpB;YACA,GAAK;AAEZ,WADA,EAAS,aAAe,QAAQ,IAAM,gBAAI,MAAM,8BAA8B,CAAC,EACxE;aACC;AACR,MAAW,GAAM;;KAGrB,CAAC,EAAa,CACf;EAsCC,WApCgB,EAChB,OAAO,MAAuC;AAC5C,OAAI;AAEF,IADA,EAAW,GAAK,EAChB,EAAS,KAAK;IAKd,IAAM,KAJS,MAAM,EAAa,OAA8D;KAC9F,UAAU;KACV,WAAW,EAAE,aAAU;KACxB,CAAC,EACqB,MAAM,8BAA8B;AAM3D,WALI,KACF,EAAU,EAAQ,EAClB,EAAU,KAAK,EACR,MAEF;YACA,GAAK;AAEZ,WADA,EAAS,aAAe,QAAQ,IAAM,gBAAI,MAAM,sBAAsB,CAAC,EAChE;aACC;AACR,MAAW,GAAM;;KAGrB,CAAC,EAAa,CACf;EAaA"}
@@ -48,6 +48,9 @@ var i = e`
48
48
  expiresAt
49
49
  sessionTtlSeconds
50
50
  contentReviewState
51
+ presentationTheme
52
+ showDashboardTitle
53
+ showBrandingFooter
51
54
  activePublicationId
52
55
  locatorPublicId
53
56
  fingerprint