@syntrologie/adapt-product 2.28.0 → 2.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/dist/__fixtures__/variant-payloads.d.ts +33 -0
  2. package/dist/__fixtures__/variant-payloads.d.ts.map +1 -0
  3. package/dist/cdn.d.ts +1 -0
  4. package/dist/cdn.d.ts.map +1 -1
  5. package/dist/cdn.js +9 -3
  6. package/dist/cdn.js.map +2 -2
  7. package/dist/{chunk-SGJGJRCP.js → chunk-7Z4Y44WC.js} +139 -6
  8. package/dist/chunk-7Z4Y44WC.js.map +7 -0
  9. package/dist/chunk-VY23O32Z.js +10963 -0
  10. package/dist/chunk-VY23O32Z.js.map +7 -0
  11. package/dist/decision/card-effects.d.ts +20 -0
  12. package/dist/decision/card-effects.d.ts.map +1 -0
  13. package/dist/decision/card.d.ts +150 -0
  14. package/dist/decision/card.d.ts.map +1 -0
  15. package/dist/decision/pdp-compose.d.ts +69 -0
  16. package/dist/decision/pdp-compose.d.ts.map +1 -0
  17. package/dist/decision/pdp-effects.d.ts +17 -0
  18. package/dist/decision/pdp-effects.d.ts.map +1 -0
  19. package/dist/decision/pdp.d.ts +214 -0
  20. package/dist/decision/pdp.d.ts.map +1 -0
  21. package/dist/native/nativeSlotSwap.d.ts +40 -0
  22. package/dist/native/nativeSlotSwap.d.ts.map +1 -0
  23. package/dist/native/nativeSlotWatcher.d.ts +135 -0
  24. package/dist/native/nativeSlotWatcher.d.ts.map +1 -0
  25. package/dist/platformAdapter.d.ts +82 -0
  26. package/dist/platformAdapter.d.ts.map +1 -0
  27. package/dist/runtime.d.ts +318 -36
  28. package/dist/runtime.d.ts.map +1 -1
  29. package/dist/runtime.js +10 -2
  30. package/dist/sanitizer.d.ts.map +1 -1
  31. package/dist/schema-primitives.d.ts +197 -12
  32. package/dist/schema-primitives.d.ts.map +1 -1
  33. package/dist/schema.d.ts +2098 -164
  34. package/dist/schema.d.ts.map +1 -1
  35. package/dist/schema.js +11 -1
  36. package/dist/scoring/pool-selection.d.ts +35 -0
  37. package/dist/scoring/pool-selection.d.ts.map +1 -0
  38. package/dist/scoring/scored-template.d.ts +106 -0
  39. package/dist/scoring/scored-template.d.ts.map +1 -0
  40. package/dist/variantCache.d.ts +5 -0
  41. package/dist/variantCache.d.ts.map +1 -0
  42. package/dist/widgets/OtherProductTileLit.d.ts +46 -0
  43. package/dist/widgets/OtherProductTileLit.d.ts.map +1 -0
  44. package/dist/widgets/PdpChartBarStackedLit.d.ts +33 -0
  45. package/dist/widgets/PdpChartBarStackedLit.d.ts.map +1 -0
  46. package/dist/widgets/PdpChartLit.d.ts +56 -0
  47. package/dist/widgets/PdpChartLit.d.ts.map +1 -0
  48. package/dist/widgets/PdpChartMetricPullLit.d.ts +33 -0
  49. package/dist/widgets/PdpChartMetricPullLit.d.ts.map +1 -0
  50. package/dist/widgets/PdpOtherProductsCarouselLit.d.ts +33 -0
  51. package/dist/widgets/PdpOtherProductsCarouselLit.d.ts.map +1 -0
  52. package/dist/widgets/PdpOtherProductsGridLit.d.ts +20 -0
  53. package/dist/widgets/PdpOtherProductsGridLit.d.ts.map +1 -0
  54. package/dist/widgets/PdpOtherProductsLit.d.ts +35 -0
  55. package/dist/widgets/PdpOtherProductsLit.d.ts.map +1 -0
  56. package/dist/widgets/PdpPeerFeedCarouselLit.d.ts +30 -0
  57. package/dist/widgets/PdpPeerFeedCarouselLit.d.ts.map +1 -0
  58. package/dist/widgets/PdpPeerFeedLit.d.ts +51 -0
  59. package/dist/widgets/PdpPeerFeedLit.d.ts.map +1 -0
  60. package/dist/widgets/PdpPeerFeedMasonryLit.d.ts +30 -0
  61. package/dist/widgets/PdpPeerFeedMasonryLit.d.ts.map +1 -0
  62. package/dist/widgets/PdpQaAccordionLit.d.ts +27 -0
  63. package/dist/widgets/PdpQaAccordionLit.d.ts.map +1 -0
  64. package/dist/widgets/PdpQaLit.d.ts +48 -0
  65. package/dist/widgets/PdpQaLit.d.ts.map +1 -0
  66. package/dist/widgets/PdpQaSideBySideLit.d.ts +27 -0
  67. package/dist/widgets/PdpQaSideBySideLit.d.ts.map +1 -0
  68. package/dist/widgets/PdpRegionalFullBleedLit.d.ts +27 -0
  69. package/dist/widgets/PdpRegionalFullBleedLit.d.ts.map +1 -0
  70. package/dist/widgets/PdpRegionalInlineNoteLit.d.ts +27 -0
  71. package/dist/widgets/PdpRegionalInlineNoteLit.d.ts.map +1 -0
  72. package/dist/widgets/PdpRegionalLit.d.ts +48 -0
  73. package/dist/widgets/PdpRegionalLit.d.ts.map +1 -0
  74. package/dist/widgets/PdpRibbonLit.d.ts +31 -0
  75. package/dist/widgets/PdpRibbonLit.d.ts.map +1 -0
  76. package/dist/widgets/PdpSectionHeaderLit.d.ts +30 -0
  77. package/dist/widgets/PdpSectionHeaderLit.d.ts.map +1 -0
  78. package/dist/widgets/PdpSlotLit.d.ts +30 -0
  79. package/dist/widgets/PdpSlotLit.d.ts.map +1 -0
  80. package/dist/widgets/PdpSlotPlaceholderLit.d.ts +22 -0
  81. package/dist/widgets/PdpSlotPlaceholderLit.d.ts.map +1 -0
  82. package/dist/widgets/PdpTrendingNewsHeroLit.d.ts +32 -0
  83. package/dist/widgets/PdpTrendingNewsHeroLit.d.ts.map +1 -0
  84. package/dist/widgets/PdpTrendingNewsLit.d.ts +42 -0
  85. package/dist/widgets/PdpTrendingNewsLit.d.ts.map +1 -0
  86. package/dist/widgets/PdpTrendingNewsMagazineLit.d.ts +32 -0
  87. package/dist/widgets/PdpTrendingNewsMagazineLit.d.ts.map +1 -0
  88. package/dist/widgets/ProductCardLit.d.ts +78 -0
  89. package/dist/widgets/ProductCardLit.d.ts.map +1 -1
  90. package/dist/widgets/ProductComparisonLit.d.ts +9 -4
  91. package/dist/widgets/ProductComparisonLit.d.ts.map +1 -1
  92. package/dist/widgets/ProductGridLit.d.ts +1 -0
  93. package/dist/widgets/ProductGridLit.d.ts.map +1 -1
  94. package/dist/widgets/ProductHeroLit.d.ts +1 -0
  95. package/dist/widgets/ProductHeroLit.d.ts.map +1 -1
  96. package/dist/widgets/ProductRecoCarouselLit.d.ts +24 -0
  97. package/dist/widgets/ProductRecoCarouselLit.d.ts.map +1 -0
  98. package/dist/widgets/SyntroPdpLit.d.ts +366 -0
  99. package/dist/widgets/SyntroPdpLit.d.ts.map +1 -0
  100. package/dist/widgets/VariantPanelLit.d.ts +98 -0
  101. package/dist/widgets/VariantPanelLit.d.ts.map +1 -0
  102. package/dist/widgets/ensureStylesInRoot.d.ts +22 -0
  103. package/dist/widgets/ensureStylesInRoot.d.ts.map +1 -0
  104. package/dist/widgets/entrance.d.ts +35 -0
  105. package/dist/widgets/entrance.d.ts.map +1 -0
  106. package/dist/widgets/renderHealth.d.ts +57 -0
  107. package/dist/widgets/renderHealth.d.ts.map +1 -0
  108. package/dist/widgets/renderHealthReporter.d.ts +66 -0
  109. package/dist/widgets/renderHealthReporter.d.ts.map +1 -0
  110. package/package.json +4 -1
  111. package/dist/chunk-QZZVFYL6.js +0 -1352
  112. package/dist/chunk-QZZVFYL6.js.map +0 -7
  113. package/dist/chunk-SGJGJRCP.js.map +0 -7
@@ -1 +1 @@
1
- {"version":3,"file":"ProductGridLit.d.ts","sourceRoot":"","sources":["../../src/widgets/ProductGridLit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,UAAU,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAErE,OAAO,EAAE,KAAK,SAAS,EAAc,MAAM,WAAW,CAAC;AAGvD,qBAAa,cAAe,SAAQ,UAAU;;IAC5C,OAAgB,UAAU;;;;;;;;;;MAIxB;IAEF,KAAK,EAAE,SAAS,GAAG,SAAS,CAAa;IACzC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAM;IAClE,eAAe,UAAS;IAIf,gBAAgB;IAIhB,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAM/C,oBAAoB,IAAI,IAAI;IA6B5B,MAAM,IAAI,cAAc,GAAG,OAAO,OAAO;CA0BnD"}
1
+ {"version":3,"file":"ProductGridLit.d.ts","sourceRoot":"","sources":["../../src/widgets/ProductGridLit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,UAAU,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAErE,OAAO,EAAE,KAAK,SAAS,EAAc,MAAM,WAAW,CAAC;AAGvD,qBAAa,cAAe,SAAQ,UAAU;;IAC5C,OAAgB,UAAU;;;;;;;;;;MAIxB;IAEF,KAAK,EAAE,SAAS,GAAG,SAAS,CAAa;IACzC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAM;IAClE,eAAe,UAAS;IAIf,gBAAgB;IAIhB,iBAAiB,IAAI,IAAI;IASzB,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAM/C,oBAAoB,IAAI,IAAI;IA6B5B,MAAM,IAAI,cAAc,GAAG,OAAO,OAAO;CA0BnD"}
@@ -20,6 +20,7 @@ export declare class ProductHeroLit extends LitElement {
20
20
  }>;
21
21
  validationError: boolean;
22
22
  createRenderRoot(): this;
23
+ connectedCallback(): void;
23
24
  willUpdate(changed: Map<string, unknown>): void;
24
25
  disconnectedCallback(): void;
25
26
  render(): TemplateResult | typeof nothing;
@@ -1 +1 @@
1
- {"version":3,"file":"ProductHeroLit.d.ts","sourceRoot":"","sources":["../../src/widgets/ProductHeroLit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,UAAU,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAGrE,OAAO,EAAE,KAAK,SAAS,EAAc,MAAM,WAAW,CAAC;AAEvD,qBAAa,cAAe,SAAQ,UAAU;;IAC5C,OAAgB,UAAU;;;;;;;;;;MAIxB;IAEF,KAAK,EAAE,SAAS,GAAG,SAAS,CAAa;IACzC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAM;IAClE,eAAe,UAAS;IAIf,gBAAgB;IAIhB,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAM/C,oBAAoB,IAAI,IAAI;IA6B5B,MAAM,IAAI,cAAc,GAAG,OAAO,OAAO;CAuEnD"}
1
+ {"version":3,"file":"ProductHeroLit.d.ts","sourceRoot":"","sources":["../../src/widgets/ProductHeroLit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,UAAU,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAGrE,OAAO,EAAE,KAAK,SAAS,EAAc,MAAM,WAAW,CAAC;AAEvD,qBAAa,cAAe,SAAQ,UAAU;;IAC5C,OAAgB,UAAU;;;;;;;;;;MAIxB;IAEF,KAAK,EAAE,SAAS,GAAG,SAAS,CAAa;IACzC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAM;IAClE,eAAe,UAAS;IAIf,gBAAgB;IAIhB,iBAAiB,IAAI,IAAI;IASzB,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAM/C,oBAAoB,IAAI,IAAI;IA6B5B,MAAM,IAAI,cAAc,GAAG,OAAO,OAAO;CAuEnD"}
@@ -0,0 +1,24 @@
1
+ import { LitElement, nothing, type TemplateResult } from 'lit';
2
+ import { type RecoProps } from '../schema';
3
+ import { type RenderHealthProbe } from './renderHealthReporter';
4
+ export declare class ProductRecoCarouselLit extends LitElement {
5
+ #private;
6
+ static properties: {
7
+ props: {
8
+ attribute: boolean;
9
+ };
10
+ _parsed: {
11
+ state: boolean;
12
+ };
13
+ };
14
+ static readonly _testing: {
15
+ healthProbe: (host: ProductRecoCarouselLit) => RenderHealthProbe | null;
16
+ };
17
+ props: RecoProps | undefined;
18
+ private _parsed;
19
+ constructor();
20
+ createRenderRoot(): this;
21
+ willUpdate(changed: Map<string, unknown>): void;
22
+ render(): TemplateResult | typeof nothing;
23
+ }
24
+ //# sourceMappingURL=ProductRecoCarouselLit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProductRecoCarouselLit.d.ts","sourceRoot":"","sources":["../../src/widgets/ProductRecoCarouselLit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,UAAU,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAErE,OAAO,EAAE,KAAK,SAAS,EAAc,MAAM,WAAW,CAAC;AACvD,OAAO,EAA0B,KAAK,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAExF,qBAAa,sBAAuB,SAAQ,UAAU;;IACpD,OAAgB,UAAU;;;;;;;MAA6D;IACvF,MAAM,CAAC,QAAQ,CAAC,QAAQ;4BACF,sBAAsB,KAAG,iBAAiB,GAAG,IAAI;MACrE;IACM,KAAK,EAAE,SAAS,GAAG,SAAS,CAAC;IACrC,QAAgB,OAAO,CAAwB;;IAyBtC,gBAAgB;IAGhB,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC;IAMxC,MAAM,IAAI,cAAc,GAAG,OAAO,OAAO;CAwBnD"}
@@ -0,0 +1,366 @@
1
+ import { LitElement, type PropertyValues } from 'lit';
2
+ import { type PdpPlanTaskClient } from '../decision/pdp-compose';
3
+ import './PdpSectionHeaderLit';
4
+ import './PdpOtherProductsCarouselLit.js';
5
+ import './PdpOtherProductsGridLit.js';
6
+ export interface VisitorAttribution {
7
+ referrer: string;
8
+ referring_domain: string;
9
+ initial_url: string;
10
+ initial_pathname: string;
11
+ utm_source: string;
12
+ utm_medium: string;
13
+ utm_campaign: string;
14
+ utm_content: string;
15
+ utm_term: string;
16
+ }
17
+ export interface VisitorGeo {
18
+ country: string;
19
+ country_code: string;
20
+ region: string;
21
+ city: string;
22
+ is_eu: boolean;
23
+ }
24
+ export interface VisitorDevice {
25
+ user_agent: string;
26
+ locale: string;
27
+ viewport_w: number | null;
28
+ viewport_h: number | null;
29
+ screen_w: number | null;
30
+ screen_h: number | null;
31
+ dpr: number | null;
32
+ is_touch: boolean;
33
+ }
34
+ export interface VisitorSignals {
35
+ attribution: VisitorAttribution;
36
+ geo: VisitorGeo;
37
+ device: VisitorDevice;
38
+ session_metrics: Record<string, string | number | boolean>;
39
+ extras: Record<string, string | number | boolean>;
40
+ }
41
+ export interface MountedInstance {
42
+ instance_id: string;
43
+ element_type: 'tile' | 'action' | 'item';
44
+ template_id: string;
45
+ placement: {
46
+ type: 'slot';
47
+ slot: string;
48
+ } | {
49
+ type: string;
50
+ [key: string]: unknown;
51
+ };
52
+ content: Record<string, unknown>;
53
+ state: string;
54
+ mounted_by: {
55
+ agent_id: string;
56
+ turn_id: string;
57
+ };
58
+ mounted_at: string;
59
+ version: number;
60
+ }
61
+ export interface MutationEnvelope {
62
+ type: 'syntro.element.mutation';
63
+ schema_version: 'v0';
64
+ mutations: Array<{
65
+ op: 'mount';
66
+ instance: MountedInstance;
67
+ }>;
68
+ }
69
+ export type { PdpModuleHeaderClient, PdpPlanEnvelope, PdpPlanTaskClient, } from '../decision/pdp-compose';
70
+ export interface RuntimeContext {
71
+ page: {
72
+ locale?: string;
73
+ routeId?: string;
74
+ title?: string;
75
+ url: string;
76
+ };
77
+ session: {
78
+ pageHistory?: Array<{
79
+ ts: number;
80
+ url: string;
81
+ }>;
82
+ sessionId?: string;
83
+ startTs: number;
84
+ };
85
+ surface: {
86
+ device: string;
87
+ host: string;
88
+ mode: string;
89
+ type: string;
90
+ };
91
+ viewport: {
92
+ height: number;
93
+ width: number;
94
+ };
95
+ }
96
+ export interface SmartCanvasRuntime {
97
+ apps?: {
98
+ has?(appId: string): boolean;
99
+ };
100
+ telemetry?: {
101
+ track?(eventName: string, props?: Record<string, unknown>): void;
102
+ };
103
+ }
104
+ interface SynOSGlobal {
105
+ runtime?: {
106
+ context: {
107
+ get(): RuntimeContext;
108
+ };
109
+ sessionMetrics?: {
110
+ getAll(): Record<string, number>;
111
+ };
112
+ telemetry?: {
113
+ getDistinctId?(): string | undefined;
114
+ getSessionId?(): string | undefined;
115
+ getSegmentFlags?(): Record<string, boolean> | undefined;
116
+ getAllFeatureFlags?(): Record<string, boolean | string> | undefined;
117
+ };
118
+ };
119
+ /** On-demand scoring (the runtime's thin `score` primitive). */
120
+ score?: (spec: unknown) => Promise<string>;
121
+ /** Batched two-axis scoring through one backend model call. */
122
+ scoreMulti?: (specs: unknown[]) => Promise<string[]>;
123
+ /**
124
+ * Authenticated transport to the runtime-backend (the runtime owns auth; the
125
+ * adaptive owns which endpoint + payload). Used for the live module endpoint.
126
+ */
127
+ authedFetch?: (path: string, init?: RequestInit) => Promise<Response>;
128
+ }
129
+ interface PdpExplainMetric {
130
+ value: string;
131
+ label: string;
132
+ /** Forensic one-liner shown in the "What we measured" drawer. */
133
+ hint?: string;
134
+ }
135
+ interface PdpExplain {
136
+ archetypeLabel: string;
137
+ archetypeDesc: string;
138
+ decisionLabel: string | null;
139
+ decisionDesc: string | null;
140
+ summary: string;
141
+ /** Hero row — punchy, scannable. */
142
+ metrics: PdpExplainMetric[];
143
+ /** Full forensic dossier — revealed in the "What we measured" drawer. */
144
+ dossier: PdpExplainMetric[];
145
+ }
146
+ /** Title-case a slug: "aging-cognitive" → "Aging Cognitive". */
147
+ declare function _titleCase(slug: string): string;
148
+ /**
149
+ * Build the "why box" content from the two model outputs + the visitor's REAL
150
+ * session signals. Every metric is either a true measurement (signals analyzed,
151
+ * scroll depth, time engaged, pages, models run, latency) or an opaque signature
152
+ * (the behavioral fingerprint). NO invented population statistics ("similar
153
+ * visitors matched", "top N%") — those are the only refutable kind, because they
154
+ * assert something about OTHER people we can't show. Everything here is provable
155
+ * from this visitor's own session.
156
+ *
157
+ * Tier 1 (here): SDK-local real metrics. Tier 2 (backend) will fold in the
158
+ * event-stream forensics (interaction rhythm, engagement entropy, friction
159
+ * signals, cursor travel) computed from `recent_observations`.
160
+ */
161
+ declare function buildExplain(opts: {
162
+ archetype: string;
163
+ description: string;
164
+ decisionArchetype: string;
165
+ decisionDescription: string;
166
+ summary: string;
167
+ signals: Record<string, unknown>;
168
+ latencyMs: number;
169
+ }): PdpExplain;
170
+ declare function gatherDevice(context: RuntimeContext | undefined): VisitorDevice;
171
+ /**
172
+ * UTM + referrer + initial URL — read from PostHog person properties
173
+ * (where the SDK writes them via setPersonPropertiesOnce).
174
+ *
175
+ * TODO: swap to `runtime.telemetry.getProperty(name)` once that getter lands.
176
+ */
177
+ declare function gatherAttribution(): VisitorAttribution;
178
+ /**
179
+ * Geo — read from the localStorage cache the SDK writes at bootstrap time
180
+ * (key `syntro_geo`).
181
+ *
182
+ * TODO: swap to `runtime.context.get().geo` once the SDK exposes that field.
183
+ */
184
+ declare function gatherGeo(): VisitorGeo;
185
+ declare function gatherSessionMetrics(runtime: SynOSGlobal['runtime']): Record<string, string | number | boolean>;
186
+ declare function gatherExtras(runtime: SynOSGlobal['runtime'], context: RuntimeContext | undefined): Record<string, string | number | boolean>;
187
+ declare function readChatExcerpt(): string;
188
+ /**
189
+ * Collect every personalization signal the SDK has access to client-side.
190
+ * Never throws — missing signals degrade to empty values.
191
+ */
192
+ export declare function gatherVisitorSignals(): VisitorSignals;
193
+ export type TemplateToTagKey = string;
194
+ export declare const TEMPLATE_TO_TAG: Record<TemplateToTagKey, string>;
195
+ /**
196
+ * Resolve the custom element tag to mount for a given plan task instance.
197
+ *
198
+ * Resolution order:
199
+ * 1. `"<kind>/<variant>"` if `variant` is non-null
200
+ * 2. `"<kind>"` (base) — covers unknown-variant fallback
201
+ * 3. `null` if the kind itself is unknown
202
+ */
203
+ export declare function resolveTagForMount(inst: PdpPlanTaskClient): string | null;
204
+ /**
205
+ * Test seam — exposes private module-scope functions for unit testing only.
206
+ * Do NOT use outside of test files.
207
+ */
208
+ export declare const _testing: {
209
+ buildExplain: typeof buildExplain;
210
+ gatherAttribution: typeof gatherAttribution;
211
+ gatherDevice: typeof gatherDevice;
212
+ gatherExtras: typeof gatherExtras;
213
+ gatherGeo: typeof gatherGeo;
214
+ gatherSessionMetrics: typeof gatherSessionMetrics;
215
+ gatherVisitorSignals: typeof gatherVisitorSignals;
216
+ readChatExcerpt: typeof readChatExcerpt;
217
+ resolveTagForMount: typeof resolveTagForMount;
218
+ TEMPLATE_TO_TAG: Record<string, string>;
219
+ titleCase: typeof _titleCase;
220
+ };
221
+ /**
222
+ * <syntro-pdp> — the dynamic personalized PDP surface.
223
+ *
224
+ * Config-first flow: gathers visitor signals from the SDK runtime, scores the
225
+ * visitor's archetype, mounts the host-supplied config presets, and generates
226
+ * the remaining live slots via the runtime container's /api/pdp/module and
227
+ * /api/pdp/dossier endpoints. Customer code mounts this one element; everything
228
+ * else is internal to the SDK.
229
+ *
230
+ * Attributes (kebab-case, set by host markup):
231
+ * - product-id (required)
232
+ * - product-name (required)
233
+ * - product-blurb (optional)
234
+ *
235
+ * Properties (set by mountable, not host markup):
236
+ * - runtimeRef: SmartCanvasRuntime — passed by the AppLoader through
237
+ * the existing widget-mountable mechanism.
238
+ */
239
+ export declare class SyntroPdpLit extends LitElement {
240
+ static properties: {
241
+ productId: {
242
+ type: StringConstructor;
243
+ attribute: string;
244
+ };
245
+ productName: {
246
+ type: StringConstructor;
247
+ attribute: string;
248
+ };
249
+ productBlurb: {
250
+ type: StringConstructor;
251
+ attribute: string;
252
+ };
253
+ runtimeRef: {
254
+ attribute: boolean;
255
+ };
256
+ _decisionState: {
257
+ state: boolean;
258
+ };
259
+ };
260
+ productId: string;
261
+ productName: string;
262
+ productBlurb: string;
263
+ /**
264
+ * SDK runtime. Null until the mountable wires it in. We only render
265
+ * the personalized surface once runtimeRef is present AND the
266
+ * activation gate passes.
267
+ */
268
+ runtimeRef: SmartCanvasRuntime | null;
269
+ /** Canonical decision and render state. */
270
+ private _decisionState;
271
+ private _composeStartedAt;
272
+ private _lastArchetype;
273
+ private _mountDurations;
274
+ /**
275
+ * Native takeover state (FEAT-1784346204). `_nativeSlots` holds the slot ids
276
+ * whose native host section exists OUTSIDE this element — the render loop
277
+ * skips those so the element never renders a duplicate qa/peer-feed section.
278
+ * `_nativeHandles` tracks each active swap so it can be restored (before a
279
+ * re-swap, and on disconnect).
280
+ */
281
+ private _nativeSlots;
282
+ private _nativeHandles;
283
+ /**
284
+ * The scored axes from the current config pass — the SAME values
285
+ * `_fireFromConfig` resolved (sport-archetype preset key + decision archetype).
286
+ * Captured at scoring time so they are already on the element when mounts
287
+ * apply, which is BEFORE `_fireFromConfig` returns. Both default to 'unknown'.
288
+ */
289
+ private _resolvedArchetype;
290
+ private _resolvedDecision;
291
+ private _effectExecutor;
292
+ private _dispatchDecision;
293
+ private _onDossierToggle;
294
+ createRenderRoot(): this;
295
+ connectedCallback(): void;
296
+ disconnectedCallback(): void;
297
+ willUpdate(changed: PropertyValues): void;
298
+ /**
299
+ * Probe the document for native host sections (`data-syntro-slot="qa"` /
300
+ * `"peer-feed"`) that live OUTSIDE this element, and record their slot ids.
301
+ * The render loop skips these slots; the mount path swaps into them.
302
+ */
303
+ private _refreshNativeSlots;
304
+ /**
305
+ * A visitor is personalized unless BOTH scored axes declined to 'unknown'.
306
+ * A fully-unknown visitor keeps the host's default native content untouched.
307
+ */
308
+ private _isPersonalizedVisitor;
309
+ updated(_changed: PropertyValues): void;
310
+ /** The host page's above-the-fold mount for the page-wide why box, if any. */
311
+ private _whyPortalEl;
312
+ private _syncDecisionRuntime;
313
+ private _syncDecisionPortal;
314
+ /**
315
+ * Emit a telemetry event via the runtime's track API.
316
+ * Wrapped in try/catch so a broken telemetry integration never crashes the
317
+ * compose flow. Always includes `source: 'sdk'` in props.
318
+ */
319
+ private _track;
320
+ private _captureDecisionTelemetry;
321
+ private _warnDecision;
322
+ private _clearDecisionPortal;
323
+ private _cleanupDecisionEffects;
324
+ private _startDecisionCompose;
325
+ /** Mount each instance into its slot. Shared by config and compose. */
326
+ private _applyMounts;
327
+ /** Render from config: score the archetype → mount the preset set-values. */
328
+ private _fireFromConfig;
329
+ /**
330
+ * The demo "why box": surfaces the archetype + behavior-summary model outputs
331
+ * and a row of impressive personalization metrics at the very top of the PDP
332
+ * (below the host banner).
333
+ *
334
+ * The NARRATIVE MUST LEAD THE PAGE: a placeholder renders the instant the
335
+ * compose flow starts streaming (before the archetype/summary land), then
336
+ * fills IN PLACE when the decision explanation arrives. Previously it rendered nothing until
337
+ * both models scored, so on a live load it popped in AFTER modules had already
338
+ * mounted — the reasoning banner trailed the content instead of leading it.
339
+ * Renders nothing only before streaming begins (pre-plan) or once done with no
340
+ * explanation (nothing to say).
341
+ */
342
+ private _renderWhyBox;
343
+ /**
344
+ * The narrative placeholder: the same quiet "How Syntrologie decided" line as
345
+ * the real why box (so it reads as "the reasoning is loading", not a different
346
+ * element), with a shimmer bar where the archetype + summary will land.
347
+ * Carries the same `data-syntro-pdp-why` marker plus `data-syntro-pdp-why-loading`,
348
+ * so the swap to the filled box is a state change, not a first appearance.
349
+ */
350
+ private _renderWhyBoxLoading;
351
+ render(): import("lit-html").TemplateResult<1>;
352
+ /**
353
+ * Self-contained skeleton (shimmer) CSS. Rendered inside the component
354
+ * during the pre-plan / streaming phase. The global section-layout +
355
+ * per-slot accent rules live in the head-injected `SECTION_LAYOUT_CSS`
356
+ * (see `ensureSectionLayoutStyles`), not here, so they're emitted once
357
+ * per document rather than once per `<syntro-pdp>` instance.
358
+ */
359
+ private static readonly _skeletonStyles;
360
+ }
361
+ declare global {
362
+ interface HTMLElementTagNameMap {
363
+ 'syntro-pdp': SyntroPdpLit;
364
+ }
365
+ }
366
+ //# sourceMappingURL=SyntroPdpLit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SyntroPdpLit.d.ts","sourceRoot":"","sources":["../../src/widgets/SyntroPdpLit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,98 @@
1
+ import { LitElement } from 'lit';
2
+ import type { VariantPayload } from '../platformAdapter';
3
+ export declare class VariantPanelLit extends LitElement {
4
+ #private;
5
+ static properties: {
6
+ payload: {
7
+ attribute: boolean;
8
+ };
9
+ productTitle: {
10
+ type: StringConstructor;
11
+ };
12
+ productImage: {
13
+ attribute: boolean;
14
+ };
15
+ state: {
16
+ type: StringConstructor;
17
+ };
18
+ error: {
19
+ type: StringConstructor;
20
+ };
21
+ _selection: {
22
+ state: boolean;
23
+ };
24
+ _touched: {
25
+ state: boolean;
26
+ };
27
+ _expandedAxes: {
28
+ state: boolean;
29
+ };
30
+ _axisFilter: {
31
+ state: boolean;
32
+ };
33
+ };
34
+ payload: VariantPayload | null;
35
+ productTitle: string;
36
+ /** Product-level hero image, passed from the card. Shown on the back face and
37
+ * used as the fallback when the selected variant carries no featured_image. */
38
+ productImage: {
39
+ src: string;
40
+ alt?: string;
41
+ } | null;
42
+ state: 'idle' | 'loading' | 'error';
43
+ error: string | null;
44
+ /** @internal */
45
+ _selection: Record<string, string>;
46
+ /** @internal */
47
+ _touched: Set<string>;
48
+ /** @internal — Tier-C axes currently showing their listbox. */
49
+ _expandedAxes: Set<string>;
50
+ /** @internal — Tier-C per-axis filter text. */
51
+ _axisFilter: Record<string, string>;
52
+ constructor();
53
+ createRenderRoot(): this;
54
+ connectedCallback(): void;
55
+ disconnectedCallback(): void;
56
+ private _onKeydown;
57
+ private _findMatchingVariant;
58
+ private _isValueDisabled;
59
+ private _hasAnyOOSForAttribute;
60
+ private _onPillClick;
61
+ private _onBack;
62
+ private _onAdd;
63
+ private _onRetry;
64
+ /** The hero image URL to show: the matched variant's featured_image when the
65
+ * current selection resolves to a variant that has one, else the product
66
+ * image. Null when neither exists. */
67
+ private _heroSrc;
68
+ private _ctaEnabled;
69
+ render(): import("lit-html").TemplateResult<1>;
70
+ private _renderAttributeRow;
71
+ static readonly SEGMENTED_MAX_OPTIONS = 3;
72
+ /** Density Tier B: a wrap row past this many options becomes a one-row
73
+ * horizontal scroll track (edge-faded, snap) instead of eating the bounded
74
+ * panel's height with wrapped rows. */
75
+ static readonly SCROLL_MIN_OPTIONS = 9;
76
+ /** Density Tier C: past this many options the axis collapses into a
77
+ * select-style trigger + scrollable listbox. ONLY the offending axis
78
+ * collapses — sibling axes keep their own tier (per Parker, 2026-07-23). */
79
+ static readonly COLLAPSE_MIN_OPTIONS = 17;
80
+ /** Inside a Tier-C listbox, a type-ahead filter appears past this count. */
81
+ static readonly FILTER_MIN_OPTIONS = 25;
82
+ private _isScrollTier;
83
+ private _renderPillRow;
84
+ private _renderSwatchRow;
85
+ private _toggleAxis;
86
+ private _onCollapsedSelect;
87
+ private _onAxisFilterInput;
88
+ /** Density Tier C — select-style trigger + bounded scrollable listbox.
89
+ * ONLY this axis collapses; siblings keep their own tier. Filter appears
90
+ * past FILTER_MIN_OPTIONS. Out-of-stock options stay visible, disabled. */
91
+ private _renderCollapsedAxis;
92
+ }
93
+ declare global {
94
+ interface HTMLElementTagNameMap {
95
+ 'syntro-variant-panel': VariantPanelLit;
96
+ }
97
+ }
98
+ //# sourceMappingURL=VariantPanelLit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VariantPanelLit.d.ts","sourceRoot":"","sources":["../../src/widgets/VariantPanelLit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,UAAU,EAAW,MAAM,KAAK,CAAC;AAChD,OAAO,KAAK,EAAyB,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAoQhF,qBAAa,eAAgB,SAAQ,UAAU;;IAC7C,OAAgB,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAUxB;IAEF,OAAO,EAAE,cAAc,GAAG,IAAI,CAAQ;IACtC,YAAY,SAAM;IAClB;oFACgF;IAChF,YAAY,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAQ;IAC1D,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAU;IAC7C,KAAK,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE5B,gBAAgB;IAChB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM;IACxC,gBAAgB;IAChB,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAa;IAClC,+DAA+D;IAC/D,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAa;IACvC,+CAA+C;IAC/C,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM;;IAuBhC,gBAAgB;IAIhB,iBAAiB,IAAI,IAAI;IAQzB,oBAAoB,IAAI,IAAI;IAKrC,OAAO,CAAC,UAAU,CAIhB;IAEF,OAAO,CAAC,oBAAoB;IAS5B,OAAO,CAAC,gBAAgB;IAexB,OAAO,CAAC,sBAAsB;IAI9B,OAAO,CAAC,YAAY;IAapB,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,MAAM;IAYd,OAAO,CAAC,QAAQ;IAIhB;;2CAEuC;IACvC,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,WAAW;IAOV,MAAM;IAwGf,OAAO,CAAC,mBAAmB;IAsB3B,MAAM,CAAC,QAAQ,CAAC,qBAAqB,KAAK;IAC1C;;4CAEwC;IACxC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,KAAK;IACvC;;iFAE6E;IAC7E,MAAM,CAAC,QAAQ,CAAC,oBAAoB,MAAM;IAC1C,4EAA4E;IAC5E,MAAM,CAAC,QAAQ,CAAC,kBAAkB,MAAM;IAExC,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,cAAc;IAuBtB,OAAO,CAAC,gBAAgB;IA4BxB,OAAO,CAAC,WAAW;IAcnB,OAAO,CAAC,kBAAkB;IAc1B,OAAO,CAAC,kBAAkB;IAI1B;;gFAE4E;IAC5E,OAAO,CAAC,oBAAoB;CAsF7B;AAID,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,sBAAsB,EAAE,eAAe,CAAC;KACzC;CACF"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Inject a `<style>` into the element's OWN root node — the shadow root that
3
+ * contains it when the widget is mounted inside another element's shadow tree
4
+ * (e.g. a canvas's `<sc-mount>`), or `document.head` when it lives in the light
5
+ * DOM (chat trail, a host PDP page).
6
+ *
7
+ * Why this exists: these product widgets render in light DOM (`createRenderRoot`
8
+ * returns `this`) and style themselves with an injected stylesheet. When a
9
+ * canvas mounts the widget inside `<sc-mount>`, the widget subtree lands inside
10
+ * `sc-mount`'s SHADOW root. A stylesheet appended to `document.head` does NOT
11
+ * cross that shadow boundary, so the widget rendered with default browser
12
+ * styling and none of its own CSS. Injecting into `getRootNode()` puts the
13
+ * stylesheet in the same tree as the element, so it applies on every surface.
14
+ * Only CSS custom-property VALUES cross shadow boundaries — which is why the
15
+ * host canvas themes the widget via `--sc-*` tokens while the layout/appearance
16
+ * CSS must travel with the widget itself.
17
+ *
18
+ * Idempotent per root: guarded by the style id so repeated mounts into the same
19
+ * root inject once; distinct roots (multiple mounts) each get their own copy.
20
+ */
21
+ export declare function ensureStylesInRoot(el: Element, id: string, css: string): void;
22
+ //# sourceMappingURL=ensureStylesInRoot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ensureStylesInRoot.d.ts","sourceRoot":"","sources":["../../src/widgets/ensureStylesInRoot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAS7E"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Entrance-animation settle helper — GPU/compositing hazard fix.
3
+ *
4
+ * The PDP widgets play a fade/slide entrance on mount. The old authoring
5
+ * rested the animated element at `opacity: 0` and relied on
6
+ * `animation: … forwards` to bring it to `opacity: 1`. When the browser
7
+ * DROPS or SUPPRESSES that animation — battery-saver mode, an over-budget
8
+ * compositor, a backgrounded tab that never runs the keyframes — the element
9
+ * stays at `opacity: 0` forever: a permanently blank PDP section. (Same class
10
+ * of bug as the ProductCard/FAQ flip resting at rotateY(180).)
11
+ *
12
+ * The fix keeps the entrance PIXEL-IDENTICAL but inverts the resting state:
13
+ * - base rule: `opacity: 1` (content is always visible at rest);
14
+ * - a transient `.is-entering` class (applied on the container at mount)
15
+ * re-introduces `opacity: 0` + the exact same keyframes with `both` fill
16
+ * so the pre-delay invisibility is preserved;
17
+ * - `@media (prefers-reduced-motion: reduce)` neutralises `.is-entering`
18
+ * (content immediately visible, no animation).
19
+ *
20
+ * This helper arms the REMOVAL of `.is-entering` once the entrance has run:
21
+ * - fast path: the container's OWN `animationend` (only when `fastPath` is
22
+ * set — i.e. the container's own keyframes are the last to finish; widgets
23
+ * with longer-running staggered children leave this off and lean on the
24
+ * belt so the class is never pulled mid-stagger);
25
+ * - belt: a `setTimeout` sized to the longest keyframe
26
+ * (delay + duration + margin) that ALWAYS fires, even if `animationend`
27
+ * never does.
28
+ *
29
+ * Removing the class is a visual no-op: the base state is `opacity: 1` and the
30
+ * `both` fill holds the final keyframe until the moment the class drops.
31
+ *
32
+ * @returns a disposer that clears the belt timer + listener (call on disconnect).
33
+ */
34
+ export declare function armEntranceSettle(onSettle: () => void, container: HTMLElement | null, settleMs: number, fastPath?: boolean): () => void;
35
+ //# sourceMappingURL=entrance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entrance.d.ts","sourceRoot":"","sources":["../../src/widgets/entrance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,IAAI,EACpB,SAAS,EAAE,WAAW,GAAG,IAAI,EAC7B,QAAQ,EAAE,MAAM,EAChB,QAAQ,UAAQ,GACf,MAAM,IAAI,CA8BZ"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * renderHealth — runtime self-detection of clipping and blank render.
3
+ *
4
+ * A product card can look correct in tests yet clip text or paint blank on a
5
+ * real host (a narrow theme column, a font that measures wider, a broken image
6
+ * CDN). The battery walks the playground at build time; this module is its
7
+ * RUNTIME counterpart — after the card paints, it re-measures itself against the
8
+ * SAME policy and emits a PostHog signal when it finds an undeclared clip or a
9
+ * blank card. Field-RUM for "the card broke on a customer's page".
10
+ *
11
+ * NON-PII discipline: only element tag/class PATHS and pixel numbers ever leave
12
+ * the widget — never text content, never customer copy. The paths are the
13
+ * structural coordinates a dashboard needs to locate the offending node.
14
+ *
15
+ * Pattern-setter: this lives in a small shared module (not inline in
16
+ * ProductCardLit) so sibling widgets (comparison, grid, hero) can adopt the same
17
+ * self-detection with one import.
18
+ */
19
+ /** A single undeclared-clip finding inside a card. */
20
+ export interface ClipFinding {
21
+ /** Structural path to the offending node, e.g. `div.sc-product-card__specs>span`. NON-PII. */
22
+ path: string;
23
+ /** How many px the node overflows its clip box (text scrollWidth overflow, or
24
+ * child escaping the card's own clip box). Rounded. */
25
+ over_px: number;
26
+ /** Why this counts as a clip. Absent for ordinary (Tier-3) undeclared clips.
27
+ * `identity-truncated` marks a Tier-1 CRITICAL text node (product name,
28
+ * price, CTA label, picker title — `[data-critical-text]`) that truncated
29
+ * even with a declared ellipsis / clip-ok. Identity text must render in full,
30
+ * so ANY horizontal overflow of a critical node is a defect. NON-PII. */
31
+ reason?: 'identity-truncated';
32
+ }
33
+ /** Result of a render-health measurement pass. */
34
+ export interface RenderHealth {
35
+ /** Undeclared clips found inside the card (empty = clean). */
36
+ clips: ClipFinding[];
37
+ /** True when the card occupies real area but painted no text AND no complete
38
+ * image (a blank card). */
39
+ blank: boolean;
40
+ }
41
+ /**
42
+ * Measure the render health of a card element. Pure DOM read — no side effects,
43
+ * no telemetry. Safe to call any time after paint. The caller (ProductCardLit)
44
+ * decides whether/when to emit.
45
+ *
46
+ * Policy mirrors tmp-live/battery.mjs:
47
+ * - identity-truncated (Tier 1): a [data-critical-text] node (name, price, CTA
48
+ * label, picker title) whose scrollWidth exceeds clientWidth by >1px — even
49
+ * WITH an ellipsis or under [data-clip-ok]. Identity text must render in full.
50
+ * - text-clip: an element with its own text whose scrollWidth exceeds
51
+ * clientWidth by >1px and has no textOverflow:ellipsis, not under [data-clip-ok].
52
+ * - element-clip: a text/media node escaping a HARD-clip ancestor by >1px,
53
+ * where the ancestor is not scrollable, not a line-clamp box, not clip-ok.
54
+ * - blank: the card has real area but no painted text and no complete image.
55
+ */
56
+ export declare function measureRenderHealth(card: Element): RenderHealth;
57
+ //# sourceMappingURL=renderHealth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderHealth.d.ts","sourceRoot":"","sources":["../../src/widgets/renderHealth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,sDAAsD;AACtD,MAAM,WAAW,WAAW;IAC1B,8FAA8F;IAC9F,IAAI,EAAE,MAAM,CAAC;IACb;4DACwD;IACxD,OAAO,EAAE,MAAM,CAAC;IAChB;;;;8EAI0E;IAC1E,MAAM,CAAC,EAAE,oBAAoB,CAAC;CAC/B;AAED,kDAAkD;AAClD,MAAM,WAAW,YAAY;IAC3B,8DAA8D;IAC9D,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB;gCAC4B;IAC5B,KAAK,EAAE,OAAO,CAAC;CAChB;AAuDD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,YAAY,CA0F/D"}