@froomle/frontend-sdk 0.0.9 → 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +396 -5
- package/dist/Recommendations.d-HGeAMYU5.d.ts +49 -0
- package/dist/chunk-Y2E7VTAE.js +5 -0
- package/dist/froomle.global.js +5 -5
- package/dist/index.d.ts +113 -27
- package/dist/index.js +1 -5
- package/dist/react.d.ts +40 -0
- package/dist/react.js +1 -0
- package/package.json +17 -5
- package/LICENSE +0 -201
- package/dist/index.cjs +0 -5
- package/dist/index.d.cts +0 -62
- package/dist/testing/testing.cjs +0 -6
- package/dist/testing/testing.cjs.map +0 -1
- package/dist/testing/testing.d.cts +0 -144
- package/dist/testing/testing.d.ts +0 -144
- package/dist/testing/testing.js +0 -6
- package/dist/testing/testing.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,8 +1,399 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Javascript Library Documentation
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
1. [Framework-Agnostic Recommendation Proxy](#framework-agnostic-recommendation-proxy)
|
|
4
|
+
2. [React Integration Helpers](#react-integration-helpers)
|
|
5
|
+
3. [JavaScript Modules](#javascript-modules)
|
|
6
|
+
4. [Supporting a New Framework](#supporting-a-new-framework)
|
|
4
7
|
|
|
5
|
-
##
|
|
8
|
+
## Framework-Agnostic Recommendation Proxy
|
|
6
9
|
|
|
7
|
-
|
|
8
|
-
|
|
10
|
+
To support multiple frontend frameworks (React and others) while preserving a single shared SDK core, the SDK uses a **proxy-based recommendation wrapper**.
|
|
11
|
+
|
|
12
|
+
This mechanism allows recommendation items to be **used immediately**, even though the underlying data may not yet be available.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
### Problem Being Solved
|
|
17
|
+
|
|
18
|
+
Frameworks like React expect values to be:
|
|
19
|
+
|
|
20
|
+
- referentially stable
|
|
21
|
+
- accessible during render
|
|
22
|
+
- optionally async-aware
|
|
23
|
+
|
|
24
|
+
At the same time, the SDK:
|
|
25
|
+
|
|
26
|
+
- batches recommendation requests
|
|
27
|
+
- resolves them later via a single backend call
|
|
28
|
+
- relies on shared static state
|
|
29
|
+
- cannot expose all internal APIs directly
|
|
30
|
+
|
|
31
|
+
Returning a raw `Promise<RecommendationItem>` would not work, because components often need to **read fields synchronously**.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
### High-Level Idea
|
|
36
|
+
|
|
37
|
+
The solution is to return a **Proxy object** that behaves as both:
|
|
38
|
+
|
|
39
|
+
- a `RecommendationItem`
|
|
40
|
+
- a `PromiseLike<RecommendationItem>`
|
|
41
|
+
|
|
42
|
+
This proxy:
|
|
43
|
+
|
|
44
|
+
- intercepts property access
|
|
45
|
+
- defers resolution until recommendations are fulfilled
|
|
46
|
+
- transparently switches to real data once available
|
|
47
|
+
|
|
48
|
+
From the consumer’s point of view, it behaves like a normal recommendation object that “fills itself in later”.
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
### Deferred Request Queue
|
|
53
|
+
|
|
54
|
+
When a recommendation is requested:
|
|
55
|
+
|
|
56
|
+
- a deferred promise is created
|
|
57
|
+
- the request is added to a shared queue
|
|
58
|
+
- no backend call is executed immediately
|
|
59
|
+
|
|
60
|
+
All pending requests are stored in a global request list until they are explicitly fulfilled.
|
|
61
|
+
|
|
62
|
+
This allows:
|
|
63
|
+
|
|
64
|
+
- batching multiple requests into one backend call
|
|
65
|
+
- predictable request ordering
|
|
66
|
+
- shared static backend state
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
### Fulfilling Recommendations
|
|
71
|
+
|
|
72
|
+
`fulfillRecommendations()`:
|
|
73
|
+
|
|
74
|
+
- executes a single backend request for all queued recommendations
|
|
75
|
+
- receives a list of recommendation items
|
|
76
|
+
- resolves each deferred promise with its corresponding item
|
|
77
|
+
- clears the request queue
|
|
78
|
+
|
|
79
|
+
This function is typically called once per render cycle (for example on application mount in React).
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
### Proxy-Based Recommendation Item
|
|
84
|
+
|
|
85
|
+
The returned object is a JavaScript `Proxy` wrapping an internal recommendation item.
|
|
86
|
+
|
|
87
|
+
The proxy provides three key behaviors:
|
|
88
|
+
|
|
89
|
+
- **Property access interception**
|
|
90
|
+
When a field is accessed, the proxy either:
|
|
91
|
+
- returns the real value (once resolved)
|
|
92
|
+
- returns a safe placeholder value
|
|
93
|
+
|
|
94
|
+
- **Promise compatibility**
|
|
95
|
+
Accessing `.then(...)` forwards to the underlying deferred promise, allowing async usage.
|
|
96
|
+
|
|
97
|
+
- **Late data injection**
|
|
98
|
+
Once the real recommendation item is available, its data is copied into the proxy target object.
|
|
99
|
+
|
|
100
|
+
This makes the transition from “unresolved” to “resolved” completely transparent.
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
### Why This Works Across Frameworks
|
|
105
|
+
|
|
106
|
+
This approach ensures that:
|
|
107
|
+
|
|
108
|
+
- the same core logic works for React and non-React frameworks
|
|
109
|
+
- recommendation items can be read synchronously
|
|
110
|
+
- async resolution integrates naturally with effects and lifecycle hooks
|
|
111
|
+
- internal SDK boundaries remain intact
|
|
112
|
+
- static backend state is shared correctly
|
|
113
|
+
|
|
114
|
+
No framework-specific logic is required in the core SDK.
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## React Integration Helpers
|
|
119
|
+
|
|
120
|
+
The SDK provides a small React-specific helper layer to integrate recommendations into React applications while preserving the SDK’s internal async model and shared state.
|
|
121
|
+
|
|
122
|
+
This layer is intentionally thin and does **not** reimplement SDK logic. It only adapts existing SDK primitives to React’s rendering and lifecycle model.
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
### `FroomleSdkInit`
|
|
127
|
+
|
|
128
|
+
`FroomleSdkInit` is a lightweight initialization component.
|
|
129
|
+
|
|
130
|
+
Its responsibility is to trigger the resolution of pending recommendation requests once the React application is mounted.
|
|
131
|
+
|
|
132
|
+
Key characteristics:
|
|
133
|
+
|
|
134
|
+
- Calls `fulfillRecommendations()` exactly once on mount
|
|
135
|
+
- Ensures all queued recommendation requests are executed
|
|
136
|
+
- Does not render anything itself
|
|
137
|
+
- Acts purely as a lifecycle hook
|
|
138
|
+
|
|
139
|
+
This component should be mounted near the root of the React tree.
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
### `useNewCreateReco`
|
|
144
|
+
|
|
145
|
+
`useNewCreateReco` is a React hook that requests a single recommendation and binds it to component state.
|
|
146
|
+
|
|
147
|
+
It bridges three concerns:
|
|
148
|
+
|
|
149
|
+
- the SDK’s promise-like recommendation model
|
|
150
|
+
- React’s render cycle
|
|
151
|
+
- referential stability across renders
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
### Hook Behavior
|
|
156
|
+
|
|
157
|
+
The hook works as follows:
|
|
158
|
+
|
|
159
|
+
1. A recommendation request is created once using `proxyReco(req)`
|
|
160
|
+
2. The result is stored in a `ref` to ensure it is not recreated on re-renders
|
|
161
|
+
3. A `then(...)` callback is registered to detect when the recommendation resolves
|
|
162
|
+
4. When resolved, the hook forces a component update
|
|
163
|
+
5. The resolved `RecommendationItem` is returned
|
|
164
|
+
|
|
165
|
+
This allows React components to render immediately and update automatically once recommendation data becomes available.
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
### Why `useRef` Is Used
|
|
170
|
+
|
|
171
|
+
`useRef` is used instead of `useState` to ensure that:
|
|
172
|
+
|
|
173
|
+
- the recommendation request is created only once
|
|
174
|
+
- no duplicate requests are triggered
|
|
175
|
+
- static SDK state remains consistent
|
|
176
|
+
- React re-renders do not affect request identity
|
|
177
|
+
|
|
178
|
+
This is critical because the SDK relies on shared internal state.
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
If you want next, I can:
|
|
183
|
+
- add a **usage example** section
|
|
184
|
+
- document `proxyReco` explicitly
|
|
185
|
+
- or explain how multiple hooks coordinate through `fulfillRecommendations()`
|
|
186
|
+
|
|
187
|
+
## JavaScript Modules
|
|
188
|
+
|
|
189
|
+
The SDK ships multiple JavaScript modules, including:
|
|
190
|
+
|
|
191
|
+
- a **default JavaScript module**
|
|
192
|
+
- a **React-specific module**
|
|
193
|
+
- **( potentially more modules in the future )**
|
|
194
|
+
|
|
195
|
+
Both modules are distributed together but serve different integration use cases.
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
### Background Problem
|
|
200
|
+
|
|
201
|
+
Originally, the default JavaScript module and the React module were **compiled separately**.
|
|
202
|
+
|
|
203
|
+
However, the React module depended on internal logic that was also used by the default module. Because both modules were built independently, this resulted in:
|
|
204
|
+
|
|
205
|
+
- the **same internal code being compiled twice**
|
|
206
|
+
- **separate static instances** of internal classes
|
|
207
|
+
- shared state (for example backend state or configuration) no longer being shared
|
|
208
|
+
|
|
209
|
+
This caused incorrect behavior, as the SDK relies on **single, shared static state** across the entire runtime.
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
### Why Not Just Re-Export Everything
|
|
214
|
+
|
|
215
|
+
Exposing all internal logic from the default module was not an option because:
|
|
216
|
+
|
|
217
|
+
- not all internal classes are part of the public API
|
|
218
|
+
- many classes must remain hidden to prevent incorrect usage
|
|
219
|
+
- exposing everything would break the SDK’s API boundaries
|
|
220
|
+
|
|
221
|
+
The React module needed access to internal functionality **without making that functionality public**.
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
### Solution: Shared Module Chunk
|
|
226
|
+
|
|
227
|
+
To solve this, the JavaScript builds are structured so that:
|
|
228
|
+
|
|
229
|
+
- shared internal code is compiled **once**
|
|
230
|
+
- both the default module and the React module depend on the **same compiled chunk**
|
|
231
|
+
- static state is shared correctly at runtime
|
|
232
|
+
|
|
233
|
+
This is achieved by compiling the modules together and extracting shared code into a **common chunk**, which both modules import.
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
### Resulting Behavior
|
|
238
|
+
|
|
239
|
+
With this setup:
|
|
240
|
+
|
|
241
|
+
- internal singletons and static state exist only once
|
|
242
|
+
- the default module and React module remain logically separate
|
|
243
|
+
- API boundaries are preserved
|
|
244
|
+
- users can import only what is intended to be public
|
|
245
|
+
- internal code reuse is safe and consistent
|
|
246
|
+
|
|
247
|
+
From the user’s perspective, the modules behave independently, while internally they share the same core implementation.
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## Supporting a New Framework
|
|
252
|
+
|
|
253
|
+
The SDK is designed so that **adding support for a new frontend framework does not require changes to the core logic**. Instead, framework support is implemented as a thin adaptation layer on top of the existing primitives.
|
|
254
|
+
|
|
255
|
+
This section describes what is required to integrate a new framework.
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
### Core Principles
|
|
260
|
+
|
|
261
|
+
When adding a new framework integration, the following principles must be preserved:
|
|
262
|
+
|
|
263
|
+
- **Single shared SDK state**
|
|
264
|
+
All framework integrations must share the same internal static state (backend, requests, configuration).
|
|
265
|
+
|
|
266
|
+
- **Deferred recommendation resolution**
|
|
267
|
+
Recommendation requests are created early and resolved later in a batched backend call.
|
|
268
|
+
|
|
269
|
+
- **No direct backend access**
|
|
270
|
+
Framework layers must never call backend logic directly. They rely on existing SDK functions.
|
|
271
|
+
|
|
272
|
+
- **No expansion of the public API**
|
|
273
|
+
Internal classes remain internal; the framework layer adapts behavior, not visibility.
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
### Required Building Blocks
|
|
278
|
+
|
|
279
|
+
A framework integration typically needs the following pieces.
|
|
280
|
+
|
|
281
|
+
#### 1. A Stable Recommendation Handle
|
|
282
|
+
|
|
283
|
+
The framework must receive a value that:
|
|
284
|
+
|
|
285
|
+
- can be accessed synchronously during render
|
|
286
|
+
- is referentially stable across renders
|
|
287
|
+
- updates automatically once data becomes available
|
|
288
|
+
|
|
289
|
+
This is achieved by using the existing **proxy-based recommendation item**, which behaves as both:
|
|
290
|
+
|
|
291
|
+
- a `RecommendationItem`
|
|
292
|
+
- a `PromiseLike<RecommendationItem>`
|
|
293
|
+
|
|
294
|
+
New frameworks should reuse this mechanism rather than reimplementing it.
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
#### 2. Deferred Request Registration
|
|
299
|
+
|
|
300
|
+
The framework layer must:
|
|
301
|
+
|
|
302
|
+
- create recommendation requests using the shared request queue
|
|
303
|
+
- avoid triggering backend requests immediately
|
|
304
|
+
- rely on deferred resolution
|
|
305
|
+
|
|
306
|
+
This ensures that:
|
|
307
|
+
|
|
308
|
+
- requests can be batched
|
|
309
|
+
- ordering is preserved
|
|
310
|
+
- backend calls remain predictable
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
#### 3. A Lifecycle Hook to Fulfill Requests
|
|
314
|
+
|
|
315
|
+
Every framework must provide **one well-defined moment** where pending recommendation requests are fulfilled.
|
|
316
|
+
|
|
317
|
+
This usually maps to:
|
|
318
|
+
|
|
319
|
+
- an application mount hook
|
|
320
|
+
- a root-level lifecycle event
|
|
321
|
+
- a global effect or initialization step
|
|
322
|
+
|
|
323
|
+
At this point, the framework integration must call:
|
|
324
|
+
|
|
325
|
+
- `fulfillRecommendations()`
|
|
326
|
+
|
|
327
|
+
This triggers the backend request and resolves all pending recommendation proxies.
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
##### How This SDK Does It
|
|
332
|
+
|
|
333
|
+
In this SDK, recommendation requests are **created lazily** during component or template execution, but they are **not fulfilled immediately**.
|
|
334
|
+
|
|
335
|
+
Instead:
|
|
336
|
+
|
|
337
|
+
- all recommendation requests are collected in a shared queue
|
|
338
|
+
- the framework integration defines a single initialization point
|
|
339
|
+
- at that point, `fulfillRecommendations()` is called once
|
|
340
|
+
|
|
341
|
+
For example:
|
|
342
|
+
|
|
343
|
+
- in React, this is done via a small root-level initialization component
|
|
344
|
+
- the call is placed inside a mount effect
|
|
345
|
+
- this ensures all components have had a chance to register their requests first
|
|
346
|
+
|
|
347
|
+
This approach guarantees that:
|
|
348
|
+
|
|
349
|
+
- all requests are batched into a single backend call
|
|
350
|
+
- request order is preserved
|
|
351
|
+
- static SDK state is shared correctly
|
|
352
|
+
- framework rendering remains predictable
|
|
353
|
+
|
|
354
|
+
The same pattern can be applied to any other framework by choosing an appropriate lifecycle boundary and invoking `fulfillRecommendations()` exactly once per render cycle or application start.
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
#### 4. Controlled Re-render or Update Trigger
|
|
358
|
+
|
|
359
|
+
Once a recommendation resolves, the framework must:
|
|
360
|
+
|
|
361
|
+
- trigger a re-render
|
|
362
|
+
- or notify the framework’s change detection system
|
|
363
|
+
|
|
364
|
+
How this is done depends on the framework:
|
|
365
|
+
|
|
366
|
+
- React: `useEffect` + state update
|
|
367
|
+
- Vue: reactive ref update
|
|
368
|
+
- Svelte: store or reactive assignment
|
|
369
|
+
- Others: equivalent lifecycle or observer mechanism
|
|
370
|
+
|
|
371
|
+
The SDK itself does **not** trigger renders; this is the responsibility of the framework adapter.
|
|
372
|
+
|
|
373
|
+
---
|
|
374
|
+
|
|
375
|
+
### What You Do *Not* Need
|
|
376
|
+
|
|
377
|
+
When supporting a new framework, you do **not** need to:
|
|
378
|
+
|
|
379
|
+
- modify `RecoBackendV2`
|
|
380
|
+
- modify DOM logic (`DomDomDom`, `FroomleDomTree`, `DomNode`)
|
|
381
|
+
- introduce framework-specific logic into the core SDK
|
|
382
|
+
- expose additional internal classes
|
|
383
|
+
|
|
384
|
+
The framework layer is purely an adapter.
|
|
385
|
+
|
|
386
|
+
---
|
|
387
|
+
|
|
388
|
+
### Minimal Integration Checklist
|
|
389
|
+
|
|
390
|
+
To support a new framework, you need:
|
|
391
|
+
|
|
392
|
+
- a wrapper that calls `proxyReco(...)`
|
|
393
|
+
- a place to call `fulfillRecommendations()`
|
|
394
|
+
- a mechanism to trigger framework updates on resolution
|
|
395
|
+
- no changes to core SDK internals
|
|
396
|
+
|
|
397
|
+
If these conditions are met, the framework will integrate correctly.
|
|
398
|
+
|
|
399
|
+
---
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
declare interface Recommendations {
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
request_id: String
|
|
5
|
+
*/
|
|
6
|
+
request_id: string
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
user_group: String
|
|
10
|
+
*/
|
|
11
|
+
user_group: string
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
user_id: String
|
|
15
|
+
*/
|
|
16
|
+
user_id: string
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
device_id: String
|
|
20
|
+
*/
|
|
21
|
+
device_id: string
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
lists(): Array<RecommendationList>
|
|
25
|
+
*/
|
|
26
|
+
lists(): RecommendationList[]
|
|
27
|
+
items(): RecommendationItem[]
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
declare interface RecommendationList {
|
|
31
|
+
limit: number
|
|
32
|
+
list_key: string
|
|
33
|
+
list_name: string
|
|
34
|
+
list_size: number
|
|
35
|
+
items: RecommendationItem[]
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
declare interface RecommendationItem {
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
Access dynamic keys
|
|
42
|
+
*/
|
|
43
|
+
get(key: string): any
|
|
44
|
+
Id: string
|
|
45
|
+
RequestId: string
|
|
46
|
+
UserGroup: string
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export type { Recommendations as R, RecommendationItem as a, RecommendationList as b };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
var i=class f{static global(e){return f.globals[e]?f.globals[e]:f.globals[e]={}}static createStatic(e,t,r){let n=null;Object.defineProperty(e,t,{enumerable:!0,get:function(){return r!=null&&(n=r(),r=null),n},set:function(s){r!=null&&(n=r(),r=null),n=s}})}static iterator(e){if(Array.isArray(e)){let t=e;return function(){return f.mkIter(t)}}else return typeof e.iterator=="function"?e.iterator.bind(e):e.iterator}static getIterator(e){return Array.isArray(e)?f.mkIter(e):e.iterator()}static mkIter(e){return new ke(e)}static extend(e){function t(){this[f.new].apply(this,arguments)}return Object.setPrototypeOf(t.prototype,e.prototype),t}static inherits(e,t){t==null&&(t=!1);function r(){t&&e&&r[f.init]&&r[f.init](),this[f.new].apply(this,arguments)}return t?r[f.init]=()=>{let n=e();n[f.init]&&n[f.init](),Object.setPrototypeOf(r.prototype,n.prototype),r[f.init]=void 0}:e&&e[f.init]?(t=!0,r[f.init]=()=>{e[f.init]&&e[f.init](),Object.setPrototypeOf(r.prototype,e.prototype),r[f.init]=void 0}):e&&Object.setPrototypeOf(r.prototype,e.prototype),r}static bind(e,t){if(t==null)return null;t.__id__==null&&(t.__id__=f.fid++);let r=null;return e.hx__closures__==null?e.hx__closures__={}:r=e.hx__closures__[t.__id__],r==null&&(r=t.bind(e),e.hx__closures__[t.__id__]=r),r}static get __name__(){return"genes.Register"}get __class__(){return f}};i.$global=typeof window!="undefined"?window:typeof global!="undefined"?global:typeof self!="undefined"?self:void 0;i.globals={};i.new=Symbol();i.init=Symbol();i.fid=0;var ke=i.global("$hxClasses")["genes._Register.ArrayIterator"]=class He extends i.inherits(){[i.new](e){this.current=0,this.array=e}hasNext(){return this.current<this.array.length}next(){return this.array[this.current++]}static get __name__(){return"genes._Register.ArrayIterator"}get __class__(){return He}};ke.prototype.array=null;ke.prototype.current=null;var Tt=i.$global,Ie=i.global("$hxClasses")["haxe.ValueException"]=class Le extends i.inherits(()=>C,!0){[i.new](e,t,r){super[i.new](String(e),t,r),this.value=e}unwrap(){return this.value}static get __name__(){return"haxe.ValueException"}static get __super__(){return C}get __class__(){return Le}};Ie.prototype.value=null;var Bt=i.$global,C=i.global("$hxClasses")["haxe.Exception"]=class de extends i.inherits(()=>Error,!0){[i.new](e,t,r){Error.call(this,e),this.message=e,this.__previousException=t,this.__nativeException=r!=null?r:this}unwrap(){return this.__nativeException}get_native(){return this.__nativeException}static caught(e){return e instanceof de?e:e instanceof Error?new de(e.message,null,e):new Ie(e,null,e)}static thrown(e){return e instanceof de?e.get_native():e instanceof Error?e:new Ie(e)}static get __name__(){return"haxe.Exception"}static get __super__(){return Error}get __class__(){return de}};C.prototype.native=null;C.prototype.__skipStack=null;C.prototype.__nativeException=null;C.prototype.__previousException=null;var jt=i.$global,P=i.global("$hxClasses").Std=class je{static string(e){return ye.__string_rec(e,"")}static parseInt(e){let t=parseInt(e);return isNaN(t)?null:t}static get __name__(){return"Std"}get __class__(){return je}};Object.defineProperty(String.prototype,"__class__",{value:String,enumerable:!1,writable:!0}),String.__name__=!0,Array.__name__=!0,mt={},gt={},pt=Number,ht=Boolean,ft={},dt={};var mt,gt,pt,ht,ft,dt;var zt=i.$global,ye=i.global("$hxClasses")["js.Boot"]=class j{static getClass(e){if(e==null)return null;if(e instanceof Array)return Array;{let t=e.__class__;if(t!=null)return t;let r=j.__nativeClassName(e);return r!=null?j.__resolveNativeClass(r):null}}static __string_rec(e,t){if(e==null)return"null";if(t.length>=5)return"<...>";let r=typeof e;switch(r=="function"&&(e.__name__||e.__ename__)&&(r="object"),r){case"function":return"<function>";case"object":if(e.__enum__){let u=i.global("$hxEnums")[e.__enum__].__constructs__[e._hx_index],c=u._hx_name;return u.__params__?(t=t+" ",c+"("+(function(g){var m;let y=[];{let v=0,b=u.__params__;for(;v<b.length;){let E=b[v];v=v+1,y.push(j.__string_rec(e[E],t))}}return m=y,m})(this).join(",")+")"):c}if(e instanceof Array){let _="[";t+=" ";let u=0,c=e.length;for(;u<c;){let g=u++;_+=(g>0?",":"")+j.__string_rec(e[g],t)}return _+="]",_}let n;try{n=e.toString}catch{return"???"}if(n!=null&&n!=Object.toString&&typeof n=="function"){let _=e.toString();if(_!="[object Object]")return _}let s=`{
|
|
2
|
+
`;t+=" ";let l=e.hasOwnProperty!=null,o=null;for(o in e)l&&!e.hasOwnProperty(o)||o=="prototype"||o=="__class__"||o=="__super__"||o=="__interfaces__"||o=="__properties__"||(s.length!=2&&(s+=`,
|
|
3
|
+
`),s+=t+o+" : "+j.__string_rec(e[o],t));return t=t.substring(1),s+=`
|
|
4
|
+
`+t+"}",s;break;case"string":return e;default:return String(e)}}static __interfLoop(e,t){if(e==null)return!1;if(e==t)return!0;let r=e.__interfaces__;if(r!=null&&(e.__super__==null||e.__super__.__interfaces__!=r)){let n=0,s=r.length;for(;n<s;){let l=n++,o=r[l];if(o==t||j.__interfLoop(o,t))return!0}}return j.__interfLoop(e.__super__,t)}static __instanceof(e,t){if(t==null)return!1;switch(t){case Array:return e instanceof Array;case"$hxCoreType__Bool":return typeof e=="boolean";case"$hxCoreType__Dynamic":return e!=null;case"$hxCoreType__Float":return typeof e=="number";case"$hxCoreType__Int":return typeof e=="number"?(e|0)===e:!1;case String:return typeof e=="string";default:if(e!=null){if(typeof t=="function"){if(j.__downcastCheck(e,t))return!0}else if(typeof t=="object"&&j.__isNativeObj(t)&&e instanceof t)return!0}else return!1;return t=="$hxCoreType__Class"&&e.__name__!=null||t=="$hxCoreType__Enum"&&e.__ename__!=null?!0:e.__enum__!=null?i.global("$hxEnums")[e.__enum__]==t:!1}}static __downcastCheck(e,t){return e instanceof t?!0:t.__isInterface__?j.__interfLoop(j.getClass(e),t):!1}static __cast(e,t){if(e==null||j.__instanceof(e,t))return e;throw C.thrown("Cannot cast "+P.string(e)+" to "+P.string(t))}static __nativeClassName(e){let t=j.__toStr.call(e).slice(8,-1);return t=="Object"||t=="Function"||t=="Math"||t=="JSON"?null:t}static __isNativeObj(e){return j.__nativeClassName(e)!=null}static __resolveNativeClass(e){return i.$global[e]}static get __name__(){return"js.Boot"}get __class__(){return j}};ye.__toStr={}.toString;var Kt=i.$global,De=i.global("$hxClasses")["js.Browser"]=class Ne{static get supported(){return this.get_supported()}static get_supported(){return typeof window!="undefined"&&typeof window.location!="undefined"?typeof window.location.protocol=="string":!1}static createXMLHttpRequest(){if(typeof XMLHttpRequest!="undefined")return new XMLHttpRequest;if(typeof ActiveXObject!="undefined")return new"ActiveXObject"("Microsoft.XMLHTTP");throw C.thrown("Unable to create XMLHttpRequest object.")}static get __name__(){return"js.Browser"}get __class__(){return Ne}};var Zt=i.$global,Y=i.global("$hxEnums")["haxe.io.Error"]={__ename__:"haxe.io.Error",Blocked:{_hx_name:"Blocked",_hx_index:0,__enum__:"haxe.io.Error"},Overflow:{_hx_name:"Overflow",_hx_index:1,__enum__:"haxe.io.Error"},OutsideBounds:{_hx_name:"OutsideBounds",_hx_index:2,__enum__:"haxe.io.Error"},Custom:Object.assign(f=>({_hx_index:3,__enum__:"haxe.io.Error",e:f}),{_hx_name:"Custom",__params__:["e"]})};Y.__constructs__=[Y.Blocked,Y.Overflow,Y.OutsideBounds,Y.Custom];Y.__empty_constructs__=[Y.Blocked,Y.Overflow,Y.OutsideBounds];var rr=i.$global,te=i.global("$hxEnums")["haxe.io.Encoding"]={__ename__:"haxe.io.Encoding",UTF8:{_hx_name:"UTF8",_hx_index:0,__enum__:"haxe.io.Encoding"},RawNative:{_hx_name:"RawNative",_hx_index:1,__enum__:"haxe.io.Encoding"}};te.__constructs__=[te.UTF8,te.RawNative];te.__empty_constructs__=[te.UTF8,te.RawNative];var ar=i.$global,_e=i.global("$hxClasses")["haxe.io.Bytes"]=class $e extends i.inherits(){[i.new](e){this.length=e.byteLength,this.b=new Uint8Array(e),this.b.bufferValue=e,e.hxBytes=this,e.bytes=this.b}getString(e,t,r){if(e<0||t<0||e+t>this.length)throw C.thrown(Y.OutsideBounds);r==null&&(r=te.UTF8);let n="",s=this.b,l=e,o=e+t;switch(r._hx_index){case 0:let _=e>0;for(;l<o;){let u=s[l++];if(u<128){if(u==0)break;n+=String.fromCodePoint(u)}else if(u<224){let c=(u&63)<<6|s[l++]&127;n+=String.fromCodePoint(c)}else if(u<240){let c=s[l++],g=(u&31)<<12|(c&127)<<6|s[l++]&127;n+=String.fromCodePoint(g)}else{let c=s[l++],g=s[l++],m=(u&15)<<18|(c&127)<<12|(g&127)<<6|s[l++]&127;n+=String.fromCodePoint(m)}}break;case 1:for(;l<o;){let u=s[l++]|s[l++]<<8;n+=String.fromCodePoint(u)}break}return n}static ofData(e){let t=e.hxBytes;return t!=null?t:new $e(e)}static get __name__(){return"haxe.io.Bytes"}get __class__(){return $e}};_e.prototype.length=null;_e.prototype.b=null;var mr=i.$global,Z=i.global("$hxClasses")["haxe.http.HttpBase"]=class Me extends i.inherits(){[i.new](e){this.url=e,this.headers=[],this.params=[],this.emptyOnData=i.bind(this,this.onData)}get responseData(){return this.get_responseData()}setHeader(e,t){let r=0,n=this.headers.length;for(;r<n;){let s=r++;if(this.headers[s].name==e){this.headers[s]={name:e,value:t};return}}this.headers.push({name:e,value:t})}setPostData(e){this.postData=e,this.postBytes=null}onData(e){}onBytes(e){}onError(e){}onStatus(e){}hasOnData(){return i.bind(this,this.onData)!=this.emptyOnData}success(e){this.responseBytes=e,this.responseAsString=null,this.hasOnData()&&this.onData(this.get_responseData()),this.onBytes(this.responseBytes)}get_responseData(){return this.responseAsString==null&&this.responseBytes!=null&&(this.responseAsString=this.responseBytes.getString(0,this.responseBytes.length,te.UTF8)),this.responseAsString}static get __name__(){return"haxe.http.HttpBase"}get __class__(){return Me}};Z.prototype.url=null;Z.prototype.responseBytes=null;Z.prototype.responseAsString=null;Z.prototype.postData=null;Z.prototype.postBytes=null;Z.prototype.headers=null;Z.prototype.params=null;Z.prototype.emptyOnData=null;var hr=i.$global,Ee=i.global("$hxClasses")["haxe.iterators.MapKeyValueIterator"]=class Ue extends i.inherits(){[i.new](e){this.map=e,this.keys=e.keys()}hasNext(){return this.keys.hasNext()}next(){let e=this.keys.next();return{value:this.map.get(e),key:e}}static get __name__(){return"haxe.iterators.MapKeyValueIterator"}get __class__(){return Ue}};Ee.prototype.map=null;Ee.prototype.keys=null;var yr=i.$global,Te=function(){};Te.__isInterface__=!0;var xr=i.$global,Ce=i.global("$hxClasses")["genes.util.EsMap"]=class be extends i.inherits(){[i.new](){this.inst=new Map}set(e,t){this.inst.set(e,t)}get(e){return this.inst.get(e)}remove(e){return this.inst.delete(e)}exists(e){return this.inst.has(e)}keys(){return be.adaptIterator(this.inst.keys())}iterator(){return be.adaptIterator(this.inst.values())}toString(){let e=[],t=be.adaptIterator(this.inst.keys());for(;t.hasNext();){let r=t.next();e.push(""+P.string(r)+" => "+P.string(this.inst.get(r)))}return"{"+e.join(", ")+"}"}clear(){this.inst.clear()}static adaptIterator(e){let t,r,n=function(){let s=e.next();t=s.value,r=s.done};return{hasNext:function(){return r==null&&n(),!r},next:function(){r==null&&n();let s=t;return n(),s}}}static get __name__(){return"genes.util.EsMap"}get __class__(){return be}};Ce.prototype.inst=null;var Sr=i.$global,Je=i.global("$hxClasses")["haxe.ds.StringMap"]=class Fe extends i.inherits(Ce){[i.new](){super[i.new]()}copy(){let e=new Fe;return e.inst=new Map(this.inst),e}keyValueIterator(){return new Ee(this)}static get __name__(){return"haxe.ds.StringMap"}static get __interfaces__(){return[Te]}static get __super__(){return Ce}get __class__(){return Fe}};var Dr=i.$global,B=i.global("$hxClasses").HxOverrides=class ze{static cca(e,t){let r=e.charCodeAt(t);if(r==r)return r}static substr(e,t,r){if(r==null)r=e.length;else if(r<0)if(t==0)r=e.length+r;else return"";return e.substr(t,r)}static now(){return Date.now()}static get __name__(){return"HxOverrides"}get __class__(){return ze}};typeof performance!="undefined"&&typeof performance.now=="function"&&(B.now=performance.now.bind(performance));var Ar=i.$global,oe=i.global("$hxClasses").StringTools=class Pe{static isSpace(e,t){let r=B.cca(e,t);return r>8&&r<14?!0:r==32}static ltrim(e){let t=e.length,r=0;for(;r<t&&Pe.isSpace(e,r);)++r;return r>0?B.substr(e,r,t-r):e}static rtrim(e){let t=e.length,r=0;for(;r<t&&Pe.isSpace(e,t-r-1);)++r;return r>0?B.substr(e,0,t-r):e}static replace(e,t,r){return e.split(t).join(r)}static get __name__(){return"StringTools"}get __class__(){return Pe}};var Vr=i.$global,We=i.global("$hxClasses").Lambda=class Xe{static exists(e,t){let r=i.getIterator(e);for(;r.hasNext();){let n=r.next();if(t(n))return!0}return!1}static get __name__(){return"Lambda"}get __class__(){return Xe}};var Ur=i.$global,we=i.global("$hxClasses").EReg=class Qe extends i.inherits(){[i.new](e,t){this.r=new RegExp(e,t.split("u").join(""))}match(e){return this.r.global&&(this.r.lastIndex=0),this.r.m=this.r.exec(e),this.r.s=e,this.r.m!=null}matched(e){if(this.r.m!=null&&e>=0&&e<this.r.m.length)return this.r.m[e];throw C.thrown("EReg::matched")}matchedPos(){if(this.r.m==null)throw C.thrown("No string matched");return{pos:this.r.m.index,len:this.r.m[0].length}}matchSub(e,t,r){if(r==null&&(r=-1),this.r.global){this.r.lastIndex=t,this.r.m=this.r.exec(r<0?e:B.substr(e,0,t+r));let n=this.r.m!=null;return n&&(this.r.s=e),n}else{let n=this.match(r<0?B.substr(e,t,null):B.substr(e,t,r));return n&&(this.r.s=e,this.r.m.index+=t),n}}map(e,t){let r=0,n="";do{if(r>=e.length)break;if(!this.matchSub(e,r)){n+=P.string(B.substr(e,r,null));break}let s=this.matchedPos();n+=P.string(B.substr(e,r,s.pos-r)),n+=P.string(t(this)),s.len==0?(n+=P.string(B.substr(e,s.pos,1)),r=s.pos+1):r=s.pos+s.len}while(this.r.global);return!this.r.global&&r>0&&r<e.length&&(n+=P.string(B.substr(e,r,null))),n}static get __name__(){return"EReg"}get __class__(){return Qe}};we.prototype.r=null;var rs=i.$global,ae=i.global("$hxClasses")["haxe.http.HttpJs"]=class Ke extends i.inherits(Z){[i.new](e){this.async=!0,this.withCredentials=!1,super[i.new](e)}request(e){this.responseAsString=null,this.responseBytes=null,this.responseHeaders=null;let t=this.req=De.createXMLHttpRequest(),r=this,n=function(c){if(t.readyState!=4)return;let g;try{g=t.status}catch{g=null}if(g==0&&De.get_supported()&&i.$global.location!=null){let m=i.$global.location.protocol.toLowerCase();new we("^(?:about|app|app-storage|.+-extension|file|res|widget):$","").match(m)&&(g=t.response!=null?200:404)}if(g==null&&(g=null),g!=null&&r.onStatus(g),g!=null&&g>=200&&g<400){r.req=null;let m=t.getAllResponseHeaders().split(`\r
|
|
5
|
+
`),y=[],v=0,b=m;for(;v<b.length;){let x=b[v];++v,x!=""&&y.push(x)}m=y;let E=new Je;r.responseHeaders=E;let h=0;for(;h<m.length;){let x=m[h];++h;let D=x.split(": "),$=D.shift(),H=D.length==1?D[0]:D.join(": ");H=oe.ltrim(oe.rtrim(H)),r.responseHeaders.inst.set($,H)}r.success(_e.ofData(t.response))}else if(g==null||g==0&&t.response==null)r.req=null,r.onError("Failed to connect or resolve host");else if(g==null){r.req=null;let m=t.response!=null?_e.ofData(t.response):null;r.responseBytes=m,r.onError("Http Error #"+t.status)}else switch(g){case 12007:r.req=null,r.onError("Unknown host");break;case 12029:r.req=null,r.onError("Failed to connect to host");break;default:r.req=null;let m=t.response!=null?_e.ofData(t.response):null;r.responseBytes=m,r.onError("Http Error #"+t.status)}};this.async&&(t.onreadystatechange=n);let s,l=this.postData,o=this.postBytes;if(l==null)if(o==null)s=null;else{let c=o;s=new Blob([c.b.bufferValue])}else o==null?s=l:s=null;if(s!=null)e=!0;else{let c=0,g=this.params;for(;c<g.length;){let m=g[c];++c,s==null?s="":s=(s==null?"null":P.string(s))+"&";let y=m.name,v=(s==null?"null":P.string(s))+encodeURIComponent(y)+"=",b=m.value;s=v+encodeURIComponent(b)}}try{if(e)t.open("POST",this.url,this.async);else if(s!=null){let c=this.url.split("?").length<=1;t.open("GET",this.url+(c?"?":"&")+(s==null?"null":P.string(s)),this.async),s=null}else t.open("GET",this.url,this.async);t.responseType="arraybuffer"}catch(c){let g=C.caught(c).unwrap();this.req=null,this.onError(g.toString());return}t.withCredentials=this.withCredentials,!We.exists(this.headers,function(c){return c.name=="Content-Type"})&&e&&this.postData==null&&t.setRequestHeader("Content-Type","application/x-www-form-urlencoded");let _=0,u=this.headers;for(;_<u.length;){let c=u[_];++_,t.setRequestHeader(c.name,c.value)}t.send(s),this.async||n(null)}static get __name__(){return"haxe.http.HttpJs"}static get __super__(){return Z}get __class__(){return Ke}};ae.prototype.async=null;ae.prototype.withCredentials=null;ae.prototype.responseHeaders=null;ae.prototype.req=null;var is=i.$global,Ae=i.global("$hxClasses").Type=class Ge{static createInstance(e,t){let r=Function.prototype.bind.apply(e,[null].concat(t));return new r}static get __name__(){return"Type"}get __class__(){return Ge}};var as=i.$global,R=i.global("$hxClasses").Reflect=class Ye{static field(e,t){try{return e[t]}catch{return null}}static getProperty(e,t){let r;if(e==null)return null;{let n;return e.__properties__?(r=e.__properties__["get_"+t],n=r):n=!1,n?e[r]():e[t]}}static setProperty(e,t,r){let n,s;e.__properties__?(n=e.__properties__["set_"+t],s=n):s=!1,s?e[n](r):e[t]=r}static fields(e){let t=[];if(e!=null){let n=Object.prototype.hasOwnProperty;for(var r in e)r!="__id__"&&r!="hx__closures__"&&n.call(e,r)&&t.push(r)}return t}static compare(e,t){return e==t?0:e>t?1:-1}static get __name__(){return"Reflect"}get __class__(){return Ye}};var fs=i.$global,Oe=i.global("$hxClasses")["internal.http.FetchHttp"]=class Ze extends i.inherits(ae){[i.new](e){this.responseStatus=0,super[i.new](e)}request(e){let t=i.$global,r=t.fetch,n=t.Headers,s=t.URLSearchParams;if(r==null){this.onError("Fetch API not found.");return}let l=Ae.createInstance(n,[]),o=0,_=this.headers;for(;o<_.length;){let b=_[o];++o,l.append(b.name,b.value)}let u=e?"POST":"GET",c=null;if(e)if(this.postData!=null)c=this.postData;else{c=Ae.createInstance(s,[]);let b=0,E=this.params;for(;b<E.length;){let h=E[b];++b,c.append(h.name,h.value)}}let g={method:u,headers:l,body:c},m=this,y=r(this.url,g).then(function(b){if(m.responseStatus=b.status,m.onStatus(b.status),b.ok)return b.text();throw C.thrown("HTTP Error: "+P.string(b.status))}).then(function(b){m.onData(b)}),v=R.field(y,"catch");v!=null&&v.apply(y,[function(b){m.onError(P.string(b))}])}static get __name__(){return"internal.http.FetchHttp"}static get __super__(){return ae}get __class__(){return Ze}};Oe.prototype.responseStatus=null;var bs=i.$global,me=function(){};me.__isInterface__=!0;var ge=function(){};ge.__isInterface__=!0;var pe=function(){};pe.__isInterface__=!0;var Ss=i.$global,a=i.global("$hxClasses")["internal.RecoBackendV2"]=class d extends i.inherits(){[i.new](){}static _requestUri(){return(d._safe_request?"https://":"http://")+d._req_domain+"/api/"+d._environment+"/recommendations/requests"}static noConsentBody(){return{device_id:"no-consent",user_group:"no-consent",version:"no-consent"}}static buildRequestBody(e){let t={lists:e,page_type:d._page_visit!=null?d._page_visit:d._page_view,channel:"www-desktop"};if(d._history.length>0&&(t.histories=d._buildHistories()),d._consent==0){let s=d.noConsentBody(),l=0,o=R.fields(s);for(;l<o.length;){let _=o[l];++l,t[_]=R.field(s,_)}}else d._user_id!=null?t.user_id=d._user_id:t.device_id=d._device_id;let r=0,n=d._others;for(;r<n.length;){let s=n[r];++r,t[s.key]=s.value}return t}static _buildHistories(){let e=[],t=0,r=d._history;for(;t<r.length;){let n=r[t];++t,e.push({id:n})}return{pageviews:e}}static requestsToLists(e){let t=[],r="",n="",s="",l=0,o=function(u,c,g){r=u,n=c,s=g,l=0},_=0;for(;_<e.length;){let u=e[_];if(++_,r==""){let c;if(u.filters.length>0){let m=u.filters[0];c=m!=null?m.key:null}else c="";let g;if(u.filters.length>0){let m=u.filters[0];g=m!=null?m.value:null}else g="";o(u.list,c,g),l+=1;continue}else{let c,g;if(r==u.list){let m=u.filters[0],y=m!=null?m.key:null;g=n!=(y!=null?y:"")}else g=!0;if(g)c=!0;else{let m=u.filters[0],y=m!=null?m.value:null;c=s!=(y!=null?y:"")}if(c){let m={limit:l,list_name:r,list_size:l};n!=""&&(s instanceof Array||(s=[s]),m[n]=s),t.push(m);let y=u.filters[0],v=u.filters[0];o(u.list,y!=null?y.key:null,v!=null?v.value:null)}}l+=1}if(l!=0){let u={limit:l,list_name:r,list_size:l};n!=""&&(s instanceof Array||(s=[s]),u[n]=s),t.push(u)}return t}static _requestRecos(e){let t=null,r=new Promise(function(m,y){t=m}),n=r;n._resolve=t,n._isFinished=!1,n._result=null;let s=r,l=null,o=new Oe(d._requestUri());o.setHeader("Content-Type","application/json");let _=d.buildRequestBody(e),u=JSON.stringify(_);o.setPostData(u),o.onError=function(m){throw C.thrown("HTTP Request Error: "+m)};try{o.request(!0)}catch(m){let y=C.caught(m).unwrap();throw C.thrown("Failed to execute synchronous request: "+P.string(y)+u)}let c=function(m){let y=JSON.parse(m),v=he.fromRequestData(y),b=s;b._isFinished||(b._result=v,b._isFinished=!0,b._resolve(v))},g=o.get_responseData();return g!=null?c(g):o.onData=c,s}static getOrder(e,t,r){let n={list_name:e,limit:r.length,list_size:r.length},s={};R.setProperty(s,t,r),R.setProperty(n,"order",s);let l=null,o=new Promise(function(g,m){l=g}),_=o;_._resolve=l,_._isFinished=!1,_._result=null;let u=o,c;return d.getRawRecommendations([n]).then(function(g){let m=[],y=g.lists()[0].items;if(y instanceof Array){let b=0,E=y;for(;b<E.length;){let h=E[b];++b;let x=h.get("categories");x!=null&&m.push(x)}}let v=u;v._isFinished||(v._result=m,v._isFinished=!0,v._resolve(m))}),u}static getRawRecommendations(e){return d._requestRecos(e)}static addHistories(e){d._history=d._history.concat(e)}static setOthers(e,t){let r=0,n=d._others;for(;r<n.length;){let s=n[r];if(++r,s.key==e){s.value=t;return}}d._others.push({key:e,value:t})}static setConsent(e){e>2&&(e=2),d._consent=e}static setChannel(e){d._channel=e}static setPageVisit(e){d._page_visit=e}static setEnvironment(e){d._environment=e}static setDeviceId(e){d._device_id=e}static setUserId(e){d._user_id=e}static setRequestDomain(e){d._req_domain=e}static setPageView(e){d._page_view=e}static setSafeRequest(e){d._safe_request=e}static setContextItem(e){d.setOthers("context_item",e)}static setContextItemType(e){d.setOthers("context_item_type",e)}static getRequestDomain(){return d._req_domain}static getEnvironment(){return d._environment}static getPageVisit(){return d._page_visit}static getUserId(){return d._user_id}static getDeviceId(){return d._device_id}static getPageView(){return d._page_view}static getConsent(){return d._consent}static getChannel(){return d._channel}static getOthers(e){let t=0,r=d._others;for(;t<r.length;){let n=r[t];if(++t,e==n.key)return n.value}return null}static getContextItem(){return d.getOthers("context_item")}static getContextItemType(){return d.getOthers("context_item_type")}static get __name__(){return"internal.RecoBackendV2"}get __class__(){return d}};a._environment=null;a._device_id="no-consent";a._user_id=null;a._consent=2;a._req_domain="europe-west1.froomle.com";a._page_visit=null;a._page_view=null;a._channel="www-desktop";a._safe_request=!0;a._history=[];a._others=[];var he=i.global("$hxClasses")["internal._RecommendationsInternal"]=class Be extends i.inherits(){[i.new](e,t,r,n,s){this.request_id=t,this.user_group=r,this.device_id=e,this.user_id=n,this._lists=s}items(){let e=[],t=0,r=this._lists;for(;t<r.length;){let n=r[t];++t;let s=0,l=n.items;for(;s<l.length;){let o=l[s];++s,e.push(o)}}return e}lists(){return this._lists}getItemsByListName(e){let t=0,r=this._lists;for(;t<r.length;){let n=r[t];if(++t,n.list_name==e)return n}return null}toJson(){let e={request_id:this.request_id,user_group:this.user_group,user_id:this.user_id,device_id:this.device_id,lists:[]},t=0,r=this._lists;for(;t<r.length;){let n=r[t];++t;let s={limit:n.limit,list_key:n.list_key,list_name:n.list_name,list_size:n.list_size,items:[]},l=0,o=n.items;for(;l<o.length;){let _=o[l];++l,s.items.push(ye.__cast(_,re).getData())}e.lists.push(s)}return JSON.stringify(e)}static fromRequestData(e){let t=R.getProperty(e,"lists"),r=[],n=0;for(;n<t.length;){let s=t[n];++n;let l=R.getProperty(s,"items"),o=[],_=0;for(;_<l.length;){let c=l[_];++_,R.setProperty(c,"request_id",R.getProperty(e,"request_id")),o.push(new re(c))}let u=new ue({limit:R.getProperty(s,"limit"),list_key:R.getProperty(s,"list_key"),list_name:R.getProperty(s,"list_name"),list_size:R.getProperty(s,"list_size"),items:o,request_id:R.getProperty(e,"request_id")});r.push(u)}return new Be(R.getProperty(e,"device_id"),R.getProperty(e,"request_id"),R.getProperty(e,"user_group"),R.getProperty(e,"user_id"),r)}static get __name__(){return"internal._RecommendationsInternal"}static get __interfaces__(){return[me]}get __class__(){return Be}};he.prototype.request_id=null;he.prototype.user_group=null;he.prototype.user_id=null;he.prototype.device_id=null;he.prototype._lists=null;var ue=i.global("$hxClasses")["internal._RecommendationsListInternal"]=class et extends i.inherits(){[i.new](e){this.items=e.items,this.limit=e.limit,this.list_key=e.list_key,this.list_name=e.list_name,this.list_size=e.list_size,this.request_id=e.request_id}static get __name__(){return"internal._RecommendationsListInternal"}static get __interfaces__(){return[ge]}get __class__(){return et}};ue.prototype.limit=null;ue.prototype.list_key=null;ue.prototype.list_name=null;ue.prototype.list_size=null;ue.prototype.items=null;ue.prototype.request_id=null;var re=i.global("$hxClasses")["internal._RecommendationItemInternal"]=class tt extends i.inherits(){[i.new](e){this.Id=R.getProperty(e,"item_id"),this.RequestId=R.getProperty(e,"request_id"),this.UserGroup=R.getProperty(e,"user_group"),this._data=e}getData(){return this._data}get(e){return this._data[e]}toJson(){return JSON.stringify(this._data)}static get __name__(){return"internal._RecommendationItemInternal"}static get __interfaces__(){return[pe]}get __class__(){return tt}};re.prototype.Id=null;re.prototype.RequestId=null;re.prototype.UserGroup=null;re.prototype._data=null;var Ds=i.$global,Ve=function(){};Ve.__isInterface__=!0;var As=i.$global,ve=i.global("$hxClasses")["internal.js.JSFroomleDomTree"]=class Se extends i.inherits(){[i.new](){}getRoot(){return this.root}createElement(e){return this.root.ownerDocument.createElement(e)}toString(){return this.root.ownerDocument.documentElement.outerHTML}static fromHTML(e){let r=new DOMParser().parseFromString(e,"text/html"),n=new Se;return n.root=r.documentElement,n}static fromDocument(e){let t=new Se;return t.root=e.documentElement,t}static get __name__(){return"internal.js.JSFroomleDomTree"}static get __interfaces__(){return[Ve]}get __class__(){return Se}};ve.prototype.root=null;var Js=i.$global,ce=i.global("$hxClasses")["internal.domHandler.DomDomDom"]=class se extends i.inherits(){[i.new](){}static _fillRecoTargets(e){let t=null,r=new Promise(function(p,w){t=p}),n=r;n._resolve=t,n._isFinished=!1,n._result=null;let s=r;if(e==null){let p=s;return p._isFinished||(p._result=!1,p._isFinished=!0,p._resolve(!1)),s}let l=[],o=new Array,_=e.querySelectorAll("*"),u=0,c=_.length;for(;u<c;){let p=u++,w=_.item(p);w instanceof HTMLElement&&o.push(w)}let g=o,m=0;for(;m<g.length;){let p=g[m];++m;let w=0,S=new Array,q=0,T=p.attributes;for(;q<T.length;){let O=T[q];++q,S.push({name:O.name,value:O.value})}let F=S;for(;w<F.length;){let O=F[w];++w,O.name=="data-froomle-reco"&&l.push(p)}}let y=[],v=0;for(;v<l.length;){let p=l[v];++v,p.getAttribute("data-froomle-request-id")==null&&(p.getAttribute("data-froomle-id")==null||p.getAttribute("data-froomle-id")=="")&&y.push(p)}if(y.length<1){let p=null,w=new Promise(function(q,T){p=q}),S=w;return S._resolve=p,S._isFinished=!1,S._result=null,w}let b=[],E=[],h="",x="",D="",$=[],H=[],J=function(p,w){if(p.length!=w.length)return!1;let S=new Array(p.length),q=0,T=p.length;for(;q<T;){let I=q++;S[I]=JSON.stringify(p[I])}let F=S,O=new Array(w.length),M=0,K=w.length;for(;M<K;){let I=M++;O[I]=JSON.stringify(w[I])}let z=O;F.sort(R.compare),z.sort(R.compare);let A=0,W=F.length;for(;A<W;){let I=A++;if(F[I]!=z[I])return!1}return!0},N=function(){let p={list_name:h,list_size:$.length,limit:$.length};x!=null&&R.setProperty(p,x,[D]);let w=0;for(;w<H.length;){let S=H[w];++w,R.setProperty(p,S.key,S.value)}b.push(p),E.push($)},ie=function(p,w,S,q,T){h=p,x=w,D=S,$=[T],H=q},k=0;for(;k<y.length;){let p=y[k];++k;let w=function(O){let M=0,K=new Array,z=0,A=O.attributes;for(;z<A.length;){let I=A[z];++z,K.push({name:I.name,value:I.value})}let W=K;for(;M<W.length;){let I=W[M];if(++M,I.name.startsWith("data-froomle-reco-filter-")){let L=B.substr(I.name,25,null),G=I.value;return{key:L,value:G}}}return{key:null,value:null}},S=function(O){let M=[],K=0,z=new Array,A=0,W=O.attributes;for(;A<W.length;){let L=W[A];++A,z.push({name:L.name,value:L.value})}let I=z;for(;K<I.length;){let L=I[K];if(++K,L.name.startsWith("data-froomle-variable-")){let G=B.substr(L.name,22,null),le=L.value;M.push({key:G,value:le})}}return M},q=p.getAttribute("data-froomle-reco"),T=w(p),F=S(p);if(h==""){ie(q,T.key,T.value,F,p);continue}else if(q==h&&T.key==x&&T.value==D&&J(H,F)){$.push(p);continue}else{N(),ie(q,T.key,T.value,F,p);continue}}h!=""&&N();let Q;if(a.getPageVisit()==null){let p=s;return p._isFinished||(p._result=!1,p._isFinished=!0,p._resolve(!1)),s}else if(a.getEnvironment()==null){let p=s;return p._isFinished||(p._result=!1,p._isFinished=!0,p._resolve(!1)),s}else try{Q=a.getRawRecommendations(b)}catch{let w=s;return w._isFinished||(w._result=!1,w._isFinished=!0,w._resolve(!1)),s}return Q.then(function(p){let w=p.lists(),S=w.length,q=0,T=S;for(;q<T;){let O=q++,M=w[O],K=M.items.length!=E[O].length,z=M.items.length,A=0,W=z;for(;A<W;){let I=A++,L=M.items[I],G=E[O][I];se._fillParameters(G,L,p.request_id)}}let F=s;F._isFinished||(F._result=!0,F._isFinished=!0,F._resolve(!0))}),s}static getAttrByPath(e,t,r){r==null&&(r="fgh");try{t=new we("\\\\[(\\\\w+)\\\\]","g").map(t,function(u){return"."+u.matched(1)}),t=oe.replace(t,"[","."),t=oe.replace(t,"]",""),B.cca(t,0)==46&&(t=B.substr(t,1,null));let s=t.split("."),l=e.get(s[0]),o=1,_=s.length;for(;o<_;){let u=o++;if(l==null)return null;l instanceof Array&&P.parseInt(s[u])!=null?l=l[P.parseInt(s[u])]:l=R.field(l,s[u])}return l}catch{return r}}static _buildHistories(e){let t=[],r=new Array,n=e.querySelectorAll("[data-froomle-id]"),s=0,l=n.length;for(;s<l;){let u=s++,c=n.item(u);c instanceof HTMLElement&&r.push(c)}let o=r,_=0;for(;_<o.length;){let u=o[_];++_,t.push(u.getAttribute("data-froomle-id"))}a.addHistories(t)}static fillParam(e,t,r,n,s){s==null&&(s="");try{let l=se.getAttrByPath(n,r,s);if(t=="inner"){e.textContent=l;let o=e.textContent}else e.setAttribute(t,l)}catch{}}static _fillParameters(e,t,r){e.setAttribute("data-froomle-id",t.get("item_id")),e.setAttribute("data-froomle-request-id",r);let n=new Array,s=e.querySelectorAll("*"),l=0,o=s.length;for(;l<o;){let c=l++,g=s.item(c);g instanceof HTMLElement&&n.push(g)}let _=n,u=0;for(;u<_.length;){let c=_[u];++u;let g=0,m=new Array,y=0,v=c.attributes;for(;y<v.length;){let E=v[y];++y,m.push({name:E.name,value:E.value})}let b=m;for(;g<b.length;){let E=b[g];if(++g,E.name.startsWith("data-froomle-param-")){let h=oe.replace(E.name,"data-froomle-param-",""),x=E.value;se.fillParam(c,h,x,t)}}}}static _orderElements(e){let t=function(h,x,D){let $=[],H=new Array,J=0,N=h.childNodes;for(;J<N.length;){let w=N[J];++J,H.push(w)}let ie=H,k=0;for(;k<ie.length;){let w=ie[k];++k;try{if(w.getAttribute("data-froomle-ordervalue")!=null){$.push(w);let q=e.createElement("span");q.setAttribute("data-froomle-tmp-node","tmp"),h.replaceChild(q,w)}}catch{}}let Q=[],p=0;for(;p<$.length;){let w=$[p];++p,Q.push(w.getAttribute("data-froomle-ordervalue"))}return{el:h,key:x,values:Q,orderChildren:$,list_name:D}},r=null,n=new Promise(function(h,x){r=h}),s=n;s._resolve=r,s._isFinished=!1,s._result=null;let l=n,o=e.getRoot(),_=new Array,u=o.querySelectorAll("*"),c=0,g=u.length;for(;c<g;){let h=c++,x=u.item(h);x instanceof HTMLElement&&_.push(x)}let m=_,y=[],v=0;for(;v<m.length;){let h=m[v];++v;let x=0,D=new Array,$=0,H=h.attributes;for(;$<H.length;){let N=H[$];++$,D.push({name:N.name,value:N.value})}let J=D;for(;x<J.length;){let N=J[x];++x,N.name.startsWith("data-froomle-order-")&&y.push(t(h,N.name.substring(19),N.value))}}if(y.length<1){let h=l;return h._isFinished||(h._result=!1,h._isFinished=!0,h._resolve(!1)),l}let b=[],E=0;for(;E<y.length;){let h=y[E];++E;let x={list_name:h.list_name,limit:h.values.length,list_size:h.values.length},D={};R.setProperty(D,h.key,h.values),R.setProperty(x,"order",D),b.push(x)}if(a.getPageVisit()==null){let h=l;return h._isFinished||(h._result=!1,h._isFinished=!0,h._resolve(!1)),l}else if(a.getEnvironment()==null){let h=l;return h._isFinished||(h._result=!1,h._isFinished=!0,h._resolve(!1)),l}try{a.getRawRecommendations(b).then(function(h){let x=h.lists(),D=x.length,$=0,H=D;for(;$<H;){let N=$++,ie=x[N],k=y[N];k.el.setAttribute("data-froomle-request-id",h.request_id);let Q=new Array,p=0,w=ie.items;for(;p<w.length;){let A=w[p];++p;let W=A.get(k.key),I=A.get(k.key),L=k.values.length,G=0,le=L;for(;G<le;){let ne=G++,fe=k.values[ne];if(W==fe){let qt=k.orderChildren.length,_t=k.orderChildren[ne];Q.push(_t),k.orderChildren.splice(ne,1),k.values.splice(ne,1);break}}}let S=Q.length,q=k.el,T=new Array,F=0,O=q.childNodes;for(;F<O.length;){let A=O[F];++F,T.push(A)}let M=T.length,K=0,z=M;for(;K<z;){let A=K++,W=k.el,I=new Array,L=0,G=W.childNodes;for(;L<G.length;){let fe=G[L];++L,I.push(fe)}let le=I[A],ne;if(le instanceof HTMLElement?ne=le.hasAttribute("data-froomle-tmp-node"):ne=!1,ne){k.el.replaceChild(Q[0],le),Q.splice(0,1);let fe=Q.length;if(Q.length==0)break}}}let J=l;J._isFinished||(J._result=!0,J._isFinished=!0,J._resolve(!0))})}catch{let x=l;x._isFinished||(x._result=!1,x._isFinished=!0,x._resolve(!1))}return l}static domInit(e){se._orderElements(e).then(function(t){se._buildHistories(e.getRoot()),se._fillRecoTargets(e.getRoot())})}static fillElementRecos(e){se._fillRecoTargets(e)}static runFromHtml(e){if(e=="")return"";let t;try{let n=new DOMParser().parseFromString(e,"text/html"),s=new ve;s.root=n.documentElement,t=s}catch{return e}return se.domInit(t),t.toString()}static get __name__(){return"internal.domHandler.DomDomDom"}get __class__(){return se}};var Ks=i.$global,V=i.global("$hxClasses").FroomleSdk=class X{static register(){X.registered||X._env_set&&(!X._page_visit_set&&!X._page_view_set||(X.registered=!0))}static buildScriptTag(){let e='<script src="https://cdn.jsdelivr.net/npm/@froomle/frontend-sdk@0.0.11/dist/froomle.global.js" data-froomle-env="'+a.getEnvironment()+'" ',t=a.getPageVisit();t!=null&&(e+='data-froomle-page-visit="'+t+'" ');let r=a.getPageView();r!=null&&(e+='data-froomle-page-view="'+r+'" ');let n=a.getDeviceId();n!=null&&(e+='data-froomle-device-id="'+n+'" ');let s=a.getUserId();s!=null&&(e+='data-froomle-user-id="'+s+'" ');let l=a.getConsent();l>0&&(e+='data-froomle-consent="'+l+'" ');let o=a.getRequestDomain();return o!=null&&(e+='data-froomle-request-domain="'+o+'" '),e+="></script>",e}static setEnvironment(e){a.setEnvironment(e),X._env_set=!0,X.register()}static setDeviceId(e){a.setDeviceId(e)}static setUserId(e){a.setUserId(e)}static setConsent(e){a.setConsent(e)}static setPageView(e){a.setPageView(e),X._page_view_set=!0,X.register()}static setPageVisit(e){a.setPageVisit(e),X._page_visit_set=!0,X.register()}static setRequestDomain(e){a.setRequestDomain(e)}static setSafeRequest(e){a.setSafeRequest(e)}static setContextItem(e){a.setContextItem(e)}static setContextItemType(e){a.setContextItemType(e)}static setCustomVariable(e,t){a.setOthers(e,t)}static getUserId(){return a.getUserId()}static getDeviceId(){return a.getDeviceId()}static getEnvironment(){return a.getEnvironment()}static getPageView(){return a.getPageView()}static getPageVisit(){return a.getPageVisit()}static getConsent(){return a.getConsent()}static getRecommendations(e){return a.getRawRecommendations(e)}static getChannel(){return a.getChannel()}static getVersion(){return"0.0.11"}static runFromHtml(e){return ce.runFromHtml(e)}static get __name__(){return"FroomleSdk"}get __class__(){return X}};V._env_set=!1;V._page_visit_set=!1;V._page_view_set=!1;V.registered=!1;var Zs=i.$global;function rt(){return"https://"+a.getRequestDomain()+"/api/"+a.getEnvironment()+"/events"}function st(f,e,t="article",r){let n={event_type:t,page_type:a.getPageVisit(),action_item:f,action_item_type:e,channel:"www-desktop"};for(let s in r)n[s]=r[s];try{fetch(rt(),{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({events:[n]})})}catch{}}var U=class U{static generateBody(){let e=[];for(let t of U.impressionQueue){let r={event_type:"impression",page_type:a.getPageVisit(),action_item:t.getAttribute("data-froomle-id"),action_item_type:"article",channel:"www-desktop"};a.getUserId()?r.user_id=a.getUserId():r.device_id=a.getDeviceId();let n=t.getAttribute("data-froomle-reco");if(n){r.list_name=n;let s=t.getAttribute("data-froomle-request-id");if(!s)throw console.error("element need reco but doesnt have request id registered yet"),new Error("element need reco but doesnt have request id registered");r.request_id=s}e.push(r)}return U.impressionQueue=[],JSON.stringify({events:e})}static sendImpressions(){U.impressionQueue.length!==0&&fetch(rt(),{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:U.generateBody()})}static getViewPortRect(){let e=window.innerWidth||document.documentElement.clientWidth,t=window.innerHeight||document.documentElement.clientHeight;return{left:0,top:0,x:0,y:0,toJSON(){},right:e,bottom:t,width:e,height:t}}static intersectsWithViewPortRect(e){let t=e.getBoundingClientRect(),r=U.getViewPortRect();return t.right>r.left&&t.left<r.right&&t.bottom>r.top&&t.top<r.bottom}static addIntersectionImpressionListener(e){U.observer.observe(e)}static processDocument(){if(a.getConsent()!=0){for(let e of document.querySelectorAll("[data-froomle-id]"))U.intersectsWithViewPortRect(e)?U.impressionQueue.push(e):U.addIntersectionImpressionListener(e);U.sendImpressions()}}};U.impressionQueue=[],U.observer=null;var ee=U;typeof document!="undefined"&&(ee.observer=new IntersectionObserver((f,e)=>{f.forEach(t=>{t.isIntersecting&&(ee.impressionQueue.push(t.target),ee.observer.unobserve(t.target))}),ee.impressionQueue.length>0&&ee.sendImpressions()}));var xe=class f{static uri(){return"https://"+a.getRequestDomain()+"/api/"+a.getEnvironment()+"/events"}static generateBody(){let e={event_type:"page_visit",page_type:a.getPageVisit(),channel:"www-desktop"};return a.getUserId()?e.user_id=a.getUserId():e.device_id=a.getDeviceId(),JSON.stringify(e)}static sendPageVisit(){a.getPageVisit()&&a.getDeviceId()!="no-consent"&&fetch(f.uri(),{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:f.generateBody()})}};var Re=class f{static uri(){return"https://"+a.getRequestDomain()+"/api/"+a.getEnvironment()+"/events"}static generateBody(){let e={event_type:"detail_pageview",page_type:"article_detail",action_item:a.getPageView(),action_item_type:"article",channel:"www-desktop"};return a.getUserId()?e.user_id=a.getUserId():e.device_id=a.getDeviceId(),JSON.stringify(e)}static sendPageView(){a.getPageView()&&a.getDeviceId()!="no-consent"&&fetch(f.uri(),{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:f.generateBody()})}};var yt=ve,nt=V.setEnvironment,it=V.setPageVisit,lt=V.setConsent,ot=V.setUserId,at=V.setDeviceId,ut=V.setRequestDomain,ct=V.setSafeRequest,bt=V.setContextItem,wt=V.setContextItemType,vt=V.setCustomVariable,xt=a.addHistories,Rt=V.setPageView;typeof window!="undefined"&&(window.setFroomleConsent=lt);var It=V.getRecommendations;if(!globalThis.froomleInitialized&&(globalThis.froomleInitialized=!0,typeof document!="undefined")){let f=document.currentScript;if(f){let e=f.getAttribute("data-froomle-device-id"),t=f.getAttribute("data-froomle-user-id"),r=f.getAttribute("data-froomle-env"),n=f.getAttribute("data-froomle-page-visit"),s=f.getAttribute("data-froomle-requestdomain"),l=f.getAttribute("data-froomle-page-view"),o=f.getAttribute("data-froomle-safe-request");nt(r),l&&Rt(l),n&&it(n),e&&at(e),t&&ot(t),s&&ut(s),o&&ct(o!=="false")}document.addEventListener("DOMContentLoaded",()=>{console.log("froomle loads dom"),ce.domInit(yt.fromDocument(document)),ee.processDocument(),xe.sendPageVisit(),Re.sendPageView();let e=new MutationObserver(t=>{for(let r of t)if(r.type==="childList"&&ee.processElement(r.target),r.type==="attributes")if(r.attributeName==="data-froomle-reco"){let n=r.target.getAttribute("data-froomle-request-id");(!n||n==="")&&ce.fillElementRecos(r.target)}else r.attributeName==="data-froomle-request-id"&&ce.fillElementRecos(r.target)})})}function Et(){let f,e;return{promise:new Promise((r,n)=>{f=r,e=n}),resolve:f,reject:e}}var qe=[];async function Ct(){let f=qe.map(r=>r.req),e=a.requestsToLists(f),t=(await a.getRawRecommendations(e)).lists().reduce((r,n)=>[...r,...n.items],[]);qe.forEach((r,n)=>{t[n]?r.deferred.resolve(t[n]):r.deferred.reject(new Error("No recommendation available"))}),qe.length=0}function Pt(f){let e,t,n={promise:new Promise((s,l)=>{e=s,t=l}),resolve:e,reject:t};return qe.push({deferred:n,req:f}),n}function St(f){let t=Pt(f).promise,r=Et(),n=function(l,o){return t.then(_=>(s.completeTarget=_,l?l(_):_),_=>o?o(_):Promise.reject(_))},s=new Proxy(new re({item_id:"",request_id:"",user_group:""}),{get(l,o,_){if(o==="then")return n;if(o==="get"){let u=Reflect.get(l,o,_);return function(...c){return u.apply(this,c)}}return typeof o!="string"?Reflect.get(l,o,_):l.get(o)?l.get(o):""},set(l,o,_,u){return o==="completeTarget"?(Object.assign(l,_),!0):Reflect.set(l,o,_,u)},has(l,o){return l.get(o)!==void 0}});return s}export{me as a,ge as b,pe as c,a as d,st as e,nt as f,it as g,lt as h,ot as i,at as j,ut as k,ct as l,bt as m,wt as n,vt as o,xt as p,It as q,Ct as r,St as s};
|